diff --git a/modules.yaml b/modules.yaml index 7882ef8..e34865d 100644 --- a/modules.yaml +++ b/modules.yaml @@ -62,6 +62,7 @@ modules: - src/boot/hardware.cpp - src/boot/loader.cpp - src/boot/memory.cpp + - src/boot/support.cpp nulldrv: kind: exe diff --git a/scripts/templates/exe.boot.j2 b/scripts/templates/exe.boot.j2 index 700f82e..c4be386 100644 --- a/scripts/templates/exe.boot.j2 +++ b/scripts/templates/exe.boot.j2 @@ -3,6 +3,7 @@ {{ super() }} ccflags = $ccflags $ + -g3 $ -DKERNEL_FILENAME=L\"jsix.elf\" $ -I${srcroot}/external/include $ -I${srcroot}/external/include/X64 diff --git a/src/boot/error.cpp b/src/boot/error.cpp index 18dcd5d..1f888bb 100644 --- a/src/boot/error.cpp +++ b/src/boot/error.cpp @@ -89,6 +89,8 @@ cpu_assert_handler::handle(uefi::status s, const wchar_t *message) } // namespace error } // namespace boot -extern "C" int _purecall() { ::boot::error::raise(uefi::status::unsupported, L"Pure virtual call"); } -void operator delete (void *) {} - +void debug_break() +{ + volatile int go = 0; + while (!go); +} diff --git a/src/boot/error.h b/src/boot/error.h index 6d4b5ac..c5435ef 100644 --- a/src/boot/error.h +++ b/src/boot/error.h @@ -58,6 +58,9 @@ public: } // namespace error } // namespace boot +/// Debugging psuedo-breakpoint. +void debug_break(); + /// Helper macro to raise an error if an operation fails. /// \arg s An expression evaluating to a UEFI status /// \arg m The error message to use on failure diff --git a/src/boot/main.cpp b/src/boot/main.cpp index b070e3e..cf09a0f 100644 --- a/src/boot/main.cpp +++ b/src/boot/main.cpp @@ -144,7 +144,7 @@ load_module( /// UEFI is still in control of the machine. (ie, while the loader still /// has access to boot services. loader::loaded_elf -bootloader_main_uefi(uefi::handle image, uefi::system_table *st, console &con) +bootloader_main_uefi(uefi::handle image, uefi::system_table *st, console &con, size_t *map_key) { error::uefi_handler handler(con); @@ -174,6 +174,9 @@ bootloader_main_uefi(uefi::handle image, uefi::system_table *st, console &con) memory::efi_mem_map efi_map = memory::get_uefi_mappings(bs); memory::build_kernel_mem_map(efi_map, args, bs); + efi_map = memory::get_uefi_mappings(bs); + *map_key = efi_map.key; + return kernel_elf; } @@ -288,10 +291,15 @@ efi_main(uefi::handle image_handle, uefi::system_table *st) error::cpu_assert_handler handler; console con(st->boot_services, st->con_out); + size_t map_key; loader::loaded_elf kernel = - bootloader_main_uefi(image_handle, st, con); + bootloader_main_uefi(image_handle, st, con, &map_key); - while(1); + try_or_raise( + st->boot_services->exit_boot_services(image_handle, map_key), + L"Failed to exit boot services"); + + debug_break(); return uefi::status::unsupported; } diff --git a/src/boot/memory.cpp b/src/boot/memory.cpp index 63a54f6..78fd115 100644 --- a/src/boot/memory.cpp +++ b/src/boot/memory.cpp @@ -67,6 +67,8 @@ init_pointer_fixup(uefi::boot_services *bs, uefi::runtime_services *rs) status_line status(L"Initializing pointer virtualization event"); uefi::event event; + bs->set_mem(&fixup_pointers, sizeof(fixup_pointers), 0); + fixup_pointer_index = 0; try_or_raise( bs->create_event( diff --git a/src/boot/support.cpp b/src/boot/support.cpp new file mode 100644 index 0000000..a438e91 --- /dev/null +++ b/src/boot/support.cpp @@ -0,0 +1,27 @@ +#include + +#include "error.h" + +extern "C" { + +/// Basic memcpy() implementation for clang. Clang requires freestanding code +/// implement memcpy(), as it may emit references to it. This basic memcpy is +/// not the most efficient, but will get linked if no other memcpy exists. +__attribute__ ((__weak__)) +void *memcpy(void *dest, const void *src, size_t n) +{ + uint8_t *cdest = reinterpret_cast(dest); + const uint8_t *csrc = reinterpret_cast(src); + for (size_t i = 0; i < n; ++i) + cdest[i] = csrc[i]; + return dest; +} + +int _purecall() +{ + ::boot::error::raise(uefi::status::unsupported, L"Pure virtual call"); +} + +} // extern "C" + +void operator delete (void *) {}