[boot] Fix call to exit_boot_services
Exiting boot services can't actually be done from inside `bootloader_uefi_main`, because there are objects in that scope that run code requiring boot services in their destructors. Also added `support.cpp` with `memcpy` because clang will emit references to `memcpy` even in freestanding mode. Added a `debug_break` function to allow for faking breakpoints when connecting to the bootloader with GDB. Tags: debug
This commit is contained in:
@@ -62,6 +62,7 @@ modules:
|
||||
- src/boot/hardware.cpp
|
||||
- src/boot/loader.cpp
|
||||
- src/boot/memory.cpp
|
||||
- src/boot/support.cpp
|
||||
|
||||
nulldrv:
|
||||
kind: exe
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
{{ super() }}
|
||||
|
||||
ccflags = $ccflags $
|
||||
-g3 $
|
||||
-DKERNEL_FILENAME=L\"jsix.elf\" $
|
||||
-I${srcroot}/external/include $
|
||||
-I${srcroot}/external/include/X64
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
27
src/boot/support.cpp
Normal file
27
src/boot/support.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#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<uint8_t*>(dest);
|
||||
const uint8_t *csrc = reinterpret_cast<const uint8_t*>(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 *) {}
|
||||
Reference in New Issue
Block a user