title: Raspberry 5 baremetal Hello World example keywords:raspi5,asm,c,kernel,arm64 # Raspberry 5 baremetal Hello World example ## Intro Here is base example that will allow to print out message to serial console, and debug application. This example is picked up from variouse resources to make easy start into baremetal programming for raspi5, similar route is for all other models. All commands are tested from raspi4, adjust sources for your system. ## Source code ### boot.S ``` .section ".text.boot" .global _start _start: // read cpu id, stop slave cores mrs x1, mpidr_el1 and x1, x1, #3 cbz x1, 2f // cpu id > 0, stop 1: wfe b 1b 2: // cpu id == 0 // set top of stack just before our code (stack grows to a lower address per AAPCS64) ldr x1, =_start mov sp, x1 // clear bss ldr x1, =__bss_start ldr w2, =__bss_size 3: cbz w2, 4f str xzr, [x1], #8 sub w2, w2, #1 cbnz w2, 3b // jump to C code, should not return 4: bl main // for failsafe, halt this core too b 1b ``` ### kernel.c ```c void main() { while (1) { } } ``` ### Makefile ```Makefile TOOLCHAIN=aarch64-linux-gnu- AS = ${TOOLCHAIN}as LD = ${TOOLCHAIN}ld SRCS = $(wildcard *.c) OBJS = $(SRCS:.c=.o) CFLAGS = -Wall -O2 -ffreestanding CC=$(TOOLCHAIN)gcc all: clean kernel8.img boot.o: boot.S ${CC} ${CFLAGS} -c boot.S -o boot.o %.o: %.c ${CC} ${CFLAGS} -c $< -o $@ kernel8.img: boot.o ${OBJS} ${LD} boot.o ${OBJS} -T linker.ld -o kernel8.elf ${TOOLCHAIN}objcopy -O binary kernel8.elf kernel8.img clean: rm -rf *.o *.img *.elf ``` ### config.txt ``` enable_jtag_gpio=1 ``` ### Compile source code ```sh make ``` ### Prepare for a boot ```sh cp ``` ## Debugging with OpenOCD+GDB The default openocd doesn't configration for raspi5. ### OpenOCD config for bcm2712.cfg If OpenOCD doesn't have the raspi5 config by default here is one that suppose to work. Copy it for example in default openocd script location in: ``` /usr/share/openocd/scripts/target/ ``` ```tcl # bcm2712.cfg # SPDX-License-Identifier: GPL-2.0-or-later # OpenOCD target config file # This file is based on target/bcm2711.cfg # I have checked that it works with Open On-Chip Debugger 0.12.0 # using the Raspberry Pi Debug-Probe interface transport select swd adapter speed 1000 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME bcm2712 } if { [info exists CHIPCORES] } { set _cores $CHIPCORES } else { set _cores 4 } if { [info exists USE_SMP] } { set _USE_SMP $USE_SMP } else { set _USE_SMP 0 } if { [info exists DAP_TAPID] } { set _DAP_TAPID $DAP_TAPID } else { set _DAP_TAPID 0x2ba00477 } # swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID swd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu # MEM-AP for direct access target create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0 # these addresses are obtained from the ROM table via 'dap info 0' command set _DBGBASE {0x80010000 0x80110000 0x80210000 0x80310000} set _CTIBASE {0x80020000 0x80120000 0x80220000 0x80320000} set _smp_command "target smp" for { set _core 0 } { $_core < $_cores } { incr _core } { set _CTINAME $_CHIPNAME.cti$_core set _TARGETNAME $_CHIPNAME.cpu$_core cti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core] target create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME set _smp_command "$_smp_command $_TARGETNAME" } if {$_USE_SMP} { eval $_smp_command } # default target is cpu0 targets $_CHIPNAME.cpu0 ``` Connecting pico probe and doint step by step analysis of basic loop ### Running OpenOCD Start openocd server ``` openocd -f interface/cmsis-dap.cfg -f target/bcm2712.cfg ``` Connect with gdb ``` gdb ``` and run inside gdb shell ``` tar ext :3333 ``` ## Links https://www.raspberrypi.com/documentation/computers/config_txt.html https://wiki.osdev.org/Raspberry_Pi_Bare_Bones https://www.rpi4os.com/part1-bootstrapping/ https://www.valvers.com/open-software/raspberry-pi/bare-metal-programming-in-c-part-1/ https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html https://macoy.me/blog/programming/RaspberryPi5Debugging https://gist.github.com/tnishinaga/219122a5f1e3973668ee78c0fb1c7bf9 https://forums.raspberrypi.com/viewtopic.php?p=2172522#p2172522 https://github.com/DSERIOUSGUY/HobOS