Hello,
I am trying to build a very simple bare metal program for blinking an LED to the Raspberry Pi Zero W, but I have encountered a few problems.
First things first, there isn't an official build target for ARMv6-Z which the RPi Zero is based on, so I had to scour the internet for a target script which I did find in this topic, after the OSDev guide didn't work.
In the topic, it does mention that even a simple for loop causes the linker to throw an error, because it predicts the use of a panic handler, and I seem to have encountered the same problem, even though I am using the same target script, and building the same way as the solution seems to indicate, with the exception of using the assembly from the OSDev guide.
Here is lib.rs:
#![no_std]
#![no_main]
#![feature(lang_items)]
#![feature(core_intrinsics)]
use core::panic::PanicInfo;
mod mem;
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}
#[panic_handler]
pub extern fn panic(_panic_info: &PanicInfo) -> ! {
loop {}
}
#[no_mangle]
pub extern fn _kernel_entry() -> ! {
mem::write_addr_val(0x2020_0008, 0b1000);
loop {
mem::write_addr_val(0x2020_001C, 1<<21);
for _ in 1..50000 {
unsafe { core::arch::asm!("nop") };
}
mem::write_addr_val(0x2020_0028, 1<<21);
for _ in 1..50000 {
unsafe { core::arch::asm!("nop") };
}
}
}
Here is mem.rs:
pub fn read_addr_val(addr: u32) -> u32 {
let mut memory_addr_val: u32 = 0;
unsafe {
memory_addr_val = core::intrinsics::volatile_load(addr as *mut u32);
};
return memory_addr_val;
}
pub fn write_addr_val(addr: u32, value: u32) {
unsafe {
core::intrinsics::volatile_store(addr as *mut u32, value);
}
}
Here is my Cargo.toml:
[package]
name = "agbos"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
Here is my Makefile:
all: clean
cargo build --target=arm-none-eabihf.json -Z build-std=core,compiler_builtins
arm-none-eabi-gcc -mcpu=arm1176jzf-s -fpic -ffreestanding -c src/boot/boot.s -o build/boot.o
arm-none-eabi-gcc -T linker.ld -o bin/agbos.elf -ffreestanding -O2 -nostdlib build/boot.o target/arm-none-eabihf/debug/libagbos.rlib
arm-none-eabi-objcopy -O binary bin/agbos.elf bin/kernel.img
clean:
rm -rf bin/*
rm -rf build/*
echo "This is a placeholder file" > bin/placeholder
echo "This is a placeholder file" > build/placeholder
And here is the error I am getting from the linker:
/usr/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/bin/ld: target/arm-none-eabihf/debug/libagbos.rlib(agbos-bc8850426024c591.kz8stg7sqqwrrvg.rcgu.o): in function `core::ptr::read::runtime':
/home/arongeo/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/intrinsics.rs:2487: undefined reference to `core::panicking::panic_nounwind'
/usr/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/bin/ld: target/arm-none-eabihf/debug/libagbos.rlib(agbos-bc8850426024c591.kz8stg7sqqwrrvg.rcgu.o): in function `core::ptr::write::runtime':
/home/arongeo/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/intrinsics.rs:2487: undefined reference to `core::panicking::panic_nounwind'
/usr/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/bin/ld: target/arm-none-eabihf/debug/libagbos.rlib(agbos-bc8850426024c591.33woj6jg28126ek3.rcgu.o): in function `core::ptr::const_ptr::<impl *const T>::is_aligned_to':
/home/arongeo/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:1566: undefined reference to `core::panicking::panic_fmt'
/usr/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/bin/ld: target/arm-none-eabihf/debug/libagbos.rlib(agbos-bc8850426024c591.44bldghmgm5fml40.rcgu.o): in function `core::ptr::const_ptr::<impl *const T>::is_aligned_to::runtime_impl':
/home/arongeo/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:1571: undefined reference to `core::panicking::panic'
/usr/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/bin/ld: target/arm-none-eabihf/debug/libagbos.rlib(agbos-bc8850426024c591.537kmjnkoq6gdird.rcgu.o): in function `core::fmt::Arguments::new_const':
/home/arongeo/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/mod.rs:401: undefined reference to `core::panicking::panic_fmt'
collect2: error: ld returned 1 exit status
As I said I use the same linker script and assembly as in the OSDev guide, with the modification that it jumps to _kernel_entry of course, and I use the target file from the other topic on this.
Thank you for your help in advance.