From 6897ae83e95300afbb236a9aa6e351cb6f816405 Mon Sep 17 00:00:00 2001 From: Fritz Stracke Date: Thu, 14 Aug 2025 14:04:33 +0200 Subject: [PATCH] feat: allow for usage of passed dtb addr When using different boot protocols, the dtb address can be passed to the loader. Use the passed dtb address instead of qemu default. Use qemu as fallback. --- src/arch/aarch64/console.rs | 2 +- src/arch/aarch64/entry.s | 26 ++++++++++++++++---------- src/arch/aarch64/mod.rs | 11 ++++++++--- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/arch/aarch64/console.rs b/src/arch/aarch64/console.rs index fd7f1496..3ad64d43 100644 --- a/src/arch/aarch64/console.rs +++ b/src/arch/aarch64/console.rs @@ -16,7 +16,7 @@ fn stdout() -> SerialPort { const SERIAL_PORT_ADDRESS: u32 = 0x09000000; let dtb = unsafe { - Fdt::from_ptr(sptr::from_exposed_addr(super::DEVICE_TREE as usize)) + Fdt::from_ptr(sptr::from_exposed_addr(super::get_dtb_addr() as usize)) .expect(".dtb file has invalid header") }; diff --git a/src/arch/aarch64/entry.s b/src/arch/aarch64/entry.s index d03af8d3..ad8a88d9 100644 --- a/src/arch/aarch64/entry.s +++ b/src/arch/aarch64/entry.s @@ -5,17 +5,20 @@ .section .text _linux: // Let's fake being linux! https://www.kernel.org/doc/Documentation/arm64/booting.txt - mov x0, #1 // code0: Do nothing here (no uefi) - b _start // code1: Branch to real stuff.... - .quad 0 // text_offset: linux needs none, neither do we + nop // code0: Do nothing here (no uefi) + b _linux_start // code1: Branch to real stuff.... + .quad 0 // text_offset: linux needs none, neither do we .quad prog_size - .quad 2 // flags: 4k pagesize. might need adjustment. Page size currently undefined. - .quad 0 // res2: reserved - .quad 0 // res3: reserved - .quad 0 // res4: reserved - .long 0x644d5241 // magic: "ARMx64" - .long 0 // res5: header size for efi boot. Not needed. + .quad 2 // flags: 4k pagesize. might need adjustment. Page size currently undefined. + .quad 0 // res2: reserved + .quad 0 // res3: reserved + .quad 0 // res4: reserved + .long 0x644d5241 // magic: "ARMx64" + .long 0 // res5: header size for efi boot. Not needed. .align 8 +_linux_start: + adr x8, dtb_addr + str x0, [x8, 0] _start: // Only proceed on the boot core. Park it otherwise. mrs x1, mpidr_el1 @@ -100,6 +103,7 @@ el_1_entry: .global l2k_pgtable .global l3_pgtable .global L0mib_pgtable +.global dtb_addr .align 12 l0_pgtable: @@ -131,4 +135,6 @@ L14mib_pgtable: L16mib_pgtable: .space 512*8, 0 L18mib_pgtable: - .space 512*8, 0 \ No newline at end of file + .space 512*8, 0 +dtb_addr: + .space 8, 0 \ No newline at end of file diff --git a/src/arch/aarch64/mod.rs b/src/arch/aarch64/mod.rs index d40e0613..7d0e9143 100644 --- a/src/arch/aarch64/mod.rs +++ b/src/arch/aarch64/mod.rs @@ -30,6 +30,7 @@ unsafe extern "C" { static mut l2k_pgtable: u64; static mut l3_pgtable: u64; static mut L0mib_pgtable: u64; + static mut dtb_addr: u64; } /// start address of the RAM at Qemu's virt emulation @@ -52,9 +53,13 @@ pub unsafe fn get_memory(_memory_size: u64) -> u64 { (ptr::addr_of_mut!(loader_end).expose_addr() as u64).align_up(LargePageSize::SIZE as u64) } +pub unsafe fn get_dtb_addr() -> u64 { + unsafe { if dtb_addr != 0 { dtb_addr } else { DEVICE_TREE } } +} + pub fn find_kernel() -> &'static [u8] { let dtb = unsafe { - Fdt::from_ptr(sptr::from_exposed_addr(DEVICE_TREE as usize)) + Fdt::from_ptr(sptr::from_exposed_addr(get_dtb_addr() as usize)) .expect(".dtb file has invalid header") }; let module_start = dtb @@ -112,7 +117,7 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { } = kernel_info; let dtb = unsafe { - Fdt::from_ptr(sptr::from_exposed_addr(DEVICE_TREE as usize)) + Fdt::from_ptr(sptr::from_exposed_addr(get_dtb_addr() as usize)) .expect(".dtb file has invalid header") }; let cpus = dtb.cpus().count(); @@ -217,7 +222,7 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { hardware_info: HardwareInfo { phys_addr_range: ram_start..ram_start + ram_size, serial_port_base: SerialPortBase::new(0x1000), - device_tree: core::num::NonZeroU64::new(DEVICE_TREE), + device_tree: unsafe { core::num::NonZeroU64::new(get_dtb_addr()) }, }, load_info, platform_info: PlatformInfo::LinuxBoot,