This Embedded Linux hands-on tutorial for the Zybo will provide step-by-step instructions for customizing your hardware, compiling the Linux Kernel and writing driver and user applications. This documentation intends to integrate knowledge and skills in FPGA logic circuit design, standalone software programming, and Linux operating system and software development, and apply them to the Zybo.
In this tutorial, we will start from the Zybo Base System Design (available on the Zybo product page of the Digilent website). The system architecture for the Zybo Base System Design is shown in the first picture in this step.
In the Zybo Base System Design, we connect UART1 to USB-UART, SD0 to the SD Card Slot, USB0 to the USB-OTG port, Enet0 to the Giga-bit Ethernet Port, and Quad SPI to the on-board QSPI Flash. These cores are hard IPs inside the Processing System (PS) and connect to on-board peripherals via Multiplexed I/O (MIO) pins. The use of PS GPIO is is connected to BTNs 4 and 5. In the Programmable Logic (PL), we have an HDMI Tx Controller, VDMA, and GPIO IP cores to talk to the ADV7511 HDMI Transmitter Chip and I2S and GPIO IP Cores for ADAU1761 Audio Codec. More details of the hardware design can be found in the documentation inside the Zybo Base System Design package.
Before going through this tutorial, we recommend that you read Getting Started with Embedded Linux -- ZedBoard first. You can follow this tutorial with the Embedded Linux Development Guide (available on the Digilent Website Embedded Linux Page). The guide will provide you with the knowledge you may need in each step of the development.
In this tutorial, we are going to use Vivado 2014.1 Webpack in a Linux environment. All the screen shots and codes are done using Vivado Design Suite2014.1 in Fedora 19 x86_64.
Required Materials:
- U-boot*
- Pre-built File System Image (available in the Zybo Linux Reference Design)
*Note: Use the Master-Next Branches until further notice
That’s it for the background information on this tutorial, now it’s time to get our hands dirty with some real design!
Source Vivado 2014.1 settings and open the design with Vivado Design Suite (vivado). You will see the Vivado window pop up.
Note: There are four settings files available in the Vivado toolset: settings64.sh for use on 64-bit machines with bash; settings32.sh for use on 32-bit machines with bash; settings32.csh for use on 32-bit machines with C Shell; and settings64.csh for use on 64-bit machines with C Shell.
We are going to detach LEDs from the GPIO core in the PS first. So, we need to click on the IP integrator and open the Block Diagram as shown in the first image in this step. Then we need to delete the current LED IP as shown in the second image. We will handle the modification of external pin location configuration (xdc file) in later steps.
Note: In Figure 4 there is a Yellow bar indicating the need for an upgrade. To upgrade hit show IP status, make sure all are selected and hit Upgrade Selected.
Before we can start implementing our myLed IP Core we need to name the Vendor that will automatically be applied in the IP packager. In Vivado 2014.1 this is not automatically done for you. To do this first go to the Project Settings under Project Manager on the left side of the window (image 1) and the project settings window will pop up. In the Project Settings Window select IP (image 2). Notice that the vendor is chosen as (none), this will cause a Vivado Internal Exception. You can name the Vendor whatever you like (image 3).
The next window will be the Add Interfaces Window. This will create the AX14 Interface for the myLed peripheral. Make sure the interface type is Lite, the mode is Slave, the data width is 32 bits and the number of registers is 4. Change the Name to S_AXI rather than S00_AXI. We only need 1 register but the minimum we can select is 4. Then click next.
In the Project Manager, click the circle next to myLed_v1_0 and highlight myLed_v1_0_S_AXI (image 1). This contains the user logic inside of the myLed IP. We need to add two lines of code to complete the user logic for this module. First we need to create a user port which called led (image 2). Next we need to connect the internal slave to this user port. We will connect slv_reg0[3:0] as we have four LEDs (image 3).
Next we need to connect the user logic to myLed. In the project manager select the file myLed_v_0. To complete the IP there are two lines of code we need to add to this file. Under the comment that says Users to add ports here, add a port for the LEDs (image 1). Connect the led output from the previous file containing the user logic to myLed (image 2).
Now that our IP is created and the User Logic is defined, we need to package our IP. Under Project Manager on the left side of the window select Package IP. A new tab will open that is called Package IP. On the left side of this tap there are a series of labels. We need to complete those that do not have green check marks.
First select IP customization Parameters. At the top of that window select the option to Merge changes from IP Customization Parameters Wizard.
The AXI4-Lite bus of myLed IP Core needs to be connected to the processing system. At the top of the window click the blue text that says Run connection automation. This will connect the inputs of the myLed IP core. You should see that S_AXI is now connected to the first output of the AXI Interconnect.
Next we need to connect the myLed IP to an external port. The myLed IP core that we implemented will not connect to the existing LEDs_4Bits port so we need to make a new external port called led. Click on the existing LED port and press delete. To create the new port right click and select create port. Name the port, select output, select vector [3:0] and press enter.
The final step is to specify the pin numbers for myled_0_LED_pin to physically connect our customized IP core to the on-board LEDs. In the Project Manager expand the Constraints section and select the base.xdc file (image 1). Within that file change the names of the external LED pins so that they match the name of our external led port (image 2).
Regenerate the bitstream for the hardware design by clicking on Generate Bitstream under Program and Debug on the left side of the window.
*Note: Use the Master-Next Branches until further notice
Get the source code for U-Boot from the Digilent git repository. There are two ways to retrieve the source code:
Using git command:
If you have git installed in your distribution, you can clone the repository to your computer by command git clone https://github.com/Digilent/u-boot-Digilent-Dev.g... The whole Git Repository is around 55MB, as shown in image 1. If you want to get a separate branch, for example the next branch follow image 2. The next contains the u-boot that is not yet released. The clone url referenced above can be found on the Digilent git-hub page as seen in image 3.
Download a compressed package:
If you only want to use u-boot once and do not want to track the updates, you can also download a compressed package from github.com: https://github.com/Digilent/u-boot-digilent. Go to the drop down box that shows the branch and select tags. The most recent tag is zynq-beta-v2.2. (image 4).
If you downloaded the tar.gz, you can decompress it using command
tar zxvf u-boot-digilent-2012.04-digilent-13.01.tar.gz
If you downloaded the zip file, you can decompress it using command
unzip u-boot-digilent-2012.04-digilent-13.01.zip
To compile U-Boot, we need cross-compile tools which are provided by Vivado 2014.1. Those tools have a prefix arm-xilinx-linux-gnueabi- to the standard names for the GCC tool chain. The prefix references the platforms that are used. The Zybo board has two arm cores so we reference arm. In order to use the cross-platform compilers, please make sure Vivado 2014.1 settings have been sourced. If not, please refer to step 2. To configure and build U-Boot for Zybo, follow the image attached to this step.
After the compilation,
the ELF (Executable and Linkable File) generated is named u-boot. We need to add a .elf extension to the file name so that Xilinx SDK can read the file layout and generate BOOT.BIN. In this tutorial, we are going to move the u-boot.elf to sd_image folder and substitute the u-boot.elf that comes along with Zybo Base System Design Package.
For the Zybo, we need set the mac address for the Ethernet in the fsbl hook. We want the mac address for the Ethernet to remain constant when we turn off and on the Zybo Board. You can swap the fsbl_hooks.c file in the FSBL project with the fsbl_hooks.c under source/vivado/SDK/fsbl in the Zybo Base System Design.
After you have saved the changes to fsbl_hooks.c,
the project will rebuild itself automatically. If it does not rebuild, Click Project->Clean to clean the project files, and Project->Build All to rebuild all the projects. The compiled ELF file is located in zybo_base_system/source/vivado/hw/zybo_bsd.sdk/SDK/SDK_Export/FSBL/Debug
In the Create Zynq Boot Image window, Click Browse to set the path for FSBL elf. Click Add to add the system.bit file found at /zybo_base_system/source/vivado/hw/zybo_bsd/zybo_bsd.sdk/SDK/SDK_Export/hw_platform_0/.Click Add to add the u-boot.elf file found at zybo_base_system/sd_image/. It is very important that the 3 files are added in this order, or else the FSBL will not work properly. It is also very important that you set FSBL.elf as the bootloader and system.bit and u-boot.elf as data files. In this tutorial, the sd_image folder is set as output folder for the BIN file. Click Create Image.
*Note: Use the Master-Next Branches until further notice
Get the Linux kernel source code from Digilent git repository. There are two ways to retrieve the source code:
Using git command: If you have git installed in your distribution, you can clone the repository to your computer by command git clone https://github.com/DigilentInc/Linux-Digilent-Dev... The whole Git Repository is around 850MB, as shown in image 1.
Download a compressed package: If you only want to use u-boot once and do not want to track the updates, you can also download a compressed package from github.com: https://github.com/DigilentInc/Linux-Digilent-Dev. Click Tags on the top right corner of the page.The most recent tag is zynq-dt-for-3.14 (image 2).
If you downloaded the tar.gz, you can decompress it using command
tar zxvf linux-digilent-v3.6-digilent-13.01.tar.gz
If you downloaded the zip file, you can decompress it using command
unzip linux-digilent-v3.6-digilent-13.01.zip
To boot the Linux Operating System on the Zybo, you need BOOT.BIN, a Linux kernel image (uImage), a device tree blob (DTB file), and a file system. BOOT.BIN has been created in Section III and uImage has been compiled in Section IV. We will now compile the DTB file. The default device tree source file is located in the Linux Kernel source at arch/arm/boot/dts/zynq-zybo.dts.
RAMDISK: For zynq only the ramdisk image has to be wrapped in a u-boot header in order for u-boot to boot with it. This is shown in the image in this step.
Plug the SD Card into the Zybo. To boot from SD card, jumper 7 needs to be configured for USB as shown on the Zybo Board and Jumper 5 must be connected to SD. Connect UART port to PC with micro USB cable and set the UART terminal on PC to 115200 baud rate, 8 data bits, 1 stop bit, no parity, and no flow control. After powering on the board, the console should be seen at the UART terminal if you use RamDisk. More information about this file system can be found in Getting Started with Embedded Linux ZedBoard.
We need to add the myLed device node into the device tree.
Make a copy of the default device tree source in the drivers folder, and modify it according to the second image. The compatibility string of the node is the same as we define in the driver source code (myled.c: line 182). The reg property defines the physical address and size of the node. The address here should match with the address of the myLed IP core in the address editor tab of the Vivado design, as shown in the last image.
Plug the SD card into the Zybo, and we can start testing our driver. Use the insmod command to install the driver module into the kernel. After the driver is installed, an entry named myled will be created under the /proc file system. Writing 0x0F to /proc/myled will light up LED 0~3. You can either remove the driver with command rmmod or power off the system by command poweroff. In both case, all the LEDs will be turned off, as shown in Figure 69 and 70. For instructions on using the terminal with the Zybo. please refer to Step V-4 or Section Boot from SD in Getting Started with Embedded Linux – ZedBoard.
Just a reminder, this is a draft. There will be an official copy that will be released on Digilentinc.com.
I appreciate any feedback to make the official copy stronger.