[−][src]Crate ruspiro_boot
RusPiRo Boot Strapping for Raspberry Pi
This crates provides the startup routines that are needed to be run from a baremetal kernel on the RaspberryPi before execution could be handed over to Rust code.
Usage
Put the following code into your main rustfile of the binary that should be build for the Raspberry Pi:
#[macro_use] extern crate ruspiro_boot; come_alive_with!(alive); run_with!(running); fn alive(core: u32) { // do one-time initialization here } fn running(core: u32) -> ! { // do any processing here and ensure you never return from this function loop {} }
The bootstrapper requires specific symbols to be known to the linker to be able to build the final binary. To use the linker script that is provided as part of this crate in your own rust binary crate you could either copy them manually from the git repository based on your desired target architecture for the build: aarch32 linker script aarch64 linker script
Features
with_panic
will ensure that a default panic handler is implemented.singlecore
enforces the compilation of the single core boot sequence. Only the main core 0 is then running.ruspiro_pi3
is passed to dependent crates to properly build them for the desired Raspberry Pi version
To successfully build a bare metal binary using this crate for the boot strapping part it is
highly recomended to use the linker script provided by this crate. Based on the target
architecture to be built it is either link32.ld or link64.ld. To
conviniently refer to the linker scripts contained in this crate it's recommended to use a
specific build script in your project that copies the required file to your current project
folder and could then be referred to with the RUSTFLAG
parameter -C link-arg=-T./link<aarch>.ld
.
The build script is a simple build.rs
rust file in your project root with the following
contents:
use std::{env, fs, path::Path}; fn main() { // copy the linker script from the boot crate to the current directory // so it will be invoked by the linker let ld_source = env::var_os("DEP_RUSPIRO_BOOT_LINKERSCRIPT") .expect("error in ruspiro build, `ruspiro-boot` not a dependency?"); let src_file = Path::new(&ld_source); let trg_file = format!( "{}/{}", env::current_dir().unwrap().display(), src_file.file_name().unwrap().to_str().unwrap() ); println!("Copy linker script from {:?}, to {:?}", src_file, trg_file); fs::copy(src_file, trg_file).unwrap(); }
To get started you could check out the template projects here
Re-exports
pub use self::macros::*; |
Modules
macros | Macros |
Macros
come_alive_with | Use this macro to define the your custom one-time-initialization entry point function to be used once the mandatory boot process has finished and the processing is handed over to the high level rust code. As each core will come come alive one after another, this function is called with the core it's running on. The next core comes alive after the actual one finished processing this function |
run_with | Use this macro to define the never-returning processing entry point function to be used for the processing after all one-time initializations have been done. This function is intended to never return and is executed on each core individually. Therefore this function is called with the core number it's running on. |