- 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/mkexts 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() ))) {
-
- boolean_t isMkext = FALSE;
- 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 either a kext or an mkext */
- if (!strncmp(devTreeNameCString, BOOTER_KEXT_PREFIX,
- CONST_STRLEN(BOOTER_KEXT_PREFIX))) {
-
- isMkext = FALSE;
-
- } else if (!strncmp(devTreeNameCString, BOOTER_MKEXT_PREFIX,
- CONST_STRLEN(BOOTER_MKEXT_PREFIX))) {
-
- isMkext = TRUE;
-
- } else {
- 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 mkext 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);
-
- if (isMkext) {
- readMkextExtensions(deviceTreeName, booterData);
- } else {
- /* 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);
- OSSafeRelease(newKext);
- }
-
- booterMemoryMap->removeProperty(deviceTreeName);
-
- } /* while ( (deviceTreeName = OSDynamicCast(OSString, ...) ) ) */
+ 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;
+ }