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,