]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/i386_vm_init.c
xnu-4903.221.2.tar.gz
[apple/xnu.git] / osfmk / i386 / i386_vm_init.c
index 81b9d6f51c8f239566b6d58254c2f3868e36e872..9b74e8d449911ea58db3ba8e0e8edfa96ff2f799 100644 (file)
@@ -100,6 +100,8 @@ vm_offset_t vm_kernel_top;
 vm_offset_t    vm_kernel_stext;
 vm_offset_t    vm_kernel_etext;
 vm_offset_t    vm_kernel_slide;
+vm_offset_t    vm_kernel_slid_base;
+vm_offset_t    vm_kernel_slid_top;
 vm_offset_t vm_hib_base;
 vm_offset_t    vm_kext_base = VM_MIN_KERNEL_AND_KEXT_ADDRESS;
 vm_offset_t    vm_kext_top = VM_MIN_KERNEL_ADDRESS;
@@ -111,6 +113,9 @@ vm_offset_t vm_prelink_einfo;
 vm_offset_t vm_slinkedit;
 vm_offset_t vm_elinkedit;
 
+vm_offset_t vm_kernel_builtinkmod_text;
+vm_offset_t vm_kernel_builtinkmod_text_end;
+
 #define MAXLORESERVE   (32 * 1024 * 1024)
 
 ppnum_t                max_ppnum = 0;
@@ -131,7 +136,7 @@ vm_offset_t virtual_avail, virtual_end;
 static pmap_paddr_t    avail_remaining;
 vm_offset_t     static_memory_end = 0;
 
-vm_offset_t    sHIB, eHIB, stext, etext, sdata, edata, sconstdata, econstdata, end;
+vm_offset_t    sHIB, eHIB, stext, etext, sdata, edata, end, sconst, econst;
 
 /*
  * _mh_execute_header is the mach_header for the currently executing kernel
@@ -139,16 +144,14 @@ vm_offset_t       sHIB, eHIB, stext, etext, sdata, edata, sconstdata, econstdata, end;
 vm_offset_t segTEXTB; unsigned long segSizeTEXT;
 vm_offset_t segDATAB; unsigned long segSizeDATA;
 vm_offset_t segLINKB; unsigned long segSizeLINK;
-vm_offset_t segPRELINKB; unsigned long segSizePRELINK;
+vm_offset_t segPRELINKTEXTB; unsigned long segSizePRELINKTEXT;
 vm_offset_t segPRELINKINFOB; unsigned long segSizePRELINKINFO;
 vm_offset_t segHIBB; unsigned long segSizeHIB;
-vm_offset_t sectCONSTB; unsigned long sectSizeConst;
-
-boolean_t doconstro_override = FALSE;
+unsigned long segSizeConst;
 
 static kernel_segment_command_t *segTEXT, *segDATA;
 static kernel_section_t *cursectTEXT, *lastsectTEXT;
-static kernel_section_t *sectDCONST;
+static kernel_segment_command_t *segCONST;
 
 extern uint64_t firmware_Conventional_bytes;
 extern uint64_t firmware_RuntimeServices_bytes;
@@ -165,12 +168,57 @@ uint64_t firmware_MMIO_bytes;
  */
 extern void    *last_kernel_symbol;
 
-#if    DEBUG
-#define        PRINT_PMAP_MEMORY_TABLE
-#define DBG(x...)       kprintf(x)
+boolean_t      memmap = FALSE;
+#if    DEBUG || DEVELOPMENT
+static void
+kprint_memmap(vm_offset_t maddr, unsigned int msize, unsigned int mcount) {
+    unsigned int         i;
+    unsigned int         j;
+    pmap_memory_region_t *p = pmap_memory_regions;
+    EfiMemoryRange       *mptr; 
+    addr64_t             region_start, region_end;
+    addr64_t             efi_start, efi_end;
+
+    for (j = 0; j < pmap_memory_region_count; j++, p++) {
+        kprintf("pmap region %d type %d base 0x%llx alloc_up 0x%llx alloc_down 0x%llx top 0x%llx\n",
+            j, p->type,
+            (addr64_t) p->base  << I386_PGSHIFT,
+            (addr64_t) p->alloc_up << I386_PGSHIFT,
+            (addr64_t) p->alloc_down << I386_PGSHIFT,
+            (addr64_t) p->end   << I386_PGSHIFT);
+        region_start = (addr64_t) p->base << I386_PGSHIFT;
+        region_end = ((addr64_t) p->end << I386_PGSHIFT) - 1;
+        mptr = (EfiMemoryRange *) maddr; 
+        for (i = 0; 
+             i < mcount;
+             i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
+            if (mptr->Type != kEfiLoaderCode &&
+                mptr->Type != kEfiLoaderData &&
+                mptr->Type != kEfiBootServicesCode &&
+                mptr->Type != kEfiBootServicesData &&
+                mptr->Type != kEfiConventionalMemory) {
+                efi_start = (addr64_t)mptr->PhysicalStart;
+                efi_end = efi_start + ((vm_offset_t)mptr->NumberOfPages << I386_PGSHIFT) - 1;
+                if ((efi_start >= region_start && efi_start <= region_end) ||
+                    (efi_end >= region_start && efi_end <= region_end)) {
+                    kprintf(" *** Overlapping region with EFI runtime region %d\n", i);
+                }
+            }
+        }
+    }
+}
+#define DPRINTF(x...)  do { if (memmap) kprintf(x); } while (0)
+
 #else
-#define DBG(x...)
+
+static void
+kprint_memmap(vm_offset_t maddr, unsigned int msize, unsigned int mcount) {
+#pragma unused(maddr, msize, mcount)
+}
+
+#define DPRINTF(x...)
 #endif /* DEBUG */
+
 /*
  * Basic VM initialization.
  */
@@ -184,6 +232,7 @@ i386_vm_init(uint64_t       maxmem,
        EfiMemoryRange *mptr;
         unsigned int mcount;
         unsigned int msize;
+       vm_offset_t maddr;
        ppnum_t fap;
        unsigned int i;
        ppnum_t maxpg = 0;
@@ -197,6 +246,8 @@ i386_vm_init(uint64_t       maxmem,
        vm_offset_t base_address;
        vm_offset_t static_base_address;
     
+       PE_parse_boot_argn("memmap", &memmap, sizeof(memmap));
+
        /*
         * Establish the KASLR parameters.
         */
@@ -251,16 +302,16 @@ i386_vm_init(uint64_t     maxmem,
                                        "__LINKEDIT", &segSizeLINK);
        segHIBB  = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
                                        "__HIB", &segSizeHIB);
-    segPRELINKB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
-                                                     "__PRELINK_TEXT", &segSizePRELINK);
-    segPRELINKINFOB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
-                                                     "__PRELINK_INFO", &segSizePRELINKINFO);
+       segPRELINKTEXTB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
+                                               "__PRELINK_TEXT", &segSizePRELINKTEXT);
+       segPRELINKINFOB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
+                                               "__PRELINK_INFO", &segSizePRELINKINFO);
        segTEXT = getsegbynamefromheader(&_mh_execute_header,
                                        "__TEXT");
        segDATA = getsegbynamefromheader(&_mh_execute_header,
                                        "__DATA");
-       sectDCONST = getsectbynamefromheader(&_mh_execute_header,
-                                       "__DATA", "__const");
+       segCONST = getsegbynamefromheader(&_mh_execute_header,
+                                       "__CONST");
        cursectTEXT = lastsectTEXT = firstsect(segTEXT);
        /* Discover the last TEXT section within the TEXT segment */
        while ((cursectTEXT = nextsect(segTEXT, cursectTEXT)) != NULL) {
@@ -278,45 +329,40 @@ i386_vm_init(uint64_t     maxmem,
        sdata = segDATAB;
        edata = segDATAB + segSizeDATA;
 
-       sectCONSTB = (vm_offset_t) sectDCONST->addr;
-       sectSizeConst = sectDCONST->size;
-       sconstdata = sectCONSTB;
-       econstdata = sectCONSTB + sectSizeConst;
-
-       if (sectSizeConst & PAGE_MASK) {
-               kernel_section_t *ns = nextsect(segDATA, sectDCONST);
-               if (ns && !(ns->addr & PAGE_MASK))
-                       doconstro_override = TRUE;
-       } else
-               doconstro_override = TRUE;
-
-       DBG("segTEXTB    = %p\n", (void *) segTEXTB);
-       DBG("segDATAB    = %p\n", (void *) segDATAB);
-       DBG("segLINKB    = %p\n", (void *) segLINKB);
-       DBG("segHIBB     = %p\n", (void *) segHIBB);
-       DBG("segPRELINKB = %p\n", (void *) segPRELINKB);
-       DBG("segPRELINKINFOB = %p\n", (void *) segPRELINKINFOB);
-       DBG("sHIB        = %p\n", (void *) sHIB);
-       DBG("eHIB        = %p\n", (void *) eHIB);
-       DBG("stext       = %p\n", (void *) stext);
-       DBG("etext       = %p\n", (void *) etext);
-       DBG("sdata       = %p\n", (void *) sdata);
-       DBG("edata       = %p\n", (void *) edata);
-       DBG("sconstdata  = %p\n", (void *) sconstdata);
-       DBG("econstdata  = %p\n", (void *) econstdata);
-       DBG("kernel_top  = %p\n", (void *) &last_kernel_symbol);
+       sconst = segCONST->vmaddr;
+       segSizeConst = segCONST->vmsize;
+       econst = sconst + segSizeConst;
+
+       assert(((sconst|econst) & PAGE_MASK) == 0);
+       
+       DPRINTF("segTEXTB    = %p\n", (void *) segTEXTB);
+       DPRINTF("segDATAB    = %p\n", (void *) segDATAB);
+       DPRINTF("segLINKB    = %p\n", (void *) segLINKB);
+       DPRINTF("segHIBB     = %p\n", (void *) segHIBB);
+       DPRINTF("segPRELINKTEXTB = %p\n", (void *) segPRELINKTEXTB);
+       DPRINTF("segPRELINKINFOB = %p\n", (void *) segPRELINKINFOB);
+       DPRINTF("sHIB        = %p\n", (void *) sHIB);
+       DPRINTF("eHIB        = %p\n", (void *) eHIB);
+       DPRINTF("stext       = %p\n", (void *) stext);
+       DPRINTF("etext       = %p\n", (void *) etext);
+       DPRINTF("sdata       = %p\n", (void *) sdata);
+       DPRINTF("edata       = %p\n", (void *) edata);
+       DPRINTF("sconst      = %p\n", (void *) sconst);
+       DPRINTF("econst      = %p\n", (void *) econst);
+       DPRINTF("kernel_top  = %p\n", (void *) &last_kernel_symbol);
 
        vm_kernel_base  = sHIB;
        vm_kernel_top   = (vm_offset_t) &last_kernel_symbol;
        vm_kernel_stext = stext;
        vm_kernel_etext = etext;
-
-    vm_prelink_stext = segPRELINKB;
-    vm_prelink_etext = segPRELINKB + segSizePRELINK;
-    vm_prelink_sinfo = segPRELINKINFOB;
-    vm_prelink_einfo = segPRELINKINFOB + segSizePRELINKINFO;
-    vm_slinkedit = segLINKB;
-    vm_elinkedit = segLINKB + segSizePRELINK;
+       vm_prelink_stext = segPRELINKTEXTB;
+       vm_prelink_etext = segPRELINKTEXTB + segSizePRELINKTEXT;
+       vm_prelink_sinfo = segPRELINKINFOB;
+       vm_prelink_einfo = segPRELINKINFOB + segSizePRELINKINFO;
+       vm_slinkedit = segLINKB;
+       vm_elinkedit = segLINKB + segSizeLINK;
+       vm_kernel_slid_base = vm_kext_base + vm_kernel_slide;
+       vm_kernel_slid_top = vm_prelink_einfo;
 
        vm_set_page_size();
 
@@ -331,7 +377,8 @@ i386_vm_init(uint64_t       maxmem,
        pmap_memory_region_count = pmap_memory_region_current = 0;
        fap = (ppnum_t) i386_btop(first_avail);
 
-       mptr = (EfiMemoryRange *)ml_static_ptovirt((vm_offset_t)args->MemoryMap);
+       maddr = ml_static_ptovirt((vm_offset_t)args->MemoryMap);
+       mptr = (EfiMemoryRange *)maddr;
         if (args->MemoryMapDescriptorSize == 0)
                panic("Invalid memory map descriptor size");
         msize = args->MemoryMapDescriptorSize;
@@ -441,7 +488,7 @@ i386_vm_init(uint64_t       maxmem,
                        break;
                }
 
-               DBG("EFI region %d: type %u/%d, base 0x%x, top 0x%x %s\n",
+               DPRINTF("EFI region %d: type %u/%d, base 0x%x, top 0x%x %s\n",
                    i, mptr->Type, pmap_type, base, top,
                    (mptr->Attribute&EFI_MEMORY_KERN_RESERVED)? "RESERVED" :
                    (mptr->Attribute&EFI_MEMORY_RUNTIME)? "RUNTIME" : "");
@@ -575,39 +622,9 @@ i386_vm_init(uint64_t      maxmem,
                }
        }
 
-#ifdef PRINT_PMAP_MEMORY_TABLE
-       {
-        unsigned int j;
-        pmap_memory_region_t *p = pmap_memory_regions;
-        addr64_t region_start, region_end;
-        addr64_t efi_start, efi_end;
-        for (j=0;j<pmap_memory_region_count;j++, p++) {
-            kprintf("pmap region %d type %d base 0x%llx alloc_up 0x%llx alloc_down 0x%llx top 0x%llx\n",
-                   j, p->type,
-                    (addr64_t) p->base  << I386_PGSHIFT,
-                   (addr64_t) p->alloc_up << I386_PGSHIFT,
-                   (addr64_t) p->alloc_down << I386_PGSHIFT,
-                   (addr64_t) p->end   << I386_PGSHIFT);
-            region_start = (addr64_t) p->base << I386_PGSHIFT;
-            region_end = ((addr64_t) p->end << I386_PGSHIFT) - 1;
-           mptr = (EfiMemoryRange *) ml_static_ptovirt((vm_offset_t)args->MemoryMap);
-            for (i=0; i<mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
-                if (mptr->Type != kEfiLoaderCode &&
-                    mptr->Type != kEfiLoaderData &&
-                    mptr->Type != kEfiBootServicesCode &&
-                    mptr->Type != kEfiBootServicesData &&
-                    mptr->Type != kEfiConventionalMemory) {
-                efi_start = (addr64_t)mptr->PhysicalStart;
-                efi_end = efi_start + ((vm_offset_t)mptr->NumberOfPages << I386_PGSHIFT) - 1;
-                if ((efi_start >= region_start && efi_start <= region_end) ||
-                    (efi_end >= region_start && efi_end <= region_end)) {
-                    kprintf(" *** Overlapping region with EFI runtime region %d\n", i);
-                }
-              }
-            }
-          }
+       if (memmap) {
+               kprint_memmap(maddr, msize, mcount);
        }
-#endif
 
        avail_start = first_avail;
        mem_actual = args->PhysicalMemorySize;