Skip to end of metadata
Go to start of metadata
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).

Booting Linux

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:

source /opt/Xilinx/Vivado/2017.2/
export CROSS_COMPILE=aarch64-linux-gnu-

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.

set hwdsgn [open_hw_design design_1_wrapper.hdf]
generate_app -hw $hwdsgn -os standalone -proc psu_cortexa53_0 -app zynqmp_fsbl -compile -sw fsbl -dir fsbl

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.

set hwdsgn [open_hw_design design_1_wrapper.hdf]
generate_app -hw $hwdsgn -os standalone -proc psu_pmu_0 -app zynqmp_pmufw -compile -sw pmufw -dir pmufw

Building ARM Trusted Firmware (ATF)

The Xilinx instructions for building ATF seem to work fine - clone the sources from, checkout the appropriate tag (e.g. xilinx-v2017.2), and build with the following to create build/zynqmp/release/bl31/bl31.elf.

make PLAT=zynqmp RESET_TO_BL31=1

Building U-Boot

Building U-Boot is similar to the Zynq-7000, but the output no longer needs to be manually renamed to u-boot.elf.

As per the Xilinx instructions, clone the sources from, checkout the appropriate tag (e.g. xilinx-v2017.2), and build with the following to create u-boot.elf.

make xilinx_zynqmp_zcu102_config

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.

open_hw_design design_1_wrapper.hdf
set_repo_path ../device-tree-xlnx
create_sw_design device-tree -os device_tree -proc psu_cortexa53_0
generate_target -dir dts

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.

//arch = zynqmp; split = false; format = BIN
        [destination_cpu = a53-0, bootloader]fsbl.elf
        [destination_cpu = a53-0, exception_level = el-3, trustzone]bl31.elf
        [destination_cpu = a53-0, exception_level = el-2]u-boot.elf

To generate 'BOOT.bin' using bootgen:

bootgen -image sd_boot.bif -arch zynqmp -w -o i BOOT.bin

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 scsi commands).

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 mkimage.

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.


PCI Express

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.

  • No labels