Zynq ZCU102

The board is Zynq UltraScale MPSoC ZCU102 Eval Kit, Rev 1.1 The port also works on the ZCU106 evaluation kit.

Xilinx maintains online material, including designs and documentation here.



Checkout the sel4test project using repo as per seL4Test

repo init -u https://github.com/seL4/sel4test-manifest.git
repo sync
mkdir cbuild
cd cbuild
../init-build.sh -DPLATFORM=zcu102 -DAARCH64=1
# The default cmake wrapper sets up a default configuration for the target platform.
# To change individual settings, run `ccmake` and change the configuration
# parameters to suit your needs.

Generated binaries can be found in the images/ directory.

The ZCU102 also supports AArch32 mode. If you choose to build the AArch32 kernel, please be sure to pass -DAARCH32=1 instead of -DAARCH64=1.

ARM Trusted Firmware (ATF)

git clone https://github.com/Xilinx/arm-trusted-firmware.git
cd arm-trusted-firmware
make PLAT=zynqmp RESET_TO_BL31=1 CROSS_COMPILE=aarch64-linux-gnu-

Generated ELF file can be found at build/zynqmp/release/bl31/bl31.elf.


git clone https://github.com/Xilinx/u-boot-xlnx.git
cd u-boot-xlnx
make xilinx_zynqmp_virt_defconfig
# Use "make menuconfig" to open the configuration interface, change the value
in "Default Device Tree" to "zynqmp-zcu102-rev1.0" or "zynqmp-zcu106-rev1.0"
make CROSS_COMPILE=aarch64-linux-gnu-

If you use gcc > 10, apply the following patch before compiling:

diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index fd825ebba6..24af549977 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -38,7 +38,6 @@ LINECOMMENT	"//".*\n
 #include "srcpos.h"
 #include "dtc-parser.tab.h"

-YYLTYPE yylloc;
 extern bool treesource_error;
 /* CAUTION: this will stop working if we ever use yyless() or yyunput() */

If you choose to use the AArch32 kernel, apply the following patch:

diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 52b08c4dbe..c9ebd33d15 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -358,7 +358,7 @@ unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
 		armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
-				    ES_TO_AARCH64);
+				    ES_TO_AARCH32);
 	} else {
 		printf("FAIL: current EL is not above EL1\n");
 		ret = EINVAL;

Generated ELF file is u-boot.elf.

Upstream U-Boot also works; instructions are here

Development Environment

Install Vivado SDK or Vitis Software Platform from Xilinx here (Requires a free Xilinx account). The following instructions are based on Vivado SDK v2019.1

First stage boot load (FSBL)

Open Vivado SDK, create a new application project.

  • OS platform: standalone
  • Hardware Platform: ZCU102_hw_platform
  • Processor: psu_cortexa53_0
  • Language: C
  • Compiler: 64-bit
  • Hypervisor Guest: No
  • Template: Zynq MP FSBL

Generated ELF file is in Debug directory

PMU firmware

Open Vivado SDK, create a new application project.

  • OS platform: standalone
  • Hardware Platform: ZCU102_hw_platform
  • Processor: psu_pmu_0
  • Language: C

Generated ELF file is in Debug directory

Booting via JTAG

Set DIP switch (SW6) to JTAG boot (on, on, on, on).

Start the Xilinx debug tool (shipped with Vivado SDK):

xsct -nodisp

Upload files to the board using XSCT prompt:

targets -set -filter {name =~ "PSU"}
mwr 0xffca0038 0x1ff
targets -set -filter {name =~ "MicroBlaze*"}
dow pmufw.elf
target -set -filter {name =~ "Cortex-A53 #0*"}
rst -processor
dow fsbl.elf
dow bl31.elf
dow u-boot.elf
# Load the seL4 image in ELF format, the file can be found in the sel4test build directory
dow elfloader/elfloader

Booting via SD Card

Get an SD card can format it with FAT32.

Set DIP switch (SW6) to SD boot (off, off, off, on)

Create a output.bif file with the following content:

    [bootloader, destination_cpu = a53-0] fsbl.elf
    [pmufw_image] pmufw.elf
    [destination_cpu = a53-0, exception_level = el-3] bl31.elf
    [destination_cpu = a53-0, exception_level = el-2] u-boot.elf

Generate the bootable binary:

bootgen -arch zynqmp -image output.bif -w on -o BOOT.bin

Copy BOOT.bin to the SD card

Insert the SD card into ZCU102 then power on the board, and drop into the U-Boot prompt. When you’re at the prompt, type the following to load the ELF file generated from builidng seL4test:

fatload mmc 0 0x8000000 sel4test-driver-image-arm-zynqmp
bootelf 0x8000000