0
votes

I am working on bare metal programming for a Raspberry Pi 3. I have been able to blink a light using a tutorial and I am now trying to do the same in Rust.

My project contains the following files:

main.rs

#![no_main]
#![no_std]
#![feature(global_asm)]

global_asm!(include_str!("start.s"));

#[panic_handler]
fn on_panic(_info: &core::panic::PanicInfo) -> ! {
    loop {}
}

start.s

.section .init
.global _start

.equ BASE,  0x3f200000 //Base address
.equ GPFSEL2, 0x08          //FSEL2 register offset 
.equ GPSET0,  0x1c          //GPSET0 register offset
.equ GPCLR0,0x28            //GPCLR0 register offset
.equ SET_BIT3,   0x08       //sets bit three b1000      
.equ SET_BIT21,  0x200000   //sets bit 21
.equ COUNTER, 0xf0000

_start:
    ldr x0, =BASE
    ldr x1, =SET_BIT3
    str x1, [x0, #GPFSEL2]
    ldr x1, =SET_BIT21
    str x1, [x0, #GPSET0]

When I compile it for aarch64-unknown-none, I get the following output:

0000000000008000 <_start>:
    8000:       d2a7e400        mov     x0, #0x3f200000                 // #1059061760
    8004:       d2800101        mov     x1, #0x8                        // #8
    8008:       f9000401        str     x1, [x0, #8]
    800c:       d2a00401        mov     x1, #0x200000                   // #2097152
    8010:       f801c001        stur    x1, [x0, #28]

Disassembly of section .comment:

0000000000000000 <.comment>:
   0:   6b6e694c        .inst   0x6b6e694c ; undefined
   4:   203a7265        .inst   0x203a7265 ; undefined
   8:   20444c4c        .inst   0x20444c4c ; undefined
   c:   302e3231        adr     x17, 5c651 <_start+0x54651>
  10:   Address 0x0000000000000010 is out of bounds.

I then use the aarch64-none-elf-objcopy --strip-all -O binary $(KERNEL_ELF) kernel.img command to make the kernel file which I copy onto the SD card.

The LED does not blink. Is there a reason for this? How can I troubleshoot?

1
note you need an infinite loop at the end of that code so it doesnt run through memory...old_timer
do the 64 bit load at 0x8000 even with kernel.img? they might start up in aarch32 at 0x8000. when you did your assembly did you do it the same way?old_timer
actually the img file doesnt have address and this is position independent so for now that address should not be an issue. but kernel.img vs kernel8.img. did aarch64 work for you with that filename?old_timer
the way you are building the binary should be identical between the asm and rust if you used the same asm (same machine code).old_timer
@old_timer when I use the Rust kernel, the green light on the Pi blinks, which I think is meant to signal a detected image. I am using the exact same assembly in the Rust version, however as the disassembly shows, the rust compiler edits it.Someone

1 Answers

0
votes

It turns out that the issue was in my arch.json file, which I was using to specify the architecture and tooling for the compiler. Changing the linker and llvm target to arm-none-eabihf fixed this issue:

{
    "llvm-target": "arm-none-eabihf",
    "target-endian": "little",
    "target-pointer-width": "32",
    "target-c-int-width": "32",
    "os": "none",
    "env": "eabi",
    "vendor": "unknown",
    "arch": "arm",
    "linker-flavor": "ld",
    "linker": "arm-none-eabi-ld",
    "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
    "executables": true,
    "relocation-model": "static",
    "no-compiler-rt": true
}