Reputation: 453
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$
Upvotes: 0
Views: 1599
Reputation: 5925
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.
Upvotes: 1