Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Supported targets in this repository:

- `grisp2`
- `kontron-albl-imx8mm`
- `rpi0w`
- `rpi02w`

## Getting Started

Expand Down
1 change: 1 addition & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ Vagrant.configure('2') do |config|
config.vm.provision 'file', source: "system_grisp2", destination: "/home/vagrant/system_grisp2"
config.vm.provision 'file', source: "system_kontron-albl-imx8mm", destination: "/home/vagrant/system_kontron-albl-imx8mm"
config.vm.provision 'file', source: "system_rpi0w", destination: "/home/vagrant/system_rpi0w"
config.vm.provision 'file', source: "system_rpi02w", destination: "/home/vagrant/system_rpi02w"

config.vm.provider :vmware_desktop do |v, override|
# On MacOS, NFS sometimes freezes, use vmware GHFS instead.
Expand Down
3 changes: 3 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ repo-level [`README.md`](../README.md).
the Vagrant wrapper fits in on non-Linux hosts.
- [`porting-notes.md`](./porting-notes.md): short field notebook of
traps encountered during target bring-up.
- [`porting-notes-rpi02w.md`](./porting-notes-rpi02w.md): delta notes
for porting from `system_rpi0w` to `system_rpi02w`.

## Index

Expand All @@ -21,6 +23,7 @@ repo-level [`README.md`](../README.md).
| `system_grisp2` | Supported | (no design doc yet) |
| `system_kontron-albl-imx8mm` | Supported | (no design doc yet) |
| `system_rpi0w` | In development; first-boot working, peripheral bring-up staged, A/B lifecycle not yet exercised on hardware | [`system_rpi0w.md`](./system_rpi0w.md) |
| `system_rpi02w` | In development; initial target scaffold for Cortex-A53/ARMv8, hardware validation pending | [`system_rpi02w.md`](./system_rpi02w.md) |

## What a target design doc should cover

Expand Down
60 changes: 60 additions & 0 deletions docs/porting-notes-rpi02w.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# `rpi02w` Porting Notes (vs `rpi0w`)

This note captures what was different when bringing up `system_rpi02w`
from the existing `system_rpi0w` target.

## CPU / ABI

- SoC class changes from ARMv6 to ARMv8-A (`cortex-a53`).
- Userspace/toolchain moves from 32-bit ARM to `aarch64-unknown-linux-gnu`.
- New toolchain defconfigs:
- `toolchain/configs/rpi02w_linux_x86_64_defconfig`
- `toolchain/configs/rpi02w_linux_aarch64_defconfig`

## Kernel / Boot Artifacts

- Kernel image consumed by firmware is `kernel8.img` (sourced from Buildroot `Image`).
- DTB switches to `bcm2710-rpi-zero-2-w.dtb`.
- `config.txt` requires 64-bit boot settings:
- `arm_64bit=1`
- `kernel=kernel8.img`
- explicit `start_file` / `fixup_file` selection
- `cmdline-a.txt` / `cmdline-b.txt` map to rootfs A/B:
- `root=/dev/mmcblk0p5` and `root=/dev/mmcblk0p6`

## Firmware Layout / fwup

- `system_rpi02w/fwup_include/fwup-common.conf` intentionally mirrors
`system_rpi0w` partition geometry to preserve the same A/B update style:
- AUTOBOOT offset/count: `2048 / 32768`
- BOOT-A offset/count: `34816 / 65536`
- BOOT-B offset/count: `100352 / 65536`
- ROOTFS-A offset/count: `167936 / 286720`
- ROOTFS-B offset/count: `456704 / 286720`
- APP offset/count: `745472 / 1048576 (expand)`
- `fwup.conf` keeps GRiSP A/B state semantics (`upgrade.*`, `validate.*`,
`rollback.*`, `status.*`) while using Pi `tryboot` behavior via
`autoboot.txt`.

## Console / Device Bring-up

- USB gadget serial remains the primary Erlang console (`ttyGS0`).
- UART console (`ttyAMA0`) remains enabled for early boot diagnostics.
- Bluetooth on mini-UART requires explicit kernel config enablement:
- `CONFIG_BT_HCIUART`, `CONFIG_BT_HCIUART_BCM`,
`CONFIG_BT_HCIUART_SERDEV`, `CONFIG_BT_BCM`
- `CONFIG_SERIAL_DEV_BUS` and `CONFIG_SERIAL_DEV_CTRL_TTYPORT`

## Build / Integration Touchpoints

- Add `system_rpi02w` folder and `VERSION`.
- Add `system_rpi02w` provisioning entry in `Vagrantfile`.
- Add `rpi02w` to supported target list in top-level `README.md`.
- Add `system_rpi02w` docs entry in `docs/README.md`.

## Observed Bring-up Pitfalls

- Stale SD boot files can hide source fixes; verify BOOT-A `config.txt` and
`cmdline.txt` match the current repo before concluding boot regressions.
- ACT LED heartbeat in `config.txt` can look like a fault blink pattern;
use UART output to classify real early-boot failures.
45 changes: 45 additions & 0 deletions docs/system_rpi02w.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# `system_rpi02w`: Architecture Notes

Design note for the Raspberry Pi Zero 2 W target.

## Overview

`system_rpi02w` is the Pi Zero 2 W sibling of `system_rpi0w`.
It keeps the same GRiSP Alloy update model (`fwup` tasks + uboot-env
schema + tryboot flow), but moves to a Cortex-A53/ARMv8 (aarch64)
toolchain and the Zero 2 W DTB.

## Key Deltas vs `system_rpi0w`

- Target name: `rpi02w`
- Toolchain tuple: `aarch64-unknown-linux-gnu`
- Crosstool configs:
- `toolchain/configs/rpi02w_linux_x86_64_defconfig`
- `toolchain/configs/rpi02w_linux_aarch64_defconfig`
- Buildroot arch selection in `system_rpi02w/defconfig`:
- `BR2_aarch64=y`
- `BR2_cortex_a53=y`
- Firmware DTB payload in `system_rpi02w/fwup.conf`:
- `bcm2710-rpi-zero-2-w.dtb`
- Kernel file consumed by fwup from SDK images:
- `${GRISP_SYSTEM}/images/Image` (packaged as `kernel8.img` in BOOT-A/B)

See also:
- [`porting-notes-rpi02w.md`](./porting-notes-rpi02w.md) for a
checklist-style delta from `system_rpi0w`.

## Build Pipeline Usage

```sh
./build-toolchain.sh rpi02w
./build-sdk.sh rpi02w
./build-project.sh rpi02w <project>
./build-firmware.sh rpi02w <artefact-prefix-or-path>
```

## Status

- Integrated into repo structure and Vagrant provisioning.
- Boot to Erlang shell confirmed on hardware.
- Bluetooth HCI UART support requires rebuilt kernel/SDK after
`linux-6.12.defconfig` updates.
2 changes: 2 additions & 0 deletions system_rpi02w/Config.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Target-specific Buildroot options for system_rpi02w go here.
# Sourced by system_common/Config.in via $BR2_EXTERNAL_GRISP_PATH.
50 changes: 50 additions & 0 deletions system_rpi02w/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Raspberry Pi Zero 2 W System Notes

Target-specific, implementation-coupled notes for `system_rpi02w`
(Raspberry Pi Zero 2 W: BCM2710A1 / Cortex-A53 / ARMv8).

## Hardware

| Property | Value |
|---|---|
| Board | Raspberry Pi Zero 2 W |
| SoC | Broadcom BCM2710A1 |
| CPU | Quad-core Cortex-A53 (ARMv8-A) |
| RAM | 512 MiB |
| Wi-Fi/BT | BCM43436, 802.11n + BT 4.2 |

## Current Target Shape

- Target name: `rpi02w`
- System directory: `system_rpi02w/`
- Toolchain tuple: `aarch64-unknown-linux-gnu`
- Toolchain configs:
- `toolchain/configs/rpi02w_linux_x86_64_defconfig`
- `toolchain/configs/rpi02w_linux_aarch64_defconfig`
- Kernel source pin: `raspberrypi/linux` tag `stable_20250916`
- Kernel DTB staged into firmware: `bcm2710-rpi-zero-2-w.dtb`

## Boot and Update Model

`system_rpi02w` follows the same model as `system_rpi0w`:

- No U-Boot bootloader in the boot chain.
- VideoCore firmware + `tryboot` A/B boot selection.
- Same GRiSP Alloy fwup task vocabulary and uboot-env schema
(`complete`, `upgrade.{a,b}`, `validate.{a,b}`, `rollback.{a,b}`).

Key files:

- `defconfig`: Buildroot target configuration.
- `linux/linux-6.12.defconfig`: custom kernel config seed.
- `fwup.conf`: firmware packaging and A/B task logic.
- `config.txt`, `cmdline-*.txt`, `autoboot-*.txt`: staged boot artifacts.
- `rootfs_overlay/etc/erlinit.config`: runtime init and console selection.

## Status

This is an initial target scaffold derived from `system_rpi0w` and adapted
for the Zero 2 W architecture and DTB path.

- Build integration is wired through the four-stage pipeline.
- Hardware validation is still required (boot, Wi-Fi/BT, A/B lifecycle).
1 change: 1 addition & 0 deletions system_rpi02w/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
6 changes: 6 additions & 0 deletions system_rpi02w/autoboot-a.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[all]
tryboot_a_b=1
boot_partition=2

[tryboot]
boot_partition=3
6 changes: 6 additions & 0 deletions system_rpi02w/autoboot-b.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[all]
tryboot_a_b=1
boot_partition=3

[tryboot]
boot_partition=2
1 change: 1 addition & 0 deletions system_rpi02w/cmdline-a.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root=/dev/mmcblk0p5 rootwait rootfstype=squashfs console=ttyAMA0,115200 console=ttyGS0
1 change: 1 addition & 0 deletions system_rpi02w/cmdline-b.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root=/dev/mmcblk0p6 rootwait rootfstype=squashfs console=ttyAMA0,115200 console=ttyGS0
60 changes: 60 additions & 0 deletions system_rpi02w/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Raspberry Pi Zero 2 W firmware config.
#
# Read by the VideoCore GPU firmware (start.elf) from the active BOOT-{A,B}
# partition. Tells the GPU how to load the Linux kernel.
#
# Keep this file identical on BOOT-A and BOOT-B unless a slot-specific quirk
# demands otherwise: fwup's complete / upgrade.* tasks write the same
# config.txt to both partitions.
#
# Several values and the miniuart-bt routing trick follow
# nerves_system_rpi0/rpi-firmware/config.txt; individual lines are marked
# "matches nerves_system_rpi0" where the specific choice is non-obvious.

# Keep the same kernel filename convention as Nerves on 64-bit Pi targets.
kernel=kernel8.img
arm_64bit=1
start_file=start.elf
fixup_file=fixup.dat

disable_splash=1

# Reserve 192 MiB of the 512 MiB SoC for the GPU/framebuffer; leaves ~320
# MiB for Linux + userland. Tunable; matches nerves_system_rpi0.
gpu_mem=192

# On-board peripherals exposed to Linux.
dtparam=i2c_arm=on
dtparam=spi=on
dtparam=audio=on

# Enable camera auto-detection for CSI. Safe to leave on even when no camera
# is connected; the kernel just skips it.
camera_auto_detect=1
display_auto_detect=1

# USB OTG / gadget mode for the CDC-ACM serial console on ttyGS0, exposed
# over the middle micro-USB port. On the host, `picocom -b 115200
# /dev/tty.usbmodem*` (macOS) or `/dev/ttyACM0` (Linux) lands on the BEAM.
dtoverlay=dwc2

# Route Bluetooth to the mini-UART and keep PL011 (ttyAMA0) free for the
# Linux console. Without this, console characters race BT traffic on the
# same UART.
enable_uart=1
dtoverlay=miniuart-bt
# The VPU clock must be fixed when the mini-UART shares the PLL with BT.
core_freq=250

# Heartbeat on the green ACT LED so the board shows signs of life without
# a UART attached.
dtparam=act_led_activelow=on
dtparam=act_led_trigger=heartbeat

# Ramoops: reserve a small RAM region for pstore so kernel oopses survive
# a warm reboot. The upstream RPi kernel already ships overlays/ramoops.dtbo
# (arch/arm/boot/dts/overlays/ramoops.dtbo); fwup.conf stages it onto
# BOOT-A/B alongside dwc2 and miniuart-bt. peripherals-init.sh (run by
# erlinit as --pre-run-exec) mounts pstore at /sys/fs/pstore so
# `ls /sys/fs/pstore` shows the previous boot's dmesg.
dtoverlay=ramoops
15 changes: 15 additions & 0 deletions system_rpi02w/crucible.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
OS_RELEASE_PRETTY_NAME="GRiSP RPi Zero 2 W"

BOOTSCHEME=NONE

SQUASHFS_PRIORITIES=(
"sbin/init" 32762
"etc/erlinit.config" 32761
)

FWUP_IMAGE_TARGETS=(
"complete" ""
)

GSU_KERNEL_PATH="/boot/kernel8.img"
GSU_PARTITIONS=""
Loading