Kernel: Simplify pre_init self-relocation a bit

Now that all declarations have hidden visibility, we don't need to use
inline asm to avoid GOT references here anymore.
This commit is contained in:
Sönke Holz authored and Sönke Holz committed 2026-08-05 15:39:22 +02:00
1 parent 681d709a8f
commit e6ae1993ea
2 files changed
+12 -49

No files matched your search

+6 -25
View File
@@ -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<PhysicalPtr>(+start_of_kernel_image);
auto dynamic_section_addr = bit_cast<PhysicalPtr>(+_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
+6 -24
View File
@@ -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<PhysicalPtr>(+start_of_kernel_image);
auto dynamic_section_addr = bit_cast<PhysicalPtr>(+_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