Unless otherwise stated, everything on this page is based on Vivado 2017.2 and a ZCU102 Revision 1.0 board with ES2 silicon (EK-U1-ZCU102-ES2-G).
The process for booting Linux on Zynq UltraScale+ has a few more steps than on Zynq-7000, some of which aren't (currently) documented well by Xilinx.
These instructions have been compiled from several different pages on the Xilinx Wiki, along with a bit of experimentation.
Before building anything, the Vivado tools need to be sourced, and the correct cross-compiler set:
Building the FSBL
The FSBL can be built in Xilinx SDK (by creating an Application Project targeting
psu_cortexa53_0 and selecting the 'Zynq MP FSBL' example project), or using HSI with the following TCL script.
I have experienced problems with the FSBL not updating correctly in SDK after changing Zynq parameters in Vivado then re-exporting the hardware design, leading to the board not booting. This could be fixed by deleting all SDK projects and starting from scratch (possibly caused by a bug in SDK).
Building the PMU firmware
PMU firmware can be built in Xilinx SDK (by creating an Application Project targeting
psu_pmu_0), or using HSI with the following TCL script.
Building ARM Trusted Firmware (ATF)
The Xilinx instructions for building ATF seem to work fine - clone the sources from https://github.com/xilinx/arm-trusted-firmware, checkout the appropriate tag (e.g.
xilinx-v2017.2), and build with the following to create
Building U-Boot is similar to the Zynq-7000, but the output no longer needs to be manually renamed to
Building the Linux Kernel
Kernel build instructions to be added here.
Building the device tree
The device tree can be created from the Xilinx Linux kernel sources (either within or out of the main source tree), or using SDK/HSI.
Device tree build instructions from kernel sources to be added here, including out-of-tree build.
The following HSI TCL script (or Xilinx SDK instructions) should theoretically create device tree sources based on the specified hardware design, however this has had problems for me (most obviously SATA did not work). Replace the
device-tree-xlnx repository path as appropriate.
Creating the boot image (BOOT.bin)
The SD card boot image should contain the FSBL, PMU firmware, ATF, and U-Boot.
This can be created using the 'Create Boot Image' option in Xilinx SDK, or by using the
bootgen tool. When using SDK, ensure the appropriate Exception Level and TrustZone options are used for ATF and U-Boot, and that bootloader and pmu partition types are used for the first two items.
To generate 'BOOT.bin' using
Loading the bitstream, device tree and kernel from U-Boot
The bitstream, device tree and kernel (and root filesystem) can be loaded from SD card, external storage (USB or SATA), flash, or a remote server via TFTP. This is similar to Zynq-7000, but with the addition of SATA support on Zynq UltraScale+ (accessed using U-Boot
The main difference between the Zynq UltraScale+ and Zynq-7000 is the ability to use the
booti command instead of
bootm. This allows the use of a standard kernel
Image file, instead of a packaged
uImage generated by
Also note that U-Boot by default seems to save its environment to a
uboot.env file on the SD card rather than to flash (which was the default on ZC706 boards).
Another thing to note is the
fpga info 0 command does not correctly display the size of the FPGA bitstream (instead showing '1 byte'). When using
fpga load, the size of the .bit file in bytes can be used instead.
The ZCU102 board supports PCIe Gen2 x1 by default, however x2 and x4 should be possible by modifying some settings in Vivado, and correctly setting the external GTR switch (see page 86 of the user guide).
The device tree will also need modifying to remove the DP/SATA/USB3 devices if these are disabled so the PCIe can use their GTR lanes.