void saveOriginalSMBIOS(void) { Node *node; SMBEntryPoint *origeps; void *tableAddress; node = DT__FindNode("/efi/platform", false); if (!node) { verbose("/efi/platform node not found\n"); return; } origeps = getSmbios(SMBIOS_ORIGINAL); if (!origeps) { return; } tableAddress = (void *)AllocateKernelMemory(origeps->dmi.tableLength); if (!tableAddress) { return; } memcpy(tableAddress, (void *)origeps->dmi.tableAddress, origeps->dmi.tableLength); DT__AddProperty(node, "SMBIOS", origeps->dmi.tableLength, tableAddress); }
void addHajoKey(const char* key) { if(key == 0 || strlen(key)<3) return; verbose("addHajoKey: \"%s\" \n", key); //sleep(5); const char *data = getStringForKey(key, &bootInfo->chameleonConfig); const char* colon = strchr(data, ':'); const char* equal = strchr(colon, '='); char nodePath[128]; strncpy(nodePath, data, colon-data); nodePath[colon-data] = 0; char attributeName[128]; strncpy(attributeName, colon+1, equal-colon-1); nodePath[equal-colon-1] = 0; int len = 0; const char* attributeValue = convertHexStr2Binary(equal+1, &len); verbose("in node \"%s\" set property \"%s\" to \"%s\" \n", nodePath, attributeName, attributeValue); Node* node = DT__FindNode(nodePath, true); if (node == 0) stop("Couldn't find/add node"); DT__AddProperty(node, attributeName, len + 1, (char*)attributeValue); }
/** * dtre_allocate_memory_range * * Allocate a memory range into the device tree. */ int dtre_allocate_memory_range(char *name, long start, long length, long type) { Node *memory_map; char *name_buffer; uint32_t *value_buffer; memory_map = DT__FindNode("/chosen/memory-map", 1); name_buffer = malloc(strlen(name) + 1); if (name_buffer == 0) return -1; strcpy(name_buffer, name); value_buffer = malloc(2 * sizeof(uint32_t)); if (value_buffer == 0) return -1; value_buffer[0] = start; value_buffer[1] = length; DT__AddProperty(memory_map, name_buffer, 2 * sizeof(uint32_t), (char *)value_buffer); return 0; }
/* * Must be called AFTER setup Acpi because we need to take care of correct * facp content to reflect in ioregs */ void setupSystemType() { Node *node = DT__FindNode("/", false); if (node == 0) stop("Couldn't get root node"); // we need to write this property after facp parsing // Export system-type only if it has been overrriden by the SystemType option DT__AddProperty(node, SYSTEM_TYPE_PROP, sizeof(Platform.Type), &Platform.Type); }
void setupBooterLog(void) { if (!msgbuf) return; Node *node = DT__FindNode("/", false); if (node) DT__AddProperty(node, "boot-log", strlen((char *)msgbuf) + 1, msgbuf); }
void setupChosenNode() { Node *chosenNode; chosenNode = DT__FindNode("/chosen", false); if (chosenNode == 0) stop("Couldn't get chosen node"); int bootUUIDLength = strlen(gBootUUIDString); if (bootUUIDLength) DT__AddProperty(chosenNode, "boot-uuid", bootUUIDLength + 1, gBootUUIDString); }
/* * Must be called AFTER getSmbios */ void setupBoardId() { Node *node; node = DT__FindNode("/", false); if (node == 0) { stop("Couldn't get root node"); } const char *boardid = getStringForKey("SMboardproduct", &bootInfo->smbiosConfig); if (boardid) DT__AddProperty(node, BOARDID_PROP, strlen(boardid)+1, (EFI_CHAR16*)boardid); }
void NBI_md0Ramdisk() { RAMDiskParam ramdiskPtr; char filename[512]; int fh = -1; // TODO: embed NBI.img in this file // If runNetbookInstaller is true, then the system has changed states, patch it snprintf(filename, sizeof(filename),"%s", "Extra/NetbookInstaller.img");; fh = open(filename, 0); if (fh >= 0) { verbose("Enabling ramdisk %s\n", filename); ramdiskPtr.size = file_size(fh); ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size); if(ramdiskPtr.size && ramdiskPtr.base) { // Read new ramdisk image contents in kernel memory. if (read(fh, (char*) ramdiskPtr.base, ramdiskPtr.size) == ramdiskPtr.size) { AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size); Node* node = DT__FindNode("/chosen/memory-map", false); if(node != NULL) { DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam), (void*)&ramdiskPtr); } else { verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename); } } else { verbose("Unable to read md0 image %s.\n", filename); } } else { verbose("md0 image %s is empty.\n", filename); } close(fh); } }
// Notify OS X that a ramdisk has been setup. XNU with attach this to /dev/md0 void md0Ramdisk() { RAMDiskParam ramdiskPtr; char filename[512]; const char* override_filename = 0; int fh = -1; int len; if(getValueForKey(kMD0Image, &override_filename, &len, &bootInfo->bootConfig)) { // Use user specified md0 file sprintf(filename, "%s", override_filename); fh = open(filename, 0); if(fh < 0) { sprintf(filename, "rd(0,0)/Extra/%s", override_filename); fh = open(filename, 0); if(fh < 0) { sprintf(filename, "/Extra/%s", override_filename); fh = open(filename, 0); } } } if(fh < 0) { sprintf(filename, "rd(0,0)/Extra/Postboot.img"); fh = open(filename, 0); if(fh < 0) { sprintf(filename, "/Extra/Postboot.img"); // Check /Extra if not in rd(0,0) fh = open(filename, 0); } } if (fh >= 0) { verbose("Enabling ramdisk %s\n", filename); ramdiskPtr.size = file_size(fh); ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size); if(ramdiskPtr.size && ramdiskPtr.base) { // Read new ramdisk image contents in kernel memory. if (read(fh, (char*) ramdiskPtr.base, ramdiskPtr.size) == ramdiskPtr.size) { AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size, kBootDriverTypeInvalid); Node* node = DT__FindNode("/chosen/memory-map", false); if(node != NULL) { DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam), (void*)&ramdiskPtr); } else { verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename); } } else { verbose("Unable to read md0 image %s.\n", filename); } } else { verbose("md0 image %s is empty.\n", filename); } close(fh); } }
void setupEfiDeviceTree(void) { EFI_CHAR8* ret = 0; EFI_CHAR16* ret16 = 0; size_t len = 0; Node *node; node = DT__FindNode("/", false); if (node == 0) stop("Couldn't get root node"); // We could also just do DT__FindNode("/efi/platform", true) // But I think eventually we want to fill stuff in the efi node // too so we might as well create it so we have a pointer for it too. node = DT__AddChild(node, "efi"); if (archCpuType == CPU_TYPE_I386) { DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_32_PROP_VALUE), (char*)FIRMWARE_ABI_32_PROP_VALUE); } else { DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_64_PROP_VALUE), (char*)FIRMWARE_ABI_64_PROP_VALUE); } DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION); DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR); // TODO: Fill in other efi properties if necessary // Set up the /efi/runtime-services table node similar to the way a child node of configuration-table // is set up. That is, name and table properties Node *runtimeServicesNode = DT__AddChild(node, "runtime-services"); if (archCpuType == CPU_TYPE_I386) { // The value of the table property is the 32-bit physical address for the RuntimeServices table. // Since the EFI system table already has a pointer to it, we simply use the address of that pointer // for the pointer to the property data. Warning.. DT finalization calls free on that but we're not // the only thing to use a non-malloc'd pointer for something in the DT DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST32->RuntimeServices); } else { DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST64->RuntimeServices); } // Set up the /efi/configuration-table node which will eventually have several child nodes for // all of the configuration tables needed by various kernel extensions. gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table"); // Now fill in the /efi/platform Node Node *efiPlatformNode = DT__AddChild(node, "platform"); // NOTE WELL: If you do add FSB Frequency detection, make sure to store // the value in the fsbFrequency global and not an malloc'd pointer // because the DT_AddProperty function does not copy its args. if (Platform.CPU.FSBFrequency != 0) DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency); // Export TSC and CPU frequencies for use by the kernel or KEXTs if (Platform.CPU.TSCFrequency != 0) DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency); if (Platform.CPU.CPUFrequency != 0) DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency); // Export system-id. Can be disabled with SystemId=No in com.apple.Boot.plist if ((ret=getSystemID())) DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, UUID_LEN, (EFI_UINT32*) ret); // Export SystemSerialNumber if present if ((ret16=getSmbiosChar16("SMserial", &len))) DT__AddProperty(efiPlatformNode, SYSTEM_SERIAL_PROP, len, ret16); // Export Model if present if ((ret16=getSmbiosChar16("SMproductname", &len))) DT__AddProperty(efiPlatformNode, MODEL_PROP, len, ret16); // Fill /efi/device-properties node. setupDeviceProperties(node); }
void setupEfiDeviceTree(void) { Node *node; const char * sz_system_id=0; EFI_CHAR8* ret=0; node = DT__FindNode("/", false); if (node == 0) { stop("Couldn't get root node"); } /* We could also just do DT__FindNode("/efi/platform", true) * But I think eventually we want to fill stuff in the efi node * too so we might as well create it so we have a pointer for it too. */ node = DT__AddChild(node, "efi"); DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION); DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_PROP_VALUE), (char*)FIRMWARE_ABI_PROP_VALUE); DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR); /* TODO: Fill in other efi properties if necessary */ /* Set up the /efi/runtime-services table node similar to the way a child node of configuration-table * is set up. That is, name and table properties */ Node *runtimeServicesNode = DT__AddChild(node, "runtime-services"); /* The value of the table property is the 32-bit physical address for the RuntimeServices table. * Sice the EFI system table already has a pointer to it, we simply use the address of that pointer * for the pointer to the property data. Warning.. DT finalization calls free on that but we're not * the only thing to use a non-malloc'd pointer for something in the DT */ DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST->RuntimeServices); /* Set up the /efi/configuration-table node which will eventually have several child nodes for * all of the configuration tables needed by various kernel extensions. */ gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table"); /* Now fill in the /efi/platform Node */ Node *efiPlatformNode = DT__AddChild(node, "platform"); /* NOTE WELL: If you do add FSB Frequency detection, make sure to store * the value in the fsbFrequency global and not an malloc'd pointer * because the DT_AddProperty function does not copy its args. */ if(fsbFrequency != 0) DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &fsbFrequency); // rek: Give the user a chance to set a fixed/reproduceable system UUID from the bootConfig sz_system_id = newStringForKey("SystemID", &bootInfo->bootConfig); ret = getUUIDFromString(sz_system_id); if (sz_system_id) { if (ret) { verbose("Customizing SystemID with : %s\n", sz_system_id); DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, sizeof(SYSTEM_ID), (EFI_UINT32*) ret); } free((void*) sz_system_id); } else // unable to determine UUID for host. Error: 35 fix DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, sizeof(SYSTEM_ID), (EFI_UINT32*)&SYSTEM_ID); /* Export TSC and CPU frequencies for use by the kernel or KEXTs */ if(tscFrequency != 0) DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &tscFrequency); if(cpuFrequency != 0) DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &cpuFrequency); /* Fill /efi/device-properties node. */ setupDeviceProperties(node); }
static void setupEfiDeviceTree(void) { Node *node; const char *value; int len; bool doit; if ((node = DT__FindNode("/", false)) == NULL) { stop("Couldn't find EFI root node"); } /* Export system-type. Allowed values are: * 0x01 for desktop computer (default) * 0x02 for portable computers */ SystemType[0] = 1; if (getValueForKey(kSystemType, &value, &len, &bootInfo->bootConfig) && value != NULL) { SystemType[0] = (unsigned char) strtoul(value, NULL, 10); if (SystemType[0] != 1 && SystemType[0] != 2) { verbose("Error: system-type must be 1 (desktop) or 2 (portable). Defaulting to 1!\n"); SystemType[0] = 1; } } verbose("Using system-type=0x%02x\n", SystemType[0]); DT__AddProperty(node, SystemType_prop, sizeof(SystemType), &SystemType); /* We could also just do DT__FindNode("/efi/platform", true) * But I think eventually we want to fill stuff in the efi node * too so we might as well create it so we have a pointer for it too. */ node = DT__AddChild(node, "efi"); DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION); DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_PROP_VALUE), (char*)FIRMWARE_ABI_PROP_VALUE); DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR); /* TODO: Fill in other efi properties if necessary */ /* Set up the /efi/runtime-services table node similar to the way a child node of configuration-table * is set up. That is, name and table properties */ Node *runtimeServicesNode = DT__AddChild(node, "runtime-services"); /* The value of the table property is the 32-bit physical address for the RuntimeServices table. * Sice the EFI system table already has a pointer to it, we simply use the address of that pointer * for the pointer to the property data. Warning.. DT finalization calls free on that but we're not * the only thing to use a non-malloc'd pointer for something in the DT */ DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST->RuntimeServices); /* Set up the /efi/configuration-table node which will eventually have several child nodes for * all of the configuration tables needed by various kernel extensions. */ gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table"); /* Now fill in the /efi/platform Node */ Node *efiPlatformNode = DT__AddChild(node, "platform"); /* NOTE WELL: If you do add FSB Frequency detection, make sure to store * the value in the fsbFrequency global and not an malloc'd pointer * because the DT_AddProperty function does not copy its args. */ if(Platform.CPU.FSBFrequency != 0) { DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency); } /* Export TSC and CPU frequencies for use by the kernel or KEXTs */ if(Platform.CPU.TSCFrequency != 0) { DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency); } if(Platform.CPU.CPUFrequency != 0) { DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency); } /* Export system-id. Can be disabled with system-id=No in com.apple.Boot.plist */ doit = true; getBoolForKey(kSystemID, &doit, &bootInfo->bootConfig); if (doit) { DT__AddProperty(efiPlatformNode, SystemID_prop, sizeof(SystemID), &SystemID); } /* Export SystemSerialNumber if present */ if (SystemSerialLength > 0) { DT__AddProperty(efiPlatformNode, SystemSerial_prop, SystemSerialLength, &SystemSerial); } /* Export Model if present */ if (ModelLength > 0) { DT__AddProperty(efiPlatformNode, Model_prop, ModelLength, &Model); } /* Fill /efi/device-properties node */ setupDeviceProperties(node); }
void initKernBootStruct( void ) { Node *node; int nameLen; static int init_done = 0; if ( !init_done ) { bootArgs = (boot_args *)malloc(sizeof(boot_args)); bootArgsPreLion = (boot_args_pre_lion *)malloc(sizeof(boot_args_pre_lion)); bootInfo = (PrivateBootInfo_t *)malloc(sizeof(PrivateBootInfo_t)); if (bootArgs == 0 || bootInfo == 0) stop("Couldn't allocate boot info\n"); bzero(bootArgs, sizeof(boot_args)); bzero(bootArgsPreLion, sizeof(boot_args_pre_lion)); bzero(bootInfo, sizeof(PrivateBootInfo_t)); // Get system memory map. Also update the size of the // conventional/extended memory for backwards compatibility. bootInfo->memoryMapCount = getMemoryMap( bootInfo->memoryMap, kMemoryMapCountMax, (unsigned long *) &bootInfo->convmem, (unsigned long *) &bootInfo->extmem ); if ( bootInfo->memoryMapCount == 0 ) { // BIOS did not provide a memory map, systems with // discontiguous memory or unusual memory hole locations // may have problems. bootInfo->convmem = getConventionalMemorySize(); bootInfo->extmem = getExtendedMemorySize(); } bootInfo->configEnd = bootInfo->config; bootArgs->Video.v_display = VGA_TEXT_MODE; DT__Initialize(); node = DT__FindNode("/", true); if (node == 0) { stop("Couldn't create root node"); } getPlatformName(platformName); nameLen = strlen(platformName) + 1; DT__AddProperty(node, "compatible", nameLen, platformName); DT__AddProperty(node, "model", nameLen, platformName); gMemoryMapNode = DT__FindNode("/chosen/memory-map", true); bootArgs->Version = kBootArgsVersion; bootArgs->Revision = kBootArgsRevision; bootArgsPreLion->Version = kBootArgsPreLionVersion; bootArgsPreLion->Revision = kBootArgsPreLionRevision; init_done = 1; } }
void initKernBootStruct( void ) { static int init_done = 0; if ( !init_done ) { int convmem; // conventional memory int extmem; // extended memory unsigned long memoryMapCount = 0; bootArgs = (boot_args *)malloc(sizeof(boot_args)); bootInfo = (PrivateBootInfo_t *)malloc(sizeof(PrivateBootInfo_t)); if (bootArgs == NULL || bootInfo == NULL) { stop("Couldn't allocate boot info\n"); return; } else { bzero(bootArgs, sizeof(boot_args)); bzero(bootInfo, sizeof(PrivateBootInfo_t)); // Get system memory map. Also update the size of the // conventional/extended memory for backwards compatibility. memoryMapCount = getMemoryMap( memoryMap, kMemoryMapCountMax, (unsigned long *) &convmem, (unsigned long *) &extmem ); if ( memoryMapCount == 0 ) { // BIOS did not provide a memory map, systems with // discontiguous memory or unusual memory hole locations // may have problems. convmem = getConventionalMemorySize(); extmem = getExtendedMemorySize(); } bootArgs->Video.v_display = VGA_TEXT_MODE; DT__Initialize(); { Node *node; node = DT__FindNode("/", true); if (node == 0) { stop("Couldn't create root node"); return; } getPlatformName(platformName, sizeof(platformName)); { int nameLen; nameLen = strlen(platformName) + 1; DT__AddProperty(node, "compatible", nameLen, platformName); DT__AddProperty(node, "model", nameLen, platformName); } } Node *gMemoryMapNode = DT__FindNode("/chosen/memory-map", true); set_env(envConvMem, convmem); set_env(envExtMem, extmem); set_env(envMemoryMap, (uint32_t)memoryMap); set_env(envMemoryMapCnt, memoryMapCount); set_env(envMemoryMapNode, (uint32_t)gMemoryMapNode); init_done = 1; } } }
/** * dtre_find_node * * Searches the device tree for the requested node. */ Node *dtre_find_node(const char *path, bool create) { return DT__FindNode(path, create); }