Skip to content

Commit 2d67b70

Browse files
committed
Support for wolfBoot ZynqMP (UltraScale+ MPSoC) SD Card
1 parent 5f13d7d commit 2d67b70

4 files changed

Lines changed: 426 additions & 15 deletions

File tree

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# wolfBoot configuration for AMD ZynqMP ZCU102 - SD Card Boot
2+
# Zynq UltraScale+ MPSoC - Dual ARM Cortex-A53
3+
#
4+
# This configuration enables SD card boot for the ZynqMP:
5+
# FSBL -> BL31 (EL3) -> wolfBoot (EL2) -> Linux (EL1)
6+
#
7+
# wolfBoot loads firmware images from MBR partitions on SD card.
8+
# Uses the generic SDHCI driver with SD1 controller (external SD slot on ZCU102).
9+
10+
ARCH?=AARCH64
11+
TARGET?=zynq
12+
13+
WOLFBOOT_VERSION?=0
14+
15+
# RSA 4096-bit with SHA3-384 (matching existing zynqmp.config)
16+
SIGN?=RSA4096
17+
HASH?=SHA3
18+
IMAGE_HEADER_SIZE?=1024
19+
20+
# Debug options
21+
DEBUG?=1
22+
DEBUG_SYMBOLS=1
23+
DEBUG_UART=1
24+
CFLAGS_EXTRA+=-DDEBUG_ZYNQ=1
25+
26+
# SD card support - use SDHCI driver
27+
DISK_SDCARD?=1
28+
DISK_EMMC?=0
29+
30+
# Disable QSPI flash when using SD card
31+
EXT_FLASH?=0
32+
NO_XIP=1
33+
34+
# ELF loading support
35+
ELF?=1
36+
37+
# General options
38+
VTOR?=1
39+
CORTEX_M0?=0
40+
NO_ASM?=0
41+
ALLOW_DOWNGRADE?=0
42+
NVM_FLASH_WRITEONCE?=0
43+
V?=0
44+
SPMATH?=1
45+
RAM_CODE?=0
46+
DUALBANK_SWAP?=0
47+
PKA?=0
48+
WOLFTPM?=0
49+
50+
# Toolchain
51+
USE_GCC=1
52+
CROSS_COMPILE=aarch64-none-elf-
53+
54+
# ============================================================================
55+
# Partition Layout - MBR
56+
# ============================================================================
57+
# SD Card partition layout (MBR):
58+
# Partition 1: boot (128MB, FAT32 LBA, bootable) - BOOT.BIN
59+
# Partition 2: OFP_A (200MB, Linux) - Primary signed image
60+
# Partition 3: OFP_B (200MB, Linux) - Update signed image
61+
# Partition 4: rootfs (remainder) - Linux root filesystem
62+
#
63+
# Use partition numbers instead of flash addresses
64+
# These are 0-based indices into the parsed partition array:
65+
# part[0]=boot, part[1]=OFP_A, part[2]=OFP_B, part[3]=rootfs
66+
WOLFBOOT_NO_PARTITIONS=1
67+
CFLAGS_EXTRA+=-DBOOT_PART_A=1
68+
CFLAGS_EXTRA+=-DBOOT_PART_B=2
69+
70+
# Disk read chunk size (512KB)
71+
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x80000
72+
73+
# Linux rootfs is on partition 4 (SD1 = mmcblk1)
74+
CFLAGS_EXTRA+=-DLINUX_BOOTARGS_ROOT=\"/dev/mmcblk1p4\"
75+
76+
# ============================================================================
77+
# Boot Memory Layout
78+
# ============================================================================
79+
# wolfBoot runs from DDR (matches hal/zynq.ld origin at 0x7FF00000)
80+
WOLFBOOT_ORIGIN=0x7FF00000
81+
82+
# Load Partition to RAM Address (Linux kernel loads here)
83+
WOLFBOOT_LOAD_ADDRESS?=0x10000000
84+
85+
# DTS (Device Tree) load address
86+
WOLFBOOT_LOAD_DTS_ADDRESS?=0x1000
87+
88+
# ============================================================================
89+
# Required for test-app (even with WOLFBOOT_NO_PARTITIONS=1)
90+
# ============================================================================
91+
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80200000
92+
WOLFBOOT_PARTITION_SIZE=0x4000000
93+
WOLFBOOT_SECTOR_SIZE=0x1000
94+
95+
# ============================================================================
96+
# Optional Debug Options (uncomment to enable)
97+
# ============================================================================
98+
# SDHCI driver debug logs
99+
#CFLAGS_EXTRA+=-DDEBUG_SDHCI
100+
# Disk layer debug logs
101+
#CFLAGS_EXTRA+=-DDEBUG_DISK
102+
# GPT partition debug logs
103+
#CFLAGS_EXTRA+=-DDEBUG_GPT
104+
# Disk read/write test at boot
105+
#CFLAGS_EXTRA+=-DDISK_TEST

docs/Targets.md

Lines changed: 160 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,28 +1984,50 @@ qemu-system-aarch64 -M raspi3b -m 1024 -serial stdio -kernel wolfboot_linux_rasp
19841984

19851985
## Xilinx Zynq UltraScale
19861986

1987-
Xilinx UltraScale+ ZCU102 (Aarch64)
1987+
AMD Zynq UltraScale+ MPSoC ZCU102 Evaluation Kit - Dual ARM Cortex-A53.
19881988

1989-
See example .config file at `config/examples/zynqmp.config`.
1990-
1991-
Example build options (.config):
1989+
wolfBoot replaces U-Boot in the ZynqMP boot flow:
19921990
```
1993-
TARGET=zynq
1994-
ARCH=AARCH64
1995-
SIGN=RSA4096
1996-
HASH=SHA3
1991+
FSBL -> PMUFW -> BL31 (EL3) -> wolfBoot (EL2) -> Linux (EL1)
19971992
```
19981993

1999-
### Building Zynq with Xilinx tools (Vitis IDE)
1994+
wolfBoot runs from DDR at `0x7FF00000` (EL2, non-secure). All clock, MIO, and DDR initialization is handled by the FSBL/PMUFW before wolfBoot starts.
1995+
1996+
This target supports **two boot paths**:
1997+
- **QSPI boot** (primary, production-style): `config/examples/zynqmp.config`
1998+
- **SD card boot** (MBR, A/B images): `config/examples/zynqmp_sdcard.config`
1999+
2000+
### Prerequisites
2001+
2002+
1. **Xilinx Vitis 2024.1 or newer**
2003+
- Set `VITIS_PATH` environment variable: `export VITIS_PATH=/opt/Xilinx/Vitis/2024.1`
2004+
2. **Toolchain**: `aarch64-none-elf-gcc`
2005+
3. **Pre-built firmware** (FSBL, PMUFW, BL31):
2006+
```sh
2007+
git clone --branch xlnx_rel_v2024.2 https://github.com/Xilinx/soc-prebuilt-firmware.git
2008+
export PREBUILT_DIR=$(pwd)/../soc-prebuilt-firmware/zcu102-zynqmp
2009+
```
2010+
2011+
### Configuration Options
2012+
2013+
Key configuration options:
2014+
2015+
- `ARCH=AARCH64` - ARM 64-bit architecture
2016+
- `TARGET=zynq` - ZynqMP platform target
2017+
- `SIGN=RSA4096` - RSA 4096-bit signatures
2018+
- `HASH=SHA3` - SHA3-384 hashing
2019+
- `ELF=1` - ELF loading support
2020+
2021+
### Building with Xilinx tools (Vitis IDE)
20002022

20012023
See [IDE/XilinxSDK/README.md](/IDE/XilinxSDK/README.md) for using Xilinx IDE
20022024

2003-
### Building Zynq with gcc-aarch64-linux-gnu
2025+
### Building with gcc-aarch64-linux-gnu
20042026

20052027
Requires `gcc-aarch64-linux-gnu` package.
20062028
Use `make CROSS_COMPILE=aarch64-linux-gnu-`
20072029

2008-
### Building Zynq with QNX
2030+
### Building with QNX
20092031

20102032
```sh
20112033
source ~/qnx700/qnxsdp-env.sh
@@ -2014,17 +2036,141 @@ make clean
20142036
make CROSS_COMPILE=aarch64-unknown-nto-qnx7.0.0-
20152037
```
20162038

2017-
#### Testing Zynq with QEMU
2039+
### QSPI Boot (default)
2040+
2041+
Use `config/examples/zynqmp.config`.
2042+
2043+
```sh
2044+
cp config/examples/zynqmp.config .config
2045+
make clean
2046+
make
2047+
```
2048+
2049+
**QSPI layout**
2050+
| Partition | Size | Address | Description |
2051+
|-------------|--------|-------------|--------------------------------|
2052+
| Bootloader | - | 0x7FF00000 | wolfBoot in DDR (loaded by FSBL) |
2053+
| Primary | 42MB | 0x800000 | Boot partition in QSPI |
2054+
| Update | 42MB | 0x3A00000 | Update partition in QSPI |
2055+
| Swap | - | 0x63E0000 | Swap area in QSPI |
2056+
2057+
**Build BOOT.BIN for QSPI**
20182058

2059+
See [IDE/XilinxSDK/README.md](/IDE/XilinxSDK/README.md) for creating BOOT.BIN with the Xilinx IDE, or use the existing BIF file:
2060+
2061+
```sh
2062+
cp ${PREBUILT_DIR}/zynqmp_fsbl.elf .
2063+
cp ${PREBUILT_DIR}/pmufw.elf .
2064+
cp ${PREBUILT_DIR}/bl31.elf .
2065+
2066+
source ${VITIS_PATH}/settings64.sh
2067+
bootgen -arch zynqmp -image ./IDE/XilinxSDK/boot.bif -w -o BOOT.BIN
20192068
```
2069+
2070+
**Signing**
2071+
2072+
```sh
2073+
tools/keytools/sign --rsa4096 --sha3 /path/to/vmlinux.bin wolfboot_signing_private_key.der 1
2074+
```
2075+
2076+
**Testing with QEMU**
2077+
2078+
```sh
20202079
qemu-system-aarch64 -machine xlnx-zcu102 -cpu cortex-a53 -serial stdio -display none \
20212080
-device loader,file=wolfboot.bin,cpu-num=0
2081+
```
2082+
2083+
---
2084+
2085+
### SD Card Boot (MBR + A/B)
2086+
2087+
Use `config/examples/zynqmp_sdcard.config`. This uses the Arasan SDHCI controller (SD1 - external SD card slot on ZCU102) and an **MBR** partitioned SD card.
20222088

2089+
**Partition layout**
2090+
| Partition | Name | Size | Type | Contents |
2091+
|-----------|--------|-----------|-------------------------------|-------------------------------------------|
2092+
| 1 | boot | 128MB | FAT32 LBA (0x0c), bootable | BOOT.BIN (FSBL + PMUFW + BL31 + wolfBoot) |
2093+
| 2 | OFP_A | 200MB | Linux (0x83) | Primary signed firmware image |
2094+
| 3 | OFP_B | 200MB | Linux (0x83) | Update signed firmware image |
2095+
| 4 | rootfs | remainder | Linux (0x83) | Linux root filesystem |
2096+
2097+
**Build wolfBoot + sign test images**
2098+
```sh
2099+
cp config/examples/zynqmp_sdcard.config .config
2100+
make clean
2101+
make
2102+
2103+
make test-app/image.bin
2104+
./tools/keytools/sign --rsa4096 --sha3 test-app/image.bin wolfboot_signing_private_key.der 1
2105+
./tools/keytools/sign --rsa4096 --sha3 test-app/image.bin wolfboot_signing_private_key.der 2
20232106
```
20242107

2025-
#### Signing Zynq
2108+
**Build BOOT.BIN for SD card**
2109+
2110+
Copy the pre-built firmware and generate BOOT.BIN:
2111+
2112+
```sh
2113+
cp ${PREBUILT_DIR}/zynqmp_fsbl.elf .
2114+
cp ${PREBUILT_DIR}/pmufw.elf .
2115+
cp ${PREBUILT_DIR}/bl31.elf .
2116+
2117+
source ${VITIS_PATH}/settings64.sh
2118+
bootgen -arch zynqmp -image ./tools/scripts/zynqmp_sd_boot.bif -w -o BOOT.BIN
2119+
```
2120+
2121+
The BIF file (`zynqmp_sd_boot.bif`) configures the boot chain:
2122+
- FSBL at A53-0 (bootloader)
2123+
- PMUFW at PMU
2124+
- BL31 at EL3 with TrustZone
2125+
- wolfBoot at EL2
2126+
2127+
**Create SD image**
2128+
```sh
2129+
dd if=/dev/zero of=sdcard.img bs=1M count=1024
2130+
sfdisk sdcard.img <<EOF
2131+
label: dos
2132+
unit: sectors
2133+
2134+
1 : start=2048, size=128M, type=c, bootable
2135+
2 : size=200M, type=83
2136+
3 : size=200M, type=83
2137+
4 : type=83
2138+
EOF
20262139

2027-
`tools/keytools/sign --rsa4096 --sha3 /srv/linux-rpi4/vmlinux.bin wolfboot_signing_private_key.der 1`
2140+
SECTOR2=$(sfdisk -d sdcard.img | awk '/sdcard.img2/ {for (i=1;i<=NF;i++) if ($i ~ /start=/) {gsub(/start=|,/, "", $i); print $i}}')
2141+
SECTOR3=$(sfdisk -d sdcard.img | awk '/sdcard.img3/ {for (i=1;i<=NF;i++) if ($i ~ /start=/) {gsub(/start=|,/, "", $i); print $i}}')
2142+
dd if=test-app/image_v1_signed.bin of=sdcard.img bs=512 seek=$SECTOR2 conv=notrunc
2143+
dd if=test-app/image_v2_signed.bin of=sdcard.img bs=512 seek=$SECTOR3 conv=notrunc
2144+
```
2145+
2146+
**Provision SD card**
2147+
```sh
2148+
sudo dd if=sdcard.img of=/dev/sdX bs=4M status=progress conv=fsync
2149+
sync
2150+
sudo mkfs.vfat -F 32 -n BOOT /dev/sdX1
2151+
sudo mount /dev/sdX1 /mnt
2152+
sudo cp BOOT.BIN /mnt/
2153+
sudo umount /mnt
2154+
sudo fdisk -l /dev/sdX
2155+
```
2156+
2157+
**Boot Mode**
2158+
2159+
Set the ZCU102 boot mode switches (SW6) for SD card boot:
2160+
2161+
| Boot Mode | MODE Pins 3:0 | SW6[4:1] |
2162+
| --------- | ------------- | -------------- |
2163+
| JTAG | 0 0 0 0 | on, on, on, on |
2164+
| QSPI32 | 0 0 1 0 | on, on, off,on |
2165+
| SD1 | 1 1 1 0 | off,off,off,on |
2166+
2167+
**Debug**
2168+
2169+
Enable SDHCI debug output by uncommenting in the config:
2170+
```
2171+
CFLAGS_EXTRA+=-DDEBUG_SDHCI
2172+
CFLAGS_EXTRA+=-DDEBUG_DISK
2173+
```
20282174

20292175

20302176
## Versal Gen 1 VMK180

0 commit comments

Comments
 (0)