[osboot] Refactor magenta loading code out of osboot Change-Id: I3ca5d46ed0e864f712c1cc7c27999394222b72c5
diff --git a/Makefile b/Makefile index 0117ae0..b48f3d7 100644 --- a/Makefile +++ b/Makefile
@@ -41,6 +41,7 @@ $(call efi_app, showmem, src/showmem.c) $(call efi_app, fileio, src/fileio.c) OSBOOT_FILES := src/osboot.c \ + src/magenta.c \ src/netboot.c \ src/netifc.c \ src/inet6.c
diff --git a/src/magenta.c b/src/magenta.c new file mode 100644 index 0000000..2da2d2e --- /dev/null +++ b/src/magenta.c
@@ -0,0 +1,354 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <magenta.h> + +#include <efilib.h> +#include <stdio.h> +#include <string.h> +#include <utils.h> + +static EFI_GUID GraphicsOutputProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; +static EFI_GUID AcpiTableGUID = ACPI_TABLE_GUID; +static EFI_GUID Acpi2TableGUID = ACPI_20_TABLE_GUID; +static UINT8 ACPI_RSD_PTR[8] = "RSD PTR "; + +uint32_t find_acpi_root(EFI_HANDLE img, EFI_SYSTEM_TABLE* sys) { + EFI_CONFIGURATION_TABLE* cfgtab = sys->ConfigurationTable; + int i; + + for (i = 0; i < sys->NumberOfTableEntries; i++) { + if (!CompareGuid(&cfgtab[i].VendorGuid, &AcpiTableGUID) && + !CompareGuid(&cfgtab[i].VendorGuid, &Acpi2TableGUID)) { + // not an ACPI table + continue; + } + if (CompareMem(cfgtab[i].VendorTable, ACPI_RSD_PTR, 8)) { + // not the Root Description Pointer + continue; + } + return (uint64_t)cfgtab[i].VendorTable; + } + return 0; +} + +#define E820_IGNORE 0 +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 +#define E820_NVS 4 +#define E820_UNUSABLE 5 + +const char* e820name[] = { + "IGNORE", + "RAM", + "RESERVED", + "ACPI", + "NVS", + "UNUSABLE", +}; + +struct e820entry { + UINT64 addr; + UINT64 size; + UINT32 type; +} __attribute__((packed)); + +static unsigned e820type(unsigned uefi_mem_type) { + switch (uefi_mem_type) { + case EfiReservedMemoryType: + case EfiPalCode: + return E820_RESERVED; + case EfiRuntimeServicesCode: + case EfiRuntimeServicesData: +#if WITH_RUNTIME_SERVICES + return E820_RESERVED; +#else + return E820_RAM; +#endif + case EfiACPIReclaimMemory: + return E820_ACPI; + case EfiACPIMemoryNVS: + return E820_NVS; + case EfiLoaderCode: + case EfiLoaderData: + case EfiBootServicesCode: + case EfiBootServicesData: + case EfiConventionalMemory: + return E820_RAM; + case EfiMemoryMappedIO: + case EfiMemoryMappedIOPortSpace: + return E820_IGNORE; + default: + if (uefi_mem_type >= 0x80000000) { + return E820_RAM; + } + return E820_UNUSABLE; + } +} + +static unsigned char scratch[32768]; +static struct e820entry e820table[128]; + +static int process_memory_map(EFI_SYSTEM_TABLE* sys, UINTN* _key, int silent) { + EFI_MEMORY_DESCRIPTOR* mmap; + struct e820entry* entry = e820table; + UINTN msize, off; + UINTN mkey, dsize; + UINT32 dversion; + unsigned n, type; + EFI_STATUS r; + + msize = sizeof(scratch); + mmap = (EFI_MEMORY_DESCRIPTOR*)scratch; + mkey = dsize = dversion = 0; + r = sys->BootServices->GetMemoryMap(&msize, mmap, &mkey, &dsize, &dversion); + if (!silent) + printf("r=%lx msz=%lx key=%lx dsz=%lx dvn=%x\n", r, msize, mkey, dsize, dversion); + if (r != EFI_SUCCESS) { + return -1; + } + if (msize > sizeof(scratch)) { + if (!silent) + printf("Memory Table Too Large (%ld entries)\n", (msize / dsize)); + return -1; + } + for (off = 0, n = 0; off < msize; off += dsize) { + mmap = (EFI_MEMORY_DESCRIPTOR*)(scratch + off); + type = e820type(mmap->Type); + if (type == E820_IGNORE) { + continue; + } + if ((n > 0) && (entry[n - 1].type == type)) { + if ((entry[n - 1].addr + entry[n - 1].size) == mmap->PhysicalStart) { + entry[n - 1].size += mmap->NumberOfPages * 4096UL; + continue; + } + } + entry[n].addr = mmap->PhysicalStart; + entry[n].size = mmap->NumberOfPages * 4096UL; + entry[n].type = type; + n++; + if (n == 128) { + if (!silent) + printf("E820 Table Too Large (%ld raw entries)\n", (msize / dsize)); + return -1; + } + } + *_key = mkey; + return n; +} + +#define ZP_E820_COUNT 0x1E8 // byte +#define ZP_SETUP 0x1F1 // start of setup structure +#define ZP_SETUP_SECTS 0x1F1 // byte (setup_size/512-1) +#define ZP_JUMP 0x200 // jump instruction +#define ZP_HEADER 0x202 // word "HdrS" +#define ZP_VERSION 0x206 // half 0xHHLL +#define ZP_LOADER_TYPE 0x210 // byte +#define ZP_RAMDISK_BASE 0x218 // word (ptr or 0) +#define ZP_RAMDISK_SIZE 0x21C // word (bytes) +#define ZP_EXTRA_MAGIC 0x220 // word +#define ZP_CMDLINE 0x228 // word (ptr) +#define ZP_SYSSIZE 0x1F4 // word (size/16) +#define ZP_XLOADFLAGS 0x236 // half +#define ZP_E820_TABLE 0x2D0 // 128 entries + +#define ZP_ACPI_RSD 0x080 // word phys ptr +#define ZP_FB_BASE 0x090 +#define ZP_FB_WIDTH 0x094 +#define ZP_FB_HEIGHT 0x098 +#define ZP_FB_STRIDE 0x09C +#define ZP_FB_FORMAT 0x0A0 +#define ZP_FB_REGBASE 0x0A4 +#define ZP_FB_SIZE 0x0A8 + +#define ZP_MAGIC_VALUE 0xDBC64323 + +#define ZP8(p, off) (*((UINT8*)((p) + (off)))) +#define ZP16(p, off) (*((UINT16*)((p) + (off)))) +#define ZP32(p, off) (*((UINT32*)((p) + (off)))) + +static void install_memmap(kernel_t* k, struct e820entry* memmap, unsigned count) { + memcpy(k->zeropage + ZP_E820_TABLE, memmap, sizeof(*memmap) * count); + ZP8(k->zeropage, ZP_E820_COUNT) = count; +} + +static void start_kernel(kernel_t* k) { + // 64bit entry is at offset 0x200 + UINT64 entry = (UINT64)(k->image + 0x200); + + // ebx = 0, ebp = 0, edi = 0, esi = zeropage + __asm__ __volatile__( + "movl $0, %%ebp \n" + "cli \n" + "jmp *%[entry] \n" ::[entry] "a"(entry), + [zeropage] "S"(k->zeropage), + "b"(0), "D"(0)); + for (;;) + ; +} + +static int load_kernel(EFI_BOOT_SERVICES* bs, uint8_t* image, size_t sz, kernel_t* k) { + UINT32 setup_sz; + UINT32 image_sz; + UINT32 setup_end; + EFI_PHYSICAL_ADDRESS mem; + + k->zeropage = NULL; + k->cmdline = NULL; + k->image = NULL; + k->pages = 0; + + if (sz < 1024) { + // way too small to be a kernel + goto fail; + } + + if (ZP32(image, ZP_HEADER) != 0x53726448) { + printf("kernel: invalid setup magic %08x\n", ZP32(image, ZP_HEADER)); + goto fail; + } + if (ZP16(image, ZP_VERSION) < 0x020B) { + printf("kernel: unsupported setup version %04x\n", ZP16(image, ZP_VERSION)); + goto fail; + } + setup_sz = (ZP8(image, ZP_SETUP_SECTS) + 1) * 512; + image_sz = (ZP32(image, ZP_SYSSIZE) * 16); + setup_end = ZP_JUMP + ZP8(image, ZP_JUMP + 1); + + printf("setup %d image %d hdr %04x-%04x\n", setup_sz, image_sz, ZP_SETUP, setup_end); + // image size may be rounded up, thus +15 + if ((setup_sz < 1024) || ((setup_sz + image_sz) > (sz + 15))) { + printf("kernel: invalid image size\n"); + goto fail; + } + + mem = 0xFF000; + if (bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, &mem)) { + printf("kernel: cannot allocate 'zero page'\n"); + goto fail; + } + k->zeropage = (void*)mem; + + mem = 0xFF000; + if (bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, &mem)) { + printf("kernel: cannot allocate commandline\n"); + goto fail; + } + k->cmdline = (void*)mem; + + mem = 0x100000; + k->pages = (image_sz + 4095) / 4096; + if (bs->AllocatePages(AllocateAddress, EfiLoaderData, k->pages + 1, &mem)) { + printf("kernel: cannot allocate kernel\n"); + goto fail; + } + k->image = (void*)mem; + + // setup zero page, copy setup header from kernel binary + ZeroMem(k->zeropage, 4096); + CopyMem(k->zeropage + ZP_SETUP, image + ZP_SETUP, setup_end - ZP_SETUP); + + CopyMem(k->image, image + setup_sz, image_sz); + + // empty commandline for now + ZP32(k->zeropage, ZP_CMDLINE) = (uint64_t)k->cmdline; + k->cmdline[0] = 0; + + // default to no ramdisk + ZP32(k->zeropage, ZP_RAMDISK_BASE) = 0; + ZP32(k->zeropage, ZP_RAMDISK_SIZE) = 0; + + // undefined bootloader + ZP8(k->zeropage, ZP_LOADER_TYPE) = 0xFF; + + printf("kernel @%p, zeropage @%p, cmdline @%p\n", + k->image, k->zeropage, k->cmdline); + + return 0; +fail: + if (k->image) { + bs->FreePages((EFI_PHYSICAL_ADDRESS)k->image, k->pages); + } + if (k->cmdline) { + bs->FreePages((EFI_PHYSICAL_ADDRESS)k->cmdline, 1); + } + if (k->zeropage) { + bs->FreePages((EFI_PHYSICAL_ADDRESS)k->zeropage, 1); + } + + return -1; +} + +int boot_kernel(EFI_HANDLE img, EFI_SYSTEM_TABLE* sys, + void* image, size_t sz, void* ramdisk, size_t rsz, + void* cmdline, size_t csz) { + EFI_BOOT_SERVICES* bs = sys->BootServices; + kernel_t kernel; + EFI_STATUS r; + UINTN key; + int n, i; + + EFI_GRAPHICS_OUTPUT_PROTOCOL* gop; + bs->LocateProtocol(&GraphicsOutputProtocol, NULL, (void**)&gop); + + printf("boot_kernel() from %p (%ld bytes)\n", image, sz); + if (ramdisk && rsz) { + printf("ramdisk at %p (%ld bytes)\n", ramdisk, rsz); + } + + if (load_kernel(sys->BootServices, image, sz, &kernel)) { + printf("Failed to load kernel image\n"); + return -1; + } + + ZP32(kernel.zeropage, ZP_EXTRA_MAGIC) = ZP_MAGIC_VALUE; + ZP32(kernel.zeropage, ZP_ACPI_RSD) = find_acpi_root(img, sys); + + ZP32(kernel.zeropage, ZP_FB_BASE) = (UINT32)gop->Mode->FrameBufferBase; + ZP32(kernel.zeropage, ZP_FB_WIDTH) = (UINT32)gop->Mode->Info->HorizontalResolution; + ZP32(kernel.zeropage, ZP_FB_HEIGHT) = (UINT32)gop->Mode->Info->VerticalResolution; + ZP32(kernel.zeropage, ZP_FB_STRIDE) = (UINT32)gop->Mode->Info->PixelsPerScanLine; + ZP32(kernel.zeropage, ZP_FB_FORMAT) = 5; // XRGB32 + ZP32(kernel.zeropage, ZP_FB_REGBASE) = 0; + ZP32(kernel.zeropage, ZP_FB_SIZE) = 256 * 1024 * 1024; + + if (cmdline) { + // Truncate the cmdline to fit on a page + if (csz >= 4095) { + csz = 4095; + } + memcpy(kernel.cmdline, cmdline, csz); + kernel.cmdline[csz] = '\0'; + } + if (ramdisk && rsz) { + ZP32(kernel.zeropage, ZP_RAMDISK_BASE) = (uint32_t) (uintptr_t) ramdisk; + ZP32(kernel.zeropage, ZP_RAMDISK_SIZE) = rsz; + } + n = process_memory_map(sys, &key, 0); + + for (i = 0; i < n; i++) { + struct e820entry* e = e820table + i; + printf("%016lx %016lx %s\n", e->addr, e->size, e820name[e->type]); + } + + r = sys->BootServices->ExitBootServices(img, key); + if (r == EFI_INVALID_PARAMETER) { + n = process_memory_map(sys, &key, 1); + r = sys->BootServices->ExitBootServices(img, key); + if (r) { + printf("Cannot ExitBootServices! (2) %s\n", efi_strerror(r)); + return -1; + } + } else if (r) { + printf("Cannot ExitBootServices! (1) %s\n", efi_strerror(r)); + return -1; + } + + install_memmap(&kernel, e820table, n); + start_kernel(&kernel); + + return 0; +}
diff --git a/src/magenta.h b/src/magenta.h new file mode 100644 index 0000000..3c2a1b9 --- /dev/null +++ b/src/magenta.h
@@ -0,0 +1,16 @@ +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <efi.h> + +typedef struct { + UINT8* zeropage; + UINT8* cmdline; + void* image; + UINT32 pages; +} kernel_t; + +int boot_kernel(EFI_HANDLE img, EFI_SYSTEM_TABLE* sys, + void* image, size_t sz, void* ramdisk, size_t rsz, + void* cmdline, size_t csz);
diff --git a/src/osboot.c b/src/osboot.c index 7639826..82e02e5 100644 --- a/src/osboot.c +++ b/src/osboot.c
@@ -7,358 +7,11 @@ #include <stdio.h> #include <string.h> -#include <utils.h> +#include <magenta.h> #include <netboot.h> - -#define E820_IGNORE 0 -#define E820_RAM 1 -#define E820_RESERVED 2 -#define E820_ACPI 3 -#define E820_NVS 4 -#define E820_UNUSABLE 5 +#include <utils.h> static EFI_GUID GraphicsOutputProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; -static EFI_GUID AcpiTableGUID = ACPI_TABLE_GUID; -static EFI_GUID Acpi2TableGUID = ACPI_20_TABLE_GUID; - -static UINT8 ACPI_RSD_PTR[8] = "RSD PTR "; - -const char* e820name[] = { - "IGNORE", - "RAM", - "RESERVED", - "ACPI", - "NVS", - "UNUSABLE", -}; - -struct e820entry { - UINT64 addr; - UINT64 size; - UINT32 type; -} __attribute__((packed)); - -unsigned e820type(unsigned uefi_mem_type) { - switch (uefi_mem_type) { - case EfiReservedMemoryType: - case EfiPalCode: - return E820_RESERVED; - case EfiRuntimeServicesCode: - case EfiRuntimeServicesData: -#if WITH_RUNTIME_SERVICES - return E820_RESERVED; -#else - return E820_RAM; -#endif - case EfiACPIReclaimMemory: - return E820_ACPI; - case EfiACPIMemoryNVS: - return E820_NVS; - case EfiLoaderCode: - case EfiLoaderData: - case EfiBootServicesCode: - case EfiBootServicesData: - case EfiConventionalMemory: - return E820_RAM; - case EfiMemoryMappedIO: - case EfiMemoryMappedIOPortSpace: - return E820_IGNORE; - default: - if (uefi_mem_type >= 0x80000000) { - return E820_RAM; - } - return E820_UNUSABLE; - } -} - -static unsigned char scratch[32768]; -static struct e820entry e820table[128]; - -int process_memory_map(EFI_SYSTEM_TABLE* sys, UINTN* _key, int silent) { - EFI_MEMORY_DESCRIPTOR* mmap; - struct e820entry* entry = e820table; - UINTN msize, off; - UINTN mkey, dsize; - UINT32 dversion; - unsigned n, type; - EFI_STATUS r; - - msize = sizeof(scratch); - mmap = (EFI_MEMORY_DESCRIPTOR*)scratch; - mkey = dsize = dversion = 0; - r = sys->BootServices->GetMemoryMap(&msize, mmap, &mkey, &dsize, &dversion); - if (!silent) - printf("r=%lx msz=%lx key=%lx dsz=%lx dvn=%x\n", r, msize, mkey, dsize, dversion); - if (r != EFI_SUCCESS) { - return -1; - } - if (msize > sizeof(scratch)) { - if (!silent) - printf("Memory Table Too Large (%ld entries)\n", (msize / dsize)); - return -1; - } - for (off = 0, n = 0; off < msize; off += dsize) { - mmap = (EFI_MEMORY_DESCRIPTOR*)(scratch + off); - type = e820type(mmap->Type); - if (type == E820_IGNORE) { - continue; - } - if ((n > 0) && (entry[n - 1].type == type)) { - if ((entry[n - 1].addr + entry[n - 1].size) == mmap->PhysicalStart) { - entry[n - 1].size += mmap->NumberOfPages * 4096UL; - continue; - } - } - entry[n].addr = mmap->PhysicalStart; - entry[n].size = mmap->NumberOfPages * 4096UL; - entry[n].type = type; - n++; - if (n == 128) { - if (!silent) - printf("E820 Table Too Large (%ld raw entries)\n", (msize / dsize)); - return -1; - } - } - *_key = mkey; - return n; -} - -#define ZP_E820_COUNT 0x1E8 // byte -#define ZP_SETUP 0x1F1 // start of setup structure -#define ZP_SETUP_SECTS 0x1F1 // byte (setup_size/512-1) -#define ZP_JUMP 0x200 // jump instruction -#define ZP_HEADER 0x202 // word "HdrS" -#define ZP_VERSION 0x206 // half 0xHHLL -#define ZP_LOADER_TYPE 0x210 // byte -#define ZP_RAMDISK_BASE 0x218 // word (ptr or 0) -#define ZP_RAMDISK_SIZE 0x21C // word (bytes) -#define ZP_EXTRA_MAGIC 0x220 // word -#define ZP_CMDLINE 0x228 // word (ptr) -#define ZP_SYSSIZE 0x1F4 // word (size/16) -#define ZP_XLOADFLAGS 0x236 // half -#define ZP_E820_TABLE 0x2D0 // 128 entries - -#define ZP_ACPI_RSD 0x080 // word phys ptr -#define ZP_FB_BASE 0x090 -#define ZP_FB_WIDTH 0x094 -#define ZP_FB_HEIGHT 0x098 -#define ZP_FB_STRIDE 0x09C -#define ZP_FB_FORMAT 0x0A0 -#define ZP_FB_REGBASE 0x0A4 -#define ZP_FB_SIZE 0x0A8 - -#define ZP_MAGIC_VALUE 0xDBC64323 - -#define ZP8(p, off) (*((UINT8*)((p) + (off)))) -#define ZP16(p, off) (*((UINT16*)((p) + (off)))) -#define ZP32(p, off) (*((UINT32*)((p) + (off)))) - -typedef struct { - UINT8* zeropage; - UINT8* cmdline; - void* image; - UINT32 pages; -} kernel_t; - -void install_memmap(kernel_t* k, struct e820entry* memmap, unsigned count) { - memcpy(k->zeropage + ZP_E820_TABLE, memmap, sizeof(*memmap) * count); - ZP8(k->zeropage, ZP_E820_COUNT) = count; -} - -void start_kernel(kernel_t* k) { - // 64bit entry is at offset 0x200 - UINT64 entry = (UINT64)(k->image + 0x200); - - // ebx = 0, ebp = 0, edi = 0, esi = zeropage - __asm__ __volatile__( - "movl $0, %%ebp \n" - "cli \n" - "jmp *%[entry] \n" ::[entry] "a"(entry), - [zeropage] "S"(k->zeropage), - "b"(0), "D"(0)); - for (;;) - ; -} - -int load_kernel(EFI_BOOT_SERVICES* bs, uint8_t* image, size_t sz, kernel_t* k) { - UINT32 setup_sz; - UINT32 image_sz; - UINT32 setup_end; - EFI_PHYSICAL_ADDRESS mem; - - k->zeropage = NULL; - k->cmdline = NULL; - k->image = NULL; - k->pages = 0; - - if (sz < 1024) { - // way too small to be a kernel - goto fail; - } - - if (ZP32(image, ZP_HEADER) != 0x53726448) { - printf("kernel: invalid setup magic %08x\n", ZP32(image, ZP_HEADER)); - goto fail; - } - if (ZP16(image, ZP_VERSION) < 0x020B) { - printf("kernel: unsupported setup version %04x\n", ZP16(image, ZP_VERSION)); - goto fail; - } - setup_sz = (ZP8(image, ZP_SETUP_SECTS) + 1) * 512; - image_sz = (ZP32(image, ZP_SYSSIZE) * 16); - setup_end = ZP_JUMP + ZP8(image, ZP_JUMP + 1); - - printf("setup %d image %d hdr %04x-%04x\n", setup_sz, image_sz, ZP_SETUP, setup_end); - // image size may be rounded up, thus +15 - if ((setup_sz < 1024) || ((setup_sz + image_sz) > (sz + 15))) { - printf("kernel: invalid image size\n"); - goto fail; - } - - mem = 0xFF000; - if (bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, &mem)) { - printf("kernel: cannot allocate 'zero page'\n"); - goto fail; - } - k->zeropage = (void*)mem; - - mem = 0xFF000; - if (bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, &mem)) { - printf("kernel: cannot allocate commandline\n"); - goto fail; - } - k->cmdline = (void*)mem; - - mem = 0x100000; - k->pages = (image_sz + 4095) / 4096; - if (bs->AllocatePages(AllocateAddress, EfiLoaderData, k->pages + 1, &mem)) { - printf("kernel: cannot allocate kernel\n"); - goto fail; - } - k->image = (void*)mem; - - // setup zero page, copy setup header from kernel binary - ZeroMem(k->zeropage, 4096); - CopyMem(k->zeropage + ZP_SETUP, image + ZP_SETUP, setup_end - ZP_SETUP); - - CopyMem(k->image, image + setup_sz, image_sz); - - // empty commandline for now - ZP32(k->zeropage, ZP_CMDLINE) = (uint64_t)k->cmdline; - k->cmdline[0] = 0; - - // default to no ramdisk - ZP32(k->zeropage, ZP_RAMDISK_BASE) = 0; - ZP32(k->zeropage, ZP_RAMDISK_SIZE) = 0; - - // undefined bootloader - ZP8(k->zeropage, ZP_LOADER_TYPE) = 0xFF; - - printf("kernel @%p, zeropage @%p, cmdline @%p\n", - k->image, k->zeropage, k->cmdline); - - return 0; -fail: - if (k->image) { - bs->FreePages((EFI_PHYSICAL_ADDRESS)k->image, k->pages); - } - if (k->cmdline) { - bs->FreePages((EFI_PHYSICAL_ADDRESS)k->cmdline, 1); - } - if (k->zeropage) { - bs->FreePages((EFI_PHYSICAL_ADDRESS)k->zeropage, 1); - } - - return -1; -} - -uint32_t find_acpi_root(EFI_HANDLE img, EFI_SYSTEM_TABLE* sys) { - EFI_CONFIGURATION_TABLE* cfgtab = sys->ConfigurationTable; - int i; - - for (i = 0; i < sys->NumberOfTableEntries; i++) { - if (!CompareGuid(&cfgtab[i].VendorGuid, &AcpiTableGUID) && - !CompareGuid(&cfgtab[i].VendorGuid, &Acpi2TableGUID)) { - // not an ACPI table - continue; - } - if (CompareMem(cfgtab[i].VendorTable, ACPI_RSD_PTR, 8)) { - // not the Root Description Pointer - continue; - } - return (uint64_t)cfgtab[i].VendorTable; - } - return 0; -} - -static EFI_GRAPHICS_OUTPUT_PROTOCOL* gop; - -int boot_kernel(EFI_HANDLE img, EFI_SYSTEM_TABLE* sys, - void* image, size_t sz, void* ramdisk, size_t rsz, - void* cmdline, size_t csz) { - kernel_t kernel; - EFI_STATUS r; - UINTN key; - int n, i; - - printf("boot_kernel() from %p (%ld bytes)\n", image, sz); - if (ramdisk && rsz) { - printf("ramdisk at %p (%ld bytes)\n", ramdisk, rsz); - } - - if (load_kernel(sys->BootServices, image, sz, &kernel)) { - printf("Failed to load kernel image\n"); - return -1; - } - - ZP32(kernel.zeropage, ZP_EXTRA_MAGIC) = ZP_MAGIC_VALUE; - ZP32(kernel.zeropage, ZP_ACPI_RSD) = find_acpi_root(img, sys); - - ZP32(kernel.zeropage, ZP_FB_BASE) = (UINT32)gop->Mode->FrameBufferBase; - ZP32(kernel.zeropage, ZP_FB_WIDTH) = (UINT32)gop->Mode->Info->HorizontalResolution; - ZP32(kernel.zeropage, ZP_FB_HEIGHT) = (UINT32)gop->Mode->Info->VerticalResolution; - ZP32(kernel.zeropage, ZP_FB_STRIDE) = (UINT32)gop->Mode->Info->PixelsPerScanLine; - ZP32(kernel.zeropage, ZP_FB_FORMAT) = 5; // XRGB32 - ZP32(kernel.zeropage, ZP_FB_REGBASE) = 0; - ZP32(kernel.zeropage, ZP_FB_SIZE) = 256 * 1024 * 1024; - - if (cmdline) { - // Truncate the cmdline to fit on a page - if (csz >= 4095) { - csz = 4095; - } - memcpy(kernel.cmdline, cmdline, csz); - kernel.cmdline[csz] = '\0'; - } - if (ramdisk && rsz) { - ZP32(kernel.zeropage, ZP_RAMDISK_BASE) = (uint32_t) (uintptr_t) ramdisk; - ZP32(kernel.zeropage, ZP_RAMDISK_SIZE) = rsz; - } - n = process_memory_map(sys, &key, 0); - - for (i = 0; i < n; i++) { - struct e820entry* e = e820table + i; - printf("%016lx %016lx %s\n", e->addr, e->size, e820name[e->type]); - } - - r = sys->BootServices->ExitBootServices(img, key); - if (r == EFI_INVALID_PARAMETER) { - n = process_memory_map(sys, &key, 1); - r = sys->BootServices->ExitBootServices(img, key); - if (r) { - printf("Cannot ExitBootServices! (2) %s\n", efi_strerror(r)); - return -1; - } - } else if (r) { - printf("Cannot ExitBootServices! (1) %s\n", efi_strerror(r)); - return -1; - } - - install_memmap(&kernel, e820table, n); - start_kernel(&kernel); - - return 0; -} #define KBUFSIZE (32*1024*1024) #define RBUFSIZE (256*1024*1024) @@ -481,7 +134,7 @@ return; } -void draw_logo(void) { +void draw_logo(EFI_GRAPHICS_OUTPUT_PROTOCOL* gop) { if (!gop) return; const uint32_t h_res = gop->Mode->Info->HorizontalResolution; @@ -600,8 +253,9 @@ InitializeLib(img, sys); InitGoodies(img, sys); + EFI_GRAPHICS_OUTPUT_PROTOCOL* gop; bs->LocateProtocol(&GraphicsOutputProtocol, NULL, (void**)&gop); - draw_logo(); + draw_logo(gop); printf("\nOSBOOT v0.2\n\n"); printf("Framebuffer base is at %lx\n\n", gop->Mode->FrameBufferBase);