From 64a6d88e5c5e73a4d683bf9bb893e4a205bb2d2b Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 25 Mar 2018 13:51:32 -0700 Subject: [PATCH] Truly enable virtual memory. Map is still identity-mapped. I think we need to sort and/or clean up the map before using a higher half address. In-kernel vga output not working yet, but do_the_set_registers() is getting called. --- src/boot/loader.h | 6 +++--- src/boot/main.c | 19 +++---------------- src/boot/memory.c | 47 +++++++++++++++++++++++++++++++--------------- src/boot/memory.h | 1 - src/boot/utility.h | 14 ++++++++++++++ 5 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/boot/loader.h b/src/boot/loader.h index 91fa356..dba4fd8 100644 --- a/src/boot/loader.h +++ b/src/boot/loader.h @@ -2,15 +2,15 @@ #include #ifndef KERNEL_PHYS_ADDRESS -#define KERNEL_PHYS_ADDRESS 0x0000000000100000 +#define KERNEL_PHYS_ADDRESS 0x100000 #endif #ifndef KERNEL_VIRT_ADDRESS -#define KERNEL_VIRT_ADDRESS 0x7fff000000000000 +#define KERNEL_VIRT_ADDRESS 0xf00000000 #endif #ifndef KERNEL_MEMTYPE -#define KERNEL_MEMTYPE 0xffffffff +#define KERNEL_MEMTYPE 0x80000000 #endif #ifndef KERNEL_FILENAME diff --git a/src/boot/main.c b/src/boot/main.c index 0a6bf7f..023d2bb 100644 --- a/src/boot/main.c +++ b/src/boot/main.c @@ -38,16 +38,6 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) // From here on out, use CHECK_EFI_STATUS_OR_FAIL instead // because the console is now set up - // Get info about the image - /* - con_status_begin(L"Gathering image information..."); - EFI_LOADED_IMAGE *info = 0; - EFI_GUID image_proto = EFI_LOADED_IMAGE_PROTOCOL_GUID; - status = ST->BootServices->HandleProtocol(ImageHandle, &image_proto, (void **)&info); - CHECK_EFI_STATUS_OR_FAIL(status); - con_status_ok(); - */ - con_status_begin(L"Loading kernel into memory..."); void *kernel_image = NULL; uint64_t kernel_length = 0; @@ -68,13 +58,12 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) version->gitsha & 0x0fffffff, version->gitsha & 0xf0000000 ? "*" : "" ); - Print(L"\n Entrypoint %d", version->entrypoint); void (*kernel_main)() = version->entrypoint; con_status_ok(); - //memory_dump_map(); + // memory_dump_map(); con_status_begin(L"Exiting boot services..."); UINTN memmap_size = 0, memmap_key = 0; @@ -97,14 +86,12 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) CHECK_EFI_STATUS_OR_FAIL(status); status = ST->BootServices->ExitBootServices(ImageHandle, memmap_key); - CHECK_EFI_STATUS_OR_FAIL(status); + CHECK_EFI_STATUS_OR_ASSERT(status, 0); status = memory_virtualize( - &kernel_image, memory_map, memmap_size, desc_size, desc_version); - - CHECK_EFI_STATUS_OR_FAIL(status); + CHECK_EFI_STATUS_OR_ASSERT(status, 0); kernel_main(); return EFI_LOAD_ERROR; diff --git a/src/boot/memory.c b/src/boot/memory.c index 7ea0fbd..8b6c34b 100644 --- a/src/boot/memory.c +++ b/src/boot/memory.c @@ -26,13 +26,19 @@ const CHAR16 *memory_type_names[] = { }; static const CHAR16 *memory_type_name(UINT32 value) { - if (value >= (sizeof(memory_type_names)/sizeof(CHAR16*))) + if (value >= (sizeof(memory_type_names)/sizeof(CHAR16*))) { + if (value == KERNEL_MEMTYPE) + return L"Kernel Image"; return L"Bad Type Value"; + } return memory_type_names[value]; } void EFIAPI memory_update_addresses(EFI_EVENT UNUSED *event, void *context) { - ST->RuntimeServices->ConvertPointer(0, (void **)context); + EFI_STATUS status; + status = ST->RuntimeServices->ConvertPointer(0, (void **)context); + + CHECK_EFI_STATUS_OR_ASSERT(status, *((void**)context)); } EFI_STATUS memory_mark_address_for_update(void **pointer) { @@ -46,17 +52,29 @@ EFI_STATUS memory_mark_address_for_update(void **pointer) { (void*)pointer, &event); - CHECK_EFI_STATUS_OR_RETURN(status, "Failed to create memory update event"); + CHECK_EFI_STATUS_OR_ASSERT(status, pointer); } -EFI_STATUS memory_virtualize(void **kernel_addr, EFI_MEMORY_DESCRIPTOR *memory_map, - UINTN memmap_size, UINTN desc_size, UINT32 desc_version) { - unsigned count = memmap_size / desc_size; - for (unsigned i=0; iType == KERNEL_MEMTYPE) { + //d->VirtualStart = (EFI_VIRTUAL_ADDRESS)KERNEL_VIRT_ADDRESS; + d->VirtualStart = (EFI_VIRTUAL_ADDRESS)d->PhysicalStart; + d->Attribute |= EFI_MEMORY_RUNTIME; + } + else /*if (d->Attribute & EFI_MEMORY_RUNTIME)*/ { + d->VirtualStart = (EFI_VIRTUAL_ADDRESS)d->PhysicalStart; + } + + d = (EFI_MEMORY_DESCRIPTOR *)((uint8_t *)d + desc_size); } return ST->RuntimeServices->SetVirtualAddressMap(memmap_size, desc_size, desc_version, memory_map); @@ -101,10 +119,9 @@ EFI_STATUS memory_dump_map() { EFI_MEMORY_DESCRIPTOR *end = (EFI_MEMORY_DESCRIPTOR *)((uint8_t *)buffer + buffer_size); EFI_MEMORY_DESCRIPTOR *d = buffer; while (d < end) { - UINTN size_bytes = d->NumberOfPages * PAGE_SIZE; - - Print(L"%23s ", memory_type_name(d->Type)); - Print(L"%016llx (%3d pages)\n", d->PhysicalStart, size_bytes / 0x1000); + int runtime = (d->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME; + Print(L"%23s%s ", memory_type_name(d->Type), runtime ? L"*" : L" "); + Print(L"%016llx (%3d pages)\n", d->PhysicalStart, d->NumberOfPages); d = (EFI_MEMORY_DESCRIPTOR *)((uint8_t *)d + desc_size); } diff --git a/src/boot/memory.h b/src/boot/memory.h index 12a2fe8..de8613b 100644 --- a/src/boot/memory.h +++ b/src/boot/memory.h @@ -4,7 +4,6 @@ EFI_STATUS memory_mark_address_for_update(void **pointer); EFI_STATUS memory_virtualize( - void **kernel_image, EFI_MEMORY_DESCRIPTOR *memory_map, UINTN memmap_size, UINTN desc_size, diff --git a/src/boot/utility.h b/src/boot/utility.h index 06e2d9e..b8c8ced 100644 --- a/src/boot/utility.h +++ b/src/boot/utility.h @@ -18,3 +18,17 @@ const CHAR16 *util_error_message(EFI_STATUS status); while (1) __asm__("hlt"); \ } +#define CHECK_EFI_STATUS_OR_ASSERT(s, d) \ + if (EFI_ERROR((s))) { \ + __asm__ __volatile__ ( \ + "movq %0, %%r8;" \ + "movq %1, %%r9;" \ + "movq %2, %%r10;" \ + "movq $0, %%rdx;" \ + "divq %%rdx;" \ + : \ + :"r"((uint64_t)s), "r"((uint64_t)d), "r"((uint64_t)__LINE__) \ + :"rax", "rdx", "r8", "r9", "r10" \ + ); \ + } +