This blog post is a long overdue continuation of the "Avnet HDL git HOWTO" blog post I wrote last year.  Like the Avnet HDL github repository of build scripts, IP, etc. for building the Vivado projects that are the hardware foundation for customers to use and customize, Avnet's PetaLinux github repository is also full of build scripts, bitbake recipes, etc. for creating BSPs that customers are able to use as the basis for their own Linux development on Avnet Zynq and Zynq UltraScale+ SOMs and development boards.  This blog will focus on building a PetaLinux BSP for the Avnet Ultra96-V2 board using a Linux bash build script from the Avnet "petalinux" github repository.


Before we Begin

Bold assumptions:

User is familiar with:

  • git commands
  • Linux command line
  • Xilinx PetaLinux tools

Software requirements:

  • Ubuntu v16.04 LTS or v18.04 LTS 64-bit host OS
  • PetaLinux tools installed
  • At least 100GB of free disk space


Repository Setup

Make the Repositories Folder

The git repositories must be installed into the same parent folder because the build scripts use relative paths to reference their required input files.  Choose a folder where you wish to clone the git repositories and run the scripts.  You will need at least 100GB of free disk space in this folder.  For example, you may wish to clone the repositories into a /home/<user>/git/avnet folder.

$ cd ~

$ mkdir -p git/avnet

$ cd git/avnet


Clone the Repositories

Clone the Avnet "petalinux", "hdl", and "bdf" git repositories.  Though we are building a PetaLinux BSP the underlying Vivado hardware platform is required and the PetaLinux build script will take care of launching the Vivado tools in the background to build this, hence the requirement now for the "hdl" and "bdf" repositories.


The "bdf" repository stores the Vivado Board Definition Files (BDFs) that are required to build or open any designs that target a known SOM or development board.  Xilinx provides BDFs for their boards (ZC702, ZCU102, etc.) and includes them in the Vivado installation.  Avnet provides this repository for the BDFs that target their SOMs and dev boards.

$ git clone


The "hdl" git repository stores all of the TCL build scripts and design input files (constraints files, IP sources, etc.).

$ git clone


The "petalinux" git repository stores all of the Linux bash build scripts and input files (Yocto recipes, patches, etc.).

$ git clone


Checkout the Correct git Branch

As you may know, git uses the concept of branches to separate revision controlled versions of source files.  For a stable repository with not many changes, like the bdf store, all changes can be tracked on the master branch.  For a more dynamic repository, like the hdl and petalinux stores, it makes sense to create branches tied to the version of Vivado and PetaLinux tools the build scripts, etc. are meant to work with

$ cd bdf

$ git checkout master

$ cd ../hdl

$ git checkout 2019.2

$ cd ../petalinux

$ git checkout 2019.2


Repository File Structure

The Avnet git repository for PetaLinux projects contains the following subdirectories:


configsContains the files needed to create specific configurations for the Linux device tree, kernel, rootfs, and u-boot.
projectsEmpty when the repository is cloned.  This is where the PetaLinux project will be created when the build script is run.
scriptsContains the scripts for each for each of the scripted build projects.


This structure has been setup for maximum flexibility in design creation as well as maximum reuse of designs . Avnet has made a commitment to using this structure to implement our designs in order to give our customers a consistent look and feel to our reference designs. This will allow anyone to be able to edit a project to fit their needs. Typically we will release a TAG (snapshot) of a project guaranteeing it’s validity for a specific configuration. This provides great flexibility for users to start with a known-good project and edit the scripts as needed to create a project that has been purpose built for the configuration they want.

The Configs Folder

Here you will see the subfolders of the numerous components of a PetaLinux project that can be configured and customized.

The files in device-tree, kernel, and rootfs generally follow naming convention of filename.BOARD_NAME or filename.PROJECT_NAME. These BOARD_NAME and PROJECT_NAME variables are defined in the build scripts that fetch these files and incorporate them into the PetaLinux build. The u-boot configurations files generally follow a naming convention of platform-top.h.<board architecture>_<boot media method>. The meta-user/ROOTFS_NAME folders contain the custom applications, scripts, bitbake build recipes, etc. to be integrated into the rootfs of the PetaLinux build.


The Scripts Folder

The scripts folder contains the PetaLinux project build and cleanup scripts for all the available projects. The scripts in this folder generally follow the naming convention of <make| clean>_<board architecture>_<target application>.sh. Scripts that are used to build the generic PetaLinux BSPs for Avnet SOMs and development boards are named <make| clean>_<board architecture>


Anatomy of a Project Script

It is important to note that the PetaLinux projects scripts will also first run the associated Vivado build script to build the underlying hardware platform that PetaLinux will run on. This is why it is a requirement that the git HDL repository also be cloned AND that it is cloned into the same parent folder as the PetaLinux git repository. There are three key portions of the PetaLinux Build Script:

  • Script Variables
  • Main Make Function
  • Build Hardware Platform
  • Create PetaLinux BSP

To get an understanding of what happens when we launch a scripted PetaLinux build, let's take a look at a sample build script and follow the chain of events that occur.  For this example we will examine the build script.


Script Variables

This section is where build options like boot method(s) for the build are set, path locations of where the Vivado and PetaLinux tools are installed, core names of the input and output build files, and relative path locations of where the input files can be found. The script specifies the Xilinx default install folders, and may need to be edited to match your environment. Different boot methods can be selected, and this in turn fetches the specific u-boot bootloader configuration that is needed for the selected boot media. Boot options include SD card, QSPI Flash, and eMMC.  Not all SOMs and dev boards support all boot methods.  The Ultra96-V2 board, for example, does not support QSPI or eMMC boot.  The default for the Ultra96-V2 is SD card boot with a ext4 partition for the root file system (rootfs).  The BUILD_BOOT_SD_OPTION is always set to yes (for the Ultra96-V2 this is always SD_EXT4 boot).

Main Make Function

This is the part of the script where the build target(s) are specified. In some cases like the MicroZed, PicoZed, and UltraZed SOMs there are different variants for the Xilinx device and Avnet carrier card that such that each has their own build configuration. The HDL_BOARD_NAME script variable defines the Avnet board target as input to the Vivado build script that is run during the build_hw_platform step.


Build Hardware Platform

The build script will first check to see if the Vivado hardware project has already been built. If it has then the script will move on to the next step to build the PetaLinux BSP. This is helpful to reduce run times when this PetaLinux script is run many times during development and debug.


Create PetaLinux BSP

This part of the script is where most of the work happens. It starts with the PetaLinux project is created:

The hardware definition file and PL bitstream from the Vivado project are copied to the PetaLinux project folder and imported into the PetaLinux project:

The project config file is patched with customized settings:

The root filesystem (rootfs), device tree, and kernel are all configured with their particular settings imported from the configs folders:

Because the script may build a u-boot image for many different boot methods, the current boot configuration must be saved:

Do a full project clean before building the first image:

The script will build a PetaLinux image for each boot method that has been specified in the script variables. The script will loop here until the PetaLinux image is built successfully and the boot method-specific product files will be saved and copied to new filenames so they won't be overwritten later.  Once the builds are complete for each of the boot methods, the binary product files are copied to a project folder and the BSP file is created.


Launch the PetaLinux Build Script

Open a command terminal and navigate to the build scripts folder.

$ cd ~/git/avnet/petalinux/scripts

$ ./


The build will begin and the terminal window will display the progress as the hardware platform is built in Vivado and the the Linux OS image is created.

Prepare the SD Card and Boot the New Linux OS Image

Once the BSP build is complete you can boot the new OS image on the Ultra96-V2 board.  If you haven't already followed the Getting Started Guide you will need to first partition the SD card with - for example - a 1GB FAT32 boot partition and (assuming you are using the provided 16GB Delkin micro SD card) and a 15GB ext4 partition.  Navigate to the 'images/linux' folder of the PetaLinux project and extract the rootfs.tar.gz file to the ext4 partition and copy the BOOT.BIN and Linux kernel image.ub files to the FAT32 partition.  Remember that you will need to have 'root' or 'su' permissions to extract the rootfs to the ext4 partition.  It is a good idea to delete anything that is already in that partition, so be careful that you don't delete anything you need to keep.  For example, on an Ubuntu host:

$ cd ~/git/avnet/petalinux/projects/ultra96v2_oob_2019_2

$ cp ./images/linux/BOOT.BIN /media/training/<UUID of FAT32 partition>/.

$ cp ./images/linux/image.ub /media/training/<UUID of FAT32 partition>/.

$ sudo rm -rf /media/training/<UUID of ext4 partition>/*

$ sudo tar xvf ./images/linux/rootfs.tar.gz -C /media/training/<UUID of ext4 partition>/

$ sync; sync (VERY IMPORTANT to sync the filesystem BEFORE ejecting the SD card!  If you don't the filesystem may be corrupted.)


The Value of a Known-Good Design and Starting Point

The key idea behind these PetaLinux build scripts and the "bdf", "hdl", and "petalinux" github repositories is to easily create a known-good BSP targeting an Avnet SOM or dev board quickly, easily, and repeatably.  Being able to start a Xilinx design from a known-good starting point is critical when designing with complex devices like Zynq and Zynq MPSoC.  There are many Linux kernel, u-boot, and root filesystem configuration details, from devicetree settings and software packages, etc., that can cause hours and days of anguish to debug if they aren't done correctly.  For the engineers at Avnet these build scripts have the added benefit of providing a starting point when it is time to update a published reference design.  Public users are also welcome to use these repositories and contribute.


Buy Ultra96-V2Buy Ultra96-V2


Buy Ultra96-V2 I-gradeBuy Ultra96-V2 I-grade


Buy 96Boards 4A Power SupplyBuy 96Boards 4A Power Supply


Buy Ultra96-V2 JTAG/UART AdapterBuy Ultra96-V2 JTAG/UART Adapter