static void FreePhysicalMemory( vm_offset_t * range ) { vm_offset_t virt; virt = ml_static_ptovirt( range[0] ); if( virt) { ml_static_mfree( virt, range[1] ); } }
void PE_init_platform(boolean_t vm_initialized, void * _args) { boot_args *args = (boot_args *)_args; if (PE_state.initialized == FALSE) { PE_state.initialized = TRUE; // New EFI-style PE_state.bootArgs = _args; PE_state.deviceTreeHead = (void *) ml_static_ptovirt(args->deviceTreeP); PE_state.video.v_baseAddr = args->Video.v_baseAddr; // remains physical address PE_state.video.v_rowBytes = args->Video.v_rowBytes; PE_state.video.v_width = args->Video.v_width; PE_state.video.v_height = args->Video.v_height; PE_state.video.v_depth = args->Video.v_depth; PE_state.video.v_display = args->Video.v_display; PE_state.video.v_scale = (kBootArgsFlagHiDPI & args->flags) ? 2 : 1; strlcpy(PE_state.video.v_pixelFormat, "PPPPPPPP", sizeof(PE_state.video.v_pixelFormat)); #ifdef kBootArgsFlagHiDPI if (args->flags & kBootArgsFlagHiDPI) PE_state.video.v_scale = kPEScaleFactor2x; else PE_state.video.v_scale = kPEScaleFactor1x; #else PE_state.video.v_scale = kPEScaleFactor1x; #endif } if (!vm_initialized) { if (PE_state.deviceTreeHead) { DTInit(PE_state.deviceTreeHead); } pe_identify_machine(args); } else { pe_init_debug(); } }
void PE_init_iokit(void) { enum { kMaxBootVar = 128 }; typedef struct { char name[32]; unsigned long length; unsigned long value[2]; } DriversPackageProp; boolean_t bootClutInitialized = FALSE; boolean_t noroot_rle_Initialized = FALSE; DTEntry entry; unsigned int size; uint32_t *map; boot_progress_element *bootPict; norootIcon_lzss = NULL; norootClut_lzss = NULL; PE_init_kprintf(TRUE); PE_init_printf(TRUE); kprintf("Kernel boot args: '%s'\n", PE_boot_args()); /* * Fetch the CLUT and the noroot image. */ if( kSuccess == DTLookupEntry(NULL, "/chosen/memory-map", &entry)) { if( kSuccess == DTGetProperty(entry, "BootCLUT", (void **) &map, &size)) { if (sizeof(appleClut8) <= map[1]) { bcopy( (void *)ml_static_ptovirt(map[0]), appleClut8, sizeof(appleClut8) ); bootClutInitialized = TRUE; } } if( kSuccess == DTGetProperty(entry, "Pict-FailedBoot", (void **) &map, &size)) { bootPict = (boot_progress_element *) ml_static_ptovirt(map[0]); default_noroot.width = bootPict->width; default_noroot.height = bootPict->height; default_noroot.dx = 0; default_noroot.dy = bootPict->yOffset; default_noroot_data = &bootPict->data[0]; noroot_rle_Initialized = TRUE; } if( kSuccess == DTGetProperty(entry, "FailedCLUT", (void **) &map, &size)) { norootClut_lzss = (uint8_t*) ml_static_ptovirt(map[0]); } if( kSuccess == DTGetProperty(entry, "FailedImage", (void **) &map, &size)) { norootIcon_lzss = (boot_icon_element *) ml_static_ptovirt(map[0]); if (norootClut_lzss == NULL) { printf("ERROR: No FailedCLUT provided for noroot icon!\n"); } } } if (!bootClutInitialized) { bcopy( (void *) (uintptr_t) bootClut, (void *) appleClut8, sizeof(appleClut8) ); } if (!noroot_rle_Initialized) { default_noroot.width = kFailedBootWidth; default_noroot.height = kFailedBootHeight; default_noroot.dx = 0; default_noroot.dy = kFailedBootOffset; default_noroot_data = failedBootPict; } /* * Initialize the spinning wheel (progress indicator). */ vc_progress_initialize( &default_progress, default_progress_data1x, default_progress_data2x, (unsigned char *) appleClut8 ); (void) StartIOKit( PE_state.deviceTreeHead, PE_state.bootArgs, gPEEFIRuntimeServices, NULL); }
void KLDBootstrap::readBooterExtensions(void) { IORegistryEntry * booterMemoryMap = NULL; // must release OSDictionary * propertyDict = NULL; // must release OSCollectionIterator * keyIterator = NULL; // must release OSString * deviceTreeName = NULL; // do not release const _DeviceTreeBuffer * deviceTreeBuffer = NULL; // do not free char * booterDataPtr = NULL; // do not free OSData * booterData = NULL; // must release OSKext * aKext = NULL; // must release OSKextLog(/* kext */ NULL, kOSKextLogProgressLevel | kOSKextLogDirectoryScanFlag | kOSKextLogKextBookkeepingFlag, "Reading startup extensions from booter memory."); booterMemoryMap = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane); if (!booterMemoryMap) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag | kOSKextLogDirectoryScanFlag, "Can't read booter memory map."); goto finish; } propertyDict = booterMemoryMap->dictionaryWithProperties(); if (!propertyDict) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogDirectoryScanFlag, "Can't get property dictionary from memory map."); goto finish; } keyIterator = OSCollectionIterator::withCollection(propertyDict); if (!keyIterator) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Can't allocate iterator for driver images."); goto finish; } /* Create dictionary of excluded kexts */ OSKext::createExcludeListFromBooterData(propertyDict, keyIterator); keyIterator->reset(); while ( ( deviceTreeName = OSDynamicCast(OSString, keyIterator->getNextObject() ))) { const char * devTreeNameCString = deviceTreeName->getCStringNoCopy(); OSData * deviceTreeEntry = OSDynamicCast(OSData, propertyDict->getObject(deviceTreeName)); /* Clear out the booterData from the prior iteration. */ OSSafeReleaseNULL(booterData); /* If there is no entry for the name, we can't do much with it. */ if (!deviceTreeEntry) { continue; } /* Make sure it is a kext */ if (strncmp(devTreeNameCString, BOOTER_KEXT_PREFIX, CONST_STRLEN(BOOTER_KEXT_PREFIX))) { continue; } deviceTreeBuffer = (const _DeviceTreeBuffer *) deviceTreeEntry->getBytesNoCopy(0, sizeof(deviceTreeBuffer)); if (!deviceTreeBuffer) { /* We can't get to the data, so we can't do anything, * not even free it from physical memory (if it's there). */ OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogDirectoryScanFlag, "Device tree entry %s has NULL pointer.", devTreeNameCString); goto finish; // xxx - continue, panic? } booterDataPtr = (char *)ml_static_ptovirt(deviceTreeBuffer->paddr); if (!booterDataPtr) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogDirectoryScanFlag, "Can't get virtual address for device tree entry %s.", devTreeNameCString); goto finish; } /* Wrap the booter data buffer in an OSData and set a dealloc function * so it will take care of the physical memory when freed. Kexts will * retain the booterData for as long as they need it. Remove the entry * from the booter memory map after this is done. */ booterData = OSData::withBytesNoCopy(booterDataPtr, deviceTreeBuffer->length); if (!booterData) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Error - Can't allocate OSData wrapper for device tree entry %s.", devTreeNameCString); goto finish; } booterData->setDeallocFunction(osdata_phys_free); /* Create the kext for the entry, then release it, because the * kext system keeps them around until explicitly removed. * Any creation/registration failures are already logged for us. */ OSKext * newKext = OSKext::withBooterData(deviceTreeName, booterData); OSSafeReleaseNULL(newKext); booterMemoryMap->removeProperty(deviceTreeName); } /* while ( (deviceTreeName = OSDynamicCast(OSString, ...) ) ) */ finish: OSSafeReleaseNULL(booterMemoryMap); OSSafeReleaseNULL(propertyDict); OSSafeReleaseNULL(keyIterator); OSSafeReleaseNULL(booterData); OSSafeReleaseNULL(aKext); return; }