/** Methods for finding, checking and fixing boot args by dmazar **/ #include #include #include #include "BootArgs.h" #include "Lib.h" #include "NVRAMDebug.h" // DBG_TO: 0=no debug, 1=serial, 2=console // serial requires // [PcdsFixedAtBuild] // gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x07 // gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xFFFFFFFF // in package DSC file #define DBG_TO 0 #if DBG_TO == 2 #define DBG(...) AsciiPrint(__VA_ARGS__); #elif DBG_TO == 1 #define DBG(...) DebugPrint(1, __VA_ARGS__); #else #define DBG(...) #endif VOID EFIAPI BootArgsPrint(VOID *bootArgs) { #if (DBG_TO > 0) || (DEBUG_TO_NVRAM > 0) BootArgs1 *BA1 = bootArgs; BootArgs2 *BA2 = bootArgs; if (BA1->Version == kBootArgsVersion1) { // pre Lion DBG("BootArgs at 0x%p\n", BA1); DBGnvr("BootArgs at 0x%p\n", BA1); DBG(" Revision: 0x%x, Version: 0x%x, efiMode: 0x%x (%d), res10: %x, res11: %x, res12: %x, res20: %x\n", BA1->Revision, BA1->Version, BA1->efiMode, BA1->efiMode, BA1->__reserved1[0], BA1->__reserved1[1], BA1->__reserved1[2], BA1->__reserved2[0] ); DBGnvr(" Revision: 0x%x, Version: 0x%x, efiMode: 0x%x (%d), res10: %x, res11: %x, res12: %x, res20: %x\n", BA1->Revision, BA1->Version, BA1->efiMode, BA1->efiMode, BA1->__reserved1[0], BA1->__reserved1[1], BA1->__reserved1[2], BA1->__reserved2[0] ); DBG(" CommandLine: %a\n", BA1->CommandLine); DBGnvr(" CommandLine: %a\n", BA1->CommandLine); DBG(" MemoryMap: 0x%x, MMSize: 0x%x, MMDescSize: 0x%x, MMDescVersion: 0x%x\n", BA1->MemoryMap, BA1->MemoryMapSize, BA1->MemoryMapDescriptorSize, BA1->MemoryMapDescriptorVersion ); DBGnvr(" MemoryMap: 0x%x, MMSize: 0x%x, MMDescSize: 0x%x, MMDescVersion: 0x%x\n", BA1->MemoryMap, BA1->MemoryMapSize, BA1->MemoryMapDescriptorSize, BA1->MemoryMapDescriptorVersion ); DBG(" Boot_Video v_baseAddr: 0x%x, v_display: 0x%x, v_rowBytes: 0x%x, v_width: %d, v_height: %d, v_depth: %d\n", BA1->Video.v_baseAddr, BA1->Video.v_display, BA1->Video.v_rowBytes, BA1->Video.v_width, BA1->Video.v_height, BA1->Video.v_depth ); DBGnvr(" Boot_Video v_baseAddr: 0x%x, v_display: 0x%x, v_rowBytes: 0x%x, v_width: %d, v_height: %d, v_depth: %d\n", BA1->Video.v_baseAddr, BA1->Video.v_display, BA1->Video.v_rowBytes, BA1->Video.v_width, BA1->Video.v_height, BA1->Video.v_depth ); DBG(" deviceTreeP: 0x%x, deviceTreeLength: 0x%x, kaddr: 0x%x, ksize: 0x%x\n", BA1->deviceTreeP, BA1->deviceTreeLength, BA1->kaddr, BA1->ksize ); DBGnvr(" deviceTreeP: 0x%x, deviceTreeLength: 0x%x, kaddr: 0x%x, ksize: 0x%x\n", BA1->deviceTreeP, BA1->deviceTreeLength, BA1->kaddr, BA1->ksize ); DBG(" efiRTServPgStart: 0x%x, efiRTServPgCount: 0x%x, efiRTServVPgStart: 0x%lx\n", BA1->efiRuntimeServicesPageStart, BA1->efiRuntimeServicesPageCount, BA1->efiRuntimeServicesVirtualPageStart ); DBGnvr(" efiRTServPgStart: 0x%x, efiRTServPgCount: 0x%x, efiRTServVPgStart: 0x%lx\n", BA1->efiRuntimeServicesPageStart, BA1->efiRuntimeServicesPageCount, BA1->efiRuntimeServicesVirtualPageStart ); DBG(" efiSystemTable: 0x%x, res2: 0x%x, perfDataStart: 0x%x, perfDataSize: 0x%x\n", BA1->efiSystemTable, BA1->__reserved2, BA1->performanceDataStart, BA1->performanceDataSize ); DBGnvr(" efiSystemTable: 0x%x, res2: 0x%x, perfDataStart: 0x%x, perfDataSize: 0x%x\n", BA1->efiSystemTable, BA1->__reserved2, BA1->performanceDataStart, BA1->performanceDataSize ); DBG(" res30: %x, res31: %x\n", BA1->__reserved3[0], BA1->__reserved3[1]); DBGnvr(" res30: %x, res31: %x\n", BA1->__reserved3[0], BA1->__reserved3[1]); } else { // Lion and up DBG("BootArgs at 0x%p\n", BA2); DBGnvr("BootArgs at 0x%p\n", BA2); DBG(" Revision: 0x%x, Version: 0x%x, efiMode: 0x%x (%d), debugMode: 0x%x, flags: 0x%x\n", BA2->Revision, BA2->Version, BA2->efiMode, BA2->efiMode, BA2->debugMode, BA2->flags ); DBGnvr(" Revision: 0x%x, Version: 0x%x, efiMode: 0x%x (%d), debugMode: 0x%x, flags: 0x%x\n", BA2->Revision, BA2->Version, BA2->efiMode, BA2->efiMode, BA2->debugMode, BA2->flags ); DBG(" CommandLine: %a\n", BA2->CommandLine); DBGnvr(" CommandLine: %a\n", BA2->CommandLine); DBG(" MemoryMap: 0x%x, MMSize: 0x%x, MMDescSize: 0x%x, MMDescVersion: 0x%x\n", BA2->MemoryMap, BA2->MemoryMapSize, BA2->MemoryMapDescriptorSize, BA2->MemoryMapDescriptorVersion ); DBGnvr(" MemoryMap: 0x%x, MMSize: 0x%x, MMDescSize: 0x%x, MMDescVersion: 0x%x\n", BA2->MemoryMap, BA2->MemoryMapSize, BA2->MemoryMapDescriptorSize, BA2->MemoryMapDescriptorVersion ); DBG(" Boot_Video v_baseAddr: 0x%x, v_display: 0x%x, v_rowBytes: 0x%x, v_width: %d, v_height: %d, v_depth: %d\n", BA2->Video.v_baseAddr, BA2->Video.v_display, BA2->Video.v_rowBytes, BA2->Video.v_width, BA2->Video.v_height, BA2->Video.v_depth ); DBGnvr(" Boot_Video v_baseAddr: 0x%x, v_display: 0x%x, v_rowBytes: 0x%x, v_width: %d, v_height: %d, v_depth: %d\n", BA2->Video.v_baseAddr, BA2->Video.v_display, BA2->Video.v_rowBytes, BA2->Video.v_width, BA2->Video.v_height, BA2->Video.v_depth ); DBG(" deviceTreeP: 0x%x, deviceTreeLength: 0x%x, kaddr: 0x%x, ksize: 0x%x\n", BA2->deviceTreeP, BA2->deviceTreeLength, BA2->kaddr, BA2->ksize ); DBGnvr(" deviceTreeP: 0x%x, deviceTreeLength: 0x%x, kaddr: 0x%x, ksize: 0x%x\n", BA2->deviceTreeP, BA2->deviceTreeLength, BA2->kaddr, BA2->ksize ); DBG(" efiRTServPgStart: 0x%x, efiRTServPgCount: 0x%x, efiRTServVPgStart: 0x%lx\n", BA2->efiRuntimeServicesPageStart, BA2->efiRuntimeServicesPageCount, BA2->efiRuntimeServicesVirtualPageStart ); DBGnvr(" efiRTServPgStart: 0x%x, efiRTServPgCount: 0x%x, efiRTServVPgStart: 0x%lx\n", BA2->efiRuntimeServicesPageStart, BA2->efiRuntimeServicesPageCount, BA2->efiRuntimeServicesVirtualPageStart ); DBG(" efiSystemTable: 0x%x, kslide: 0x%x, perfDataStart: 0x%x, perfDataSize: 0x%x\n", BA2->efiSystemTable, BA2->kslide, BA2->performanceDataStart, BA2->performanceDataSize ); DBGnvr(" efiSystemTable: 0x%x, kslide: 0x%x, perfDataStart: 0x%x, perfDataSize: 0x%x\n", BA2->efiSystemTable, BA2->kslide, BA2->performanceDataStart, BA2->performanceDataSize ); DBG(" keyStDtStart: 0x%x, keyStDtSize: 0x%x, bootMemStart: 0x%lx, bootMemSize: 0x%lx\n", BA2->keyStoreDataStart, BA2->keyStoreDataSize, BA2->bootMemStart, BA2->bootMemSize ); DBGnvr(" keyStDtStart: 0x%x, keyStDtSize: 0x%x, bootMemStart: 0x%lx, bootMemSize: 0x%lx\n", BA2->keyStoreDataStart, BA2->keyStoreDataSize, BA2->bootMemStart, BA2->bootMemSize ); DBG(" PhysicalMemorySize: 0x%lx (%d GB), FSBFrequency: 0x%lx (%d MHz)\n", BA2->PhysicalMemorySize, BA2->PhysicalMemorySize / (1024 * 1024 * 1024), BA2->FSBFrequency, BA2->FSBFrequency / 1000000 ); DBGnvr(" PhysicalMemorySize: 0x%lx (%d GB), FSBFrequency: 0x%lx (%d MHz)\n", BA2->PhysicalMemorySize, BA2->PhysicalMemorySize / (1024 * 1024 * 1024), BA2->FSBFrequency, BA2->FSBFrequency / 1000000 ); DBG(" pciConfigSpaceBaseAddress: 0x%lx, pciConfigSpaceStartBusNumber: 0x%x, pciConfigSpaceEndBusNumber: 0x%x\n", BA2->pciConfigSpaceBaseAddress, BA2->pciConfigSpaceStartBusNumber, BA2->pciConfigSpaceEndBusNumber ); DBGnvr(" pciConfigSpaceBaseAddress: 0x%lx, pciConfigSpaceStartBusNumber: 0x%x, pciConfigSpaceEndBusNumber: 0x%x\n", BA2->pciConfigSpaceBaseAddress, BA2->pciConfigSpaceStartBusNumber, BA2->pciConfigSpaceEndBusNumber ); } #endif } BootArgs gBootArgs; BootArgs* EFIAPI GetBootArgs(VOID *bootArgs) { BootArgs1 *BA1 = bootArgs; BootArgs2 *BA2 = bootArgs; ZeroMem(&gBootArgs, sizeof(gBootArgs)); if (BA1->Version == kBootArgsVersion1) { // pre Lion gBootArgs.MemoryMap = &BA1->MemoryMap; gBootArgs.MemoryMapSize = &BA1->MemoryMapSize; gBootArgs.MemoryMapDescriptorSize = &BA1->MemoryMapDescriptorSize; gBootArgs.MemoryMapDescriptorVersion = &BA1->MemoryMapDescriptorVersion; gBootArgs.deviceTreeP = &BA1->deviceTreeP; gBootArgs.deviceTreeLength = &BA1->deviceTreeLength; gBootArgs.kaddr = &BA1->kaddr; gBootArgs.ksize = &BA1->ksize; gBootArgs.efiRuntimeServicesPageStart = &BA1->efiRuntimeServicesPageStart; gBootArgs.efiRuntimeServicesPageCount = &BA1->efiRuntimeServicesPageCount; gBootArgs.efiRuntimeServicesVirtualPageStart = &BA1->efiRuntimeServicesVirtualPageStart; gBootArgs.efiSystemTable = &BA1->efiSystemTable; } else { // Lion and up gBootArgs.MemoryMap = &BA2->MemoryMap; gBootArgs.MemoryMapSize = &BA2->MemoryMapSize; gBootArgs.MemoryMapDescriptorSize = &BA2->MemoryMapDescriptorSize; gBootArgs.MemoryMapDescriptorVersion = &BA2->MemoryMapDescriptorVersion; gBootArgs.deviceTreeP = &BA2->deviceTreeP; gBootArgs.deviceTreeLength = &BA2->deviceTreeLength; gBootArgs.kaddr = &BA2->kaddr; gBootArgs.ksize = &BA2->ksize; gBootArgs.efiRuntimeServicesPageStart = &BA2->efiRuntimeServicesPageStart; gBootArgs.efiRuntimeServicesPageCount = &BA2->efiRuntimeServicesPageCount; gBootArgs.efiRuntimeServicesVirtualPageStart = &BA2->efiRuntimeServicesVirtualPageStart; gBootArgs.efiSystemTable = &BA2->efiSystemTable; } return &gBootArgs; } VOID EFIAPI BootArgsFix(BootArgs *BA, EFI_PHYSICAL_ADDRESS gRellocBase) { *BA->MemoryMap = *BA->MemoryMap - (UINT32)gRellocBase; *BA->deviceTreeP = *BA->deviceTreeP - (UINT32)gRellocBase; *BA->kaddr = *BA->kaddr - (UINT32)gRellocBase; } /** Searches for bootArgs from Start and returns pointer to bootArgs or ... does not return if can not be found. **/ VOID * EFIAPI BootArgsFind(IN EFI_PHYSICAL_ADDRESS Start) { UINT8 *ptr; UINT8 archMode = sizeof(UINTN) * 8; BootArgs1 *BA1; BootArgs2 *BA2; // start searching from 0x200000. ptr = (UINT8*)(UINTN)Start; while(TRUE) { // check bootargs for 10.7 and up BA2 = (BootArgs2*)ptr; if (BA2->Version==2 && BA2->Revision==0 // plus additional checks - some values are not inited by boot.efi yet && BA2->efiMode == archMode && BA2->kaddr == 0 && BA2->ksize == 0 && BA2->efiSystemTable == 0 ) { break; } // check bootargs for 10.4 - 10.6.x BA1 = (BootArgs1*)ptr; if (BA1->Version==1 && (BA1->Revision==6 || BA1->Revision==5 || BA1->Revision==4) // plus additional checks - some values are not inited by boot.efi yet && BA1->efiMode == archMode && BA1->kaddr == 0 && BA1->ksize == 0 && BA1->efiSystemTable == 0 ) { break; } ptr += 0x1000; } DBG("Found bootArgs2 at %p\n", ptr); return ptr; }