This repository constructs a PYNQ image from the Ubuntu repositories and the sources of the other constituent parts.
It's highly recommended to run these scripts inside of a virtual machine. The image building requires doing a lot of things as root and while every effort has been made to ensure it doesn't break the world this is far from guaranteed. This flow must be run in a Ubuntu based Linux distribution and has been tested on Ubuntu 16.04 and Ubuntu 18.04. Other Linux versions might work but may require different or additional packages. The build process is optimised for 4-cores and can take up to 50 GB of space.
- Ensure that sudo is configured for passwordless use and that proxy settings and other environment variables are forwarded correctly.
- Run
scripts/setup_host.sh
- Install Petalinux (e.g. 2022.1)
- Ensure that Petalinux is on the PATH
- Ensure that the prebuilt pynq sdist and rootfs tarballs are in the sdbuild/prebuilt folder
- Run
make BOARDDIR=<boards_directory>
to recreate all board images - Wait for a couple of hours
The setup_host.sh
script install a set of packages required either for Vivado
or the other build tools. It installs crosstool-ng which is not included in the
ubuntu repository and an up-to-date and slightly patched version of QEMU which
fixes some race conditions in the ubuntu-shipped version. See the source of the
script for more details in what exactly needs to be done to configure your own
environment if the script proves insufficient. Also, make sure you have the
appropriate Vivado licenses to build for your target board, in particular
HDMI IP.
The image process is designed for the quick building of multiple board images across both ZYNQ and ZYNQ Ultrascale+ architectures. The build is split into board agnostic and board specific sections. First a generic image is created for each device family consisting of the base Ubuntu root filesystem and the PYNQ packages such as Jupyter and the Microblaze compiler.
The ubuntu
folder contains all of the files for the initial bootstrap of the
Ubuntu root filesystem. For this release we are targeting the 18.04 Bionic
Beaver release but other versions can be added here if desired. The bionic
folder contains subfolders for the arm
and aarch64
architectures each
containing a multistrap
config file, a set of patches to apply to the
filesystem and a config
file listing the packages to be installed.
Packages form the core of the image flow and each consists of up to four files, all of which are optional:
- A
Makefile
which adds to thePACKAGE_BUILD_${PACKGE_NAME}
variable any targets that are required. This should be used for downloading or compiling files that can be done on the host. If the package needs to run architecture- specific rules this can be added toPACKAGE_BUILD_${PACKAGE_NAME}_${ARCH}
. - A
pre.sh
bash script called before running the chroot which ordinarily copies files into the chroot. The chroot location is passed as the first argument. - A
qemu.sh
bash script called from within the context of the chroot. As the chroot is run with QEMU the minimum possible amount of work should be done here. - A
post.sh
bash script called after running the chroot which ordinarily cleans up any temporary files. The chroot location is passed as the first argument.
Scripts should not polluted their current working directory instead using the
location specified by $BUILD_ROOT
for all temporary files. This is also the
recommend place for the makefile to deposit files for the bash scripts to
subsequently use. Each package script is passed ARCH
and PYNQ_BOARDNAME
as environment variables.
Each board in the boards
subdirectory of the PYNQ repo contains a *.spec
file, (optional) some packages, and (optional) Petalinux BSP related files.
The *.spec
file details the BSP file to use,
the bitstream to load on boot and any additional packages that
should be installed in the root filesystem.
The *.spec
file should be placed in the root folder for the board and
all paths within it should be given relative to it.
There are three main variables the spec file is responsible for setting:
BSP_${BOARD}
BITSTREAM_${BOARD}
STAGE4_PACKAGES_${BOARD}
${BOARD}
must be the same as the name of the folder containing the spec file.
This will also ultimately be the value of the $BOARD environment variable in
the final image.
There are two flows for porting to a new board. The simplest approach is to
take a pre-existing PetaLinux BSP and our pre-built board-agnostic image
appropriate to the architecture - arm for Zynq-7000 and aarch64 for Zynq
UltraScale+. The scripts/image_from_prebuilt.sh
script will take these two
components and create an image without needing to run the whole image creation
flow. See that script for the details of the arguments that are needed.
For more substantial board support you will need to create a board repository based on either a PetaLinux BSP or an HDF file from Vivado. The steps to create a board repository are detailed below.
First you need to create folder to act as a board repository -
myboards
in this example - and create a subfolder to hold the spec for
the board you are porting to - myboards/Myboard
.
You also need to create a spec file - by convention
Myboard.spec
. This will set make variables for the board as follow:
BSP_Myboard := Myboard.bsp
BITSTREAM_Myboard := Myboard.bit
# Optionally install some additional packages
STAGE4_PACKAGES_Myboard := my_package
The main prerequisite for porting to a new board is the existence of a valid
Petalinux BSP (Myboard.bsp
) for the board targeting the correct
version of the Xilinx tools. This can be done in multiple ways shown below.
You may already have a Vivado project to start with. In that case, either
(1) the make flow to build your hardware project
(all the way to the *.hdf
file), or (2) the pre-built *.hdf
file has to
be provided. The SD build flow will take that *.hdf
file in and generate
the BSP. BSP_Myboard
in the *.spec
file can be left empty.
Meta-user configurations can be added to the myboards/Myboard/petalinux_bsp
folder so the patches will be applied to the new BSP.
You may already have a BSP downloaded somewhere, or constructed
previously. In that case, you can just specify BSP_Myboard
in
the *.spec
file, and the SD build flow will take that BSP file in and build
the boot files.
Again, meta-user configurations can be added to the
myboards/Myboard/petalinux_bsp
folder so the patches will be applied to the
new BSP. For more details about customising the
boot files please refer to the Petalinux documentation.
Custom packages can be placed in a packages
subfolder of the and will be
picked up automatically if referenced. This is a convenient way of installing
custom notebooks or Python packages if desired for your board.
(1) Collect a prebuilt board-agnostic root filesystem tarball and a prebuilt PYNQ source distribution.
Starting in PYNQ v3.0, by default the SD card build flow expects a prebuilt root filesystem and a PYNQ source distribution to speedup and simplify user rebuilds of SD card images. These binaries can be found at the PYNQ boards page and copied into the sdbuild prebuilt folder
# For rebuilding all SD cards, both arm and aarch64 root filesystems
# may be required depending on boards being targetted.
cp pynq_rootfs.<arm|aarch64>.tar.gz <PYNQ repository>/sdbuild/prebuilt/pynq_rootfs.<arm|aarch64>.tar.gz
cp pynq-<version>.tar.gz <PYNQ repository>/sdbuild/prebuilt/pynq_sdist.tar.gz
With all the files prepared, the SD card image can be built by navigating to the following directory and running make:
cd <PYNQ repository>/sdbuild/
make
You can force a PYNQ source distribution rebuild by setting the REBUILD_PYNQ_SDIST variable when invoking make
make REBUILD_PYNQ_SDIST=True
You can force a root filesystem build by setting the REBUILD_PYNQ_ROOTFS variable when invoking make:
make REBUILD_PYNQ_ROOTFS=True
All boot files are created using Petalinux based on a provided BSP. To generate the boot files only:
make boot_files BOARDDIR=<absolute_path>/myboards
To generate sysroot:
make sysroot BOARDDIR=<absolute_path>/myboards
To generate the Petalinux BSP for future use:
make bsp BOARDDIR=<absolute_path>/myboards
To use a previously built PYNQ source distribution tarball and/or rootfs, instead of moving the files into the prebuilt folder, you can specify the PYNQ_SDIST
and PYNQ_ROOTFS
environment variables
make PYNQ_SDIST=<sdist tarball path> PYNQ_ROOTFS=<rootfs tarball path>
By default the SD build flow will pull from https://ports.ubuntu.com. This can
be changed by setting the PYNQ_UBUNTU_REPO
environment variable. The
repository link in the final image will remain unchanged.