U-Boot Secondary Program Loader On Zybo

Hi Everyone,

Today I’ll take you through how to create the U-Boot SPL for our Zybo board.  The SPL is able to replace the FSBL but currently may not support secure boot or encrypted bitstream.  The SPL isn’t supported by Xilinx so like I mentioned above it could be missing some features that the FSBL supports.  Let’s get started!

If you haven’t done so before let’s clone the U-Boot repo, for this example we will need the Xilinx repo, to the best of my knowledge mainline u-boot is missing a python script that creates boot.bin (more on boot.bin later).

git clone https://github.com/Xilinx/u-boot-xlnx.git

We should have the SDK arm cross compiler installed from our previous steps, if you don’t you’ll have to install the Xilinx SDK.  The good news is there is a command line version of the tools that is slightly smaller.  If you’re not sure if the compiler is installed we can check.   If you are using Linux the tools should be located here:

/$(PATH TO SDK TOOLS)/Xilinx/SDK/2015.3/gnu/arm/lin/bin/

If we can see the executable arm-xilinx-linux-eabi-gcc then the tools are installed, the above line will be different depending on the location and the version of the SDK that you have installed.

To create the secondary program loader we need to copy two very important files to the u-boot source tree.  These files are our ps7_init files, these files are extremely important they initialize our processor and are needed so that boot.bin works properly.  If we forget to copy the files over or we don’t copy them to the correct location the build will still work and boot.bin will be generated but it won’t work.  This can be frustrating and is hard to debug.  I’m going to assume that you have ps7_init.c and ps7_init.h files and you either got generic ones from Xilinx git repository (https://github.com/Xilinx/embeddedsw) or you generated them when you exported your hardware design.

We’ll need to copy them to u-boot-xlnx/board/xilinx/zynq/custom_hw_platform.  If we were using another board like a ZedBoard, MicroZed, ZC706 or ZC702 we would need to copy them to another location.  Look under board/xilinx/zynq in the u-boot source tree for more info.  When we copy the files over we need to rename them to ps7_init_gpl.c and ps7_init_gpl.h, the need for the name change is based on what u-boot expects for the files to be named.  I’m not sure if these files need to be under GPL licence to be properly  included in the build if you were going to use this in a commercial product.  I’ll keep researching and hopefully find an answer and post back here when I do.

Let’s go ahead and copy those files, assuming the ps7_init files are in your PWD

cp ./ps7_init.c $(PATH_TO_UBOOT_SRC)/u-boot-xlnx/board/xilinx/zynq/custom_hw_platform/ps7_init_gpl.c

cp ./ps7_init.h $(PATH_TO_UBOOT_SRC)/u-boot-xlnx/board/xilinx/zynq/custom_hw_platform/ps7_init_gpl.h

Make sure we update our new ps7_init_gpl.c to include ps7_init_gpl.h not ps7_init.h which it will be including by default if we are using ones that were generated with Vivado.

Everything is pretty much ready to build, one added bonus is Zybo is now supported by u-boot and is included in the configs directory.  If we look at $(PATH_TO_UBOOT_SRC)/u-boot-xilinx/configs we can see all the supported boards.  We should see zynq_zybo_defconfig, if you don’t then do a git pull and make sure you have the latest source code.

make CROSS_COMPILE=arm-xilinx-linux-gnueabi- zynq_zybo_defconfig

This will configure our build properly and get it ready make our build files.

make CROSS_COMPILE=arm-xilinx-linux-gnueabi-

After this command our build will start and we should see all the files getting compiled and linked.  Once our build is finished we should see the following output:

MKIMAGE u-boot.img
./tools/zynq-boot-bin.py -o boot.bin -u spl/u-boot-spl.bin
Input file is: spl/u-boot-spl.bin
Output file is: boot.bin
Using /home/greg/src/emb_linux/u-boot-xlnx/spl/u-boot-spl.bin to get image length – it is 47632 (0xba10) bytes
After checksum waddr= 0x13 byte addr= 0x4c
Number of registers to initialize 0
Generating binary output /home/greg/src/emb_linux/u-boot-xlnx/boot.bin

We see our u-boot image file was created (u-boot.img) and we also see the spl being created, the interesting part of this output is the zynq-boot-bin.py script.  This script takes u-boot-spl.bin as an input file and creates the boot image, our case it’s boot.bin which is the file the Zybo needs to boot.  The last time I built this using mainline the python script wasn’t called automatically after the build.  I’m not sure if we need to do that manually in the mainline build but using the xilinx version of u-boot it’s done automatically for us which makes life easier.

Now that the build is done we need to copy the following files to the FAT32 partition of our sdcard.  Copy over boot.bin and u-boot.img, we can now put the sdcard back into the Zybo and boot it and we should see u-boot boot into the console.

Please leave any questions or comments and I’ll answer them as soon as I can.


Let’s Start Again

Hi Folks,

Looks like I’ve been MIA for a while now, so let’s get back to it.  I’ve got a lot of Zynq information to share and some great articles to post.  Here’s a preview of what’s coming:

  • U-Boot SPL, how to use U-boot instead of the SDK generated bootloader for the first stage boot loader
  • Device Tree, I’ll finally go through making our device tree
  • Xenomai 3.0  (Cobalt) on the Zybo, yes it runs and it works great!
  • PREEMPT_RT patch
  • Creating a Debian rootfs with all the fun applications we need and make it persistent
  • Creating a RTDM driver for Xenomai and a RT application
  • QNX, for anyone that has a QNX 6.5 hobbyist license, I’ll go over how to create a very basic BSP for the Zybo

The U-Boot SPL post will be up this weekend, and I’ll aim for a new post every week.

Thanks for reading and posting, I will be responding to the questions and comments the best I can.





Step 4a: Let’s build stock Linux For Zynq

Hi Everyone,

Sorry for the delay in posting this, but here is step 4a which is building the stock Linux kernel.  We’ll do the stock Linux kernel first and then move on to the root filesystem, then we’ll come back and build the Xenomai variant for all those who want a real time embedded system.  I’ll add some more pictures to this once I’ve gotten some more time, which is hopefully soon.

Let’s get the Linux kernel source from the Xilinx repo.  Clone the repo:

git clone https://github.com/Xilinx/linux-xlnx.git

This may take a while if you have a slow connection, but once it’s sync’d you now have the Linux kernel source.  If you take a look at the directory in the kernel source <path to kernel source>/arch/arm/configs, we should see all the different configurations we can build.  We are interested in the Zynq ones, we’ll use the xilinx_zynq_defconfig.  Make sure we have exported our CROSS_COMPILER environment variable:

exoport CROSS_COMPILER=arm-xilinx-linux-gnueabi-

Just like when we built u-boot make sure we have the cross compiler in our PATH variable.  Once we’ve done that, we can go ahead and start to compile the kernel, let’s first make sure we have a clean build environment:

make mrproper

let’s configure the kernel to build for zynq:

make ARCH=arm xilinx_zynq_defconfig

If we wanted to build in any custom options we can now run

make ARCH=arm menuconfig

This will run the menuconfig utility and allow us to customize the kernel components we want to build.  If you do run that make sure you’ve saved your changes and once your done run:

make ARCH=arm UIMAGE_LOADADDR=0x8000 uImage

The build should take about 5-10 minutes and once we’re complete we should be able to find the image in linux-xlnx/arch/arm/boot/.

The build may fail if you don’t have mkimage installed so depending on your distro do some searching and find what package you need to install.

So we still have two more steps to complete before we can put this on the sdcard and boot the Zybo.  We need to build a root filesystem and compile the device tree binary blob.  The Linux device tree is extremely interesting and is the way the kernel knows what hardware is present in the system.  It’s worth the time to read up about the Linux device tree, especially if you may be building your own custom board.

I’ll leave you guys with building the Kernel and the next post will be to compile the device tree and create the root filesystem.  My next post will come much quicker.


Helpful Links:




Step 3: Building U-boot and boot image

Hi Again,

So in the previous steps we’ve built the bitstream and the first stage bootloader now all we need is to build u-boot and we’ll have something to run on our Zybo.  If you’ve been working on a windows machine you’ll need to switch to a Linux machine for these next steps.  It does look like you can build u-boot on windows using the Xilinx SDK software but I used Linux, maybe building u-boot with Windows will be another blog post.  Once you have a virtual machine running Linux or a system running Linux we’ll need to install a couple items before we can start getting and building u-boot.  First, if you have a 64-bit system you’ll have to install the 32-bit libraries for your Linux distro before we can use the code sorcery toolchain.  This link will show you what commands to use based on the flavour of Linux you’ve chosen.  Next make sure you have git installed, we’ll need to use git to download the sources needed to build u-boot and later Linux and Xenomai.  To install Linux on Ubuntu , go to the terminal and type in:

bash> sudo apt-get install git

on red hat based distro

bash> sudo yum install git

Once we’ve got those tools installed it’s time to get our toolchain from Xilinx.  Follow the steps on the Xilinx wiki follow the steps to download and install the command line tools.  We’ll be building u-boot, linux and xenomai all from the command line.  After completing the toolchain install and adding the xilinx tools into our PATH variables we should be able to type

bash> arm-xilinx-linux-gnueabi-gcc

on the command line and get an error saying no input files specified.

  Screenshot from 2014-03-25 10:02:36

If we see this error then everything is setup and we are ready to download U-boot, if not then you’ve probably forgot to add the toolchain location to your PATH variable.  Take a look back at the Xilinx wiki to make sure you’ve exported bothe CROSS_COMPILER variable and your modified PATH variable.

We are now ready to configure u-boot from source for Zybo.  The Xilinx wiki on u-boot is a great resource to get us started.  It’s gear towards the Zed board which is okay because the Zybo is very similar.  I only had to change one piece of source code to get it to work.  I’ve been able to configure u-boot from both the Zed board config and the generic one. I’ll go over it modifying the Zedboard config.  Let’s fetch the source:

bash> git clone git://github.com/Xilinx/u-boot-xlnx.git

Let’s take a look at the config files, in include/configs we should see a file called zynq_zed.h,  this file is how u-boot knows how to configure the system.  Let’s edit this file for zybo, all we have to do is add the following line:

#define CONFIG_ZYNQ_PS_CLK_FREQ 50000000UL

We need to add this because the peripheral clock on the Zybo is 50Mhz, on the Zedboard it’s 33.3Mhz.  I got u-boot to work with and without this change but I’ll add it in here since we need to keep this in mind when we try to get the Linux debug console to work.

Once we’ve saved that file, let’s configure u-boot to build for our target by entering :

‘make zynq_zed_config’

Screenshot from 2014-03-25 10:45:16

type ‘make’ and we should be able to watch the build output and hopefully see no errors.

Screenshot from 2014-03-25 10:48:23

So u-boot is now built, now we need to gather the bitstream from step 1, the first stage boot loader elf file from step 2 and the u-boot executable into one location that the SDK can see.  So if you are doing this on two machines like I am make sure there is a shared folder somewhere that we can put the files.

If we do an ‘ls’ in the u-boot directory we should see a file with no extension named ‘u-boot’.  Copy this file to a separate location.  Rename this file to u-boot.elf

Open the Xilinx SDK, and under the Xilinx tools drop down menu, select ‘Create Zynq Boot Image’

Screenshot from 2014-03-25 10:53:37

I called the bif file zybo, next add the first stage bootloader first, with the partition type bootlader.  Order is important so make add this file first.  Next add the bitstream file with partition type datafile and then u-boot.elf again add it as datafile.  Make sure you’ve specified an output directory and then click create image.  We should now see u-boot.bin in that directory.  Rename that file BOOT.bin, this is the file that the processor will look for when power is applied.

We have the boot image that will boot the board, all we need now is the create an SD Card to hold the files.  Grab a 4GB (or larger) SD Card, hopefully your system has an SD Card reader or you have a USB one.  Pop the SD Card in and make sure your OS can see it.  We’ll need to use a Linux utility called Gparted to create the partitions on the SD Card.  If you have a Linux distro that allows you to download programs from a software repo, use that to find gparted, if not follow this link for instructions on how install it.

Once Gparted is installed run it and we should be able to see the hard drivers on the system.  We should be able to use the drop down in the top right to find our SD Card.  Once we’ve found it we can go ahead and erase all the current partitions.  WARNING!!! This will erase all the contents of the SD Card so if you have something you want to keep copy somewhere safe before this step! WARNING!!!

Unmount the partition if needs and highlight the current partitions, delete those partitions (right click) and we should see all the space on the SD Card as unallocated.  Click the check mark to apply those changes.  Click the unallocated space and right click and select new, the size of this partition can be small since it only holds the bootfile, but we also could have a RAM disk here so let’s make it atleast 512MB, the file system HAS TO BE FAT32.  Make sure to give it a label name so we can identify it later.  Click add to finish.  Highlight and right click the unallocated space and select new, the size should be the rest of the SD Card, and make the file system type ext4.  We can use this as the rootfs when Linux starts up.  Click the green check mark again and the operations should be applied.  The SD Card is now ready we can eject it safely from the OS.

Insert the SD Card again so the host sees it and then copy over the BOOT.bin file to the FAT32 partition. Safely eject the SD Card, we are almost done.

On the Zybo make sure the boot jumper is set for SD Card boot.  Insert the SDCard, connect the Zybo to the host machine using a USB cable, and apply power.  You should see the green and red LED light up and then some yellow LED activity on the UART to show U-boot is sending data to the UART.

Open a terminal program like minicom on Linux or Teraterm on windows and configure it according to our UART settings:

Screenshot from 2014-03-25 11:25:38

We should see something similar for U-boot output:

Screenshot from 2014-03-25 11:26:02

I will post some short videos and more pictures shortly from my zybo booting into u-boot.  The next step is to build the Linux kernel with the Xenomai patches, and compile our device tree.  I should have this up in the next couple of days.  There were numerous manual merges I had to make when applying the xenomai patches for some reason.  I may split it into two steps.

As always leave questions or comments here and I will do my best to get answer them!

Step 2: Export our design to the Xilinx SDK and Create the First Stage Bootloader

Hey All!!

Thanks for to all who’ve read this blog, also thanks to everyone that have left a comment.  I will create an example that uses the FPGA to pass information about the switch states to the ARM, but first I will finish up getting Xenomai to run.  So the example of getting information from the FPGA to the ARM will be done in a Xenomai user space RT thread.

We’ve got our design ready and built in Vivado.  The next step is to export this hardware design to the SDK and create a first stage boot loader that will will combine with the .bit file and uboot to create get the board to boot into the uboot shell.

Verify that you were able to create the bit file without problems, so generate it again and look at the output of Vivado.  Once that was been successfully generated let’s export the design to the SDK.

Screenshot from 2014-03-17 09:42:35

Right click your system.bd in your design sources and select ‘export hardware for SDK’, select a folder where we can export the design to and a workspace.  Make sure to check to box that asks if you would like to launch the SDK.  Also make sure to include the bit file checkbox, in my picture it’s not selected but it should be by default if you generate the bit stream before you export your hardware.

Screenshot from 2014-03-17 09:53:03

Make sure you have the block diagram open or there will be an error when the SDK launches.  When this error message occurs we see some prints in the console out : ‘”export_hardware” works only for active block diagrams’, so make sure your block diagram is active before we export it to the SDK.

Screenshot from 2014-03-19 09:25:07

Once the export is complete we should see the SDK open with an XML file that describes our system.

Screenshot from 2014-03-19 09:26:26

Next let’s create the first stage bootloader we will need to boot our board.  Select File -> New ->Application Project and enter a project name for our boot loader, I used zybo_fsbl.  The hardware platform should be filled in with the information that was exported from Vivado and make sure that under Board Support Package we have ‘Create New’ selected. Click Next and we should see some templates to choose from.  Select Zynq FSBL as the template project and hit ‘Finish’.

Screenshot from 2014-03-19 09:42:07

Once we clock finish the our first stage bootloader project and bsp should compile and be ready to go.  From here we could do some bare metal examples of a simple C program running on Zybo, I will probably come back to this later but for now let’s get U-boot compiled and ready to go.

Step 3 – building U-boot and creating a boot image is next and should be ready to post in a couple days.  Any questions please leave a comment or email me.  If you have questions about building Linux or booting the board feel free to ask them and I’ll answer them as soon as I can.  Those steps I’m hoping will be up next week.

Helpful Links:



Step 1: Hardware design for Zybo

Let’s start by getting Vivado installed.  I used Xilinx Vivado to do my hardware design, it was easy to use and has all the programs we need built in.  My development environment was a Macbook pro running a VM for windows and one for Linux.  I could have done the whole thing in Linux, but at the time of me bringing Xenomai up I didn’t have ISE or Vivado installed in my Linux environment. I like CentOS for my Linux distro, it’s has a very nice and clean interface and I find it very stable.  It runs great in VM fusion, I will leave the Linux install to the reader but message me if you need help.

If you go to the Xilinx download page here you can choose the installer package you need, I choose the installer for both Linux and Windows.  The download is so big might as well grab both in case you need to change development environments later.  As mentioned this is a huge download so either do this at night or maybe grab a couple of cups of coffee while you wait.  Once you’ve got Vivado install it and select the defaults.  Zybo was recognized by both Linux and Windows with no problems.  Once Vivado is installed let’s go get the files we need from Digilent.  Dowload the ZYBO Board Definition File for configuring the Zynq Processing System core in Xilinx Platform Studio and Vivado IP Integrator and ZYBO Master XDC File for Vivado designs these two files will be needed in Vivado to create the initial hardware design.  Next let’s start up Vivado and create a new project.

Screenshot from 2014-03-13 11:09:54

Name your project, and select a place to put it, once that is done select RTL project and click next.

Screenshot from 2014-03-13 11:10:51

Click next for the next two dialogues, when asked to add a constraints file stop and let’s add the one that we downloaded from Digilent.

Screenshot from 2014-03-13 11:11:26

Screenshot from 2014-03-13 11:15:13

Screenshot from 2014-03-13 11:18:54

This should tell Vivado about the hardware we are going to use.  Next we need to tell Vivado what chip we are using, if we look back at the Digilent website for the Zybo we can make a note of the following information:

The ZYBO offers the following on-board ports and peripherals:

  • ZYNQ XC7Z2010-1CLG400C
  • 512MB x32 DDR3 w/ 1050Mbps bandwidth
  • Dual-role (Source/Sink) HDMI port
  • 16-bits per pixel VGA output port
  • Trimode (1Gbit/100Mbit/10Mbit) Ethernet PHY
  • MicroSD slot (supports Linux file system)
  • OTG USB 2.0 PHY (supports host and device)

The top line is what we want and will help us identify the chip.  From the drop down menus select Zynq-7000 for Family, Zynq-7000 for sub family, clg400 for package, -1 for speed grade and C for temp grade.  You will have two choices left xc7z010clg-400-1 and xc7z020clg400-1, choose the fist one since your Zynq chip is the Xilinx Zynq-7000 (Z-7010) as mentioned on the Digilent website.  You also want to grab the hardware guide for Zybo, it will help in future posts if you are following along.

Screenshot from 2014-03-13 11:20:33

We are ready to confirm and create the project

Screenshot from 2014-03-13 11:23:34

So we should now have Vivado open with a new project like the picture below.

Screenshot from 2014-03-13 11:44:44

Now we are ready to create the block diagram and add some IP.

In the left side of the screen click on create block design.  I named my block design system but I don’t think the name really matters.

Screenshot from 2014-03-13 11:47:29

Now that we have a new block design, we can go ahead and add some IP to it.  Click Add IP on the green highlight that appeared in the diagram window. Scroll down and select Zynq7 Processing System.

Screenshot from 2014-03-13 11:48:47

Press Enter and you should now see a Zynq processor on your block design.

Screenshot from 2014-03-13 11:49:14

So far so good, let’s double-click the Zynq block and customize our IP to the Zybo.

Screenshot from 2014-03-13 11:49:43

Now let’s import the XPS settings that we downloaded from the Digilent site that will describe our hardware, click the import XPS settings button

Screenshot from 2014-03-13 11:50:06

Select the .xml file that we downloaded from Digilent, click OK.  Now click OK in the import XPS settings window.

Screenshot from 2014-03-13 11:50:21

So we now see some check marks beside some peripherals.  Let’s take a second and look at the clock configuration.  Click the clock configuration in the left side of the window, you should see something like the picture below.

Screenshot from 2014-03-13 11:51:16

Make a note of the input frequency.  This is DIFFERENT from both Zedboard and MicroZed and can cause some really frustrating problems when trying to add correct features to the device tree when we boot Linux.  I’ll explain what I ran into when we go over how to get Xenomai/Linux to boot. Click Ok and the customization screen should close and our processor should now have some inputs and outputs.

Screenshot from 2014-03-13 11:51:59

Connect the FCLK_CLK0 to the M_AXI_GP0_ACLK, once we scroll over the input a pencil appears and then connect each input similar to Labview if anyone has used that before.

Screenshot from 2014-03-13 11:54:10

This pretty much just feeds a clock to the FPGA and is the most basic FPGA design we can do.  I’m not a FPGA expert and plan to use the Zybo to further my learning when it comes to FPGA design.  I believe this pretty much brings the FPGA up and nothing else, so nothing on the FPGA is being used.  Let’s validate our design, before we start to create the HDL wrappers and bit file. Run the Block Automation as suggested by the green highlight.

Screenshot from 2014-03-13 11:58:23

Click the sources tab on the block design and right-click the system.bd file and select Create HDL Wrapper.

Screenshot from 2014-03-13 12:04:55

Once that is complete we should see some Verilog or VHDL files.  Now we can go ahead and generate the bitstream file, this should be on the left side of the screen near the bottom.

Screenshot from 2014-03-13 12:09:49

Once we are done, we can open the implemented design.

Screenshot from 2014-03-13 12:12:37

We are pretty much done!  The next step is to export our design to the Xilinx SDK to create the first stage bootloader.  This will be the subject of my next post.  Remember to save your project since we’ll need it in my next post.

If anyone runs into problems let me know I may have a step or two out-of-order, but I was able to create the bit file again following these steps.  Questions and comments are always welcome.

Helpful links:







Getting Started with Zybo

Over the next couple of weeks I will post steps on how to get your Zybo ready to run Xenomai.  Here are the steps that are needed to get your Zybo ready to run Xenomai (or regular Linux).

  • Create a design in Vivado for Zybo
  • Create the First Stage Bootloader
  • Build u-boot
  • Create the boot image
  • Checkout and patch Xilinx Linux with Xenomai  (this stage got tricky)
  • Compile the Linux Kernel with Xenomai support
  • Compile the Xenomai user space support
  • Create a rootfs
  • Prepare the SDCard
  • Run the Xeno latency test

I probably forgot a step so that list might change.  It sounds like a lot but it’s pretty straight forward once you uncover some of the tricks.  I found that the hardware guide for Zybo is your friend when trying to figure out why things for the Zedboard won’t work right out of the box.  I will start the first post in a few minutes and hopefully have it up in a couple hours and I’m aiming to have all the steps done very soon.

Thanks to all who read this, leave comments or questions