diff --git a/apis/buttons/src/lib.rs b/apis/buttons/src/lib.rs index 565970f..f5d08b5 100644 --- a/apis/buttons/src/lib.rs +++ b/apis/buttons/src/lib.rs @@ -135,7 +135,7 @@ mod tests; // Driver number and command IDs // ----------------------------------------------------------------------------- -const DRIVER_NUM: u32 = 3; +pub const DRIVER_NUM: u32 = 3; // Command IDs const BUTTONS_COUNT: u32 = 0; diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index a863392..3509a40 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -14,6 +14,9 @@ libtock_platform = { path = "../platform" } [features] +# Initialize an allocator for access to heap memory +alloc_init = [] + # By default, libtock_runtime looks for the LIBTOCK_PLATFORM variable to decide # what layout file to use. If you are providing your own linker script, set # no_auto_layout to disable the layout file logic. diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 1054e41..b5c519a 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -19,6 +19,7 @@ //! and provide its own layout file. #![no_std] +#![feature(strict_provenance)] #![warn(unsafe_op_in_unsafe_fn)] pub mod startup; diff --git a/runtime/src/startup/mod.rs b/runtime/src/startup/mod.rs index 769bfe9..052479f 100644 --- a/runtime/src/startup/mod.rs +++ b/runtime/src/startup/mod.rs @@ -10,6 +10,8 @@ core::arch::global_asm!(include_str!("asm_arm.s")); #[cfg(target_arch = "riscv32")] core::arch::global_asm!(include_str!("asm_riscv32.s")); +static APP_HEAP_SIZE: Option<&'static str> = option_env!("APP_HEAP_SIZE"); + /// `set_main!` is used to tell `libtock_runtime` where the process binary's /// `main` function is. The process binary's `main` function must have the /// signature `FnOnce() -> T`, where T is some concrete type that implements @@ -83,6 +85,8 @@ extern "C" fn rust_start() -> ! { extern "Rust" { fn libtock_unsafe_main() -> !; static rt_header: RtHeader; + #[cfg(feature = "alloc_init")] + fn libtock_alloc_init(heap_bottom: *mut u8, heap_size: usize); } // TODO: Implement a safe memop API in libtock_platform and migrate these @@ -92,16 +96,46 @@ extern "C" fn rust_start() -> ! { // impact the execution of this process. #[cfg(not(feature = "no_debug_memop"))] unsafe { + // specify the top of the application stack which grows downwards TockSyscalls::syscall2::<{ syscall_class::MEMOP }>([ 10u32.into(), rt_header.stack_top.into(), ]); + + // specify the start of the application heap which grows upwards TockSyscalls::syscall2::<{ syscall_class::MEMOP }>([ 11u32.into(), rt_header.initial_break.into(), ]); } + #[cfg(feature = "alloc_init")] + { + let app_heap_size: usize = match APP_HEAP_SIZE { + Some(var) => var + .parse() + .ok() + .expect("could not parse APP_HEAP_SIZE as usize!"), + None => 9000, + }; + + // the heap starts after the `bss` section + let app_heap_bottom = unsafe { rt_header.bss_start.add(rt_header.bss_size) }; + + assert_eq!(app_heap_bottom.addr(), unsafe { + rt_header.bss_start.addr() + rt_header.bss_size + }); + + let app_heap_end = unsafe { app_heap_bottom.add(app_heap_size) }; + + unsafe { + // tell the kernel the new app heap break (which is the upper address bound of the process) + TockSyscalls::syscall2::<{ syscall_class::MEMOP }>([0u32.into(), app_heap_end.into()]); + + libtock_alloc_init(app_heap_bottom, app_heap_size); + } + } + // Safety: libtock_unsafe_main is defined by the set_main! macro, and its // signature matches the signature in the `extern` block in this function. unsafe { diff --git a/rust-toolchain b/rust-toolchain index e911a96..d139e12 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,7 +1,7 @@ [toolchain] # See https://rust-lang.github.io/rustup-components-history/ for a list of # recently nightlies and what components are available for them. -channel = "nightly-2022-06-10" +channel = "nightly-2023-02-01" components = ["clippy", "miri", "rustfmt"] targets = ["thumbv7em-none-eabi", "riscv32imac-unknown-none-elf",