This article will discuss the steps needed to download and compile a Bootable (SD) Linux Image for the ZCU102 using the OSL flow.
Table of Contents
Introduction
The recommended flow for building a Linux system is to use the Petalinux tools. However, this article offers an alternative for users that want full visibility into the Image.
This assumes that the users has downloaded Vitis 2020.1 (used to by the devcetree generator).
Some steps are duplicated. For example, the cross_compile steps. This is intentional to allow the users to build each image in isolation.
However, users must use the same tag, as there are dependencies between pmufw and atf for example.The rootFS is downloaded from the released images from here
Build FSBL
- git clone https://github.com/Xilinx/embeddedsw
- cd embeddedsw
- git checkout xilinx-v2020.1
- cd embeddedsw/lib/sw_apps/zynqmp_fsbl/src
- make "BOARD=zcu102-es2" "PROC=a53" "CFLAGS+=-DFSBL_DEBUG_INFO"
Build PMU Firmware
- cd embeddedsw/lib/sw_apps/zynqmp_pmufw/src
- make
Build ATF
- git clone https://github.com/Xilinx/arm-trusted-firmware.git
- cd arm-trusted-firmware
- git checkout xilinx-v2020.1
- export CROSS_COMPILE=aarch64-linux-gnu-
- export ARCH=aarch64
- make DEBUG=0 RESET_TO_BL31=1 PLAT=zynqmp bl31
Note: If users want to debug (ie use the symbols) the ATF in Vitis, then set the DEBUG=1. This will place the ATF in DDR at 0x1000
Build u-boot
- git clone https://github.com/Xilinx/u-boot-xlnx.git
- cd u-boot-xlnx
- git checkout xilinx-v2020.1
- export CROSS_COMPILE=aarch64-linux-gnu-
- export ARCH=aarch64
- make xilinx_zynqmp_zcu102_rev1_0_defconfig
- git clone https://git.kernel.org/pub/scm/utils/dtc/dtc.git
- cd dtc
- make
- export PATH=$PATH:/<Your Path>/dtc
- cd u-boot-xlnx
- make
Note: If users want to debug (ie use the symbols) the u-boot in Vitis, then use the u-boot (renamed u-boot.elf) in the boot image.
Build Linux Image:
- git clone https://github.com/Xilinx/linux-xlnx.git
- cd linux-xlnx
- git checkout xilinx-v2020.1
- export CROSS_COMPILE=aarch64-linux-gnu-
- export ARCH=arm64
- make xilinx_zynqmp_defconfig
- make
Build device-tree
- mkdir repo/my_dt
- cd repo/my_dt
- git clone https://github.com/Xilinx/device-tree-xlnx
- cd device-tree-xlnx
- git checkout xilinx-v2020.1
- cd ../../../
- Create a .tcl file with the following contents:
proc gen_dtb {hdf} { open_hw_design $hdf set_repo_path ./repo create_sw_design device-tree -os device_tree -proc psu_cortexa53_0 generate_target -dir my_dts }
- Launch HSI, and execute the following commands:
- source <your_filename>.tcl
- gen_dtb <HDF_FILE>.xsa
- Exit HSI
Do do this, open my_dts/system-top.dts and update the gem3 node, by appending the content below:
&gem3 { status = "okay"; local-mac-address = [00 0a 35 00 02 90]; phy-mode = "rgmii-id"; phy-handle = <&phy0>; phy0: phy@c { reg = <0xc>; ti,rx-internal-delay = <0x8>; ti,tx-internal-delay = <0xa>; ti,fifo-depth = <0x1>; }; };
Users can also add the dtsi here to my_dts directory, and include this into the DT structure. For a quick guide on Devicetree debugging, see the wiki here
Compile the devicetree (DTB)
- dtc -I dts -O dtb -o my_dts/system-top.dtb my_dts/system-top.dts
Note: For the 2018.3 release version onward, the 'include' syntax in device-tree files changed from /include/ to the 'C' style #include. Depending on which version of the device-tree-compiler (dtc) is being used, this may cause parsing errors when the .dts file is read. To fix this, all instances of #include need to be replaced with /include/.
Note: To verify, users can use the command below and investigate if the gem3 node was updated:
- dtc -I dtb -O dts -o my_dts/system-dump.dts my_dts/system-top.dtb
Create SD image
Build The bootgen binary
- git clone https://github.com/Xilinx/bootgen
- cd bootgen
- make
- export PATH=$PATH:/<Your Path>/bootgen
Create the BIF file with the contents below:
the_ROM_image: { [fsbl_config] a53_x64 [bootloader, destination_cpu=a53-0] embedded/lib/sw_apps/zynqmp_fsbl/src/fsbl.elf [pmufw_image] embeddedsw/lib/sw_apps/zynqmp_pmufw/src/executable.elf [destination_device=pl] design_1_wrapper.bit [destination_cpu=a53-0, load=0x00100000] my_dts/system-top.dtb [destination_cpu=a53-0,exception_level=el-3,trustzone] arm-trusted-firmware/build/zynqmp/release/bl31/bl31.elf [destination_cpu=a53-0,exception_level=el-2] u-boot-xlnx/u-boot.elf }
- bootgen -arch zynqmp -image bootgen.bif -o i BOOT.BIN -w on
Creating the FIT image:
/dts-v1/; / { description = "U-Boot fitImage for plnx_aarch64 kernel"; #address-cells = <1>; images { kernel@0 { description = "Linux Kernel"; data = /incbin/("./linux-xlnx/arch/arm64/boot/Image"); type = "kernel"; arch = "arm64"; os = "linux"; compression = "none"; load = <0x80000>; entry = <0x80000>; hash@1 { algo = "sha1"; }; }; fdt@0 { description = "Flattened Device Tree blob"; data = /incbin/("./my_dts/system.dtb"); type = "flat_dt"; arch = "arm64"; compression = "none"; hash@1 { algo = "sha1"; }; }; ramdisk@0 { description = "ramdisk"; data = /incbin/("./petalinux-user-image-plnx_aarch64.cpio.gz"); type = "ramdisk"; arch = "arm64"; os = "linux"; compression = "none"; hash@1 { algo = "sha1"; }; }; }; configurations { default = "conf@1"; conf@1 { description = "Boot Linux kernel with FDT blob + ramdisk"; kernel = "kernel@0"; fdt = "fdt@0"; ramdisk = "ramdisk@0"; hash@1 { algo = "sha1"; }; }; conf@2 { description = "Boot Linux kernel with FDT blob"; kernel = "kernel@0"; fdt = "fdt@0"; hash@1 { algo = "sha1"; }; }; }; };
- u-boot-xlnx/tools/mkimage -f fitimage.its fitimage.itb
Load the BOOT.BIN and the fitImage.itb on the SD card and boot. Stop at uboot, and
- fatload mmc 0 0x3000000 fitimage
- bootm 0x3000000
Users, can also update the uboot u-boot-xlnx/include/configs/Xilinx_zynqmp.h to add this: