Как скомпилировать код ARMv8 для Raspberry pi 3

#assembly #raspberry-pi #raspberry-pi3 #armv8

#сборка #raspberry-pi #raspberry-pi3 #armv8

Вопрос:

Я следовал руководству по здесь, чтобы запрограммировать базовую ОС для моего raspberry pi. Я прочитал документацию и изменил регистры, чтобы они работали, но поскольку raspberry pi 3 64-разрядный и, следовательно, использует ARMv8, lsl выходит за рамки. Я использую Mac, поэтому использовал YAGARTO и действительно не знаю, как и где получить другой компилятор для 64-разрядной версии.

Код для всех, кому интересно:

 .section .init
.globl _start
_start:

ldr r0,=0x3f200000


mov r1,#1
lsl r1,#21
str r1,[r0,#16]


mov r1,#1
lsl r1,#47
str r1,[r0,#28]

loop$: 
b loop$
  

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

1. Это все еще 32-разрядный код ARM. 64-разрядный код ARM (ARM64, AArch64) выглядит немного иначе. Это не похоже на x86, где изменился только размер регистров; ARM64 — это совершенно другая архитектура с другими регистрами и инструкциями.

2. есть много примеров, которые можно найти через raspberrypi.org форумы baremetal. aarch32 и aarch64.

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

4. Вы самостоятельно разобрались с Мандельбротом? Я как раз собирался прокомментировать. Вы повторно использовали y переменную.

5. @Blorgbeard, спасибо, что разобрался с этим. Я заметил, что после того, как я изменил некоторые числа и получил бесконечный цикл. Спасибо:)

Ответ №1:

Я бы предложил взглянуть на примеры aarch64 Дэвида Уэлча для RaspberryPi 3 здесь. Его загрузчик позволяет загружать файлы в формате .hex для удобства.
Для справки, вы можете создать .hex из из скомпилированного исполняемого файла, используя следующую команду:

 aarch64-none-objcopy program.elf -O ihex example.elf example.hex
  

Что касается набора инструментов, Linaro и ARM предоставляют наборы инструментов только для Linux и mingw, насколько я знаю. Но вы могли бы использовать наборы инструментов, созданные отдельными пользователями для OSX, такие как этот, предоставленный Серхио Бенитесом.

Обновление: удобной альтернативой может быть установка u-boot на вашу SD-карту на основе отличной процедуры, описанной здесь.

Предполагая, что у вас будет набор инструментов aarch64-none, установленный в / opt, так что путь к aarch64-none-gcc будет:

 /opt/aarch64-none/bin/aarch64-none-gcc
  

Упрощенная процедура, подходящая для ваших нужд, будет:

Создание минимального config.txt на вашей SD-карте,

 enable_uart=1
arm_control=0x200
kernel=u-boot.bin
  

Копирование bootcode.bin, fixup.dat и start.elf на SD-карту,

Сборка u-boot,

 wget ftp://ftp.denx.de/pub/u-boot/u-boot-2019.01.tar.bz2
tar Jxf u-boot-2019.01.tar.bz2
cd u-boot-2019.01
make CROSS_COMPILE=/opt/aarch64-none/bin/aarch64-none- ARCH=arm64  rpi_3_defconfig all
  

Копирование u-boot.bin на SD-карту — теперь он должен содержать следующие файлы:

 2019-04-08  06:03 PM               108 config.txt
2019-04-08  04:11 PM         2,873,444 start.elf
2019-04-08  04:11 PM            52,296 bootcode.bin
2019-04-08  04:11 PM             6,701 fixup.dat
2019-04-08  04:08 PM           479,872 u-boot.bin
  

Установка SD-карты в Raspberry-pi3,
Предполагая, что у вас установлен ключ последовательного подключения к USB и эмулятор терминала, настроенный на использование последовательного порта USB со следующими настройками:

 115200 bps, 8 data bits, 1 stop bit, no parity, no hardware flow control
  

Теперь вы можете включить свое устройство и нажать CTRL C как можно скорее, чтобы прервать процесс загрузки:

 U-Boot 2019.01 (Apr 08 2019 - 16:07:23 -0400)

DRAM:  948 MiB
RPI 3 Model B (0xa22082)
MMC:   mmc@7e202000: 0, sdhci@7e300000: 1
Loading Environment from FAT... *** Warning - bad CRC, using default environment

In:    serial
Out:   vidconsole
Err:   vidconsole
Net:   No ethernet found.
starting USB...
USB0:   scanning bus 0 for devices... 3 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
Hit any key to stop autoboot:  0
U-Boot> <INTERRUPT>
  

Переменная среды bootdelay установлена в 2 (секунды), вам нужно установить ее в -1 (бесконечно), чтобы избежать использования CTRL C при каждой загрузке:

 U-Boot> printenv bootdelay
bootdelay=2
U-Boot> setenv bootdelay -1
U-Boot> saveenv
Saving Environment to FAT... OK
U-Boot>
  

Если вы введете команду сброса, pi перезагрузится, но u-boot остановится:

 U-Boot> reset
resetting ...
U

‡t-Boot 2019.01 (Apr 08 2019 - 16:07:23 -0400)

DRAM:  948 MiB
RPI 3 Model B (0xa22082)
MMC:   mmc@7e202000: 0, sdhci@7e300000: 1
Loading Environment from FAT... OK
In:    serial
Out:   vidconsole
Err:   vidconsole
Net:   No ethernet found.
starting USB...
USB0:   scanning bus 0 for devices... 3 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
U-Boot>
  

Теперь вы можете использовать все доступные команды u-boot для проверки / изменения памяти и загрузки / выполнения программы:

Создайте файл с именем hello-aarch64.s со следующим содержимым:

                   .title "hello-aarch64.s"
                  .arch  armv8-a
                  .equ   AUX_MU_IO_REG, 0x3F215040  
                  .equ   AUX_MU_LSR_REG, 0x3F215054 
                  .text
                  .section .text.startup,"ax"    
                  .globl Reset_Handler
Reset_Handler:    stp  x29, x30,  [sp, #-16]!        
                  adr  x19, msg
                  ldr  x20,= AUX_MU_IO_REG
                  ldr  x21,= AUX_MU_LSR_REG
loop:             ldrb w0, [x19], 1                  
                  cbz  w0, done               
wait:             ldrb w1, [x21]
                  tbz  w1, #5, wait
                  strb w0, [x20]
                  b    loop
done:             ldp  x29,x30,  [sp], #16                 
                  ret
                  .balign 16
msg:              .asciz "Hello, aarch64 bare-metal world!rn"
                  .end
  

Поскольку мы будем вызывать программу из u-boot и не хотим ее аварийного завершения, программа должна соответствовать стандарту вызова процедур ARM для 64-разрядной архитектуры ARM — здесь это несколько излишне, потому что мы не вызываем никакой функции, но это не имеет значения.

Программа может быть скомпилирована и файл s-записи создан с помощью следующих команд:

 CROSS_COMPILE= /opt/aarch64-none/bin/aarch64-none-
AS=${CROSS_COMPILE}as
LD=${CROSS_COMPILE}ld
OBJCOPY=${CROSS_COMPILE}objcopy
OBJDUMP=${CROSS_COMPILE}objdump
${AS} -o hello-aarch64.o hello-aarch64.s
${LD} -e Reset_Handler --section-start .text=0x00200000 -Map=hello-aarch64.map -o hello-aarch64.elf hello-aarch64.o 
${OBJCOPY} hello-aarch64.elf -O srec hello-aarch64.srec
  

Теперь программу можно загрузить и выполнить:
Введите следующую команду в u-boot:

 U-Boot> loads
## Ready for S-Record download ...
  

Из эмулятора терминала отправьте hello-aarch64.srec файл в u-boot (без x-modem, без kermit, просто файл как есть).

 ## First Load Addr = 0x00200000
## Last  Load Addr = 0x00200067
## Total Size      = 0x00000068 = 104 Bytes
## Start Addr      = 0x00200000
U-Boot>
  

Используйте go команду из u-boot для выполнения вашей программы ( go команда на самом деле call одна).

 U-Boot> go 0x00200000
## Starting application at 0x00200000 ...
Hello, aarch64 bare-metal world!
## Application terminated, rc = 0x0
U-Boot>
  

Вот и все, теперь у вас должна быть отличная и стандартная среда для изучения языка ассемблера aarch64.

Извините за многословие, но целью было предоставить минималистичную, но полную процедуру для людей, которым она понадобится.