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 BooterKextFileInfo *
| 764 | * and we are fixing it's pointers also. |
| 765 | */ |
| 766 | VOID |
| 767 | DevTreeFix(BootArgs *BA) |
| 768 | { |
| 769 | DTEntry DevTree; |
| 770 | DTEntry MemMap; |
| 771 | CHAR8 *PropName; |
| 772 | DTMemMapEntry *PropValue; |
| 773 | BooterKextFileInfo *KextInfo; |
| 774 | |
| 775 | OpaqueDTPropertyIterator OPropIter; |
| 776 | DTPropertyIterator PropIter = &OPropIter; |
| 777 | |
| 778 | |
| 779 | DevTree = (DTEntry)(UINTN)(*BA->deviceTreeP); |
| 780 | |
| 781 | DBG("Fixing DevTree at %p\n", DevTree); |
| 782 | DBGnvr("Fixing DevTree at %p\n", DevTree); |
| 783 | DTInit(DevTree, BA->deviceTreeLength); |
| 784 | if (!EFI_ERROR(DTLookupEntry(NULL, "/chosen/memory-map", &MemMap))) { |
| 785 | DBG("Found /chosen/memory-map\n"); |
| 786 | if (!EFI_ERROR(DTCreatePropertyIterator(MemMap, PropIter))) { |
| 787 | DBG("DTCreatePropertyIterator OK\n"); |
| 788 | while (!EFI_ERROR(DTIterateProperties(PropIter, &PropName))) { |
| 789 | DBG("= %a, val len=%d: ", PropName, PropIter->CurrentProperty->Length); |
| 790 | // all /chosen/memory-map props have DTMemMapEntry (address, length) |
| 791 | // values. we need to correct the address |
| 792 | |
| 793 | // basic check that value is 2 * UINT32 |
| 794 | if (PropIter->CurrentProperty->Length != 2 * sizeof(UINT32)) { |
| 795 | // not DTMemMapEntry, usually "name" property |
| 796 | DBG("NOT DTMemMapEntry\n"); |
| 797 | continue; |
| 798 | } |
| 799 | |
| 800 | // get value (Address and Length) |
| 801 | PropValue = (DTMemMapEntry*)(((UINT8*)PropIter->CurrentProperty) + sizeof(DeviceTreeNodeProperty)); |
| 802 | DBG("MM Addr = %x, Len = %x ", PropValue->Address, PropValue->Length); |
| 803 | |
| 804 | // second check - Address is in our reloc block |
| 805 | // (note: *BA->kaddr is not fixed yet and points to reloc block) |
| 806 | if ((PropValue->Address < *BA->kaddr) || |
| 807 | (PropValue->Address >= *BA->kaddr + *BA->ksize)) |
| 808 | { |
| 809 | DBG("DTMemMapEntry->Address is not in reloc block, skipping\n"); |
| 810 | continue; |
| 811 | } |
| 812 | |
| 813 | // check if this is Kext entry |
| 814 | if (AsciiStrnCmp(PropName, BOOTER_KEXT_PREFIX, AsciiStrLen(BOOTER_KEXT_PREFIX)) == 0) { |
| 815 | // yes - fix kext pointers |
| 816 | KextInfo = (BooterKextFileInfo*)(UINTN)PropValue->Address; |
| 817 | DBG(" = KEXT %a at %x ", (CHAR8*)(UINTN)KextInfo->bundlePathPhysAddr, KextInfo->infoDictPhysAddr); |
| 818 | KextInfo->infoDictPhysAddr -= (UINT32)gRelocBase; |
| 819 | KextInfo->executablePhysAddr -= (UINT32)gRelocBase; |
| 820 | KextInfo->bundlePathPhysAddr -= (UINT32)gRelocBase; |
| 821 | DBG("-> %x ", KextInfo->infoDictPhysAddr); |
| 822 | } |
| 823 |
no test coverage detected