/** * enter additional data into the DeviceTree */ int prepare_devicetree_stage2(void) { void *deviceTreeP; uint32_t deviceTreeLength; Node *memory_map = CreateMemoryMapNode(); assert(memory_map); /* Insert the cool iBoot-like stuff. */ uint32_t one = 1; uint64_t ecid = 0xBEEFBEEFBEEFBEEF; assert(gChosen); CreateDeviceTreeNode(gChosen, "firmware-version", "iBoot-1234.5.6~93", sizeof("iBoot-1234.5.6~93")); CreateDeviceTreeNode(gChosen, "debug-enabled", &one, sizeof(uint32_t)); CreateDeviceTreeNode(gChosen, "secure-boot", &one, sizeof(uint32_t)); CreateDeviceTreeNode(gChosen, "die-id", &ecid, sizeof(uint64_t)); CreateDeviceTreeNode(gChosen, "unique-chip-id", &ecid, sizeof(uint64_t)); CreateDeviceTreeNode(DT__RootNode(), "serial-number", "SOMESRNLNMBR", sizeof("SOMESRNLNMBR")); /* Verify we have a ramdisk. */ if (ramdisk_base) { void *reloc_ramdisk_base = (void *)memory_region_reserve(&kernel_region, ramdisk_size, 4096); printf ("creating ramdisk at 0x%x of size 0x%x, from image at 0x%x\n", reloc_ramdisk_base, ramdisk_size, ramdisk_base); bcopy((void *)ramdisk_base, reloc_ramdisk_base, ramdisk_size); AllocateMemoryRange(memory_map, "RAMDisk", (uint32_t) reloc_ramdisk_base, ramdisk_size, kBootDriverTypeInvalid); } /* Flatten the finalized device-tree image. */ DT__FlattenDeviceTree(NULL, &deviceTreeLength); /* Allocate memory for it. */ deviceTreeP = memory_region_reserve(&kernel_region, deviceTreeLength, 0); /* Flatten. */ DT__FlattenDeviceTree((void **)&deviceTreeP, &deviceTreeLength); /* Enter into Boot-Args */ gBootArgs.deviceTreeLength = deviceTreeLength; gBootArgs.deviceTreeP = (void *)phystov(deviceTreeP, gBootArgs.virtBase, gBootArgs.physBase); printf("creating device tree at 0x%x of size 0x%x\n", deviceTreeP, deviceTreeLength); return true; }
void finalizeBootStruct(void) { { int i; EfiMemoryRange *kMemoryMap = NULL; MemoryRange *range = NULL; uint64_t sane_size = 0; /* Memory size to use for defaults calculations */ unsigned long memoryMapCount = (unsigned long)get_env(envMemoryMapCnt); if (memoryMapCount == 0) { // XXX could make a two-part map here stop("No memory map found\n"); return; } // convert memory map to boot_args memory map kMemoryMap = (EfiMemoryRange *)AllocateKernelMemory(sizeof(EfiMemoryRange) * memoryMapCount); if (kMemoryMap == NULL) { stop("Unable to allocate kernel space for the memory map\n"); return; } bootArgs->MemoryMap = (uint32_t)kMemoryMap; bootArgs->MemoryMapSize = sizeof(EfiMemoryRange) * memoryMapCount; bootArgs->MemoryMapDescriptorSize = sizeof(EfiMemoryRange); bootArgs->MemoryMapDescriptorVersion = 0; for (i=0; i<memoryMapCount; i++, kMemoryMap++) { range = &memoryMap[i]; if (!range || !kMemoryMap) { stop("Error while computing kernel memory map\n"); return; } switch(range->type) { case kMemoryRangeACPI: kMemoryMap->Type = kEfiACPIReclaimMemory; break; case kMemoryRangeNVS: kMemoryMap->Type = kEfiACPIMemoryNVS; break; case kMemoryRangeUsable: kMemoryMap->Type = kEfiConventionalMemory; break; case kMemoryRangeReserved: default: kMemoryMap->Type = kEfiReservedMemoryType; break; } kMemoryMap->PhysicalStart = range->base; kMemoryMap->VirtualStart = range->base; kMemoryMap->NumberOfPages = range->length >> I386_PGSHIFT; kMemoryMap->Attribute = 0; switch (kMemoryMap->Type) { case kEfiLoaderCode: case kEfiLoaderData: case kEfiBootServicesCode: case kEfiBootServicesData: case kEfiConventionalMemory: /* * Consolidate usable memory types into one. */ sane_size += (uint64_t)(kMemoryMap->NumberOfPages << I386_PGSHIFT); break; case kEfiRuntimeServicesCode: case kEfiRuntimeServicesData: case kEfiACPIReclaimMemory: case kEfiACPIMemoryNVS: case kEfiPalCode: /* * sane_size should reflect the total amount of physical ram * in the system, not just the amount that is available for * the OS to use */ sane_size += (uint64_t)(kMemoryMap->NumberOfPages << I386_PGSHIFT); break; default: break; } } if (sane_size == 0) { // I Guess that if sane_size == 0 we've got a big problem here, // and it means that the memory map was not converted properly stop("Unable to convert memory map into proper format\n"); return; } #define MEG (1024*1024) /* * For user visible memory size, round up to 128 Mb - accounting for the various stolen memory * not reported by EFI. */ sane_size = (sane_size + 128 * MEG - 1) & ~((uint64_t)(128 * MEG - 1)); bootArgs->PhysicalMemorySize = sane_size; bootArgs->FSBFrequency = get_env(envFSBFreq); } { uint32_t size; void *addr; // Flatten device tree DT__FlattenDeviceTree(0, &size); addr = (void *)AllocateKernelMemory(size); if (addr == 0) { stop("Couldn't allocate device tree\n"); return; } DT__FlattenDeviceTree((void **)&addr, &size); if (!size) { stop("Couldn't get flatten device tree\n"); return; } bootArgs->deviceTreeP = (uint32_t)addr; bootArgs->deviceTreeLength = size; } }
void finalizeBootStruct(void) { uint32_t size; void *addr; int i; EfiMemoryRange *memoryMap; MemoryRange *range; int memoryMapCount = bootInfo->memoryMapCount; if (memoryMapCount == 0) { // XXX could make a two-part map here stop("Unable to convert memory map into proper format\n"); } // convert memory map to boot_args memory map memoryMap = (EfiMemoryRange *)AllocateKernelMemory(sizeof(EfiMemoryRange) * memoryMapCount); bootArgs->MemoryMap = (uint32_t)memoryMap; bootArgs->MemoryMapSize = sizeof(EfiMemoryRange) * memoryMapCount; bootArgs->MemoryMapDescriptorSize = sizeof(EfiMemoryRange); bootArgs->MemoryMapDescriptorVersion = 0; for (i = 0; i < memoryMapCount; i++, memoryMap++) { range = &bootInfo->memoryMap[i]; switch(range->type) { case kMemoryRangeACPI: memoryMap->Type = kEfiACPIReclaimMemory; break; case kMemoryRangeNVS: memoryMap->Type = kEfiACPIMemoryNVS; break; case kMemoryRangeUsable: memoryMap->Type = kEfiConventionalMemory; break; case kMemoryRangeReserved: default: memoryMap->Type = kEfiReservedMemoryType; break; } memoryMap->PhysicalStart = range->base; memoryMap->VirtualStart = range->base; memoryMap->NumberOfPages = range->length >> I386_PGSHIFT; memoryMap->Attribute = 0; } // copy bootFile into device tree // XXX // add PCI info somehow into device tree // XXX // Flatten device tree DT__FlattenDeviceTree(0, &size); addr = (void *)AllocateKernelMemory(size); if (addr == 0) { stop("Couldn't allocate device tree\n"); } DT__FlattenDeviceTree((void **)&addr, &size); bootArgs->deviceTreeP = (uint32_t)addr; bootArgs->deviceTreeLength = size; // Copy BootArgs values to older structure memcpy(&bootArgsPreLion->CommandLine, &bootArgs->CommandLine, BOOT_LINE_LENGTH); memcpy(&bootArgsPreLion->Video, &bootArgs->Video, sizeof(Boot_Video)); bootArgsPreLion->MemoryMap = bootArgs->MemoryMap; bootArgsPreLion->MemoryMapSize = bootArgs->MemoryMapSize; bootArgsPreLion->MemoryMapDescriptorSize = bootArgs->MemoryMapDescriptorSize; bootArgsPreLion->MemoryMapDescriptorVersion = bootArgs->MemoryMapDescriptorVersion; bootArgsPreLion->deviceTreeP = bootArgs->deviceTreeP; bootArgsPreLion->deviceTreeLength = bootArgs->deviceTreeLength; bootArgsPreLion->kaddr = bootArgs->kaddr; bootArgsPreLion->ksize = bootArgs->ksize; bootArgsPreLion->efiRuntimeServicesPageStart = bootArgs->efiRuntimeServicesPageStart; bootArgsPreLion->efiRuntimeServicesPageCount = bootArgs->efiRuntimeServicesPageCount; bootArgsPreLion->efiSystemTable = bootArgs->efiSystemTable; bootArgsPreLion->efiMode = bootArgs->efiMode; bootArgsPreLion->performanceDataStart = bootArgs->performanceDataStart; bootArgsPreLion->performanceDataSize = bootArgs->performanceDataSize; bootArgsPreLion->efiRuntimeServicesVirtualPageStart = bootArgs->efiRuntimeServicesVirtualPageStart; }
/** * dtre_flatten * * Flatten the device tree. */ void dtre_flatten(void *data, uint32_t length) { return DT__FlattenDeviceTree(data, &length); }