summaryrefslogtreecommitdiff
path: root/md
diff options
context:
space:
mode:
Diffstat (limited to 'md')
-rw-r--r--md/writeup/raspberry5_baremetal_helloworld.md229
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