DevTree contains /chosen/memory-map with properties with 8 byte values * (DTMemMapEntry: UINT32 Address, UINT32 Length): * "name" = this is exception - not DTMemMapEntry * "BootCLUT" = 8bit boot time colour lookup table * "Pict-FailedBoot" = picture shown if booting fails * "RAMDisk" = ramdisk * "Driver- " = Kext, UINT32 Address points to BooterKextFileIn
| 596 | * and we are fixing it's pointers also. |
| 597 | */ |
| 598 | VOID |
| 599 | DevTreeFix(BootArgs *BA) |
| 600 | { |
| 601 | DTEntry DevTree; |
| 602 | DTEntry MemMap; |
| 603 | CHAR8 *PropName; |
| 604 | DTMemMapEntry *PropValue; |
| 605 | BooterKextFileInfo *KextInfo; |
| 606 | |
| 607 | OpaqueDTPropertyIterator OPropIter; |
| 608 | DTPropertyIterator PropIter = &OPropIter; |
| 609 | |
| 610 | DevTree = (DTEntry)(UINTN)(*BA->deviceTreeP); |
| 611 | |
| 612 | DBG("Fixing DevTree at %p\n", DevTree); |
| 613 | DBGnvr("Fixing DevTree at %p\n", DevTree); |
| 614 | DTInit(DevTree, BA->deviceTreeLength); |
| 615 | if (!EFI_ERROR(DTLookupEntry(NULL, "/chosen/memory-map", &MemMap))) { |
| 616 | DBG("Found /chosen/memory-map\n"); |
| 617 | if (!EFI_ERROR(DTCreatePropertyIterator(MemMap, &OPropIter))) { |
| 618 | DBG("DTCreatePropertyIterator OK\n"); |
| 619 | while (!EFI_ERROR(DTIterateProperties(PropIter, &PropName))) { |
| 620 | DBG("= %a, val len=%d: ", PropName, PropIter->CurrentProperty->Length); |
| 621 | // all /chosen/memory-map props have DTMemMapEntry (address, length) |
| 622 | // values. we need to correct the address |
| 623 | |
| 624 | // basic check that value is 2 * UINT32 |
| 625 | if (PropIter->CurrentProperty->Length != 2 * sizeof(UINT32)) { |
| 626 | // not DTMemMapEntry, usually "name" property |
| 627 | DBG("NOT DTMemMapEntry\n"); |
| 628 | continue; |
| 629 | } |
| 630 | |
| 631 | // get value (Address and Length) |
| 632 | PropValue = (DTMemMapEntry*)(((UINT8*)PropIter->CurrentProperty) + sizeof(DeviceTreeNodeProperty)); |
| 633 | DBG("MM Addr = %x, Len = %x ", PropValue->Address, PropValue->Length); |
| 634 | |
| 635 | // second check - Address is in our reloc block |
| 636 | // (note: *BA->kaddr is not fixed yet and points to reloc block) |
| 637 | if ((PropValue->Address < *BA->kaddr) |
| 638 | || (PropValue->Address >= *BA->kaddr + *BA->ksize)) |
| 639 | { |
| 640 | DBG("DTMemMapEntry->Address is not in reloc block, skipping\n"); |
| 641 | continue; |
| 642 | } |
| 643 | |
| 644 | // check if this is Kext entry |
| 645 | if (AsciiStrnCmp(PropName, BOOTER_KEXT_PREFIX, AsciiStrLen(BOOTER_KEXT_PREFIX)) == 0) { |
| 646 | // yes - fix kext pointers |
| 647 | KextInfo = (BooterKextFileInfo*)(UINTN)PropValue->Address; |
| 648 | DBG(" = KEXT %a at %x ", (CHAR8*)(UINTN)KextInfo->bundlePathPhysAddr, KextInfo->infoDictPhysAddr); |
| 649 | KextInfo->infoDictPhysAddr -= (UINT32)gRelocBase; |
| 650 | KextInfo->executablePhysAddr -= (UINT32)gRelocBase; |
| 651 | KextInfo->bundlePathPhysAddr -= (UINT32)gRelocBase; |
| 652 | DBG("-> %x ", KextInfo->infoDictPhysAddr); |
| 653 | } |
| 654 | |
| 655 | // fix address in mem map entry |
no test coverage detected