Running Petalinux based linux system on Zedboard via jtag and SD card

Summary: This short tutorial demonstrates how to run and test the first petalinux based customized linux system on Zedboard via jtag and SD card.

Implementation: This tutorial is the continuation of the first lecture. It thus assumes that the reader has already created, configured and built a petalinux based customized linux system by using petalinux-create, petalinux-config, and petalinux-build commands, respectively. After building the linux system, it can be run and tested on Zedboard via JTAG. To this end, turn on and set the configuration jumpers of the zedboard into JTAG boot mode (see the figure given below).

Then, run the following command from the project directory of petalinux:

  • petalinux-boot –jtag –prebuilt 3   

The command downloads the newly built linux solution into zedboard. Lastly, connect the serial  port of zedboard with the PC and configure its baud rate to 115200. The serial port allows us to do further actions after the linux system is up.

Second part of the tutorial explains the steps necessary to run the linux system on zedboard via SD card as follows.

  • Generate Boot Image which usually contains a first stage bootloader image, FPGA bitstream (optional) and U-Boot. The syntax of the command used to generate the boot image is following:
    • petalinux-package –boot –fsbl <FSBL image> –fpga <FPGA bitstream> –u-boot
  • Prepare SD card for the linux system
    • Insert and unmount all the partitions of the SD card of size 8 Ghz by using umout command:
      • sudo umount /media/<location of mount>
    • Delete the existing partitions and create two new partitions with the first partition of size 1GHz and remaining size for the other partition.
      • sudo fdisk /dev/<name of the directory>
    • After having two partitions, Format the former by using FAT and the later by using ext4. The syntax of the commands is following
      • mkfs.vfat -F 32 -n BOOT /dev/<first partition>
      • mkfs.ext4 -L rootfs /dev/<second partition>  
  • Copy the the necessary files into first partition of SD card
    • cp images/linux/BOOT.BIN /media/<first partition>
    • cp images/linux/image.ub /media/<first partition>
  • Copy the the necessary files into second partition of SD card
      • cp images/linux/rootfs.cpio /media/<second partion>
  • Insert the SD card into SD card slot of zedboard and Configure it into  SD card boot mode (see figure given below).

Lastly, connect the serial  port of zedboard with the PC and configure its baud rate to 115200. The serial port allows us to do further actions after the linux system is up.

The video given below also explains all the steps needed to run and test first Petalinux based linux solution on Zedboard via jtag and SDcard.



Installation of Petalinux and running the first Petalinux based linux system on QEMU

Summary: This short tutorial, first, defines the petalinux, board support packages (BSP) and quick emulator (QEMU) used in zynq 7000 linux programming. It, secondly, describes the steps necessary to install petalinux on Ubuntu PC. Finally, an example on how to run and test the petalinux based linux system in QEMU is demonstrated.

1.  Definitions of Petalinux, BSP and QEMU: Petalinux, which is based on the yocto project, is a  Xilinx development toolchain which provides us everything necessary to build, test, customize and deploy an embedded linux system. Furthermore, it is an embedded linux distro maintained by Xilinx and targets Xilinx System on Chip (SoC) designs. It also has an integrated full system quick emulator (QEMU).  Developers can test and verify the customized linux solution on QEMU before deploying it on the actual hardware. Additionally, Xilnix also provides Board Support packages (BSP) for various Xilinx evaluation boards. A BSP describes the various hardware features supported by the corresponding evaluation board. Petalinux uses these BSPs to configure the kernel as per specification defined in them.  

2. Installation of Petalinux: The steps used to install the petalinux on Ubuntu 18.04.4 LTS are summarized as follow:

  • Download the petalinux version of your choice from the link (click here for the link). For example, I am using petalinux v2017.4.
  • Change the access permission of the download files by executing the following command. sudo chmod +x <download path>/
  • Petalinux tool requires a number of standard development tools and libraries. For your convenience, I have listed all these dependencies here. sudo apt install tofrodo,  iproute, gawk, gcc, git-core, make, net-tools, ncurses-dev, libncurses5-dev, zlib1g-dev, flex, bison, lib32z1, lib32ncurses5, lib32bz2-1.0, ia32gcc1, lib32stdc++6, libselinux1,  libssl-dev,  libssl1.0-dev.
  •  Change the access permission of the location where you want to install the petalinux with this command. sudo chmod 755 <installing location for petalinux>
  • Run sudo chmod 755 /tmp command to change the access permission of tmp folder.
  • Install the petalinux with the command. <download path>/ <installing location for petalinux>
  • Run the command source <installing location for petalinux>/
  • If you get the WARNING: /bin/sh is not bash! After running this command, please run the following subset of commands.
    • chsh -s /bin/bash.
    • Log out and then run these commands.
    • sudo rm /bin/sh.
    • sudo ln -s /bin/bash /bin/sh.
  • Lastly, upon running echo $PETALINUX command, it will give you the installed path of the petalinux.3. Running the first Petalinux based linux system on Qemu: In this tutorial, Zedboard is chosen as a Xilinx evaluation board. The steps involved in testing first petalinux based linux system on QEMU are listed below:
  • Download the corresponding BSP for Zedboard from Xilinx official website (click here for the link).
  • create a basic project template by using petalinux-create command.  petalinux-create -t project -s <location of BSP>/Avnet-Digilent-ZedBoard-v2016.2-final.bsp
  • The project can be customized by using The petalinux-config command. For our special case, we don’t need to do any customization. Run petalinux-config and select exit.
  • Builds either the entire embedded Linux system or a specified component of the Linux system by using petalinux-build command. for our example, please run petalinux-build.

After petalinux-build command, the linux solution is ready to deploy into hardware. We however first run the solution on QEMU to verify the functionality of the newly built linux system. petalinux-boot –qemu command is used to run the linux system on QEMU. after running the petalinux-boot –qemu –kernel, you need to login with following credential: username: root, password: root. The video given below explains all the steps needed to install and run first Petalinux based linux solution on QEMU.

UART Peripheral (UART 0, and UART1) implementation on ZedBoard, a development board for Zynq 7000

Abstract:  UART is one of the most common wired communication protocols used in low data rate applications. There are two UART controller interfaces, namely UART 0, and UART 1, readily available in PS part of Zynq 7000, which can be used to communicate with external devices equipped with UART interface. In this tutorial, Both UARTS are implemented over MIO Pins, where UART1, and UART0 are connected to USB UART, and Pmod E  over MIO 48-49, and MIO 14-15 respectively.

Implementation: The block diagram illustrated in the following figure provides an overview of implementation of UART(s) in ZedBoard.


The PS part of Zynq 7000 contains many I/O peripheral (IOP) controller interface for data communication. The two UART interfaces ,UART 0 and UART 1, in PS enable Zynq to communicate with any external devices that incorporates UART interface. These UART interfaces can be mapped to either MIO or EMIO. MIO pins allow PS to directly exchange information with external device over UART interface, while EMIO pins make possible the data exchange between PL and PS within Zynq.

In this tutorial both UARTs are implemented over MIO pins, where UART 0 and UART 1 are mapped on MIO 14-15, and MIO 48-49 respectively. MIO 14-15 pins are mapped to PmodE 9-10 in ZedBoard, therefore external UART pins should be connected on these pins. MIO 48-49 pins are mapped to USB UART connector, hence any micro USB connected on this connector should be able to exchange data. It is worth noting that  these UARTs can be mapped on other MIO or EMIO pins.

The TCL file available in the following GitHub link can be used to generate the UART 0, and UART 1 related hardware files in Vivado. The SDK project containing the C driver files of UART interfaces are available in this GitHub Link. Each link has read me files instructing to build the complete project.

The video given below explains all the steps needed to implement UARTs over MIO interfaces in ZedBoard.

Part 3: Implementation of GPIO via EMIO in All Programmable SoC (AP SoC) Zynq 7000

Abstract: In this tutorial, ZedBoard is used to implement GPIO via EMIO. Here, the GPIOs i.e., 5 buttons, 8 sliding switches, 8 LEDs, and Pmod A B C D which are not directly accessible in PS of ZedBoard are used. These GPIOs are controlled and monitored by PS through PL via EMIO interface.

Implementation: The block diagram illustrated in following figure provides an overview of implementation


The PS in ZedBoard can communicate with PL via EMIO interface. The PS uses Bank 2 ( Pins 54–85 ) and 3 ((Pins 86–117 ) to access and configure the EMIO interface. Each 32-bit bank independently controls 32 EMIO pins with each pin can be configured either input or output at a time. The EMIO pins are wired to PL, communicating with buttons, LEDs, sliding switches and PMODs.

The TCL file available in the following GitHub link can be used to generate the EMIO relatd hardware files (i.e., bitstream file) in Vivado. The SDK project containing the C driver files of EMIO interfaces are available in this GitHub Link. Each link has read me files instructing to build the complete project.

The video given below explains all the steps needed to implement GPIO via EMIO interfaces in ZedBoard.

Part 2: Implementation of GPIO via MIO on ZedBoard by using Vivado

Abstract: In this tutorial, ZedBoard is used to implement GPIO via MIO. Here, the GPIOs i.e., two buttons, one LED, and Pmod E which are directly accessible in PS of ZedBoard are used to implement the MIO concept.

Implementation : There are following two ways to implement the above-mentioned GPIOs in Zedboard.

  1. Go to following GitHub link Click here for GitHub Link and follow the instructions given in this link.
  2. The second way is explained here:

Open Vivado, select the zedboard from Boards, and click on finish.


Create block design and click OK.


Select Zynq7 Processor System from search box and run Run Block Automation and click Ok



Double click on processing_system7_0, deselect the reset, AXI interface, clock and some peripherals (PS-PL configuration>General>Enable Clock Reset>FCLOCK_RESET0_N, PS-PL configuration>GP Master AXI Interface> M AXI GPO interface, Clock Configuration>PL Fabric Clocks>FCLK_CLK0, Peripheral I/O Pins>TTC0, and USB0), and click Ok. You would have the following beautiful figure.


validate you design, generate output products and create HDL wrapper


Lastly, export hardware and launch the SDK. In SDK environment create application project and select hello world and finish it. Copy the code following code and paste it into helloworld.c file

/***************************** Include Files ********************************/
#include “xparameters.h”
#include “xgpiops.h”
#include “xstatus.h”
#include <xil_printf.h>
#include “sleep.h”
/************************** Variable Definitions **************************/
XGpioPs Gpio;    /* The driver instance for GPIO Device. */
XGpioPs_Config *ConfigPtr;
int main(void)
int Status;
u32 InputData;
/* Initialize the GPIO driver. */
ConfigPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr,
if (Status != XST_SUCCESS) {
XGpioPs_SetDirectionPin(&Gpio, 50, 0);
XGpioPs_SetOutputEnablePin(&Gpio, 50, 0);
XGpioPs_SetDirectionPin(&Gpio, 7, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 7, 1);
XGpioPs_SetDirectionPin(&Gpio, 0, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 0, 1);
XGpioPs_SetDirectionPin(&Gpio, 9, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 9, 1);
XGpioPs_SetDirectionPin(&Gpio, 10, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 10, 1);
XGpioPs_SetDirectionPin(&Gpio, 11, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 11, 1);
XGpioPs_SetDirectionPin(&Gpio, 12, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 12, 1);
XGpioPs_SetDirectionPin(&Gpio, 13, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 13, 1);
XGpioPs_SetDirectionPin(&Gpio, 14, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 14, 1);
XGpioPs_SetDirectionPin(&Gpio, 15, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 15, 1);
InputData = XGpioPs_ReadPin(&Gpio, 50);
XGpioPs_WritePin(&Gpio, 7, InputData);
XGpioPs_WritePin(&Gpio, 0, 1);
XGpioPs_WritePin(&Gpio, 9, 1);
XGpioPs_WritePin(&Gpio, 10,1);
XGpioPs_WritePin(&Gpio, 11,1);
XGpioPs_WritePin(&Gpio, 12,0);
XGpioPs_WritePin(&Gpio, 13,0);
XGpioPs_WritePin(&Gpio, 14,0);
XGpioPs_WritePin(&Gpio, 15,0);
XGpioPs_WritePin(&Gpio, 0, 0);
XGpioPs_WritePin(&Gpio, 9, 0);
XGpioPs_WritePin(&Gpio, 10,0);
XGpioPs_WritePin(&Gpio, 11,0);
XGpioPs_WritePin(&Gpio, 12,1);
XGpioPs_WritePin(&Gpio, 13,1);
XGpioPs_WritePin(&Gpio, 14,1);
XGpioPs_WritePin(&Gpio, 15,1);

Finally, on the run icon click Run As> Launch On Hardware (System Debugger). Congratulation, you are able to control or monitor external signals via MIO on PS of Zedboad.


Part 1: Implementation of GPIO via MIO and EMIO in All Programmable SoC (AP SoC) Zynq 7000

Abstract: The tutorial provides a brief overview of available input/output peripherals (IOPs) and their relation with multiplexed input/output (MIO) and extended MIO (EMIO) in Zynq 7000. After that, a comprehensive detail of general purpose input/output (GPIO), which is one of the available IOPs in Zynq 7000, and its programming via MIO and EMIO is explained. Lastly, the GPIOs are implemented by making use of Vivado and Zedboard as a software and hardware platform respectively.

To facilitate the learners, this tutorial is sub-divided into three parts:

  • A theoretical overview of IOPs and detailed version of GPIO with their relations with MIO/EMIO,
  • Implementation of GPIO via MIO on Zedboard, and Vivado,
  • Implementation of GPIO via EMIO on Zedboard and Vivado.

Part 1: Implementation of GPIO via MIO and EMIO in All Programmable SoC (AP SoC) Zynq 7000

The IOPs (e.g., USB, UART, I2C and so on) can interact with Zynq 7000 SoC via either MIOs or EMIOs. The processor system (PS) part of Zynq 7000 has many built-in IOP controller with each controller provides its own driver available in the form of C code, enabling the users to integrate the external IOPs with PS without any extra overhead. In the following tutorials, we will be using these drivers to configure external IOPs. It is important to note that these controller are only available in PS part, so IOPs can only communicate with this part of Zynq 7000 SoC. If someone is interested in using IOPs in programmable logic (PL) part of Zynq 7000 SoC, he shall design the pertaining accelerator or can used Xilinx accelerator in PL. PS of Zynq directly can interact with the external IOPs via MIO.  The MIO pins however are limited in number.  Xilinx also provides its solution by introducing EMIO pins. So, EMIO can be used to exploit IOP controllers available in PS to make direct communication between PS and PL or to interact with the external IOPs via PL in case if all the MIO pins are occupied. The available IOP controllers in PS of Zynq are shown in the following figure.

GPIO: General purpose input/output (GPIO) ,shown in red dotted rectangle in the above figure, is one of the IOPs supported by Zynq 7000. According to Wikipedia “GPIO is an uncommitted digital signal pin on an integrated circuit or electronic circuit board whose behavior—including whether it acts an input or output—is controllable by the user at run time. GPIOs have no predefined purpose and are unused by default”.  It is cleared from the definition of GPIOs that their functions and IO directions are fully configurable. Their application includes but not limited to monitor and control the other circuitry. They can be used to implement low data rate communication standards (e.g., 12C, UART, SPI, etc.).  In Zynq 7000, PS can use GPIO to monitor or control the signals in PL and in external world via EMIO and MIO respectively.

The GPIO peripheral provides a software with observation and control of up to 54 device pins via the MIO module. It also provides access to 64 inputs from the Programmable Logic (PL) and 128 outputs to the PL through the EMIO interface. The GPIO is organized into four banks of registers that group related interface signals.

Each GPIO can be independently and dynamically programmed as input, output, or interrupt sensing. Software can read all GPIO values within a bank using a single load instruction, or write data to one or more GPIOs (within a range of GPIOs) using a single store instruction. The GPIO control and status registers are memory mapped at base address 0xE000_A000 [ug585].

  • Bank0: 32-bit bank controlling MIO pins[31:0]
  • Bank1: 22-bit bank controlling MIO pins[53:32]
  • Bank2: 32-bit bank controlling EMIO signals[31:0]
  • Bank3: 32-bit bank controlling EMIO signals[63:32]
Banks of Register related to GPIO [ug585]

Functional Description of GPIO banks: All the registers used to configure GPIO bank(s) (bank0 and bank1) are shown in the following figure and the functions of the registers are summarized as follows:

  • DATA_RO enables software to observe the value on the device pin,
  • DATA allows all 32 bits data to write at one time,
  • MASK_DATA_LSW and MASK_DATA_MSW enable any combination of up to 16 LSB or MSB bits to write respectively,
  • DIRM control the direction of the respective bank (e.g., when DIRM[x]==0, the output driver is disabled), OEN enables the outputs ( e.g., when OEN[x]==0, the output driver is disabled),
  • INT_MASK (read only) shows which bits are currently masked or enabled,
  • 1 to any bit of INT_EN register enables/unmasks that signal for interrupts,
  • 1 to any bit of INT_DIS register masks that signal for interrupts,
  • INT_STAT register shows if an interrupt event has occurred or not. Writing a 1 to a bit in this register clears the interrupt status for that bit.
  • INT_TYPE register controls whether the interrupt is edge sensitive or level sensitive
  • POLARITY register controls whether the interrupt is active-Low or active High (or falling-edge sensitive or rising-edge sensitive).
  • If INT_TYPE is set to edge sensitive, then INT_ON_ANY register enables an interrupt event on both rising and falling edges. This register is ignored if INT_TYPE is set to level sensitive.
Functional Description of GPIO [ug585]

Detailed explanation of AP-SoC Zynq 7000 Architecture

Zynq 7000 AP SoC ,as shown in Figure given below, mainly consists of two parts: Processor System(PS), Programmable Logic(PL). PS literally employs to implement software functions of a hybrid system while hardware related functions are realized in PL. The PS part in Zynq 7000 is further composed of Application Processor Unit (APU), Memory interfaces, Central interconnects, Input Output Peripherals (IOPs), and Multiplexed IO (MIO). APU is the central part of the PS which controls and regulates all parts of PS.APU can have either single CPU or dual CPU. Two independent L1 D cache and I cache are, respectively, employed for data and instructions in each CPU. Snoop Control Unit (SCU) are exploited to maintain the coherency between L1 caches of both processor. Coherency ensures that caches in the respective CPU have updated data. L2 caches further act as bridge between L1 cache and DDR ram. DDR ram are relatively bigger memory (e.g. 512MB in Zedboard). Besides L1, L2, and DDR ram, there is 256KB On Chip Memory (OCM) which can be used for the application which requires low latency. Watch Dog Timers (AWDT, SWDT) are utilized to reset the PS when it malfunctions.

Additionally, Timers (private timer, TTC) can be employed as timer or counter.  There are 8 Direct Memory Access (DMA) in PS as well which also plays considerable role in improving the performance of the PS. The key feature of MMU is the address translation. It translates addresses of code and data from the virtual view of memory to the physical addresses in the real system. It enables tasks or applications to be written in a way which requires them to have no knowledge of the physical memory map of the system, or about other programs which might be running at the same time. This makes programming of applications much simpler, as it enables to use the same virtual memory address space for each.

The generic interrupt controller (GIC) is a centralized resource for managing interrupts sent to the CPUs from the PS and PL. The controller enables, disables, masks, and prioritizes the interrupt sources and sends them to the selected CPU (or CPUs) in a programmed manner as the CPU interface accepts the next interrupt. Central interconnect acts as a bridge between IOP, memory interfaces, memory interfaces, and General port (GP). As shown in the Figure 1 that there many IOP controllers in PS. The I/O Peripherals (IOP) are a collection of industry-standard interfaces for external data Communication. IOP controller can access both OCM and DDR ram via central interconnects. IOPs can be accessed via 54 pins MIO which are dynamically shared among different IOPs.

In Zynq 7000 SoC, The PS and PL can be tightly or loosely coupled using multiple interfaces and other signals that have a combined total of over 3,000 connections. This enables user to effectively integrate user-created hardware accelerators and other functions in the PL logic that are accessible to the processors and can also access memory resources in the processing system. The PS and the PL are on separate power domains, enabling the user to design power efficient design. Extended MIO (EMIO), GP, High Performance (HP) ports, and accelerator coherency port (ACP) enable the users to connect the PL with PS for variety of applications. IOPs of PS can be passed to PL via EMIO. GP are low data rate interface which are mainly used to configure the custom accelerators in PL part. HP port are used for data flow. HP port can access OCM and DDR ram respectively, for low latency and relatively larger data storage. ACP has even lower latency than HP and like HP it can access OCM and DDR depending upon the application. Any kind of logic can be implemented in PL part of SoC. It has 12 ADC as well. Programmable IO enables PL to talk with the external world. The Zynq-7000 AP SoC can be booted securely or non-securely. The PL configuration bitstream can be applied securely or non-securely. Both of these use the 256b AES decryption and SHA authentication blocks that are part of the PL. Therefore, to use these security features, the PL must be powered on.