PYNQ Linux on ZedBoard

Hi There!

The PYNQ Linux is a fun, easy and maker-friendly Ubuntu 15.04 rootfs. It comes bundled with the PYNQ-Z1 board, and the official documentations doesn’t even utter a word on how to build or port this image on any other Zynq. Maybe because it’s too obvious how to do so.

What you need to run Linux on any ARM board?

  1. BOOT image (BOOT.bin)
  2. kernel image (uImage)
  3. devicetree blob (devicetree.dtb)
  4. rootfs

What we need to worry about? everything but the rootfs.


Write the image file on SD card same as in the pynq tutorial, and replace the files in BOOT partition with these… ZedBoard BOOT files

Detailed Explanation (as if you asked for it)

0. Set up environment.

You’ll obviously need to do this all a Desktop Linux system. I’ve tried doing onWindows, doesn’t work well with MinGW. Haven’t tried CygWin or Linux Subsystem for Windows, you may give it a try if you’re brave enough.

0.1 Set up the Bash environment to work with Xilinx SDK tools,

0.2 SD Card Patitioning

you don’t really need to create partitions of the SD card because loading the image file from the PYNQ linux will do that for you, however you can do it anyways which should look like… (Use GParted or something)


  • Type: fat32
  • Free Space Preceding: 4MB (IMPORTANT!!!)
  • Size: 52MB
  • Label: BOOT (Optional)


  • Type: ext4
  • Size: whatever is left
  • Label: rootfs (Optional)


  • DO NOT REMOVE SD CARD WITHOUT UNMOUNTING IT! Really, don’t. It creates badblocks in the SD card which might cause issues booting up the Zynq.
  • You can check my GitHub @parthpower for the modified u-boot and Linux codes to work around this.

1. Make BOOT.bin

-> To create BOOT.bin, you’ll need 3 things (which you’d have heard everywhere).

  1. First Stage Bootloader to dump the bitstream and call the second stage bootloader
  2. bitstream
  3. Second Stage Bootloader (u-boot.elf)

I’m not going in details of first two things, as they are simple and you can just google them… Come on now! Ok, in short, make Vivado project with only PS, export it to the SDK, create FSLB application project and you’re good!

Let’s get to the main part, MAKING u-boot.elf!!!!

Clone the Xilinx UBoot repo from the Xilinx github, checkout to the latest stable release (I used xilinx-v2016.4) (in case you need code)

Now, you got to change some stuff in u-boot-xlnx/include/configs/zynq-common.h, find this line “sdboot=if mmcinfo;” and make it look like as below


Wait, what did we just messed with? Like what the hell happened?

If you go through the “Ubuntu on ZedBoard” tutorial by Avnet, they explain it’s for using the rootfs from the filesystem instead of a RAM disk.

To make u-boot,

You should add u-boot-xlnx/tools to the PATH. It’ll be useful making the Linux Image later on.

Get the “u-boot” file from the root of the u-boot source directory, rename it to u-boot.elf. Now just make the BOOT.bin, open “Create Boot Image” in SDK use the FSBL.elf, bit file and the u-boot.elf. Mind the order of the files because that’s how the Zynq will be booted. FSBL configures the PL with the bit file then loads the second stage bootloader; u-boot.


2. Make Linux Kernel Image

The Linux Kernel Image is the actual Kernel being loaded by the u-boot and which has the rootfs of pynq distribution. In less technical words, Linux Kernel is the base system which loads the higher-level root filesystem from the mount point. Now we’re done with the theory part, Let’s make the kernel!

Fetch the sources,

Just default config, and make it!

That’s it and you have your Linux kernel image ready at linux-xlnx/arch/arm/boot/uImage save it somewhere safe.

3. Device Tree Blob

What? Device tree blob is a “block-of-binary” which specifies memory location of the peripherals, their compatible driver names, and some configurations of the peripherals. It’s lots of information about the hardware specification of the SoC.

The dtb is compiled from dts (device tree string). For a PS-only design, the dts is already there in the linux-xlnx repository at /linux-xlnx/arch/arm/boot/dts/zynq-zed.dts

We need to modify it a little bit to load the rootfs, (yeah, lots of efforts just to load the rootfs)

find the line starting with bootargs and change it to,

By default, it has bootargs are set to load the rootfs from a ramdisk. But we configured the u-boot not to load the rootfs as ramdisk. So we are mounting it from /dev/mmcblk0p2 (partition 2 of the memory card)

Now go to the root of linux-xlnx and

and you have the dtb file at  /linux-xlnx/arch/arm/boot/dts/zynq-zed.dtb rename it to devicetree.dtb and copy it somewhere safe.

4. rootfs

The root file system we want to use if the one provided by the PYNQ. Download the latest version from // Extract it, and write the image to the sd card. Use dd or Win32DiskImage tool or whatever you wish.

Mount the SD card, look into the BOOT partition, replace all the files, BOOT.bin, uImage, devicetree.dtb with the ones we’ve created, and you’re done. Seriously, you’re done!

Good thing is, you can put any Linux distribution as long as it is made up on Linux Kernel 3.17 in the rootfs file system and it should work. I tried Linaro , it quite didn’t work well with me. Try playing around, let me know what works and what don’t work!

Happy Hacking!

Some Really Good References,





2 thoughts on “PYNQ Linux on ZedBoard”

  1. Hi, what a great idea. I followed your hints and it worked well. Then i modified the pynq block design, the constraint file and the devicetree and now I can run pmod examples (ie. pmod_ad1, spi) on the zedboard with jupyter notebook. That’s fun!
    Best regards, Andreas

Leave a Reply