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
12 changes: 12 additions & 0 deletions .github/workflows/test-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,18 @@ jobs:
arch: aarch64
config-file: ./config/examples/zynqmp_sdcard.config

zynq7000_test:
uses: ./.github/workflows/test-build.yml
with:
arch: arm
config-file: ./config/examples/zynq7000.config

zynq7000_sdcard_test:
uses: ./.github/workflows/test-build.yml
with:
arch: arm
config-file: ./config/examples/zynq7000_sdcard.config
Comment thread
dgarske marked this conversation as resolved.

versal_vmk180_test:
uses: ./.github/workflows/test-build-aarch64.yml
with:
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ ifeq ($(TARGET),sama5d3)
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
endif

ifeq ($(TARGET),zynq7000)
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
endif

ifeq ($(TARGET),rp2350)
MAIN_TARGET:=include/target.h keytools wolfboot_signing_private_key.der pico-sdk-info
endif
Expand Down
66 changes: 66 additions & 0 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,28 @@ ifeq ($(ARCH),ARM)
CFLAGS+=-DWOLFBOOT_USE_STDLIBC
endif

ifeq ($(TARGET),zynq7000)
# AMD/Xilinx Zynq-7000 (Cortex-A9, ARMv7-A) - ZC702 Evaluation Kit.
# Loaded by Xilinx FSBL into DDR; see hal/zynq7000.{c,h,ld}.
CORTEX_A9=1
UPDATE_OBJS:=src/update_ram.o
CFLAGS+=-DWOLFBOOT_DUALBOOT -fno-builtin -ffreestanding
# Do NOT define WOLFBOOT_USE_STDLIBC: newlib's memcpy uses unaligned
# LDRs which fault on ARMv7-A whenever the active mapping treats memory
# as Strongly-Ordered (typically MMU off, but also some boot-stage
# configurations). wolfBoot's startup keeps FSBL's MMU + flat 1:1
# mapping enabled to avoid that, but we still link against the
# aligned-safe memcpy in src/string.c so unaligned loads can never
# surprise us regardless of MMU state.
# The legacy 64-byte uImage header strip is only meaningful when the
# payload is a Linux kernel (LINUX_PAYLOAD=1). Bare-metal payloads
# shouldn't risk a ~1-in-2^32 false-positive collision against
# UBOOT_IMG_HDR_MAGIC, so the flag is gated on LINUX_PAYLOAD.
ifeq ($(LINUX_PAYLOAD),1)
CFLAGS+=-DWOLFBOOT_UBOOT_LEGACY
endif
endif

ifeq ($(TARGET),va416x0)
CFLAGS+=-I$(WOLFBOOT_ROOT)/hal/vorago/ \
-I$(VORAGO_SDK_DIR)/common/drivers/hdr/ \
Expand Down Expand Up @@ -344,6 +366,49 @@ ifeq ($(CORTEX_A5),1)
-DWOLFSSL_ARM_ARCH=7 -DWOLFSSL_ARMASM_INLINE -DWOLFSSL_ARMASM_NO_NEON
endif
endif
else
ifeq ($(CORTEX_A9),1)
# Cortex-A9 (ARMv7-A, 32-bit) - Zynq-7000.
# Build in ARM state (-marm); reset vector lands in ARM mode after FSBL.
# Note: do not filter out -mthumb from CFLAGS/LDFLAGS - that converts the
# variables to simple-expansion flavor and breaks lazy $(LSCRIPT) expansion
# in test-app/Makefile. -marm appended later wins over -mthumb anyway.
FPU=-mfpu=vfp3-d16
CFLAGS+=-mcpu=cortex-a9 -mtune=cortex-a9 -marm -mno-unaligned-access
LDFLAGS+=-mcpu=cortex-a9 -mtune=cortex-a9 -marm -static \
-Wl,-z,noexecstack
# Cortex-A9 uses the same generic ARMv7-A startup as Cortex-A5
# (src/boot_arm32_start.S handles VBAR, per-mode stacks, cache
# invalidate, async-abort enable for any ARMv7-A target).
OBJS+=src/boot_arm32.o src/boot_arm32_start.o
# Linux/U-Boot payload: enable MMU + FDT codepaths in update_ram.c so DTBs
# can be loaded from a separate signed PART_DTS_BOOT partition. The MMU
# itself stays inherited from FSBL's flat 1:1 mapping; wolfBoot does not
# manage page tables on Cortex-A9.
ifeq ($(MMU),1)
CFLAGS+=-DMMU -DWOLFBOOT_FDT
OBJS+=src/fdt.o
endif
# SD card / eMMC boot: swap the update_ram loader for update_disk + GPT.
# The SDHCI HAL hooks live in hal/zynq7000.c and translate the generic
# Cadence-layout driver to the Arasan SDHCI v2.0 controller.
ifneq ($(filter 1,$(DISK_SDCARD) $(DISK_EMMC)),)
CFLAGS+=-DWOLFBOOT_UPDATE_DISK -DMAX_DISKS=1
UPDATE_OBJS:=src/update_disk.o
OBJS += src/gpt.o
OBJS += src/disk.o
endif
ifeq ($(NO_ASM),1)
MATH_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sp_c32.o
else
MATH_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sp_arm32.o
ifneq ($(NO_ARM_ASM),1)
OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/arm/armv8-32-sha256-asm.o
OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/arm/armv8-32-sha256-asm_c.o
CFLAGS+=-DWOLFSSL_SP_ARM32_ASM -DWOLFSSL_ARMASM -DWOLFSSL_ARMASM_NO_HW_CRYPTO \
-DWOLFSSL_ARM_ARCH=7 -DWOLFSSL_ARMASM_INLINE -DWOLFSSL_ARMASM_NO_NEON
endif
endif
else
# All others use boot_arm.o
OBJS+=src/boot_arm.o
Expand Down Expand Up @@ -456,6 +521,7 @@ else
endif
endif
endif
endif


## Renesas RX
Expand Down
66 changes: 66 additions & 0 deletions config/examples/zynq7000.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
ARCH?=ARM
TARGET?=zynq7000
SIGN?=ECC256
HASH?=SHA256

# Cortex-A9 (Zynq-7000) - selected automatically via TARGET=zynq7000 in arch.mk.
# wolfBoot replaces U-Boot in the Z7 boot flow (BootROM -> FSBL -> wolfBoot ->
# kernel/app, no U-Boot stage). This single config supports both bare-metal
# and Linux payloads from QSPI.
DEBUG?=0
DEBUG_UART?=1
V?=0
SPMATH?=1

# Linux payload support (no-op for plain bare-metal payloads):
# LINUX_PAYLOAD=1 -> do_boot uses ARM Linux boot ABI (r0=0, r1=~0,
# r2=DTB_phys, r3=0). Bare-metal apps don't read these
# registers, so the same ABI is fine for them.
# MMU=1 -> enables update_ram.c DTB-load codepath and pulls in
# src/fdt.o. wolfBoot itself does NOT manage page
# tables; it inherits FSBL's flat 1:1 DDR mapping.
# ELF=1 -> wolfBoot understands ELF inputs (e.g. vmlinux) and
# loads only their LOAD segments. Flat binaries (zImage,
# bare-metal .bin) fall through to raw-binary boot.
# Cost vs. a strictly bare-metal-only build: ~5 KB extra wolfBoot binary
# from the FDT/MMU/ELF support, in exchange for one config that covers
# both payload types.
LINUX_PAYLOAD=1
MMU=1
ELF=1

# wolfBoot itself is staged by FSBL to DDR at 0x04000000 (hal/zynq7000.ld);
# the verified payload (kernel or bare-metal app) is staged at
# WOLFBOOT_LOAD_ADDRESS, well clear of wolfBoot. 1 GB DDR3 on ZC702
# starts at 0x00000000.
WOLFBOOT_LOAD_ADDRESS=0x10000000

# DTB load address (Linux only). Kernel reads it from r2. 16 MB clear of
# WOLFBOOT_LOAD_ADDRESS. Ignored for bare-metal payloads.
WOLFBOOT_LOAD_DTS_ADDRESS=0x11000000

# QSPI flash (16 MB N25Q128A on ZC702) via XQspiPs (hal/zynq7000.c).
# Override EXT_FLASH=0 on the make command line for JTAG-only dev builds.
EXT_FLASH?=1
NO_XIP=1

# QSPI partition layout (16 MB total) - sized for a full Linux kernel + DTB
# pair so the same layout also works for bare-metal payloads.
# 0x000000 - 0x07FFFF BOOT.BIN (FSBL + wolfboot, 512 KB)
# 0x080000 - 0x0FFFFF DTS_BOOT (signed DTB, 512 KB - Linux only)
# 0x100000 - 0x6FFFFF BOOT_A (~6 MB primary)
# 0x700000 - 0x77FFFF DTS_UPD (signed update DTB, 512 KB - Linux only)
# 0x780000 - 0xDFFFFF UPDATE_B (~6.5 MB update)
# 0xE00000 - 0xE0FFFF SWAP (64 KB scratch)
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x00100000
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x00780000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x00E00000
WOLFBOOT_PARTITION_SIZE=0x00600000
WOLFBOOT_SECTOR_SIZE=0x10000

WOLFBOOT_DTS_BOOT_ADDRESS=0x00080000
WOLFBOOT_DTS_UPDATE_ADDRESS=0x00700000

IMAGE_HEADER_SIZE=1024

CROSS_COMPILE?=arm-none-eabi-
113 changes: 113 additions & 0 deletions config/examples/zynq7000_sdcard.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
ARCH?=ARM
TARGET?=zynq7000
SIGN?=ECC256
HASH?=SHA256

# Cortex-A9 Zynq-7000 SD-card boot variant. Uses the generic SDHCI driver
# (src/sdhci.c) with HAL hooks in hal/zynq7000.c that translate between the
# driver's Cadence SD4HC register layout and the Arasan SDHCI v2.0 standard
# layout used by the Zynq-7000 controller (same IP family as ZynqMP's v3.0,
# just an older revision; the translation is reused from hal/zynq.c).
#
# wolfBoot replaces U-Boot in the Z7 boot flow (BootROM -> FSBL -> wolfBoot
# -> kernel/app, no U-Boot stage). This single config supports both
# bare-metal and Linux payloads from SD card -- see the LINUX_PAYLOAD/MMU/
# ELF block below.
DEBUG?=0
DEBUG_UART?=1
V?=0
SPMATH?=1

# SD card boot - swaps update_ram.o for update_disk.o + GPT/disk support.
DISK_SDCARD=1
NO_XIP=1

# Linux payload support (no-op for plain bare-metal payloads):
# LINUX_PAYLOAD=1 -> do_boot uses ARM Linux boot ABI (r0=0, r1=~0,
# r2=DTB_phys, r3=0). Bare-metal apps don't read
# these registers, so the same ABI is fine for them.
# MMU=1 -> pulls in src/fdt.o for FDT-aware paths in
# update_disk.c. wolfBoot does NOT manage page
# tables; it inherits FSBL's flat 1:1 DDR mapping.
# ELF=1 -> wolfBoot understands ELF inputs (e.g. vmlinux) and
# loads only their LOAD segments. Flat binaries
# (zImage, bare-metal .bin) fall through to raw-
# binary boot.
# For Linux from SD use tools/scripts/zynq7000/prepare_linux.sh APPENDED=1
# (DTB concatenated to zImage and signed as one image). update_disk.c does
# not read a separate PART_DTS_BOOT partition; the appended-DTB path is
# what carries the device tree to the kernel via CONFIG_ARM_APPENDED_DTB.
LINUX_PAYLOAD=1
MMU=1
ELF=1

# Stage payload at low DDR (clear of wolfBoot at 0x04000000-0x040FFFFF).
WOLFBOOT_LOAD_ADDRESS=0x10000000

# DTB load address (Linux only, used by update_disk.c when a FIT image
# carries a DTB). Ignored for bare-metal and for the appended-DTB Linux
# flow. 16 MB clear of WOLFBOOT_LOAD_ADDRESS.
WOLFBOOT_LOAD_DTS_ADDRESS=0x11000000

# MBR partition layout on the SD card. Pure MBR (no GPT) - the Zynq-7000
# BootROM (UG821 ch.6.3) only accepts MBR with the first partition as
# FAT32 and the Active flag set. wolfBoot's src/disk.c falls back to MBR
# parsing when no protective-GPT entry is present.
# MBR p1 (wolfBoot idx 0): FAT32-LBA Active - holds BOOT.BIN for BootROM.
# MBR p2 (wolfBoot idx 1): Linux raw (0x83) - signed boot image.
# MBR p3 (wolfBoot idx 2): Linux raw (0x83) - signed update image.
# tools/scripts/zynq7000/prepare_sdcard.sh lays this out; BOOT_PART_A/B tell
# update_disk.c which MBR entries (0-indexed) to use for boot/update.
CFLAGS_EXTRA+=-DBOOT_PART_A=1 -DBOOT_PART_B=2

# Arasan SDHCI v2.0 on Zynq-7000 is 3.3V-only, no UHS-I. The generic
# driver tries to push the card to UHS-I SDR25 / 50 MHz / High Speed mode
# which is invalid for our v2.0 + 3.3V combo and causes DTOE on the first
# data transfer (MBR read). Cap the post-init clock at SD default-speed
# 25 MHz; the HSE bit is also masked in hal/zynq7000.c sdhci_reg_write so
# the controller stays in single-edge timing the card matches.
# Cap the post-init SDHCI clock at 6 MHz. The Arasan SDHCI v2.0 on
# Zynq-7000 has a clock-dependent state-cleanup issue: at 12 MHz multi-
# block reads (CMD18) work, but a single-block read (CMD17) issued
# immediately after a CMD18+CMD12 sequence times out (DTOE) on the first
# data block. At 24 MHz even the very first CMD17 fails. 6 MHz / 4-bit
# bus is plenty fast for boot-time loading (~3 MB/s) and is well below
# the v2.0 quirk threshold; raise this if a future fix in src/sdhci.c
# adds an explicit DAT-line reset between transfers.
CFLAGS_EXTRA+=-DSDHCI_CLK_50MHZ=6000 -DSDHCI_CLK_25MHZ=6000

# update_disk.c reads images in DISK_BLOCK_SIZE chunks. Default 512 B = one
# disk_read = one CMD17 per 512 B, which makes a multi-MB Linux load issue
# thousands of CMDs and stall the card with per-CMD overhead. Bump to
# 512 KB so each disk_read pulls 1024 blocks via one CMD18 SDMA (matches
# ZynqMP). Verified on ZC702 with a 4.76 MB appended-DTB zImage: 9 CMD18s
# complete in well under a second. The default 4 KB SDMA buffer boundary
# is left in place -- overriding it to 512 KB stalled SDMA on Arasan v2.0.
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x80000

# Uncomment for verbose SDHCI driver logging when bringing up new boards
# or debugging timing issues.
#CFLAGS_EXTRA+=-DDEBUG_SDHCI

# Image-header partition addresses are unused for disk boot (kept for the
# Makefile sanity checks). update_disk.c finds images by GPT entry, not by
# memory address.
Comment thread
dgarske marked this conversation as resolved.
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x00100000
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x00700000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x00D00000
WOLFBOOT_PARTITION_SIZE=0x00600000
# Sector size of WOLFBOOT_PARTITION (not the SD physical sector, which is
# always 512 B). Used as the smallest erase/copy unit for the BOOT/UPDATE
# partitions; must be > IMAGE_HEADER_SIZE.
WOLFBOOT_SECTOR_SIZE=0x1000

IMAGE_HEADER_SIZE=1024

# Required by image.c when MMU=1 is set, even though update_disk.c never
# opens PART_DTS_BOOT/PART_DTS_UPDATE (the disk boot path uses appended-
# DTB or FIT, not a separate DTB partition). Set to dummy addresses to
# satisfy the build.
WOLFBOOT_DTS_BOOT_ADDRESS=0x0
WOLFBOOT_DTS_UPDATE_ADDRESS=0x0

CROSS_COMPILE=arm-none-eabi-
Loading
Loading