Quick Porting of PYNQ using Pre-built Images

This is a quick post showing how to use the pre-built images we ship with each PYNQ release to quickly get PYNQ up and running on a new board. The starting point for porting PYNQ is to have a working Petalinux BSP for the board - for details on creating a BSP for a custom board please refer to the Petalinux documentation. For this example we’ll use the ZC706 BSP.


To begin with we need the following requirements

  1. Ubuntu instance (preferable a virutal machine)
  2. Correct version of Petalinux installed and on the PATH (See the documentation - for 2.5 use Petalinux 2019.1)
  3. kpartx and zerofree packages installed
  4. Most recent board agnostic image from listed under Other boards
  5. Clone of PYNQ repository at the release version corresponding to the pre-built - v2.5 at the time of writing
  6. BSP file for the correct version of Petalinux. Xilinx BSPs are available from downloads section of
  7. Optionally sudo set up for passwordless operation

With the prerequistes in place we can go to the PYNQ/sdbuild folder and run the scripts/ script using bash. Running it with no arguments shows what’s expected

$ bash scripts/

scripts/ board bsp_file arch prebuilt

Script for generating a board-specific image from a board agnostic prebuilt image

board    : The name of the board
bsp_file : The BSP file to use
arch     : The architecture of the system - either arm or aarch64
prebuilt : The image to use as a base

Most of the arguments are self-explanatory except possibly for the board arguments. This is the name of the resulting image and will also appear in the BOARD environment variable once the image is booted.

Placing the BSP and prebuilt image in the sdbuild folder means that the full command for generating the ZC706 image is

$ bash scripts/ ZC706 xilinx-zc706-v2019.1-final.bsp arm bionic.arm.2.5.img

Once the script has finished the image will be in the outputs folder ready to be burned to an SD card.

Customising the image

As our pre-built images are designed to be completely generic they do not configure Ethernet. The drivers will still be present but the Ethernet port will need to be configured manually. To create an image with Ethernet preconfigured we need to create a board repository for the board in question where we can add the ethernet package that is provided by the sdbuild flow to set up the Ethernet port. For full details on creating a board repository see the PYNQ documentation.

For the purposes of this example we are going to create a ZC706.spec file containing the following:

ARCH_ZC706 = arm
BSP_ZC706 = xilinx-zc706-v2019.1-final.bsp
STAGE4_PACKAGES_ZC706 = ethernet

This file is going to live in a folder structure of test_repo/ZC706 along with the BSP file.

To build our more customised SD card image while still using the pre-built we can run

$ make BOARDDIR=test_repo PREBUILT=bionic.arm.2.5.img

To avoid checking all of the dependencies that are not required for building from a prebuilt we can instead use the nocheck_images target

$ make BOARDDIR=test_repo PREBUILT=bionic.arm.2.5.img nocheck_images

Again the resulting image will appear in the output folder.


where I have to put the test_repo/ZC706 folder

For this walkthrough I put the test_repo folder in the sdbuild folder to make the paths nicer. It can go anywhere as long as the BOARDDIR= is correct.


5 posts were split to a new topic: Issues: Quick Porting of PYNQ using Pre-built Images

mkdir -p /home/mass/Videos/PYNQ/sdbuild/output/dist
mkdir -p /home/mass/Videos/PYNQ/sdbuild/output/dist/arm
cp -rf /home/mass/Videos/PYNQ/sdbuild/build/PYNQ/dist/.tar.gz /home/mass/Videos/PYNQ/sdbuild/output/dist/arm
cp: cannot stat '/home/mass/Videos/PYNQ/sdbuild/build/PYNQ/dist/
.tar.gz’: No such file or directory
Makefile:324: recipe for target ‘/home/mass/Videos/PYNQ/sdbuild/output/dist/arm’ failed
make: *** [/home/mass/Videos/PYNQ/sdbuild/output/dist/arm] Error 1

i Got this error
when i try to customize the image by giving make BOARDDIR=test_repo PREBUILT=bionic.arm.2.5.img

Maybe PYNQ_SDIST is not set properly?

2 posts were split to a new topic: Ethernet issue, custom board

Hi Peter,

I am trying to port PYNQ to a UltraZed7-EV. Your procedure seems pretty straightforward and I end up with an image in the output directory. I wrote that image using Win32DiskImager and I see the partition and boot files but when I boot I’m getting a kernel panic as if the rootfs is not written correctly.

Do you now what might be causing this?



Hi Peter,

I’m missing something basic about the build process and I hope that you can help me. I’m sure the answer is somewhere in the scripts.

My problem with not being able to boot was caused by a mismatch between my SD card partition and where the process was attempting to locate the rootfs. My rootfs is on the second partition of the SD card /dev/mmcblk1p2. I am able to work around the problem by stopping the boot process and changing the bootargs - setenv bootargs ‘earlycon clk_ignore_unused root=/dev/mmcblk1p2 rw rootwait’. That allows me to successfully boot.

I examined my petalinux-config and in the Image Packaging Configuration the device node of the SD device was set to /dev/mmcblk0p2. I thought that I could just correct that and rebuild and repackage the boot files and my problem would be solved. I also thought that I could enable ethernet using the same process. I created the boot files and copied them to the SD card but left the rootfs partition as it was. But that didn’t work. Why is that? Do I have to regenerate the full image?

Do I have to use the package interface to reconfigure the image? Your process to add ethernet does work but I wasn’t sure how to customize packages. I do see a resizefs package and thought I could try to modify that but I thought I’d ask first. Sorry - just a bit confused by the different build processes.


Sorry I missed your first message

The PYNQ meta-layer overrides the petalinux defaults for the kernel boot args - you can change them here in the appropriate _bootargs.dtsi file.

The image consists of two partitions - the FAT boot partition which is what you see when the card is placed into a windows machine; and an ext4 root filesystem which contains our Ubuntu-derivative. The boot partition is generated entirely with Petalinux and contains the kernel and the bootloaders so any changes to those can be updated by changing the BOOT.BIN or image.ub files.

About halfway through the boot process the kernel will hand over to systemd running on the root filesystem so any changes there will involved updating the ext4 part of the image. This is what the rest of the sdbuild folder is built to do - i.e. the Ubuntu configurations and packages in our own custom format. Generally the easiest way to deploy changes here is to re-burn the image.

In the Ethernet case we need to add configuration files into the root filesystem to allow for Ubuntu networking management software to correctly set up IP addresses and the like hence why this needs a full image change.


Thanks Peter.

You solved my problem again. It would have taken me a while to figure out what was happening. Again, this stuff all makes sense if you know how it works.

A couple of things that are probably worth mentioning:

  1. After I fixed the root partition issue, booting was fine but the jupyter service wouldn’t consistently start. It turns out that when the I “wrote” the *.img file to the SD card, the root partition ended up being full which caused all sorts of funny issues. Luckily, I had already looked at the resizefs package and I just added that to the custom board build. Now things look good. I’ll have to play with it and try some overlays.

  2. Even though I’m not using the dist tarball it is still trying to copy it to the output so I get an error during the custom build. Since I’m using the prebuilt image this doesn’t cause a problem but it shouldn’t produce an error in this case.

Anyway, thanks again. I’m sure glad that you documented this process and have been available to answer my questions.


Hi Peter,

I successfully built a PYNQ image for the UltraZed-EV but I ran into a problem trying to upgrade that to DPU-PYNQ. I think that my issue is that the board agnostic image doesn’t contain the XRT files for the rootfs. Is there a specific method that we would use to customize the board to add those? I was able to upgrade my Ultra96v2_PYNQv2.5 (prebuilt image) to DPU-PYNQ but when I tried with the UltraZed-EV it did not have the zocl.ko file (actually it was missing the /lib/modules/4.19.0-xilinx-v2019.1/extra directory) and the upgrade failed.


Hi Ralph

Sorry I completely missed your question. There’s an xrt package as part of the PYNQ repository you can add to STAGE4_PACKAGES as shown above which will add zocl and the XRT runtime to the image.


Thanks Peter,

Adding the xrt package worked and I’ve been able to upgrade to DPU-PYNQ. One issue that I came across is that the Avnet UltraZed boards assign /dev/mmcblk1 to the SD card so that the script needs to be changed when using those boards in addition to the pynq_bootargs.dtsi. I was puzzled as to why resize didn’t work when using the pre-built image.


Hi to everyone, im making a PYNQ image for a custom board with this comand “make BOARDDIR=test_repo PREBUILT=bionic.arm.2.5.img” from a bsp created with petalinux and including the ethernet package, if i boot my board from the petalinux image, ethernet works, at least i can do ping.
This is what i modify in the sistem-user in device-tree for petalinux
/include/ “system-conf.dtsi”
/ {
amba {
ethernet@e000b000 {
status = “okay”;
phy-mode = “mii”;
phy-handle = <&phy0>;
local-mac-address = [00 0a 35 00 00 00];
phy0: phy@1 {

     reg = <1>;
     device_type = "ethernet-phy";
 xlnx,phy-type = <5>;

But when boot from the PYNQ image, ethernet doesnt work (I use the same files in project-spec that in petalinux build). I tried modifiing some things,
for example, I add a ethernet.cfg to the u-boot-xlnx_%.bbappend
#CONFIG_DWC_ETH_QOS is not set
#CONFIG_E1000 is not set
#CONFIG_ETHOC is not set
#CONFIG_RTL8139 is not set
#CONFIG_RTL8169 is not set
#CONFIG_SUN8I_EMAC is not set

and device-tree as follows
/include/ “system-conf.dtsi”
/ {
amba {
ethernet@e000b000 {
status = “okay”;
phy-mode = “mii”;
phy-handle = <&ethernet_phy>;
local-mac-address = [00 0a 35 00 00 00];
ethernet_phy: ethernet-phy@1{

	 reg = <1>;
	 device_type = "ethernet-phy";
	 xlnx,phy-type = <5>;

macb0: ethernet@e000b000 {
compatible = “cdns,zynq-gem”;
phy-mode = “mii”;

My board is a EBAZ4205 (, that has a IP101GA PHY with RMII or MII interface.
My hardware design has ethernet 0 with MDIO on EMIO, added pins to xdc to match

I attach the boot log from petalinux and pynq image.

Thanks in advance.

ebaz_boot.txt (24.1 KB)

petalinux_bsp_boot.txt (15.9 KB)