diff --git a/config/linker-script.x b/config/linker-script.x index 7f9a8fa5..bf896a07 100644 --- a/config/linker-script.x +++ b/config/linker-script.x @@ -6,16 +6,14 @@ SECTIONS . = 0x80000000; /* Output a text section, starting with the entry point */ - .entry_point : ALIGN(0x1000) { - *(.entry_point) - } .text : ALIGN(0x4) { + _start *(.text) *(.text.*) } /* Output the rodata */ - .rodata : ALIGN(0x1000) { + .rodata : ALIGN(0x8) { KEEP(*(__*)) *(.rodata) *(.rodata.*) @@ -23,7 +21,7 @@ SECTIONS /* Finally, all data */ /* NOTE: no need to page-align bss, both bss and data are RW */ - .data : ALIGN(0x1000) { + .data : ALIGN(0x8) { KEEP(*(__*)) *(.data) *(.data.*) diff --git a/src/arch/metal.rs b/src/arch/metal.rs index c0a1aebe..cdc611e1 100644 --- a/src/arch/metal.rs +++ b/src/arch/metal.rs @@ -5,6 +5,7 @@ use core::ptr; use super::{Architecture, MCause, Mode}; use crate::virt::VirtContext; +use crate::{_stack_end, main}; /// Bare metal RISC-V runtime. pub struct Metal {} @@ -197,6 +198,25 @@ fn read_mtvec() -> usize { return mtvec; } +// —————————————————————————————— Entry Point ——————————————————————————————— // + +global_asm!( +r#" +.text +.global _start +_start: + ld sp, __stack_addr + j {main} + +// Store the address of the stack in memory +// That way it can be loaded as an absolute value +__stack_addr: + .dword {stack} +"#, + main = sym main, + stack = sym _stack_end, +); + // ————————————————————————————— Context Switch ————————————————————————————— // global_asm!( diff --git a/src/main.rs b/src/main.rs index 4a9505f5..0b6c4a16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,6 @@ mod logger; mod platform; mod virt; -use core::arch::asm; use core::panic::PanicInfo; use arch::{pmpcfg, Arch, Architecture}; @@ -19,31 +18,16 @@ use crate::virt::VirtContext; // Defined in the linker script extern "C" { - static _stack_start: usize; - static _stack_end: usize; + pub(crate) static _stack_start: usize; + pub(crate) static _stack_end: usize; } -#[no_mangle] -#[link_section = ".entry_point"] -pub unsafe extern "C" fn _start() -> ! { - /// Address of the top of the stack (stack grow towerd lower addresses) - static STACK: &'static usize = unsafe { &_stack_end }; - - // Initialize stack pointer and jump into main - // TODO: zero-out the BSS (QEMU might do it for us, but real hardware will not) - asm!( - "mv sp, {stack}", - "j {main}", - main = sym main, - stack = in(reg) STACK, - options(noreturn) - ); -} - -extern "C" fn main() -> ! { +pub(crate) extern "C" fn main(hart_id: usize, device_tree_blob_addr: usize) -> ! { init(); log::info!("Hello, world!"); + log::info!("Hart ID: {}", hart_id); log::info!("mstatus: 0x{:x}", Arch::read_mstatus()); + log::info!("DTS address: 0x{:x}", device_tree_blob_addr); log::info!("Preparing jump into payload"); let payload_addr = Plat::load_payload();