Skip to content

Commit d064061

Browse files
committed
build: Add tooling and configuration for Raspberry Pi 5
1 parent 644474c commit d064061

10 files changed

Lines changed: 186 additions & 24 deletions

File tree

19_kernel_heap/Makefile

Lines changed: 78 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## SPDX-License-Identifier: MIT OR Apache-2.0
22
##
33
## Copyright (c) 2018-2023 Andre Richter <andre.o.richter@gmail.com>
4+
## Copyright (c) 2026 Devansh Lodha <devanshlodha12@gmail.com>
45

56
include ../common/docker.mk
67
include ../common/format.mk
@@ -63,6 +64,22 @@ else ifeq ($(BSP),rpi4)
6364
JTAG_BOOT_IMAGE = ../X1_JTAG_boot/jtag_boot_rpi4.img
6465
LD_SCRIPT_PATH = $(shell pwd)/kernel/src/bsp/raspberrypi
6566
RUSTC_MISC_ARGS = -C target-cpu=cortex-a72 -C force-frame-pointers
67+
else ifeq ($(BSP),rpi5)
68+
TARGET = aarch64-unknown-none-softfloat
69+
KERNEL_BIN = kernel8.img
70+
QEMU_BINARY = echo "RPi5 QEMU not supported"; \#
71+
QEMU_MACHINE_TYPE =
72+
QEMU_RELEASE_ARGS =
73+
QEMU_TEST_ARGS =
74+
OBJDUMP_BINARY = aarch64-none-elf-objdump
75+
NM_BINARY = aarch64-none-elf-nm
76+
READELF_BINARY = aarch64-none-elf-readelf
77+
GDB_BINARY = aarch64-elf-gdb
78+
GDB_INIT_FILE = ../debug/pi5/gdb-init.txt
79+
OPENOCD_ARG = -f ../debug/pi5/cmsis-dap.cfg -f ../debug/pi5/raspberrypi5.cfg
80+
JTAG_BOOT_IMAGE = ../X2_pi5_jtag_halt_stub/halt_stub.img
81+
LD_SCRIPT_PATH = $(shell pwd)/kernel/src/bsp/raspberrypi
82+
RUSTC_MISC_ARGS = -C target-cpu=cortex-a76 -C force-frame-pointers
6683
endif
6784

6885
# Export for build.rs.
@@ -129,11 +146,11 @@ COMPILER_ARGS = --target=$(TARGET) \
129146

130147
# build-std can be skipped for helper commands that do not rely on correct stack frames and other
131148
# custom compiler options. This results in a huge speedup.
132-
RUSTC_CMD = cargo rustc $(COMPILER_ARGS) -Z build-std=core,alloc --manifest-path $(KERNEL_MANIFEST)
133-
DOC_CMD = cargo doc $(COMPILER_ARGS)
134-
CLIPPY_CMD = cargo clippy $(COMPILER_ARGS)
135-
TEST_CMD = cargo test $(COMPILER_ARGS) -Z build-std=core,alloc --manifest-path $(KERNEL_MANIFEST)
136-
OBJCOPY_CMD = rust-objcopy \
149+
BASE_RUSTC_CMD = cargo rustc $(COMPILER_ARGS) -Z build-std=core,alloc --manifest-path $(KERNEL_MANIFEST)
150+
BASE_DOC_CMD = cargo doc $(COMPILER_ARGS)
151+
BASE_CLIPPY_CMD = cargo clippy $(COMPILER_ARGS)
152+
BASE_TEST_CMD = cargo test $(COMPILER_ARGS) -Z build-std=core,alloc --manifest-path $(KERNEL_MANIFEST)
153+
BASE_OBJCOPY_CMD = rust-objcopy \
137154
--strip-all \
138155
-O binary
139156

@@ -149,27 +166,41 @@ DOCKER_CMD = docker run -t --rm -v $(shell pwd):/work/tutorial -w /wo
149166
DOCKER_CMD_INTERACT = $(DOCKER_CMD) -i
150167
DOCKER_ARG_DIR_COMMON = -v $(shell pwd)/../common:/work/common
151168
DOCKER_ARG_DIR_JTAG = -v $(shell pwd)/../X1_JTAG_boot:/work/X1_JTAG_boot
169+
DOCKER_ARG_DIR_HALT = -v $(shell pwd)/../X2_pi5_jtag_halt_stub:/work/X2_pi5_jtag_halt_stub
170+
DOCKER_ARG_DIR_DEBUG = -v $(shell pwd)/../debug:/work/debug
152171
DOCKER_ARG_DEV = --privileged -v /dev:/dev
153172
DOCKER_ARG_NET = --network host
154173

155174
# DOCKER_IMAGE defined in include file (see top of this file).
156175
DOCKER_QEMU = $(DOCKER_CMD_INTERACT) $(DOCKER_IMAGE)
157176
DOCKER_TOOLS = $(DOCKER_CMD) $(DOCKER_IMAGE)
158177
DOCKER_TEST = $(DOCKER_CMD) $(DOCKER_ARG_DIR_COMMON) $(DOCKER_IMAGE)
159-
DOCKER_GDB = $(DOCKER_CMD_INTERACT) $(DOCKER_ARG_NET) $(DOCKER_IMAGE)
178+
DOCKER_GDB = $(DOCKER_CMD_INTERACT) $(DOCKER_ARG_NET) $(DOCKER_ARG_DIR_DEBUG) $(DOCKER_IMAGE)
160179

161180
# Dockerize commands, which require USB device passthrough, only on Linux.
162181
ifeq ($(shell uname -s),Linux)
163182
DOCKER_CMD_DEV = $(DOCKER_CMD_INTERACT) $(DOCKER_ARG_DEV)
164183

165184
DOCKER_CHAINBOOT = $(DOCKER_CMD_DEV) $(DOCKER_ARG_DIR_COMMON) $(DOCKER_IMAGE)
166185
DOCKER_JTAGBOOT = $(DOCKER_CMD_DEV) $(DOCKER_ARG_DIR_COMMON) $(DOCKER_ARG_DIR_JTAG) $(DOCKER_IMAGE)
167-
DOCKER_OPENOCD = $(DOCKER_CMD_DEV) $(DOCKER_ARG_NET) $(DOCKER_IMAGE)
186+
DOCKER_OPENOCD = $(DOCKER_CMD_DEV) $(DOCKER_ARG_NET) $(DOCKER_ARG_DIR_DEBUG) $(DOCKER_IMAGE)
187+
STUB_MAKE_CMD = $(DOCKER_CMD) $(DOCKER_ARG_DIR_HALT) -w /work/X2_pi5_jtag_halt_stub $(DOCKER_IMAGE) make
188+
else ifeq ($(shell uname -s),Darwin)
189+
DOCKER_OPENOCD =
190+
GDB_CMD = $(GDB_BINARY)
191+
STUB_MAKE_CMD = $(MAKE) -C ../X2_pi5_jtag_halt_stub
168192
else
169193
DOCKER_OPENOCD = echo "Not yet supported on non-Linux systems."; \#
194+
STUB_MAKE_CMD = echo "Not yet supported on non-Linux systems."; \#
170195
endif
171196

172-
197+
# These commands are always local, as per the repository's design
198+
RUSTC_CMD = $(BASE_RUSTC_CMD)
199+
DOC_CMD = $(BASE_DOC_CMD)
200+
CLIPPY_CMD = $(BASE_CLIPPY_CMD)
201+
TEST_CMD = $(BASE_TEST_CMD)
202+
OBJCOPY_CMD = $(BASE_OBJCOPY_CMD)
203+
CLEAN_CMD = cargo clean
173204

174205
##--------------------------------------------------------------------------------------------------
175206
## Targets
@@ -191,6 +222,7 @@ $(LAST_BUILD_CONFIG):
191222
##------------------------------------------------------------------------------
192223
$(KERNEL_ELF_RAW): $(KERNEL_ELF_RAW_DEPS)
193224
$(call color_header, "Compiling kernel ELF - $(BSP)")
225+
@echo "RUSTC_CMD: RUSTFLAGS=\"$(RUSTFLAGS_PEDANTIC)\" $(RUSTC_CMD)"
194226
@RUSTFLAGS="$(RUSTFLAGS_PEDANTIC)" $(RUSTC_CMD)
195227

196228
##------------------------------------------------------------------------------
@@ -297,7 +329,15 @@ nm: $(KERNEL_ELF)
297329
## Push the JTAG boot image to the real HW target
298330
##------------------------------------------------------------------------------
299331
jtagboot:
332+
ifeq ($(BSP),rpi5)
333+
$(call color_header, "Building RPi5 Halt Stub")
334+
@$(STUB_MAKE_CMD)
335+
@cp $(JTAG_BOOT_IMAGE) kernel8.img
336+
$(call color_progress_prefix, "Finished")
337+
@echo "Created kernel8.img. Please copy this to your SD card."
338+
else
300339
@$(DOCKER_JTAGBOOT) $(EXEC_MINIPUSH) $(DEV_SERIAL) $(JTAG_BOOT_IMAGE)
340+
endif
301341

302342
##------------------------------------------------------------------------------
303343
## Start OpenOCD session
@@ -312,7 +352,11 @@ openocd:
312352
gdb-opt0: RUSTC_MISC_ARGS += -C opt-level=0
313353
gdb gdb-opt0: $(KERNEL_ELF)
314354
$(call color_header, "Launching GDB")
315-
@$(DOCKER_GDB) gdb-multiarch -q $(KERNEL_ELF)
355+
ifeq ($(BSP),rpi5)
356+
@$(GDB_CMD) -q -x $(GDB_INIT_FILE) $(KERNEL_ELF)
357+
else
358+
@$(GDB_CMD) -q $(KERNEL_ELF)
359+
endif
316360

317361

318362

@@ -323,19 +367,18 @@ gdb gdb-opt0: $(KERNEL_ELF)
323367

324368
test_unit test_integration: FEATURES += --features test_build
325369

326-
ifeq ($(QEMU_MACHINE_TYPE),) # QEMU is not supported for the board.
327-
328-
test_boot test_unit test_integration test:
329-
$(call color_header, "$(QEMU_MISSING_STRING)")
330-
331-
else # QEMU is supported.
332-
333370
##------------------------------------------------------------------------------
334371
## Run boot test
335372
##------------------------------------------------------------------------------
336373
test_boot: $(KERNEL_BIN)
337-
$(call color_header, "Boot test - $(BSP)")
374+
ifeq ($(BSP),rpi5)
375+
@$(call color_header, "Skipping boot test for $(BSP) (no QEMU support)")
376+
else ifeq ($(QEMU_MACHINE_TYPE),)
377+
@$(call color_header, "$(QEMU_MISSING_STRING)")
378+
else
379+
@$(call color_header, "Boot test - $(BSP)")
338380
@$(DOCKER_TEST) $(EXEC_TEST_DISPATCH) $(EXEC_QEMU) $(QEMU_RELEASE_ARGS) -kernel $(KERNEL_BIN)
381+
endif
339382

340383
##------------------------------------------------------------------------------
341384
## Helpers for unit and integration test targets
@@ -376,18 +419,30 @@ endef
376419
## Run unit test(s)
377420
##------------------------------------------------------------------------------
378421
test_unit:
379-
$(call color_header, "Compiling unit test(s) - $(BSP)")
380-
$(call test_prepare)
422+
ifeq ($(BSP),rpi5)
423+
@echo "## Compiling unit test(s) for $(BSP), but not running."
424+
@echo "Due to no QEMU support, tests are built but not executed."
425+
@echo "Load and run the test binaries on-target manually for verification."
426+
@RUSTFLAGS="$(RUSTFLAGS_PEDANTIC)" $(TEST_CMD) --no-run --lib
427+
else
428+
@$(call color_header, "Compiling unit test(s) - $(BSP)")
429+
@$(call test_prepare)
381430
@RUSTFLAGS="$(RUSTFLAGS_PEDANTIC)" $(TEST_CMD) --lib
431+
endif
382432

383433
##------------------------------------------------------------------------------
384434
## Run integration test(s)
385435
##------------------------------------------------------------------------------
386436
test_integration:
387-
$(call color_header, "Compiling integration test(s) - $(BSP)")
388-
$(call test_prepare)
437+
ifeq ($(BSP),rpi5)
438+
@echo "## Compiling integration test(s) for $(BSP), but not running."
439+
@echo "Due to no QEMU support, tests are built but not executed."
440+
@echo "Load and run the test binaries on-target manually for verification."
441+
@RUSTFLAGS="$(RUSTFLAGS_PEDANTIC)" $(TEST_CMD) --no-run $(TEST_ARG)
442+
else
443+
@$(call color_header, "Compiling integration test(s) - $(BSP)")
444+
@$(call test_prepare)
389445
@RUSTFLAGS="$(RUSTFLAGS_PEDANTIC)" $(TEST_CMD) $(TEST_ARG)
446+
endif
390447

391448
test: test_boot test_unit test_integration
392-
393-
endif

19_kernel_heap/tools/translation_table_tool/bsp.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# SPDX-License-Identifier: MIT OR Apache-2.0
44
#
55
# Copyright (c) 2021-2023 Andre Richter <andre.o.richter@gmail.com>
6+
# Copyright (c) 2026 Devansh Lodha <devanshlodha12@gmail.com>
67

78
# Raspberry Pi 3 + 4
89
class RaspberryPi
@@ -41,6 +42,8 @@ def phys_addr_space_end_page
4142
x[0]
4243
when :rpi4
4344
x[1]
45+
when :rpi5
46+
x[2]
4447
else
4548
raise
4649
end

19_kernel_heap/tools/translation_table_tool/main.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# SPDX-License-Identifier: MIT OR Apache-2.0
55
#
66
# Copyright (c) 2021-2023 Andre Richter <andre.o.richter@gmail.com>
7+
# Copyright (c) 2026 Devansh Lodha <devanshlodha12@gmail.com>
78

89
require 'rubygems'
910
require 'bundler/setup'
@@ -23,7 +24,7 @@
2324
KERNEL_ELF = KernelELF.new(kernel_elf_path)
2425

2526
BSP = case BSP_TYPE
26-
when :rpi3, :rpi4
27+
when :rpi3, :rpi4, :rpi5
2728
RaspberryPi.new
2829
else
2930
raise

X2_pi5_jtag_halt_stub/Makefile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# SPDX-License-Identifier: MIT OR Apache-2.0
2+
#
3+
# Copyright (c) 2025 Devansh Lodha <devanshlodha12@gmail.com>
4+
5+
# This Makefile is designed to be called from the parent directory's
6+
# Docker environment, which provides the aarch64-elf toolchain.
7+
8+
CROSS_COMPILE ?= aarch64-elf-
9+
OBJCOPY = $(CROSS_COMPILE)objcopy
10+
AS = $(CROSS_COMPILE)as
11+
LD = $(CROSS_COMPILE)ld
12+
13+
IMG_NAME = halt_stub.img
14+
ELF_NAME = halt_stub.elf
15+
OBJ_NAME = start.o
16+
17+
.PHONY: all clean
18+
19+
all: $(IMG_NAME)
20+
21+
$(IMG_NAME): $(ELF_NAME)
22+
@echo "--- Building Halt Stub Image ---"
23+
@$(OBJCOPY) -O binary $(ELF_NAME) $(IMG_NAME)
24+
25+
$(ELF_NAME): $(OBJ_NAME)
26+
@$(LD) -T linker.ld -o $(ELF_NAME) $(OBJ_NAME)
27+
28+
$(OBJ_NAME): start.s
29+
@$(AS) -o $(OBJ_NAME) start.s
30+
31+
clean:
32+
@rm -f $(IMG_NAME) $(ELF_NAME) $(OBJ_NAME)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_ ����

X2_pi5_jtag_halt_stub/linker.ld

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* SPDX-License-Identifier: MIT OR Apache-2.0
3+
*
4+
* Copyright (c) 2025 Devansh Lodha <devanshlodha12@gmail.com>
5+
*/
6+
7+
ENTRY(_start)
8+
SECTIONS
9+
{
10+
. = 0x80000;
11+
.text : { *(.text.boot) }
12+
}

X2_pi5_jtag_halt_stub/start.s

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* SPDX-License-Identifier: MIT OR Apache-2.0
3+
*
4+
* Copyright (c) 2025 Devansh Lodha <devanshlodha12@gmail.com>
5+
*/
6+
7+
.section ".text.boot"
8+
.global _start
9+
_start:
10+
wfe // Wait for event (low-power idle)
11+
b _start

debug/pi5/cmsis-dap.cfg

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: MIT OR Apache-2.0
2+
#
3+
# Copyright (c) 2025 Devansh Lodha <devanshlodha12@gmail.com>
4+
5+
adapter driver cmsis-dap

debug/pi5/gdb-init.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# SPDX-License-Identifier: MIT OR Apache-2.0
2+
#
3+
# Copyright (c) 2025 Devansh Lodha <devanshlodha12@gmail.com>
4+
5+
# 1. Connect to the OpenOCD server.
6+
target remote 127.0.0.1:3333
7+
8+
# 2. Reset the Pi and halt it at the very beginning.
9+
monitor reset init
10+
11+
# 3. Load your program's symbols and code into the Pi's RAM.
12+
load
13+
14+
# 4. Set the Program Counter to the start of our code.
15+
set $pc = 0x80000
16+
17+
# 5. Continue
18+
continue

debug/pi5/raspberrypi5.cfg

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# SPDX-License-Identifier: MIT OR Apache-2.0
2+
#
3+
# Copyright (c) 2025 Devansh Lodha <devanshlodha12@gmail.com>
4+
5+
transport select swd
6+
adapter speed 4000
7+
reset_config srst_push_pull srst_only
8+
set _CHIPNAME bcm2712
9+
set _DAP_TAPID 0x4ba00477
10+
set _CHIPCORES 4
11+
swd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID
12+
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
13+
set _DBGBASE {0x80010000 0x80110000 0x80210000 0x80310000}
14+
set _CTIBASE {0x80020000 0x80120000 0x80220000 0x80320000}
15+
for { set _core 0 } { $_core < $_CHIPCORES } { incr _core } {
16+
set _CTINAME $_CHIPNAME.cti$_core
17+
set _TARGETNAME $_CHIPNAME.cpu$_core
18+
cti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]
19+
target create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -coreid $_core -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME
20+
$_TARGETNAME configure -event gdb-attach { halt }
21+
}
22+
targets $_CHIPNAME.cpu0
23+
init
24+
$_CHIPNAME.cpu0 configure -event reset-init { halt }

0 commit comments

Comments
 (0)