misc: Relocate to below 4GiB if possible when loaded above 4GiB

This commit is contained in:
mintsuki 2024-03-25 20:13:53 +01:00
parent 94e1b955c3
commit 2419a8c5be

View File

@ -28,6 +28,8 @@ void stage3_common(void);
#if defined (UEFI)
extern symbol __slide;
extern symbol __image_size;
extern symbol _start;
noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
gST = SystemTable;
@ -37,6 +39,28 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS status;
#if defined (__x86_64__)
if ((uintptr_t)__slide >= 0x100000000) {
size_t image_size_pages = ALIGN_UP((size_t)__image_size, 4096) / 4096;
size_t new_base;
for (new_base = 0x1000; new_base + image_size_pages < 0x100000000; new_base += 0x1000) {
EFI_PHYSICAL_ADDRESS _new_base = (EFI_PHYSICAL_ADDRESS)new_base;
status = gBS->AllocatePages(AllocateAddress, EfiLoaderData, image_size_pages, &_new_base);
if (status == 0) {
goto new_base_gotten;
}
}
panic(false, "Limine does not support being loaded above 4GiB");
new_base_gotten:
memcpy((void *)new_base, __slide, (size_t)__image_size);
__attribute__((ms_abi))
void (*new_entry_point)(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable);
new_entry_point = (void *)(new_base + ((uintptr_t)_start - (uintptr_t)__slide));
new_entry_point(ImageHandle, SystemTable);
__builtin_unreachable();
}
#endif
gST->ConOut->EnableCursor(gST->ConOut, false);
init_memmap();
@ -52,12 +76,6 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
init_gdt();
#endif
#if defined (__x86_64__)
if ((uintptr_t)__slide >= 0x100000000) {
panic(false, "Limine does not support being loaded above 4GiB");
}
#endif
disk_create_index();
boot_volume = NULL;