diff --git a/Kernel/Arch/aarch64/pre_init.cpp b/Kernel/Arch/aarch64/pre_init.cpp index 9016af5e2fa..3641be90da7 100644 --- a/Kernel/Arch/aarch64/pre_init.cpp +++ b/Kernel/Arch/aarch64/pre_init.cpp @@ -19,39 +19,20 @@ namespace Kernel { +extern "C" u8 start_of_kernel_image[]; +extern "C" u8 _DYNAMIC[]; + extern "C" [[noreturn]] void init(); -static UNMAP_AFTER_INIT PhysicalPtr physical_load_base() -{ - PhysicalPtr physical_load_base; - - asm volatile( - "adrp %[physical_load_base], start_of_kernel_image\n" - : [physical_load_base] "=r"(physical_load_base)); - - return physical_load_base; -} - -static UNMAP_AFTER_INIT PhysicalPtr dynamic_section_addr() -{ - PhysicalPtr dynamic_section_addr; - - // Use adrp+add explicitly to prevent a GOT load. - asm volatile( - "adrp %[dynamic_section_addr], _DYNAMIC\n" - "add %[dynamic_section_addr], %[dynamic_section_addr], :lo12:_DYNAMIC\n" - : [dynamic_section_addr] "=r"(dynamic_section_addr)); - - return dynamic_section_addr; -} - extern "C" [[noreturn]] void pre_init(PhysicalPtr flattened_devicetree_paddr); extern "C" [[noreturn]] void pre_init(PhysicalPtr flattened_devicetree_paddr) { // Apply relative relocations as if we were running at KERNEL_MAPPING_BASE. // This means that we shouldn't access anything during pre_init that relies on relocations (e.g. vtables). // Otherwise, we would have to relocate twice: once while running identity mapped, and again when we enable the MMU. - if (!ELF::perform_relative_relocations(physical_load_base(), KERNEL_MAPPING_BASE, dynamic_section_addr())) + auto physical_load_base = bit_cast(+start_of_kernel_image); + auto dynamic_section_addr = bit_cast(+_DYNAMIC); + if (!ELF::perform_relative_relocations(physical_load_base, KERNEL_MAPPING_BASE, dynamic_section_addr)) panic_without_mmu("Failed to perform relative relocations"sv); // We want to drop to EL1 as soon as possible, because that is the diff --git a/Kernel/Arch/riscv64/pre_init.cpp b/Kernel/Arch/riscv64/pre_init.cpp index df518d92712..64dd0ff3e8b 100644 --- a/Kernel/Arch/riscv64/pre_init.cpp +++ b/Kernel/Arch/riscv64/pre_init.cpp @@ -15,6 +15,9 @@ namespace Kernel { +extern "C" u8 start_of_kernel_image[]; +extern "C" u8 _DYNAMIC[]; + UNMAP_AFTER_INIT void dbgln_without_mmu(StringView message) { auto probe_result = SBI::Base::probe_extension(SBI::EID::DebugConsole); @@ -45,35 +48,14 @@ UNMAP_AFTER_INIT void dbgln_without_mmu(StringView message) panic_without_mmu("Unexpected trap"sv); } -static UNMAP_AFTER_INIT PhysicalPtr physical_load_base() -{ - PhysicalPtr physical_load_base; - - asm volatile( - "lla %[physical_load_base], start_of_kernel_image\n" - : [physical_load_base] "=r"(physical_load_base)); - - return physical_load_base; -} - -static UNMAP_AFTER_INIT PhysicalPtr dynamic_section_addr() -{ - PhysicalPtr dynamic_section_addr; - - // Use lla explicitly to prevent a GOT load. - asm volatile( - "lla %[dynamic_section_addr], _DYNAMIC\n" - : [dynamic_section_addr] "=r"(dynamic_section_addr)); - - return dynamic_section_addr; -} - extern "C" [[noreturn]] UNMAP_AFTER_INIT void pre_init(FlatPtr boot_hart_id, PhysicalPtr flattened_devicetree_paddr) { // Apply relative relocations as if we were running at KERNEL_MAPPING_BASE. // This means that we shouldn't access anything during pre_init that relies on relocations (e.g. vtables). // Otherwise, we would have to relocate twice: once while running identity mapped, and again when we enable the MMU. - if (!ELF::perform_relative_relocations(physical_load_base(), KERNEL_MAPPING_BASE, dynamic_section_addr())) + auto physical_load_base = bit_cast(+start_of_kernel_image); + auto dynamic_section_addr = bit_cast(+_DYNAMIC); + if (!ELF::perform_relative_relocations(physical_load_base, KERNEL_MAPPING_BASE, dynamic_section_addr)) panic_without_mmu("Failed to perform relative relocations"sv); // Catch traps in pre_init