简体   繁体   中英

How to compile ARMv8 code for Raspberry pi 3

I've been following the tutorial at here to program a basic OS for my raspberry pi. I've read the documentation and changed the registers so that they should run but as the raspberry pi 3 is 64 bit and therefore uses ARMv8 the lsl is out of bounds. I'm using mac so was using YAGARTO and don't really know how or where to get another compiler for 64 bit.

The code for anyone interested:

.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$

I would suggest to have a look at David Welch's aarch64 examples for the RaspberryPi 3 here . His bootloader allows uploading files in .hex format for convenience.
For the record, you can create a .hex from from a compiled executable using the following command:

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

Regarding the toolchain, Linaro and ARM are only providing toolchains for Linux and mingw as far as I know. But you could use toolchains built by individuals for OSX, such as this one provided by Sergio Benitez.

Update: a convenient alternative could be to install u-boot on your SD-card based on the excellent procedure described here .

Assuming you would have the aarch64-none toolchain installed in /opt so that the path to aarch64-none-gcc would be:

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

A simplified procedure suitable to your needs would be:

Creating a minimal config.txt on your SD-card,

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

Copying bootcode.bin , fixup.dat and start.elf to the SD-card,

Building 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

Copying u-boot.bin to the SD-card - it should now contain the following files:

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

Installing the SD-Card into the Raspberry-pi3, Assuming you have a serial-to-USB dongle installed and a terminal emulator configured to use the USB serial port with the following settings:

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

You could now power-up your device, and press CTRL+C as soon as possible to interrupt the boot process:

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>

The bootdelay environment variable is set to 2 (seconds), you need to set it to -1 (infinite) in order to avoid using CTRL+C every time you boot:

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

If you enter the reset command, the pi will reboot, but u-boot will stop:

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>

You can now use all available u-boot commands for examining/changing the memory, and loading/executing a program:

Create a file named hello-aarch64.s with the following content:

                  .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!\r\n"
                  .end

Because we will call the program from u-boot and don't want to crash it, the program should be compliant with the ARM Procedure Call Standard for the ARM 64-bit Architecture - this is somewhat overkill here because we are not calling any function, but it does not matter.

The program can be compiled and an s-record file created by using the following commands:

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

The program can now be uploaded and executed: Enter the following command in u-boot:

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

From the terminal emulator, send the hello-aarch64.srec file to u-boot (no x-modem, no kermit, just the file as is).

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

Use the go command from u-boot for executing your program (the go command is actually a call one).

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

This is it, you should now have a great and standard environment for learning the aarch64 assembly language.

Sorry for having been verbose, but the goal was to provide a minimalist but complete procedure for people who would need one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM