diff options
| -rw-r--r-- | md/writeup/raspberry5_baremetal_helloworld.md | 229 | 
1 files changed, 229 insertions, 0 deletions
diff --git a/md/writeup/raspberry5_baremetal_helloworld.md b/md/writeup/raspberry5_baremetal_helloworld.md new file mode 100644 index 0000000..ba5a575 --- /dev/null +++ b/md/writeup/raspberry5_baremetal_helloworld.md @@ -0,0 +1,229 @@ +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  | 
