Skip to content
Open
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
16 changes: 16 additions & 0 deletions .github/workflows/test-build-aarch64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ on:
required: false
type: boolean
default: false
fips:
# Download the FIPS-ready wolfSSL tree into ../ before building, for a
# build-only FIPS=1 verification (see WOLFBOOT_LIB_WOLFSSL in make-args).
required: false
type: boolean
default: false

jobs:

Expand Down Expand Up @@ -126,6 +132,16 @@ jobs:
unsigned long psu_ddr_qos_init_data(void) { return 1UL; }
STUB

- name: Download FIPS-ready wolfSSL
if: ${{ inputs.fips }}
run: |
set -euxo pipefail
sudo apt-get install -y unzip
curl -fsSL --retry 3 --retry-delay 5 -o /tmp/wolfssl-fips-ready.zip \
https://www.wolfssl.com/wolfssl-5.9.2-gplv3-fips-ready.zip
unzip -q /tmp/wolfssl-fips-ready.zip -d ..
test -f ../wolfssl-5.9.2-gplv3-fips-ready/wolfcrypt/src/fips.c

- name: Build wolfboot
run: |
make ${{inputs.make-args}}
16 changes: 16 additions & 0 deletions .github/workflows/test-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ on:
make-args:
required: false
type: string
fips:
# Download the FIPS-ready wolfSSL tree into ../ before building.
required: false
type: boolean
default: false

jobs:

Expand Down Expand Up @@ -42,6 +47,17 @@ jobs:
run: |
make -C tools/keytools && make -C tools/bin-assemble

- name: Download FIPS-ready wolfSSL
if: ${{ inputs.fips }}
run: |
set -euxo pipefail
# Runs inside the CI container (no sudo/apt); unpack with python3,
# which is already a build dependency.
curl -fsSL --retry 3 --retry-delay 5 -o /tmp/wolfssl-fips-ready.zip \
https://www.wolfssl.com/wolfssl-5.9.2-gplv3-fips-ready.zip
python3 -m zipfile -e /tmp/wolfssl-fips-ready.zip ..
test -f ../wolfssl-5.9.2-gplv3-fips-ready/wolfcrypt/src/fips.c

- name: Build wolfboot
run: |
make ${{inputs.make-args}}
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/test-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,42 @@ jobs:
config-file: ./config/examples/raspi3-encrypted.config
make-args: wolfboot.bin CROSS_COMPILE=aarch64-linux-gnu-

cm4_test:
uses: ./.github/workflows/test-build-aarch64.yml
with:
arch: aarch64
config-file: ./config/examples/cm4.config
make-args: wolfboot.bin

cm4_sdcard_test:
uses: ./.github/workflows/test-build-aarch64.yml
with:
arch: aarch64
config-file: ./config/examples/cm4_sdcard.config
make-args: wolfboot.bin

cm4_emmc_test:
uses: ./.github/workflows/test-build-aarch64.yml
with:
arch: aarch64
config-file: ./config/examples/cm4_emmc.config
make-args: wolfboot.bin

cm4_fips_test:
uses: ./.github/workflows/test-build-aarch64.yml
with:
arch: aarch64
config-file: ./config/examples/cm4.config
make-args: wolfboot.bin FIPS=1 WOLFBOOT_LIB_WOLFSSL=../wolfssl-5.9.2-gplv3-fips-ready NO_ARM_ASM=1
fips: true

sim_fips_test:
uses: ./.github/workflows/test-build.yml
with:
arch: host
config-file: ./config/examples/sim-fips.config
fips: true

sim_tfm_smallstack_test:
uses: ./.github/workflows/test-build.yml
with:
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ tools/unit-tests/unit-update-ram-enc
tools/unit-tests/unit-update-ram-enc-nopart
tools/unit-tests/unit-va416x0-fram
tools/unit-tests/unit-wolfhsm_flash_hal
tools/unit-tests/unit-ubootenv
tools/unit-tests/__pycache__/*


Expand Down Expand Up @@ -427,3 +428,9 @@ port/stmicro/stm32h5-tz-wolfhsm/out/

# CI-only generated Libero settings stub (see tools/ci/gen_mpfs_libero_stub.sh)
tools/ci/mpfs_libero_stub/
# CM4 disk-boot test artifacts (fetched RPi firmware, built/signed payloads)
tools/scripts/cm4/fw/
tools/scripts/cm4/*.elf
tools/scripts/cm4/*.bin
tools/scripts/cm4/linux/
tools/scripts/cm4/rauc/
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,10 @@ ifeq ($(TARGET),raspi3)
MAIN_TARGET:=wolfboot.bin
endif

ifeq ($(TARGET),cm4)
MAIN_TARGET:=wolfboot.bin
endif

ifeq ($(TARGET),sim)
CFLAGS+=-fno-pie
LDFLAGS+=-no-pie
Expand Down
22 changes: 21 additions & 1 deletion arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,27 @@ ifeq ($(ARCH),AARCH64)
SPI_TARGET=nxp
endif

# Default ARM ASM setting for unrecognized AARCH64 targets
ifeq ($(TARGET),cm4)
# Raspberry Pi Compute Module 4 - Broadcom BCM2711, Cortex-A72
ARCH_FLAGS=-mcpu=cortex-a72+crypto -march=armv8-a+crypto -mtune=cortex-a72
# -mstrict-align: the plain RAM-boot config runs with the MMU off (simple
# startup), where all memory is Device-nGnRnE and unaligned access faults.
# The FIPS / disk configs bring up an identity MMU first (CM4_USE_MMU in
# hal/cm4.c). cm4 defaults to NO_ARM_ASM=1 (portable C, no NEON structure
# loads), so -mstrict-align keeps every config safe either way.
CFLAGS+=$(ARCH_FLAGS) -DCORTEX_A72 -mstrict-align
# RAUC A/B slot selection via a raw U-Boot env partition (wolfBoot replaces
# U-Boot's boot script). Adds the env state-machine module + define.
ifeq ($(CM4_RAUC_AB),1)
OBJS+=src/ubootenv.o
CFLAGS+=-DCM4_RAUC_AB
endif
endif

# Default ARM ASM setting for unrecognized AARCH64 targets. cm4 is excluded
# from the asm path (defaults NO_ARM_ASM=1): the plain config runs MMU-off
# where NEON multi-register loads would fault, and the FIPS path mandates
# portable-C crypto anyway.
ifeq ($(filter zynq versal nxp_ls1028a,$(TARGET)),)
NO_ARM_ASM?=1
endif
Expand Down
28 changes: 28 additions & 0 deletions config/examples/cm4.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Raspberry Pi CM4 (BCM2711) - RAM-boot authenticated boot.
#
# For wolfCrypt FIPS 140-3, build with FIPS=1 pointing at a FIPS / FIPS-ready
# wolfSSL tree. The FIPS module uses portable-C crypto, so NO_ARM_ASM is
# required. Entropy comes from the BCM2711 RNG200 hardware TRNG (hal/cm4.c).
# See docs/FIPS.md for the in-core hash-seal procedure (done on-target). e.g.:
# make FIPS=1 WOLFBOOT_LIB_WOLFSSL=../wolfssl-5.9.2-gplv3-fips-ready NO_ARM_ASM=1
#FIPS?=1
#WOLFBOOT_LIB_WOLFSSL?=../wolfssl-5.9.2-gplv3-fips-ready
#NO_ARM_ASM?=1
ARCH?=AARCH64
TARGET?=cm4
SIGN?=ECC384
HASH?=SHA384
DEBUG?=1
VTOR?=1
SPMATH?=1
IMAGE_HEADER_SIZE?=1024
PKA?=0
WOLFTPM?=0
DEBUG_UART?=0
NO_XIP?=1
NO_QNX?=1
WOLFBOOT_SECTOR_SIZE=0x400
WOLFBOOT_NO_PARTITIONS=1
WOLFBOOT_RAMBOOT_MAX_SIZE=0x20000000
WOLFBOOT_LOAD_ADDRESS?=0x3080000
WOLFBOOT_LOAD_DTS_ADDRESS?=0x400000
54 changes: 54 additions & 0 deletions config/examples/cm4_emmc.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Raspberry Pi CM4 (BCM2711) - onboard eMMC A/B disk boot.
#
# wolfBoot drives the BCM2711 EMMC2 controller (Arasan SDHCI v3.0 @ 0xFE340000)
# to read GPT A/B image partitions from the onboard eMMC via update_disk.c, and
# boots the highest valid version with rollback.
#
# Transfer mode: SDHCI_SDMA_DISABLED forces PIO. The BCM2711 EMMC2 SDMA
# boundary-restart and cache coherency are not yet validated (same Arasan
# family as the Versal quirk); DISK_EMMC compiles in the PIO BRR-race
# workaround in src/sdhci.c. SDHCI_FORCE_CARD_DETECT: the onboard eMMC has no
# routed card-detect line.
#
# Bring-up: uncomment DEBUG_SDHCI (+ DEBUG_DISK / DEBUG_GPT) for verbose
# controller/partition tracing over the mini-UART console.
#
# For wolfCrypt FIPS 140-3, build with FIPS=1 pointing at a FIPS / FIPS-ready
# wolfSSL tree (NO_ARM_ASM required; entropy from the RNG200 TRNG). See
# docs/FIPS.md. e.g.:
# make FIPS=1 WOLFBOOT_LIB_WOLFSSL=../wolfssl-5.9.2-gplv3-fips-ready NO_ARM_ASM=1
#FIPS?=1
#WOLFBOOT_LIB_WOLFSSL?=../wolfssl-5.9.2-gplv3-fips-ready
#NO_ARM_ASM?=1
ARCH?=AARCH64
TARGET?=cm4
SIGN?=ECC384
HASH?=SHA384
IMAGE_HEADER_SIZE?=1024
DEBUG?=0
DEBUG_UART?=1
DISK_SDCARD?=0
DISK_EMMC?=1
CFLAGS_EXTRA+=-DSDHCI_FORCE_CARD_DETECT
CFLAGS_EXTRA+=-DSDHCI_SDMA_DISABLED
#CFLAGS_EXTRA+=-DDEBUG_SDHCI
#CFLAGS_EXTRA+=-DDEBUG_DISK
#CFLAGS_EXTRA+=-DDEBUG_GPT
EXT_FLASH?=0
NO_XIP=1
NO_QNX?=1
ELF?=1
VTOR?=1
SPMATH?=1
PKA?=0
WOLFTPM?=0
WOLFBOOT_NO_PARTITIONS=1
CFLAGS_EXTRA+=-DBOOT_PART_A=1
CFLAGS_EXTRA+=-DBOOT_PART_B=2
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x80000
WOLFBOOT_LOAD_ADDRESS?=0x10000000
WOLFBOOT_RAMBOOT_MAX_SIZE=0x2BC00000
WOLFBOOT_LOAD_DTS_ADDRESS?=0x1000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80200000
WOLFBOOT_PARTITION_SIZE=0x4000000
WOLFBOOT_SECTOR_SIZE=0x1000
87 changes: 87 additions & 0 deletions config/examples/cm4_emmc_linux.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Raspberry Pi CM4 (BCM2711) - onboard eMMC A/B disk boot of a REAL Linux kernel
# (FIT), as opposed to cm4_emmc.config which boots the disk_app prove-out stub.
#
# Chain: RPi VideoCore firmware -> wolfBoot (kernel8.img @ 0x200000) -> reads a
# signed FIT (hal/cm4.its: kernel + bcm2711-rpi-cm4.dtb) from the eMMC A/B image
# partition -> verifies the outer ECDSA384/SHA384 signature -> loads + gzip-
# decompresses the kernel to 0x10000000, copies the DTB to WOLFBOOT_LOAD_DTS_
# ADDRESS -> drops EL2->EL1 (el2_to_el1_boot) handing the DTB in x0 -> Linux.
# The kernel mounts its rootfs from a separate eMMC ext4 partition (root= on the
# cmdline, injected via the FIT bootargs / hal_dts_fixup).
#
# Target: GCX "iron-butterfly" Yocto Scarthgap, kernel 6.6.63, raspberrypi4-64.
# GCX's UBOOT_LOADADDRESS is also 0x10000000, so their kernel loads identically.
#
# DRAFT: not yet HW-validated. The disk-driver half is identical to the proven
# cm4_emmc.config; the Linux-handoff half (EL1 entry, FIT kernel, DTB placement,
# partition sizing) needs bring-up with real GCX artifacts. Items marked VERIFY
# are the known unknowns.
ARCH?=AARCH64
TARGET?=cm4
SIGN?=ECC384
HASH?=SHA384
IMAGE_HEADER_SIZE?=1024
DEBUG?=0
DEBUG_UART?=1

# --- eMMC disk driver (identical to the validated cm4_emmc.config) -----------
DISK_SDCARD?=0
DISK_EMMC?=1
CFLAGS_EXTRA+=-DSDHCI_FORCE_CARD_DETECT
CFLAGS_EXTRA+=-DSDHCI_SDMA_DISABLED
#CFLAGS_EXTRA+=-DDEBUG_SDHCI
#CFLAGS_EXTRA+=-DDEBUG_DISK
#CFLAGS_EXTRA+=-DDEBUG_GPT
EXT_FLASH?=0
NO_XIP=1
NO_QNX?=1
ELF?=1
VTOR?=1
SPMATH?=1
PKA?=0
WOLFTPM?=0
WOLFBOOT_NO_PARTITIONS=1
CFLAGS_EXTRA+=-DBOOT_PART_A=1
CFLAGS_EXTRA+=-DBOOT_PART_B=2
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x80000

# --- Linux boot additions ----------------------------------------------------
# gzip-decompress the FIT kernel subimage at load time (kernel = Image.gz).
GZIP?=1
# Enter the kernel at EL2 (the RPi firmware brings the secondary CPUs up at EL2,
# so the primary must match or Linux warns "CPUs started in inconsistent modes"
# and KVM is unavailable). This is the default cm4 EL2 direct-jump handoff, which
# already passes the DTB in x0 - so we do NOT define BOOT_EL1/EL2_HYPERVISOR here.
# Console UART: the Linux mini-UART (bcm2835-aux) fails to register cleanly on
# this DTB, so use dtoverlay=disable-bt (routes the PL011 onto GPIO14/15) and
# build wolfBoot for the PL011. See hal/cm4.c (CM4_UART_PL011) and the config.txt
# generated by tools/scripts/cm4/prepare_emmc_linux.sh (adds disable-bt).
CFLAGS_EXTRA+=-DCM4_UART_PL011
# Use the RPi firmware's fully-patched DTB (RAM size, mini-UART clock, serial
# no.) for the kernel-only FIT, and inject the kernel command line. wolfBoot
# captures the firmware DTB pointer at _cm4_entry (x0). See hal/cm4.c
# hal_get_boot_dts(). Scoped here so the stub/FIPS builds are unaffected.
CFLAGS_EXTRA+=-DCM4_FIRMWARE_DTB
# Rootfs partition for the simple first-boot layout (p3). Overrides the
# LINUX_BOOTARGS_ROOT default in hal/cm4.c. With CM4_UART_PL011 the full cmdline is:
# earlycon=pl011,mmio32,0xfe201000 console=ttyAMA0,115200 root=/dev/mmcblk0p3 ...
CFLAGS_EXTRA+=-DLINUX_BOOTARGS_ROOT=\"/dev/mmcblk0p3\"

# Stage the signed FIT here (NOT 0x10000000): the FIT's kernel subimage has
# load=0x10000000, and a gzip kernel decompresses FIT-data -> 0x10000000. If the
# FIT itself were also at 0x10000000 the decompression output would overwrite its
# own compressed input mid-stream (observed: "FIT gunzip failed rc=-4"). 0x18000000
# (384MB) sits above the decompressed kernel (0x10000000 + ~30MB) with margin.
WOLFBOOT_LOAD_ADDRESS?=0x18000000
WOLFBOOT_RAMBOOT_MAX_SIZE=0x2BC00000
# VERIFY: DTB landing zone. 0x1000 (the stub config value) is too low for a real
# kernel; 0x08000000 (128 MB) sits below the kernel (256 MB) and above wolfBoot
# (2 MB). Confirm no collision with RPi low-memory reservations / kernel early
# use on HW.
WOLFBOOT_LOAD_DTS_ADDRESS?=0x08000000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80200000
# VERIFY: partition size must hold the FIT (kernel Image.gz ~10-15 MB + DTB).
# 0x4000000 (64 MB) is ample; the separate ext4 rootfs partition is sized in the
# eMMC-layout script, not here.
WOLFBOOT_PARTITION_SIZE=0x4000000
WOLFBOOT_SECTOR_SIZE=0x1000
66 changes: 66 additions & 0 deletions config/examples/cm4_emmc_rauc.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Raspberry Pi CM4 (BCM2711) - production RAUC A/B boot: wolfBoot replaces GCX's
# U-Boot as the RAUC slot arbiter. Same Linux boot as cm4_emmc_linux.config, plus
# wolfBoot reads a raw U-Boot-env partition (RAUC bootloader=uboot, fw_setenv),
# runs the BOOT_ORDER / BOOT_<name>_LEFT state machine, decrements the try counter
# (so a hung slot fails over), and injects "root=<slot> rauc.slot=<name>".
#
# eMMC GPT layout (0-based indices in [brackets]):
# p1 boot FAT [0] : RPi fw + wolfBoot kernel8.img + config.txt (disable-bt)
# p2 uboot-env raw [1] : U-Boot env (RAUC fw_env.config -> this partition)
# p3 fitImage raw [2] : wolfBoot-signed kernel FIT (shared across A/B)
# p4 rootfs_A ext4 [3] : RAUC slot A
# p5 rootfs_B ext4 [4] : RAUC slot B
# p6 data ext4 [5] : persistent /data
#
# Target: GCX "iron-butterfly" Yocto Scarthgap, kernel 6.6.63, raspberrypi4-64.
ARCH?=AARCH64
TARGET?=cm4
SIGN?=ECC384
HASH?=SHA384
IMAGE_HEADER_SIZE?=1024
DEBUG?=0
DEBUG_UART?=1

# --- eMMC disk driver --------------------------------------------------------
DISK_SDCARD?=0
DISK_EMMC?=1
CFLAGS_EXTRA+=-DSDHCI_FORCE_CARD_DETECT
CFLAGS_EXTRA+=-DSDHCI_SDMA_DISABLED
#CFLAGS_EXTRA+=-DDEBUG_SDHCI
#CFLAGS_EXTRA+=-DDEBUG_DISK
EXT_FLASH?=0
NO_XIP=1
NO_QNX?=1
ELF?=1
VTOR?=1
SPMATH?=1
PKA?=0
WOLFTPM?=0
WOLFBOOT_NO_PARTITIONS=1
# Shared kernel FIT lives on p3 (index 2); no per-slot kernel, so A==B.
CFLAGS_EXTRA+=-DBOOT_PART_A=2
CFLAGS_EXTRA+=-DBOOT_PART_B=2
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x80000

# --- Linux boot (see cm4_emmc_linux.config for the rationale) -----------------
GZIP?=1
CFLAGS_EXTRA+=-DCM4_UART_PL011
CFLAGS_EXTRA+=-DCM4_FIRMWARE_DTB
# Fallback root if the RAUC env read fails (normally root= comes from the slot).
CFLAGS_EXTRA+=-DLINUX_BOOTARGS_ROOT=\"/dev/mmcblk0p4\"

# --- RAUC A/B slot selection (wolfBoot replaces U-Boot's boot.scr) ------------
# CM4_RAUC_AB is a make var: arch.mk links src/ubootenv.o and defines -DCM4_RAUC_AB.
CM4_RAUC_AB?=1
# 0-based GPT index of the raw U-Boot-env partition (p2). Match RAUC fw_env.config.
CFLAGS_EXTRA+=-DCM4_UBOOT_ENV_PART=1
# RAUC bootname -> rootfs device. Match RAUC system.conf slot devices.
CFLAGS_EXTRA+=-DCM4_ROOT_A=\"/dev/mmcblk0p4\"
CFLAGS_EXTRA+=-DCM4_ROOT_B=\"/dev/mmcblk0p5\"

WOLFBOOT_LOAD_ADDRESS?=0x18000000
WOLFBOOT_RAMBOOT_MAX_SIZE=0x2BC00000
WOLFBOOT_LOAD_DTS_ADDRESS?=0x08000000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80200000
WOLFBOOT_PARTITION_SIZE=0x4000000
WOLFBOOT_SECTOR_SIZE=0x1000
Loading
Loading