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
17 changes: 17 additions & 0 deletions .github/workflows/test-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,23 @@ jobs:
config-file: ./config/examples/raspi3-encrypted.config
make-args: wolfboot.bin CROSS_COMPILE=aarch64-linux-gnu-

tegra234_test:
uses: ./.github/workflows/test-build.yml
with:
arch: aarch64
# Tegra234 bare-metal BL33: build the bootloader only (RAM boot, no
# factory.bin), mirroring raspi3.
config-file: ./config/examples/tegra234.config
make-args: wolfboot.bin CROSS_COMPILE=aarch64-linux-gnu-

tegra234_linux_test:
uses: ./.github/workflows/test-build.yml
with:
arch: aarch64
# Tegra234 DRAM-staged Linux boot (MMU/EL2->EL1/DTB code path).
config-file: ./config/examples/tegra234-linux.config
make-args: wolfboot.bin CROSS_COMPILE=aarch64-linux-gnu-

sim_tfm_smallstack_test:
uses: ./.github/workflows/test-build.yml
with:
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,12 @@ ifeq ($(TARGET),raspi3)
MAIN_TARGET:=wolfboot.bin
endif

# Tegra234 bare-metal BL33 boots from RAM (loaded by an earlier stage),
# like raspi3: build the bootloader binary, no contiguous flash factory.bin.
ifeq ($(TARGET),tegra234)
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
endif

ifeq ($(TARGET),sim)
CFLAGS+=-fno-pie
LDFLAGS+=-no-pie
Expand Down
24 changes: 24 additions & 0 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,30 @@ ifeq ($(ARCH),AARCH64)
SPI_TARGET=nxp
endif

ifeq ($(TARGET),tegra234)
# NVIDIA Jetson Orin (Tegra234, Cortex-A78AE): bare-metal wolfBoot as the
# BL33 firmware stage. The UEFI-application alternative is the aarch64_efi
# target. See hal/tegra234.c.
ARCH_FLAGS=-mcpu=cortex-a78+crypto -march=armv8.2-a+crypto
CFLAGS+=$(ARCH_FLAGS) -DCORTEX_A78
# Bring-up: dump the state the prior stage handed wolfBoot (entry EL,
# SCTLR/MMU/cache bits, handoff x0/DTB pointer). Opt-out for a quiet build.
ifeq ($(TEGRA234_HANDOFF_DUMP),1)
CFLAGS+=-DTEGRA234_HANDOFF_DUMP
endif
# MMU/WOLFBOOT_FDT/DUALBOOT + fdt.o come from the shared AARCH64 block (all
# aarch64 targets enable them). tegra234 stays MMU-off at runtime (1:1
# physical); the flags only pull in the FDT/DTS codepath. For a Linux boot,
# drop from EL2 to EL1 with the DTB in x0 when the config requests it
# (config/examples/tegra234-linux.config).
ifeq ($(EL2_HYPERVISOR),1)
CFLAGS+=-DEL2_HYPERVISOR=1
endif
ifeq ($(BOOT_EL1),1)
CFLAGS+=-DBOOT_EL1
endif
endif

# Default ARM ASM setting for unrecognized AARCH64 targets
ifeq ($(filter zynq versal nxp_ls1028a,$(TARGET)),)
NO_ARM_ASM?=1
Expand Down
38 changes: 38 additions & 0 deletions config/examples/tegra234-linux.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# NVIDIA Jetson Orin / Tegra234 - bare-metal BL33, DRAM-staged Linux boot.
#
# wolfBoot runs as the bare-metal BL33 (replacing edk2 UEFI), verifies a signed
# Linux kernel bundled into the BL33 image in DRAM, and boots it EL2->EL1 with a
# device tree - no storage driver required. This sidesteps the SDMMC1 controller
# bring-up (still open; see hal/tegra234.c). The kernel + DTB are bundled by
# tools/scripts/tegra234-mkpoc.sh.
#
# For the storage-based (SDHCI) variant, see tegra234.config + DISK_SDCARD.
ARCH=AARCH64
TARGET=tegra234
SIGN?=ECC384
HASH?=SHA384
DEBUG?=1
DEBUG_UART?=1
TEGRA234_HANDOFF_DUMP?=1
SPMATH?=1
NO_XIP?=1
# Skip GIC init in the shared bare-metal startup (Orin is GICv3; BL31 set it up).
NO_QNX?=1
WOLFBOOT_SECTOR_SIZE?=0x1000
WOLFBOOT_NO_PARTITIONS=1

# --- Linux boot payload plumbing ---------------------------------------------
# MMU/WOLFBOOT_FDT are enabled for all aarch64 targets by arch.mk (they only
# switch on the FDT/DTS code path - the two-argument do_boot that forwards a
# DTB pointer; tegra234 stays MMU-off at runtime, 1:1 physical, which is what
# the arm64 Linux boot protocol wants - wolfBoot builds no page tables).
# This config adds the EL2->EL1 drop with the DTB in x0 (the Linux boot ABI).
EL2_HYPERVISOR=1
BOOT_EL1=1

# RAM staging: the bundled payload lives high (at BL33_BASE+0x80000). update_ram
# copies the kernel to LOAD_ADDRESS and relocates the DTB to LOAD_DTS_ADDRESS,
# both in low DRAM, 2 MB-aligned, clear of the 43 MB kernel footprint.
WOLFBOOT_RAMBOOT_MAX_SIZE=0x4000000
WOLFBOOT_LOAD_ADDRESS?=0xA0000000
WOLFBOOT_LOAD_DTS_ADDRESS?=0xA4000000
36 changes: 36 additions & 0 deletions config/examples/tegra234.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# NVIDIA Jetson Orin / Tegra234 - bare-metal wolfBoot as the BL33 firmware stage.
#
# BL33 is the normal-world bootloader that ARM Trusted Firmware (BL31) hands off
# to; wolfBoot replaces the edk2 UEFI / cpu-bootloader slot. This HAL brings up
# the TCU console + ARMv8 generic timer + BPMP IPC on the shared AArch64 startup.
# This base config boots a bundled signed payload at EL2; for the EL2->EL1 +
# device-tree Linux boot contract use config/examples/tegra234-linux.config.
# Validated on hardware via non-persistent RCM boot (see docs/Targets.md,
# "NVIDIA Jetson Orin (NVIDIA Tegra234) BL33 firmware").
#
# To run wolfBoot under UEFI instead (board-agnostic) use the aarch64_efi target
# (config/examples/aarch64_efi.config).
#
# Toolchain: a bare-metal aarch64-none-elf- toolchain, or aarch64-linux-gnu-
# for the freestanding bootloader-only build (the wolfboot.bin target links
# -ffreestanding -nostartfiles, so the Linux GNU toolchain works too -- this is
# what CI uses via CROSS_COMPILE=aarch64-linux-gnu-).
ARCH=AARCH64
TARGET=tegra234
SIGN?=ECC384
HASH?=SHA384
DEBUG?=1
DEBUG_UART?=1
# Bring-up: print the handoff state (entry EL, SCTLR/MMU/cache, x0/DTB pointer)
# from hal_init. Set to 0 for a quiet build once the handoff is characterized.
TEGRA234_HANDOFF_DUMP?=1
SPMATH?=1
# Boot media is external (SD/eMMC/NVMe via ext_flash); no internal flash.
NO_XIP?=1
# Skip GIC init in the shared bare-metal startup (Orin is GICv3; BL31 set it up).
NO_QNX?=1
WOLFBOOT_SECTOR_SIZE?=0x1000
WOLFBOOT_NO_PARTITIONS=1
# DRAM load addresses (mirror hal/tegra234.ld).
WOLFBOOT_LOAD_ADDRESS?=0x90000000
WOLFBOOT_LOAD_DTS_ADDRESS?=0x91000000
22 changes: 22 additions & 0 deletions docs/Targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ This README describes configuration of supported targets.
* [NXP T10xx PPC (T1024 / T1040)](#nxp-qoriq-t10xx-ppc-t1024--t1040)
* [NXP T2080 PPC](#nxp-qoriq-t2080-ppc)
* [Qemu x86-64 UEFI](#qemu-x86-64-uefi)
* [NVIDIA Jetson Orin (NVIDIA Tegra234) BL33 firmware](#nvidia-jetson-orin-nvidia-tegra234-bl33-firmware)
* [Raspberry Pi pico 2 (rp2350)](#raspberry-pi-pico-rp2350)
* [RealTek RTL8735B (AmebaPro2)](#realtek-rtl8735b-amebapro2)
* [Renesas RA6M4](#renesas-ra6m4)
Expand Down Expand Up @@ -7865,6 +7866,27 @@ You can `Ctrl-C` or login as `root` and power off qemu with `poweroff`



## NVIDIA Jetson Orin (NVIDIA Tegra234) BL33 firmware

wolfBoot can run on the NVIDIA Jetson Orin two ways: as an `aarch64_efi` UEFI application (documented separately), or - this `tegra234` target - as **bare-metal firmware** that replaces the **BL33** stage. BL33 is the normal-world bootloader that ARM Trusted Firmware (BL31) hands off to at EL2 non-secure with the MMU off; on Jetson it is the edk2 UEFI / cpu-bootloader (cpubl) slot. Running bare-metal instead of under UEFI puts wolfBoot much closer to the root of trust, with a far smaller trusted surface beneath it - wolfBoot owns its own console, clocks, and boot handoff.

On an unfused developer board the BL33 slot is directly replaceable: MB2 and the earlier stages are inside NVIDIA's signed/fused root of trust and would require NVIDIA signing tooling, but BL33 is not signature-enforced. The bare-metal HAL (`hal/tegra234.c`) provides the Tegra Combined UART (TCU) console, the ARMv8 generic timer, a BPMP IPC driver (clocks/resets over the CPU-NS IVC channel), and a "handoff dump" (entry EL, SCTLR/MMU/cache bits, handoff `x0`) enabled with `TEGRA234_HANDOFF_DUMP=1`.

Validated on hardware (Jetson Orin Nano dev kit, non-persistent RCM boot): wolfBoot runs as BL33 at EL2, verifies a signed payload with wolfCrypt (ECC384/SHA384), drops from EL2 to EL1, and hands off with a device tree in `x0` - the arm64 Linux boot contract - straight out of DRAM with no storage driver. The payload and DTB are bundled into the BL33 image (see `tools/scripts/tegra234-mkpoc.sh` and `config/examples/tegra234-linux.config`). Loading a full kernel from storage is still in progress, bounded by two limits: MB2 caps the BL33 image at 4 MB (so a full kernel cannot be bundled - it must be loaded from storage or a pre-staged DRAM location), and microSD (SDHCI, `DISK_SDCARD`) is blocked on the closed SDMMC1 controller bring-up. See `hal/tegra234.c` for the full boot-chain map and open questions.

Build the bootloader binary (no hardware needed to compile):

```
cp config/examples/tegra234.config .config
make wolfboot.bin CROSS_COMPILE=aarch64-linux-gnu-
```

Build the BL33 image for the DRAM-staged verify + EL2->EL1 + device-tree boot:

```
tools/scripts/tegra234-mkpoc.sh
```

## Intel x86_64 with Intel FSP support

This setup is more complex than the UEFI approach described earlier, but allows
Expand Down
Loading
Loading