multiboot: Take better care of not having the reloc stub overwritten

This commit is contained in:
mintsuki 2022-07-05 20:42:09 +02:00
parent 8e54ea461b
commit 009fb59b69
2 changed files with 20 additions and 10 deletions

View File

@ -166,6 +166,7 @@ bool multiboot1_load(char *config, char *cmdline) {
// Realloc elsewhere ranges to include mb1 info, modules, and elf sections
struct elsewhere_range *new_ranges = ext_mem_alloc(sizeof(struct elsewhere_range) *
(ranges_count
+ 1 /* relocation stub range */
+ 1 /* mb1 info range */
+ n_modules
+ (section_hdr_info ? section_hdr_info->num : 0)));
@ -174,6 +175,15 @@ bool multiboot1_load(char *config, char *cmdline) {
pmm_free(ranges, sizeof(struct elsewhere_range) * ranges_count);
ranges = new_ranges;
// Load relocation stub where it won't get overwritten (dummy elsewhere range)
size_t reloc_stub_size = (size_t)multiboot_reloc_stub_end - (size_t)multiboot_reloc_stub;
void *reloc_stub = ext_mem_alloc(reloc_stub_size);
memcpy(reloc_stub, multiboot_reloc_stub, reloc_stub_size);
ranges[ranges_count].elsewhere = (uintptr_t)reloc_stub;
ranges[ranges_count].target = (uintptr_t)reloc_stub;
ranges[ranges_count].length = reloc_stub_size;
ranges_count++;
// GRUB allocates boot info at 0x10000, *except* if the kernel happens
// to overlap this region, then it gets moved to right after the
// kernel, or whichever PHDR happens to sit at 0x10000.
@ -374,11 +384,6 @@ bool multiboot1_load(char *config, char *cmdline) {
#endif
}
// Load relocation stub where it won't get overwritten (hopefully)
size_t reloc_stub_size = (size_t)multiboot_reloc_stub_end - (size_t)multiboot_reloc_stub;
void *reloc_stub = ext_mem_alloc(reloc_stub_size);
memcpy(reloc_stub, multiboot_reloc_stub, reloc_stub_size);
#if uefi == 1
efi_exit_boot_services();
#endif

View File

@ -299,6 +299,7 @@ bool multiboot2_load(char *config, char* cmdline) {
// Realloc elsewhere ranges to include mb2 info, modules, and elf sections
struct elsewhere_range *new_ranges = ext_mem_alloc(sizeof(struct elsewhere_range) *
(ranges_count
+ 1 /* relocation stub range */
+ 1 /* mb2 info range */
+ n_modules
+ (section_hdr_info ? section_hdr_info->num : 0)));
@ -307,6 +308,15 @@ bool multiboot2_load(char *config, char* cmdline) {
pmm_free(ranges, sizeof(struct elsewhere_range) * ranges_count);
ranges = new_ranges;
// Load relocation stub where it won't get overwritten (dummy elsewhere range)
size_t reloc_stub_size = (size_t)multiboot_reloc_stub_end - (size_t)multiboot_reloc_stub;
void *reloc_stub = ext_mem_alloc(reloc_stub_size);
memcpy(reloc_stub, multiboot_reloc_stub, reloc_stub_size);
ranges[ranges_count].elsewhere = (uintptr_t)reloc_stub;
ranges[ranges_count].target = (uintptr_t)reloc_stub;
ranges[ranges_count].length = reloc_stub_size;
ranges_count++;
// GRUB allocates boot info at 0x10000, *except* if the kernel happens
// to overlap this region, then it gets moved to right after the
// kernel, or whichever PHDR happens to sit at 0x10000.
@ -665,11 +675,6 @@ bool multiboot2_load(char *config, char* cmdline) {
}
#endif
// Load relocation stub where it won't get overwritten (hopefully)
size_t reloc_stub_size = (size_t)multiboot_reloc_stub_end - (size_t)multiboot_reloc_stub;
void *reloc_stub = ext_mem_alloc(reloc_stub_size);
memcpy(reloc_stub, multiboot_reloc_stub, reloc_stub_size);
#if uefi == 1
efi_exit_boot_services();
#endif