Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/amd64/stand/prekern Clarify.



details:   https://anonhg.NetBSD.org/src/rev/9633ee406cec
branches:  trunk
changeset: 1009918:9633ee406cec
user:      maxv <maxv%NetBSD.org@localhost>
date:      Thu May 07 17:58:26 2020 +0000

description:
Clarify.

diffstat:

 sys/arch/amd64/stand/prekern/elf.c |  77 ++++++++++++++++++++++---------------
 sys/arch/amd64/stand/prekern/mm.c  |  39 ++++++++++--------
 2 files changed, 66 insertions(+), 50 deletions(-)

diffs (209 lines):

diff -r 3c5d31e0caa6 -r 9633ee406cec sys/arch/amd64/stand/prekern/elf.c
--- a/sys/arch/amd64/stand/prekern/elf.c        Thu May 07 17:10:02 2020 +0000
+++ b/sys/arch/amd64/stand/prekern/elf.c        Thu May 07 17:58:26 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: elf.c,v 1.20 2020/05/07 16:49:59 maxv Exp $    */
+/*     $NetBSD: elf.c,v 1.21 2020/05/07 17:58:26 maxv Exp $    */
 
 /*
  * Copyright (c) 2017-2020 The NetBSD Foundation, Inc. All rights reserved.
@@ -300,6 +300,37 @@
 }
 
 void
+elf_fixup_boot(vaddr_t bootva, paddr_t bootpa)
+{
+       const paddr_t basepa = kernpa_start;
+       const vaddr_t headva = (vaddr_t)eif.ehdr;
+       size_t i, offboot;
+
+       /*
+        * Fix up the 'sh_offset' field of the REL/RELA/SYM/STR sections, which
+        * are all in the "boot" region.
+        */
+       for (i = 0; i < eif.ehdr->e_shnum; i++) {
+               if (eif.shdr[i].sh_type != SHT_STRTAB &&
+                   eif.shdr[i].sh_type != SHT_REL &&
+                   eif.shdr[i].sh_type != SHT_RELA &&
+                   eif.shdr[i].sh_type != SHT_SYMTAB) {
+                       continue;
+               }
+               if (eif.shdr[i].sh_offset == 0) {
+                       /* The bootloader dropped it. */
+                       continue;
+               }
+
+               /* Offset of the section within the boot region. */
+               offboot = basepa + eif.shdr[i].sh_offset - bootpa;
+
+               /* We want (headva + sh_offset) to be the VA of the region. */
+               eif.shdr[i].sh_offset = (bootva + offboot - headva);
+       }
+}
+
+void
 elf_map_sections(void)
 {
        const paddr_t basepa = kernpa_start;
@@ -333,45 +364,27 @@
 
                secva = mm_map_segment(segtype, secpa, secsz, secalign);
 
-               /* We want (headva + sh_offset) to be the VA of the section. */
+               /*
+                * Fix up the 'sh_offset' field of the NOBITS/PROGBITS sections.
+                * We want (headva + sh_offset) to be the VA of the section.
+                */
                ASSERT(secva > headva);
                shdr->sh_offset = secva - headva;
        }
 }
 
 void
-elf_build_boot(vaddr_t bootva, paddr_t bootpa)
+elf_build_info(void)
 {
-       const paddr_t basepa = kernpa_start;
-       const vaddr_t headva = (vaddr_t)eif.ehdr;
-       size_t i, j, offboot;
-
-       for (i = 0; i < eif.ehdr->e_shnum; i++) {
-               if (eif.shdr[i].sh_type != SHT_STRTAB &&
-                   eif.shdr[i].sh_type != SHT_REL &&
-                   eif.shdr[i].sh_type != SHT_RELA &&
-                   eif.shdr[i].sh_type != SHT_SYMTAB) {
-                       continue;
-               }
-               if (eif.shdr[i].sh_offset == 0) {
-                       /* hasn't been loaded */
-                       continue;
-               }
-
-               /* Offset of the section within the boot region. */
-               offboot = basepa + eif.shdr[i].sh_offset - bootpa;
-
-               /* We want (headva + sh_offset) to be the VA of the region. */
-               eif.shdr[i].sh_offset = (bootva + offboot - headva);
-       }
+       size_t i, j;
 
        /* Locate the section names */
        j = eif.ehdr->e_shstrndx;
        if (j == SHN_UNDEF) {
-               fatal("elf_build_boot: shstrtab not found");
+               fatal("elf_build_info: shstrtab not found");
        }
        if (j >= eif.ehdr->e_shnum) {
-               fatal("elf_build_boot: wrong shstrtab index");
+               fatal("elf_build_info: wrong shstrtab index");
        }
        eif.shstrtab = (char *)((uint8_t *)eif.ehdr + eif.shdr[j].sh_offset);
        eif.shstrsz = eif.shdr[j].sh_size;
@@ -382,10 +395,10 @@
                        break;
        }
        if (i == eif.ehdr->e_shnum) {
-               fatal("elf_build_boot: symtab not found");
+               fatal("elf_build_info: symtab not found");
        }
        if (eif.shdr[i].sh_offset == 0) {
-               fatal("elf_build_boot: symtab not loaded");
+               fatal("elf_build_info: symtab not loaded");
        }
        eif.symtab = (Elf_Sym *)((uint8_t *)eif.ehdr + eif.shdr[i].sh_offset);
        eif.symcnt = eif.shdr[i].sh_size / sizeof(Elf_Sym);
@@ -393,13 +406,13 @@
        /* Also locate the string table */
        j = eif.shdr[i].sh_link;
        if (j == SHN_UNDEF || j >= eif.ehdr->e_shnum) {
-               fatal("elf_build_boot: wrong strtab index");
+               fatal("elf_build_info: wrong strtab index");
        }
        if (eif.shdr[j].sh_type != SHT_STRTAB) {
-               fatal("elf_build_boot: wrong strtab type");
+               fatal("elf_build_info: wrong strtab type");
        }
        if (eif.shdr[j].sh_offset == 0) {
-               fatal("elf_build_boot: strtab not loaded");
+               fatal("elf_build_info: strtab not loaded");
        }
        eif.strtab = (char *)((uint8_t *)eif.ehdr + eif.shdr[j].sh_offset);
        eif.strsz = eif.shdr[j].sh_size;
diff -r 3c5d31e0caa6 -r 9633ee406cec sys/arch/amd64/stand/prekern/mm.c
--- a/sys/arch/amd64/stand/prekern/mm.c Thu May 07 17:10:02 2020 +0000
+++ b/sys/arch/amd64/stand/prekern/mm.c Thu May 07 17:58:26 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mm.c,v 1.26 2020/05/07 17:10:02 maxv Exp $     */
+/*     $NetBSD: mm.c,v 1.27 2020/05/07 17:58:26 maxv Exp $     */
 
 /*
  * Copyright (c) 2017-2020 The NetBSD Foundation, Inc. All rights reserved.
@@ -417,8 +417,8 @@
        /* The "boot" region begins right after the kernel segments */
        bootpa = bootspace_get_kern_segs_end_pa();
 
-       /* The prekern consumed some memory up until pa_avail, this covers
-        * SYM+REL and EXTRA */
+       /* The prekern consumed some EXTRA memory up until pa_avail, this
+        * covers REL/RELA/SYM/STR and EXTRA */
        size = (pa_avail - bootpa);
        npages = size / PAGE_SIZE;
 
@@ -428,11 +428,10 @@
                    randva + i * PAGE_SIZE, MM_PROT_READ|MM_PROT_WRITE);
        }
 
-       /* At this point both "head" and "boot" are mapped, so we can build
-        * the ELF info */
-       elf_build_boot(randva, bootpa);
+       /* Fix up the ELF sections located in the "boot" region */
+       elf_fixup_boot(randva, bootpa);
 
-       /* Map the ISA I/O MEM right after EXTRA */
+       /* Map the ISA I/O MEM right after EXTRA, in pure VA */
        iom_base = randva + npages * PAGE_SIZE;
        npages = IOM_SIZE / PAGE_SIZE;
        for (i = 0; i < npages; i++) {
@@ -456,15 +455,15 @@
 
 /*
  * The bootloader has set up the following layout of physical memory:
- * +------------+-----------------+---------------+------------------+-------+
- * | ELF HEADER | SECTION HEADERS | KERN SECTIONS | SYM+REL SECTIONS | EXTRA |
- * +------------+-----------------+---------------+------------------+-------+
+ * +------------+--------------+------------+------------------------+-------+
+ * | ELF HEADER | SECT HEADERS | KERN SECTS | REL/RELA/SYM/STR SECTS | EXTRA |
+ * +------------+--------------+------------+------------------------+-------+
  * This was done in the loadfile_elf32.c:loadfile_dynamic() function.
  *
  * We abstract this layout into several "regions":
- * +------------------------------+---------------+--------------------------+
- * |         Head region          |  Kernel segs  |       Boot region        |
- * +------------------------------+---------------+--------------------------+
+ * +---------------------------+------------+--------------------------------+
+ * |         Head region       | Kern segs  |          Boot region           |
+ * +---------------------------+------------+--------------------------------+
  *
  * There is a variable number of independent regions we create: one head,
  * several kernel segments, one boot. They are all mapped at random VAs.
@@ -477,11 +476,15 @@
  * sections, in a 1:1 manner (one segment is associated with one section).
  * The segments are mapped at random VAs and referenced in bootspace.segs[].
  *
- * "Boot" contains various information, including the ELF Sym+Rel sections,
- * plus extra memory the prekern has used so far; it is a region that the
- * kernel will eventually use for module_map. Boot is placed *after* the
- * other regions in physical memory. In virtual memory however there is no
- * constraint, so its VA is randomly selected in the main KASLR window.
+ * "Boot" contains miscellaneous information:
+ *  - The ELF Rel/Rela/Sym/Str sections of the kernel
+ *  - Some extra memory the prekern has consumed so far
+ *  - The ISA I/O MEM, in pure VA
+ *  - Eventually the module_map, in pure VA (the kernel uses the available VA
+ *    at the end of "boot")
+ * Boot is placed *after* the other regions in physical memory. In virtual
+ * memory however there is no constraint, so its VA is randomly selected in
+ * the main KASLR window.
  *
  * At the end of this function, the bootspace structure is fully constructed.
  */



Home | Main Index | Thread Index | Old Index