Linux Kernel and Boot Loader
To the extent possible, the NDI examples attempt to follow the vendor specific boot flow and methods for building a Linux kernel and U-Boot boot-loader. The following sections detail specific customizations made to enable the otherwise standard vendor boot-loader and kernel to work with the NDI FPGA examples.
Altera
The Altera U-Boot bootloader and Linux kernel are built from git repositories provided by altera-opensource on github. See RocketBoards.org for full details.
Directory Structure
The following Altera project subdirectories can be found in the fpga_reference_design/linux_kernel directory:
agilex7
DK-SI-AGI027FA Agilex-7 SoC DevKit
a10-socdk
Arria-10 SoC Development Kit
SoCKit
Arrow/Terasic SoCKit
Build Requirements
Building the Linux kernel and U-Boot bootloader requires an appropriate cross compiler for the target archiecture. On Debian and similar systems, this can be accomplished by installing the appropriate packages:
sudo apt-get install cpp-aarch64-linux-gnu
sudo apt-get install gcc-arm-linux-gnueabihfAlternately an appropriate 3rd party cross compiler can be used, or a toolchain can be built directly from source.
Building an Existing Project
The build instructions from Altera involve quite a few manual steps:
https://www.rocketboards.org/foswiki/Documentation/BuildingBootloaderCycloneVAndArria10 https://altera-fpga.github.io/rel-25.1/embedded-designs/agilex-7/f-series/soc/boot-examples/ug-linux-boot-agx7-soc/
These steps have mostly been automated via a Makefile, with some additional changes to customize the kernel as needed for the NDI Advanced SDK (enable UIO devices and create custom device-tree nodes).
The Makefile will checkout the source directories, patch and configure as required, then build the files required to boot and create a uSD image. Warnings about watchdog and timer drivers are expected while building U-Boot from the Altera released sources and can be ignored.
The configuration snippet uio.fragment enables the required uio kernel modules.
The patch file 0001-NewTek-Altera-NDI-device-tree-entries.patch adds the required device-tree nodes for logic in the FPGA fabric. See the instructions from Altera for full details:
https://www.rocketboards.org/foswiki/Documentation/HOWTOCreateADeviceTree
Note:
If you follow the RocketBoards instructions for generating the Cyclone-V boot files, the FPGA will not be programmed by default. The provided Makefile builds a u-boot.scr file which is executed by the default Altera U-Boot bootcmd. This script programs the FPGA prior to loading the Linux kernel and device-tree.
Xilinx
The following boards and NDI configurations are supported. For a full list of available targets run make help in the fpga_reference_design/linux_kernel directory.
Arty-Z7-20-Enc
NDI encoder for the Digilent Arty Z7-20
Zybo-Z7-20-Enc
NDI encoder for the Digilent Zybo Z7-20
Zybo-Z7-20-Enc-Lite
NDI encoder for the Digilent Zybo Z7-20 with 16-bit SDRAM
Zybo-Z7-20-Dec
NDI decoder for the Digilent Zybo Z7-20
ZCU104-Enc
NDI encoder for the Xilinx ZCU104
ZCU104-Dec
NDI decoder for the Xilinx ZCU104
Xilinx offers at least two different approaches to generating the bootloaders, device tree, and Linux kernel.
PetaLinux flow
Open Source Linux (OSL) Flow
The OSL flow essentially builds each component required to boot the example design independently and then packages them together in a BOOT.BIN file along with a kernel, kernel modules, kernel headers, and a device tree. It offers the highest degree of transparency and control to the user and avoids the need to deal with the vagaries of alternate methods like Yocto or PetaLinux. It requires only that the user have installed the appropriate version of Vitis, which provides the ARM cross-compilers, XSCT, bootgen, and other supporting tools.
Required Xilinx Tools
Building the Xilinx example designs requires that the user have installed the AMD Vitis Unified Software Platform version 2024.2. Xilinx has recently merged Vivado and Vitis together and they generally should be installed concurrently. Vitis provides example design source code, the SDK, bare-metal libraries, as well as the cross-compilers, XSCT, bootgen and other supporting tools.
Installation instructions, supported platforms, and other details can be found in "UG1742, Vitis Release Notes and Installation Guide". After installation, users should prepare their environment by sourcing the appropriate settings script, found at <install_dir>/Vitis/2024.2/settings64.sh before attempting to build any of the example designs.
Generating Example Designs
The steps required for building the bootloaders and kernel are described to some degree on the Xilinx wiki and forums and have generally been automated via a top-level Makefile. To build one of the example designs, run make all with the following variables set accordingly:
XSA_BOARD- The target board:ZCU104,Zybo-Z7-20, orArty-Z7-20XSA_BOARD_PROJ- The design to build:Enc,Dec, orEnc-lite(Zybo only)
Note that case is significant and that the combination matches the project names in ../src/fpga as well as the device tree snippets in device-tree/.
Configuration Files
Each Xilinx board has a corresponding entry in boards/ which contains configuration settings used by the make process. The appropriate file to use is determined by the value of the XSA_BOARD variable and determines the flags to use for compiling the bootloader, the kernel, and other settings. Refer to the Makefile and fragments in mk/ for more details.
Each Xilinx project has a corresponding entry in device-tree/ which contains a device tree include file that will be included in the device tree source and ultimately compiled during the build process. The appropriate file to use is determined by the value of the XSA_BOARD_PROJ variable. Refer to the Makefile and fragments in mk/ for more details.
Output Products
There are many ways to boot Xilinx devices, this discussion is limited to what is done here. The build process produces several artifacts required for booting the system:
BOOT.BIN- The initial binary used to boot the system prior to loading the kernelsystem.dtb- The flattened device tree passed to the kernel by U-bootImageorzImage- The Linux kernel loaded by U-bootKernel modules and headers
Bootloaders and BOOT.BIN
The BOOT.BIN file created for the example designs contains the following content:
First-stage bootloader (FSBL)
U-boot ELF
Minimal U-boot device tree (used by U-Boot before loading the kernel)
Bitstream
Ultrascale+ devices also contain:
ARM Trusted Firmware (ATF)
Platform management unit (PMU) firmware
The origins of each component of the BOOT.BIN are the following:
The FSBL source code is exported by XSCT using the contents of the associated Xilinx support archive. After export, the source code and linker script are cross compiled for the target platform. Build flags for the FSBL are controlled by variables set in the appropriate board specific file in the
boards/directory. The FSBL ELF is staged for later packaging.The Makefile fetches the specified tag of the Xilinx U-boot fork, applies the defconfig from the file defined by
XSA_BOARDand cross-compiles it for the target platform. The U-boot ELF and a minimal device tree are staged for later packaging. It is worth noting that the Xilinx platforms used for NDI Advanced SDK example designs all have some level of support by U-boot and the device tree that is created is sufficient to boot a kernel from the SD card.The bitstream is extracted from the provided Xilinx support archive (XSA) file and staged for later packaging.
The PMU firmware (ZCU104 only) source code is exported by XSCT using the contents of the XSA file. The PMUFW is cross-compiled in the same was as the FSBL, with PMUFW specific build variables that can be useful for debugging. The user is referred to the Xilinx wiki and especially UG1137, the Zynq MPSoC Software Developers Guide, for more details regarding PMU use and configuration.
The Makefile fetches the specified tag of the ARM trusted firmware (ATF) and builds it for the target platform. The
bl31.elfit creates is then staged for later packaging.Once the FSBL and U-boot binaries, minimal U-boot device tree, bitstream, and PMUFW and ATF are staged, the appropriate
.biffile is installed alongside them andbootgenis run construct theBOOT.BINthat will eventually be transferred to/bootof an SD card. An MD5 hash is computed for each component as well as the final product. See UG1283 for more information on the use ofbootgento create and dumpBOOT.BINfiles.Once
bootgenhas finished assembling theBOOT.BINfile, it is copied to a project specific location in theoutputdirectory.
Flattened Device Tree
Generating the device tree source code and the flattened device tree requires several steps:
The Makefile fetches the indicated tag of the Xilinx device-tree source generator which is a large collection of Tcl scripts and board specific details for Xilinx IP and development boards. The DTS generator uses the XSA to infer IP settings and connections.
The path to that repo is used together with the project XSA file to create a directory containing all the files required to build a device tree for the specific Vivado project.
The files in the device tree source directory then undergo some modifications (see
mk/dtb.mkfor details) prior to compilation.The appropriate
.dtsifile indevice-tree/is included at this stage before the final device tree source is compiled into the flattened device tree.The flattened device tree and the top level source code are copied into the same project-specific location in the
outputdirectory that theBOOT.BINwas.
Kernel and Modules
The Linux kernel follows a much more familiar set of steps:
The Makefile fetches the indicated tag of the Xilinx fork of the Linux kernel source tree. To save space and time, this is a limited clone of the tree.
The kernel is built using an external build directory (using the
O=option), which allows the same source tree to be used to build multiple architectures.Default kernel configurations are used for both ARM and ARM64 kernels.
The kernel, modules, and headers are installed into
output/$(ARCH)/.
Rebuilding Example Designs after Modification
Rebuilding example designs after modifications to the FPGA projects is straightforward as long as a couple of caveats are followed:
The project naming conventions need to remain the same in order for device tree include files to be properly included
In principle, any new IP added that the kernel needs to be aware of will be automatically included by the device tree source generator. In practice, some manual modifications via the
.dtsifile may be required.Run
make cleanwhich will remove the staging area and output directories but preserve the git repos that were downloaded toextern/. Then runmake allwith theXSA_BOARDandXSA_BOARD_PROJset appropriately.
Petalinux Flow
The PetaLinux design flow is an alternative to the OSL flow that the NDI Advanced SDK uses. No PetaLinux projects are provided.
Suggested Steps for PetaLinux Projects
The PetaLinux commands and recommended work flow have changed in recent revisions of the tools and the following steps should only be used as a guide. For more detailed information, including the most recent commands and arguments, refer to "UG1144 PetaLinux Tools Documentation: Reference Guide" and other documents, in particular the Xilinx wiki.
The general approach to building a PetaLinux project based on the NDI Advanced SDK would be the following:
Export the hardware platform from Vivado and make sure that the bitstream is included in the exported Xilinx support archive (XSA)
Create a PetaLinux project
$ petalinux-create -t project <project_name>Import the new hardware definition and configure the project
$ cd <project_name>$ petalinux-config --get-hw-description <path-to-vivado-project>Configure the project, kernel, U-boot, and rootfs
$ petalinux-config -c u-boot$ petalinux-config -c kernel$ petalinux-config -c rootfsAdd device tree include files from
device-tree/for the target platform to the PetaLinux project. This has typically been done by copying it to a location with theproject-metadirectory, but this may vary by version. If the design to be built includes additional IP or other modifications that affect the device tree, these need to be made as well, typically by hand.Build the project.
$ petalinux-buildPackage the system for deployment (note that there are likely many options that will need to be included for this command)
$ petalinux-package <options>
Once the project has been completed, boot images are typically located in the project tree at images/linux. The kernel and kernel modules will need to be extracted from the project along with the device tree and BOOT.BIN for transfer to an SD card. Various kernel images are usually generated during the build process. Kernel modules can be extracted from the rootfs tarball that is created during the build.
Last updated
Was this helpful?

