wolfBoot now supports SD card boot on the AMD/Xilinx Zynq UltraScale+ MPSoC (PR #699). This brings authenticated, signature-verified boot of Linux directly from SD card partitions on the ZCU102 evaluation kit, complementing the existing QSPI flash boot path that has been the sole production boot option until now.
The ZCU102 (quad-core Cortex-A53, dual Cortex-R5, FPGA fabric) remains one of the most widely deployed UltraScale+ boards in industrial, aerospace, and communications applications. Adding SD card boot gives teams on this mature platform a second fully verified boot path. One that is easier to provision in the field, supports much larger firmware payloads than QSPI, and provides a straightforward A/B update mechanism with automatic fallback.
Boot Chain
wolfBoot replaces U-Boot in the standard ZynqMP boot flow:

wolfBoot runs at EL2, reads and verifies firmware from SD card partitions, then boots the payload at EL1. All low-level hardware init is delegated to vendor firmware. The secure bootloader (wolfBoot) focuses solely on secure image selection and verification.
Partition Layout and GPT/MBR Support
wolfBoot’s disk subsystem (src/disk.c) supports both GPT (GUID Partition Table) and MBR (Master Boot Record) partition schemes. The ZynqMP SD card configuration uses MBR for simplicity and broad compatibility:
| Partition | Name | Size | Type | Contents |
| 1 | boot | 128 MB | FAT32 LBA (0x0c), bootable | BOOT.BIN (FSBL + PMUFW + BL31 + wolfBoot) |
| 2 | OFP_A | 200 MB | Linux (0x83) | Primary signed firmware image |
| 3 | OFP_B | 200 MB | Linux (0x83) | Update signed firmware image |
| 4 | rootfs | Remainder | Linux (0x83) | Linux root filesystem |
At boot, wolfBoot reads image headers from both A and B partitions, selects the higher-versioned image, verifies its SHA3-384 integrity hash and RSA-4096 signature, and falls back to the other partition on failure. GPT is available for platforms that require it (e.g., the x86 FSP targets), giving wolfBoot a unified disk layer across architectures.
Generic SDHCI Driver
Rather than a one-off driver, we built a portable SDHCI driver (src/sdhci.c) with a clean platform abstraction. It handles SD card initialization, single/multi-block reads (CMD17/CMD18), SDMA with PIO fallback, 4-bit bus negotiation, and configurable clock dividers. Each platform implements five hook functions:
uint32_t sdhci_reg_read(uint32_t offset); void sdhci_reg_write(uint32_t offset, uint32_t val); void sdhci_platform_init(void); void sdhci_platform_irq_init(void); void sdhci_platform_set_bus_mode(int is_emmc);
On the ZynqMP, the Arasan SDHCI controller uses standard register offsets, while the generic driver uses Cadence SD4HC layout internally. The platform layer translates by subtracting the 0x200 SRS offset. The ZCU102 uses SD1 (0xFF170000, external slot), and since the FSBL already configures the SD controller, wolfBoot’s platform init simply verifies accessibility.
The driver is already validated on both ZynqMP and Versal platforms and is designed for easy porting to any SDHCI-compliant controller.
Getting Started
Build and Sign
cp config/examples/zynqmp_sdcard.config .config make clean make # Sign primary (v1) and update (v2) images ./tools/keytools/sign --rsa4096 --sha3 firmware.bin wolfboot_signing_private_key.der 1 ./tools/keytools/sign --rsa4096 --sha3 firmware.bin wolfboot_signing_private_key.der 2
Generate BOOT.BIN
cp ${PREBUILT_DIR}/zynqmp_fsbl.elf .
cp ${PREBUILT_DIR}/pmufw.elf .
cp ${PREBUILT_DIR}/bl31.elf .
source ${VITIS_PATH}/settings64.sh
bootgen -arch zynqmp -image ./tools/scripts/zynqmp_sd_boot.bif -w -o BOOT.BIN
Create SD Card Image
dd if=/dev/zero of=sdcard.img bs=1M count=1024 sfdisk sdcard.img < < EOF label: dos 1 : start=2048, size=128M, type=c, bootable 2 : size=200M, type=83 3 : size=200M, type=83 4 : type=83 EOF # Write signed images to partitions 2 and 3, then flash sudo dd if=sdcard.img of=/dev/sdX bs=4M status=progress && sync sudo mkfs.vfat -F 32 -n BOOT /dev/sdX1 sudo mount /dev/sdX1 /mnt && sudo cp BOOT.BIN /mnt/ && sudo umount /mnt
Set ZCU102 boot mode switches (SW6) to SD1: SW6[4:1] = off, off, off, on.
For complete step-by-step instructions — including QSPI boot, boot mode tables, QEMU testing, and signing options — see the Xilinx Zynq UltraScale section in docs/Targets.md. The SD Card Boot (MBR + A/B) subsection covers the full SD card workflow.
Additional Capabilities
- Encrypted images: AES-256-CTR, AES-128-CTR, or ChaCha20 encryption at rest with transparent decryption before verification.
- ELF loading: With ELF=1, wolfBoot parses ELF binaries and loads sections to their correct addresses with MMU mappings.
- Post-quantum signatures: LMS and XMSS are supported by changing the SIGN parameter.
- Debug output: Enable DEBUG_SDHCI and DEBUG_DISK for verbose driver and partition logging.
Summary
SD card boot on the ZynqMP gives wolfBoot users two fully authenticated boot paths on one of the most widely deployed UltraScale+ platforms: QSPI for locked-down production and SD for development, field provisioning, and larger payloads. The generic SDHCI driver and GPT/MBR disk layer are reusable across targets, making it straightforward to bring SD card secure boot to additional platforms.
- Pull request: wolfBoot PR #699
- Full target documentation: docs/Targets.md — Xilinx Zynq UltraScale
- Contact: support@wolfssl.com
If you have questions about any of the above, please contact us at facts@wolfssl.com or call us at +1 425 245 8247.
Download wolfSSL Now

