This version (11 Jan 2018 10:20) was approved by Alexandru Ardelean, Michael Hennerich.The Previously approved version (19 Oct 2017 11:14) is available.Diff

Building the ZynqMP / MPSoC Linux kernel and devicetrees from source

The script method

We provide a script that does automates the build for Zynq using the Linaro toolchain.

Note that this script differs from the one for Zynq.

The script takes up to 3 parameters, but if left blank, it uses defaults:

  1. <local_kernel_dir> - default is linux-adi if left blank ; use this, if you want to use an already cloned kernel repo
  2. <devicetree_file> - which device tree should be exported/copied from the build ; default is zynqmp-zcu102-rev10-ad9361-fmcomms2-3.dtb for Zynq
  3. <path_to_other_toolchain> - in case you have your own preferred ARM64 toolchain [other than Linaro's or Xilinx's] you can use override it with this 3rd param

The script will:

  1. clone the ADI kernel tree
  2. download the Linaro GCC toolchain [if no other is specified]
  3. build the ADI kernel tree
  4. export/copy the Image file and device tree file out of the kernel build folder

Running the script in one line [with defaults]

wget && chmod +x && ./ zynqmp

Building using Petalinux

Please see here: Building with Petalinux

On the development host

Create a local copy of ADI's kernel tree

git clone

or do a git pull in an existing repository.

Checkout the master development/master branch

dave@hal9000:~/github-linux-build/linux$ git checkout master
Already on 'master'
Your branch is up-to-date with 'origin/master'.

Add aarch64-linux-gnu-gcc to PATH

Vivado 2016.2 SDK may be installed into a different directory

dave@hal9000:~/github-linux-build/linux$ export PATH=$PATH:/opt/Xilinx/SDK/2017.2/gnu/aarch64/lin/aarch64-linux/bin

Other toolchains/compilers for ARM may work as well, but the ones described here have been tested and found to work.

Using the Linaro toolchain

Alternatively, the Linaro toolchain/compiler can be used to compile to kernel. Linaro compilers (that work with ZYNQMP) can be downloaded from: . Always use the latest release just in case.

Setup cross compile environment variables

dave@hal9000:~/github-linux-build/linux$ export ARCH=arm64

dave@hal9000:~/github-linux-build/linux$ export CROSS_COMPILE=$(pwd)/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-

Configure the kernel

Inside the repository, generate the configuration file before building the kernel tree.

dave@hal9000:~/github-linux-build/linux$ make adi_zynqmp_defconfig 
# configuration written to .config

Build the kernel

Build the kernel via 'make'. This is the same for all Xlinx ZYNQMP MPSoC FPGAs.

dave@hal9000:~/github-linux-build/linux$ make -j5 Image UIMAGE_LOADADDR=0x8000
  CHK     include/config/kernel.release
  CHK     include/generated/uapi/linux/version.h
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/basic/bin2c

[ -- snip --]

  CC      init/version.o
  LD      init/built-in.o
  KSYM    .tmp_kallsyms1.o
  KSYM    .tmp_kallsyms2.o
  LD      vmlinux
  SORTEX  vmlinux
  OBJCOPY arch/arm64/boot/Image

Build the devicetree FCMOMMS2/3

Build the one that fits your FPGA carrier and FMC card

device tree board
zynqmp-zcu102-rev10-ad9361-fmcomms2-3.dts ZCU102 Rev. 1.0 and the AD-FMCOMMS2-EBZ or AD-FMCOMMS3-EBZ board
zynqmp-zcu102-rev10-ad9364-fmcomms4.dts ZCU102 Rev. 1.0 and the AD-FMCOMMS4-EBZ or AD-FMCOMMS4-EBZ board
zynqmp-zcu102-revB-ad9361-fmcomms2-3.dts ZCU102 Rev.B and the AD-FMCOMMS2-EBZ or AD-FMCOMMS3-EBZ board
zynqmp-zcu102-revB-ad9364-fmcomms4.dts ZCU102 Rev.B and the AD-FMCOMMS4-EBZ board

The device tree zynqmp-zcu102-revA.dts can also be used for any ZCU102 FPGA that uses an SD card for boot up. Building the device tree uses 'make' by turning the .dts file to a .dtb. The command is simply 'make' plus the device tree name with a .dtb file extension.

dave@hal9000:~/github-linux-build/linux$  make xilinx/zynqmp-zcu102-rev10-ad9361-fmcomms2-3.dtb
  DTC     arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev10-ad9361-fmcomms2-3.dtb

Copy the generated files to your SD Card

The output files for building the kernel and device tree are Image and <device_tree_name>.dtb. Refer to the code below to find their respective output directories. The device tree file needs to be renamed to system.dtb. See kuiper-linux for more information in configuring the SD card.

dave@hal9000:~/github-linux-build/linux$ cp arch/arm64/boot/Image /media/michael/BOOT/
dave@hal9000:~/github-linux-build/linux$ cp arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revB-ad9361-fmcomms2-3.dtb /media/michael/BOOT/system.dtb

Building the ZynqMP boot image

The boot image BOOT.BIN is build using the bootgen tool which requires several input files.

Instructions on how to build the Xilinx Shell Archive (XSA) handover file can be found here:

All further steps are lengthy explained on the Xilinx Wiki Page

Use script to build BOOT.BIN

For ease of use we provide a bash shell script which allows building BOOT.BIN from system_top.xsa, u-boot.elf and either bl31.elf or a path to the Arm Trusted Firmware repository


The script can be downloaded from here:

NOTE: After downloading the script you need to make it executable

$ chmod +x


usage: system_top.xsa u-boot.elf (download | bl31.elf | <path-to-arm-trusted-firmware-source>) [output-archive]
  • Make sure that Vivado and Vitis is included in the path and a cross compiler for arm64 exists before running the script. For more information about cross compilers, see Building the ZynqMP / MPSoC Linux kernel and devicetrees from source.
  • Path to system_top.xsa and u-boot.elf are required parameters.
    • To find system_top.xsa, see Building HDL. After building a project in the HDL repository, it can be found inside a <project>_<board>.sdk folder.
    • See the note at the bottom of the page regarding u-boot.elf.
  • The 3rd argument must either be download (which will git clone the ATF repository), bl31.elf or the file system path to the Arm Trusted Firmware source code repository
    • See the note at the bottom of the page regarding bl31.elf.
  • An optionally 4th name parameter can be given to tar.gz the output directory. (name.tar.gz)
  • BOOT.BIN and other build output files are located at the newly created local directory named: output_boot_bin.
  • This script requires Xilinx Vitis and bootgen in the PATH.
    • A simple way is to source Vivado settings[32|64].sh for Linux:
$ source /opt/Xilinx/Vivado/202x.x/
  • When using cygwin, you can add the following in the ~/.bashrc configuration file:
export PATH=$PATH:/cygdrive/c/Xilinx/Vivado/202x.x/bin
export PATH=$PATH:/cygdrive/c/Xilinx/Vitis/202x.x/bin
export PATH=$PATH:/cygdrive/c/Xilinx/Vitis/202x.x/gnu/microblaze/nt/bin

NOTE: u-boot.elf and bl31.elf
For those who don't want to build u-boot or bl31 themselves.
Both u-boot.elf and bl31.elf can be extracted from the project folder on the SD Card image, bootgen_sysfiles.tgz.

u-boot.elf may have a different name, rename that .elf file to u-boot.elf before using.

14 Feb 2018 15:09 · Michael Hennerich

DisplayPort - no picture?

The default configuration for most of the projects is to use the HDMI output, and that is what the configuration is set up for.

For DisplayPort projects, you may need to add a custom xorg.conf file.

root@analog:~# printf "Section \"Device\"\n  Identifier \"myfb\"\n  Driver \"fbdev\"\n  Option \"fbdev\" \"/dev/fb0\"\nEndSection\n" > /etc/X11/xorg.conf
root@analog:~# cat /etc/X11/xorg.conf 
Section "Device"
  Identifier "myfb"
  Driver "fbdev"
  Option "fbdev" "/dev/fb0"

After following that, the board should be rebooted.

You can find a list with tested monitors here. Resolution or image problems may appear if there is used a monitor that was not tested.

11 Jan 2018 10:19 · Alexandru Ardelean
resources/eval/user-guides/ad-fmcomms2-ebz/software/linux/zynqmp.txt · Last modified: 11 Jan 2018 10:20 by Alexandru Ardelean