Hello all,
I'm a newbie in the Embedded rust world and in particular in the "bare metal rust execution". I'm working on a basic bare-metal Rust project that runs on qemu-system-aarch64
.
When calling the read_buf
function, which modifies a mutable slice, the program freezes in QEMU. If I comment out read_buf
or modify it so that it doesn't accept a slice, the program runs to completion. The problem appears when the function is not inlined (whatever is inside the function as long as it takes the reference to the slice as a parameter).
Here’s the problematic function :
#[inline(never)]
pub fn read_buf(buf: &mut [u8]) {
for i in 0..buf.len() {
buf[i] = (i + 35) as u8;
}
}
If I remove the inline(never), it works. If I change the function to accept a e.g., usize instead of the reference to the slice, it works. If I don't call the function, it works. But here, it freezes the execution.
Here’s the caller function :
pub extern "C" fn not_main() {
let out_str = b"AArch64 Bare Metal\n";
for byte in out_str {
unsafe {
while (ptr::read_volatile(UART0_FR) & UART_FR_TXFF) != 0 {}
ptr::write_volatile(UART0, *byte);
}
}
let mut toto: [u8; 16] = [0; 16];
for i in 0..10 {
toto[i] = i as u8;
}
read_buf(&mut toto); // <== Freezes execution
for byte in &toto {
unsafe {
while (ptr::read_volatile(UART0_FR) & UART_FR_TXFF) != 0 {}
ptr::write_volatile(UART0, *byte);
}
}
unsafe { system_off(); }
}
Build & Execution
cargo build --release
qemu-system-aarch64 -machine virt \
-m 1024M \
-cpu cortex-a53 \
-nographic \
-kernel target/aarch64-unknown-none/release/Toto
My ld
file:
ENTRY(_start)
SECTIONS
{
. = 0x40080000;
.text.boot : { *(.text.boot) }
.text : { *(.text) }
.data : { *(.data) }
.rodata : { *(.rodata) }
.bss : { *(.bss) }
. = ALIGN(8);
. = . + 0x4000;
LD_STACK_PTR = .;
}
My start.s
file:
.globl _start
.extern LD_STACK_PTR
.section ".text.boot"
_start:
ldr x30, =LD_STACK_PTR
mov sp, x30
bl not_main
.equ PSCI_SYSTEM_OFF, 0x84000008
.globl system_off
system_off:
ldr x0, =PSCI_SYSTEM_OFF
hvc #0
My .cargo/config.toml
[build]
target = "aarch64-unknown-none"
[target.aarch64-unknown-none]
rustflags = ["-C", "link-arg=--script=aarch64-qemu.ld"]
And my Cargo.toml
:
[package]
name = "aarch64-bare-metal"
version = "0.1.0"
edition = "2024"
[dependencies]
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
[[bin]]
name = "Toto"
path = "src/main.rs"
test = false
doctest = false
bench = false
Any help would be greatly appreciated.
Thanks