Rust on QEMU (AArch64) - Issue with function call Freezing Execution

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