Невозможно мигнуть светодиодом Raspberry Pi с использованием ржавчины из голого металла

#rust #raspberry-pi #arm #raspberry-pi3 #bare-metal

Вопрос:

Я работаю над программированием на голом металле для Raspberry Pi 3. Я смог мигнуть светом с помощью учебника, и теперь я пытаюсь сделать то же самое в Rust.

Мой проект содержит следующие файлы:

main.rs

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

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

#[panic_handler]
fn on_panic(_info: amp;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]
 

Когда я компилирую его для aarch64-неизвестно-нет, я получаю следующий вывод:

 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.
 

Затем я использую aarch64-none-elf-objcopy --strip-all -O binary $(KERNEL_ELF) kernel.img команду, чтобы создать файл ядра, который я копирую на SD-карту.

Светодиод не мигает. Есть ли для этого причина? Как я могу устранить неполадки?

Комментарии:

1. обратите внимание, что вам нужен бесконечный цикл в конце этого кода, чтобы он не проходил через память…

2. загружается ли 64-разрядная версия при 0x8000 даже с kernel.img? они могут запуститься в aarch32 при 0x8000. когда вы делали свою сборку, вы делали это таким же образом?

3. на самом деле у файла img нет адреса, и это не зависит от позиции, поэтому на данный момент этот адрес не должен быть проблемой. но kernel.img против kernel8.img. работал ли для вас aarch64 с этим именем файла?

4. способ, которым вы создаете двоичный файл, должен быть идентичным между asm и rust, если вы использовали один и тот же asm (один и тот же машинный код).

5. @old_timer когда я использую ядро ржавчины, на Pi мигает зеленый индикатор, который, как я думаю, должен сигнализировать об обнаруженном изображении. Я использую точно такую же сборку в версии Rust, однако, как показывает разборка, компилятор rust редактирует ее.

Ответ №1:

Оказывается, проблема была в моем arch.json файле, который я использовал для указания архитектуры и инструментов для компилятора. Изменение компоновщика и цели llvm для arm-none-eabihf устранения этой проблемы:

 {
    "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
}