Install and Run Ubuntu 20.04 on Xilinx Zynq-7000 SoC ZC706 Through a Bootable SD Card, and Access It Through the Serial Port

In a new research project we are going to use the Zynq-7000 SoC ZC 706 Evaluation Kit. Below I document the steps I took to prepare Ubuntu 20.04 for the evaluation board and make sure it is running by connecting through a serial port. Additionally I document how I enabled remote access for colleagues and myself (so I don’t have to use the UART port every time I want to connect to the board).

I thank Chathura Niroshan for writing up the steps for installing Ubuntu 16.04 on Zynq-7000 SoC ZC702. To ensure I followed the correct and most up-to-date steps, I used PetaLinux’s Reference Guide and his write up side by side to install Ubuntu on a bootable SD card for ZC706.

The main difference between the steps I took and Chathura’s steps is that I did not need Vivado to create a hardware design. Instead, I used a readily available board support packages (BSP) file for ZC706 that includes a default hardware design. (Nevertheless, because I thought I am going to need Vivado during the steps, I did download and install it. I experienced an issue during the installation which I could resolve with the solution mentioned in this comment which instructs to install packages libtinfo5 and libncurses5.)

I executed the steps below on my laptop with an Intel CPU E3-1505M v5 and 64GB RAM that is running Ubuntu 20.04. To create the bootable files I used PetaLinux Tools version 2020.2 and copied them to a 256 GB SD card.

Create Bootable SD Card

We need to format the SD card and create 2 partitions of which the first will contain the boot information and the second partition will contain the root filesystem. First three steps under the section Configuring SD Card ext File System Boot of the Reference Guide describe how these partitions should be configured. Following the steps below we can create such two partitions:

  1. Insert the SD card into the SD card reader slot connected to your machine.
  2. Open up a terminal (e.g. ctrl+alt+t) and run sudo gparted . If you don’t have gparted, install it with sudo apt install gparted .
  3. From the menu GParted > Devices select the SD card.
  4. On each partition that is on the SD card, right click and select Delete to get a single “unallocated” partition.
  5. Right click and select New on the “unallocated” partition. Configure the partition as follows:
    - Free space preceding (MiB): 4
    - New size (MiB): 500
    - File system: fat32
    - Label: BOOT
    Don’t change the other settings. After done configuring, click Add.
  6. Right click and select New on the “unallocated” partition that follows the BOOT pratition (i.e. the “unallocated” partition that isn’t 4.00 MiB in size). This partition will occupy all the space that follows the BOOT partition. Configure the partition as follows:
    - Free space preceding (MiB): 0
    - Free space following (MiB): 0
    - File system: ext4
    - Label: RootFS
    Don’t change the other settings. After done configuring, click Add.
  7. Finally, to commit the changes select Edit > Apply All Operations from the menu.

Install PetaLinux Tools

As noted under the section Installation Steps in the Reference Guide, the recommended minimum workstation requirements are a 2 GHz CPU with 8 cores at minimum, 8 GB of RAM and 100 GB of free disk space. In my case, I did fine with a CPU of 4 cores and 2.8 GHz clock speed. Although Ubuntu 20.04 (running on my laptop) was not listed as a Supported OS, I had no issues installing and using PetaLinux Tools after getting the required packages. Steps for installing PetaLinux Tools v2020.2:

  1. As mentioned in the Reference Guide, PetaLinux requires that /bin/sh is ‘bash’. Check by executing ls -l /bin/sh if it is pointing to ‘bash’ or ‘dash’. If it is ‘dash’, reconfigure it by executing sudo dpkg-reconfigure dash . Select <No> when asked “Use dash as the default system shell (/bin/sh)?”. /bin/sh should now be ‘bash’.
  2. Get the PetaLinux 2020.2 Installer file
    petalinux-v2020.2-final-installer.run from https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/embedded-design-tools/2020-2.html.
  3. Verify that you have the correct and whole file. The command
    md5sum petalinux-v2020.2-final-installer.run
    should result in 687b018f7502a4258bd633dc483bde79.
  4. Create the directory where you would like to install PetaLinux. In the steps below I will use INSTALL_DIR to indicate the installation directory. As an example, you can set INSTALL_DIR to ~/tools/petalinux/v20202.2/ by executing INSTALL_DIR=~/tools/petalinux/v2020.2/ and create the directory by executing mkdir -p $INSTALL_DIR in the terminal.
  5. Execute the installer file to install PetaLinux at INSTALL_DIR:
    bash ./petalinux-v2020.2-final-installer.run --dir $INSTALL_DIR
    In my case, the installer reported missing the packages autoconf, libtool, gcc-multilib andzlib1g:i386. After installing them with sudo apt install the installer was able to continue. I ignored the warnings related to unsupported OS and missing tftp server. The tftp server is necessary if you are booting the board through tftp.
  6. Every time before working with PetaLinux Tools, set up the environment in the terminal by sourcing the settings.sh file in INSTALL_DIR, e.g.,
    source $INSTALL_DIR/settings.sh . Sourcing settings.sh gives an error under the ZSH terminal. Make sure you are operating in a bash terminal (executing bash will give you a bash terminal). If setting up succeeded, echo $PETALINUX should output the directory path where PetaLinux is installed.

Prepare BOOT Partition Files

Next we prepare the boot files that we will copy to the SD card. More information about the performed steps below can be found under sections PetaLinux BSP Installation, PetaLinux Configuration and Build System Image, Boot Images Storage Configuration, Build System Image and Generate Boot Image for Zynq-7000 Devices of the Reference Guide.

  1. Download the board support package (BSP) file for your board, in our case xilinx-zc706-v2020.2-final.bsp for ZC706, from https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/embedded-design-tools/2020-2.html. Important to highlight from the Reference Guide is that PetaLinux 2020.2 only works with hardware designs exported from Vivado Design Suite version 2020.2. So in case you are using a different version of PetaLinux, it might be better to get the BSP file from the download page of your version of PetaLinux.
  2. Open a ‘bash’ terminal (press ctrl+alt+t then execute bash) and source the settings.sh file residing in the installation directory of PetaLinux tools, e.g. source $INSTALL_DIR/settings.sh .
  3. Because petalinux-create creates a new project in the current working directory, pick the directory where you want to create a new project and enter that directory, e.g.: mkdir -p ~/projects/zc706 && cd ~/projects/zc706
  4. Create a new petalinux project with petalinux-create -t project -s ~/Downloads/xilinx-zc706-v2020.2-final.bsp -n plnx-files. Option -n allows you to name your project. Note that building the boot files requires between 50–100 GB of free temporary space. By default the directory build/tmp inside the project directory is used. If necessary, you can adjust the directory for the temporary files with the --tmpdir option.
  5. Next we configure our target system. Enter the new petalinux project directory (plnx-files in my case) and execute petalinux-config to start the configuration. Note that we do not need to import the hardware description (--get-hw-description), because it is already provided by the BSP file. If you get an error while executing the config command, you can check file build/config.log to find more details about it. If you get an error that says Failed to generate <..>/Kconfig.syshw, installing package libtinfo5 through apt might resolve your issue.
  6. In the opened System Configuration window, we go over the following settings:
    - Under Image Packaging Configuration > Root filesystem type select EXT4 (SD/eMMC/SATA/USB).
    - Under Subsystem AUTO Hardware Settings > Advanced bootable images storage Settings > boot image settings > image storage media select primary sd.
    - Under Subsystem AUTO Hardware Settings > Advanced bootable images storage Settings > kernel image settings > image storage media select primary sd.
  7. Save and exit the configuarion window.
  8. Now start building with petalinux-build. This is a long process that shows a progress bar. This step creates, among other files, the files images/linux/image.ub and images/linux/boot.scr. We will copy these two files to the SD card in later steps.
  9. Finally create the BOOT.BIN file with petalinux-package --boot --format BIN --fsbl images/linux/zynq_fsbl.elf --fpga images/linux/system.bit --u-boot. We will also copy this file to the SD card later.

Prepare RootFS Partition Files

We will install Ubuntu 20.04 LTS in the RootFS partition. Since the rootfs.tar.gz file, created during the petalinux build above, does not contain Ubuntu, we ignore that file and follow steps from digikey.com’s wiki page to get Ubuntu 20.04 LTS root filesystem.

  1. Download the tar file ubuntu-20.04-minimal-armhf-2020–05–10.tar.xz from https://rcn-ee.com/rootfs/eewiki/minfs/ubuntu-20.04-minimal-armhf-2020-05-10.tar.xz.
  2. Verify that you have the correct and whole file. The command
    md5sum ubuntu-20.04-minimal-armhf-2020–05–10.tar.xz
    should result in 16da487c1178439d68e18cf55accb774.
  3. Extract the downloaded tar file:
    tar xf ubuntu-20.04-minimal-armhf-2020–05–10.tar.xz
    This will create a directory ubuntu-20.04-minimal-armhf-2020-05-10 that includes armhf-rootfs-ubuntu-focal.tar. We will extract this tar file to the SD card in the next section.

Copy Files to the SD Card

Related section for copying files to the SD card is the Copying Image Files section in the Reference Guide. Steps for preparing the Ubuntu root filesystem are from digikey’s wiki page.

  1. Insert the SD card into the SD card reader slot connected to your machine.
  2. If the partitions are not mounted, you can mount them to a directory with the commant sudo mount /dev/<partition-on-device> <directory> , e.g.:
    - sudo mount /dev/mmcblk0p1 ~/sdcard/boot
    - sudo mount /dev/mmcblk0p2 ~/sdcard/rootfs
    Assuming that ~/sdcard/boot and ~/sdcard/rootfs already exist in user’s home directory. You can find the device partitions either by running the command lsblk or by starting up gparted with sudo gparted.
  3. Copy the boot files image.ub, boot.scr and BOOT.BIN to the BOOT partition, e.g.:
    - cp $ZC706_PLX_DIR/images/linux/image.ub ~/sdcard/boot
    - cp $ZC706_PLX_DIR/images/linux/boot.scr ~/sdcard/boot
    - cp $ZC706_PLX_DIR/images/linux/BOOT.BIN ~/sdcard/boot
    Assuming that $ZC706_PLX_DIR points to the petalinux project directory.
  4. Extract the Ubuntu rootfs tar file to the RootFS partition and set RootFS ownership to root and permissions to 755, e.g.:
    - tar xfvp $ZC706_UBUNTU_DIR/armhf-rootfs-ubuntu-focal.tar -C ~/sdcard/rootfs
    - sudo chown root:root ~/sdcard/rootfs
    - sudo chmod 755 ~/sdcard/rootfs
    Assuming that $ZC706_UBUNTU_DIR points to directory ubuntu-20.04-minimal-armhf-2020-05-10 created in the previous section Prepare RootFS Partition Files.
  5. Finalize by synchronizing the writes to the SD card by running sync . The SD card is ready to be inserted into the board’s SD card slot.

Connect to the Board Through the Serial Port

To test our installation, we connect through the serial port and see if the board is booting into Ubuntu.

  1. Start with the board turned off.
  2. Insert the SD card to the board’s SD card slot.
  3. Configure the Boot Mode Switch on the board to boot from the SD card (see image below). Switches 1 to 5 are respectively configured to be 0, 0, 1, 1 and 0. With 1’s pointing towards the digits 1–5.
  4. Connect your machine to the board through its USB-to-UART bridge using an A-Male to Mini-B cable.
  5. Power on your board.
  6. In a terminal (ctrl+alt+t), execute the command lsusb to find out if the board is successfully connected to your machine. If there is a line that contains CP210x, it means your connection with the board succeeded and you can proceed. In my case this line looked like: Bus 001 Device 021: ID 10c4:ea60 Silicon Labs CP210x UART Bridge.
    Otherwise, you will probably need to install the Silabs drivers from https://www.silabs.com/support/resources. Search for VCP to list the drivers under Software. Download the drivers for your machine, extract the downloaded file and follow the instructions in INSTALL.
    If you want to check if the drivers are installed on your machine by default, you can run the following commands:
    dpkg -L linux-modules-extra-`uname -r` | grep cp210
    If this lists a cp210x.ko file, you have the drivers installed and you should see the connection with the board with lsusb when the board is powered on.
  7. Find out which USB tty port the board is connected to by executing the following in a terminal:
    dmesg | grep -i cp210 | grep -i tty
    In my case, it is ttyUSB0.
  8. Start up the serial port terminal: sudo gtkterm.
    If you don’t have it, install it first with: sudo apt install gtkterm.
  9. Open the terminal configuration via Configuration > Port.
  10. Configure the Serial port as follows:
    - Port: the tty port found in step 7 above. ttyUSB0 in my case.
    - Bits: 8
    - Baud Rate: 115200
    - Stopbits: 1
    - Parity: none
    - Flow control: none
  11. Press OK and your serial port terminal is up. You should now be able to communicate with your board. If you don’t see anything, it might mean that there is currently no output ongoing. Press Enter or any other keyboard to start interacting. The default username and password for the installed Ubuntu is ubuntu and temppwd respectively. If you will enable remote access over the internet, mind changing the default password first.

Image supporting step 3 above:

Boot Mode Switch configured to boot from the SD card. Image from xilinx-wiki.atlassian.net.

References for the steps above:

Enable Remote Access From Outside Local Network

Finally, I will describe the steps I took to enable remote access to the boards to colleagues and myself. This will allow to connect through SSH and will save myself from having to connect through the serial port every time. Ubuntu installed on the board already allows connecting with SSH. However, because it is behind the firewall of my Verizon router, I had to adjust the firewall settings to allow incoming SSH requests and route them to the board.

Important: consider changing the default password of the ubuntu user on the board before making the board accessible over the internet.

Adjusting firewall settings:

  1. Make sure the board is ON and connected to the router with an Ethernet cable.
  2. Find the router IP address through https://whatismyipaddress.com/. Alternatively the router’s local network IP can be used which is usually of the form 192.168.X.Y, for example, 192.168.1.1 or 192.168.1.255.
  3. Browse to the router’s IP address by entering it in the browser’s address bar.
  4. Enter the login credentials which can be found on the sticker behind your router.
  5. Go to Firewall settings then Port Forwarding.
  6. Enable Advanced settings.
  7. Under “Create new port forwarding rule:” change “Select IP from menu” to the arm board’s IP. Also change “Application To Forward” to Custom Ports which will bring up a few extra input fields.
  8. Set the remaining input fields as follows:
    - Protocol: TCP.
    - Source Ports: Any.
    - Destination Ports: Specify. By default SSH listens on port 22. So this would be the port you would specify. However, it is a good practice to change the default listening port to dodge brute force attacks on default ports. Generally ports between 30000 and 65535 are free to use. If you change the destination port, you have to add option -p to the ssh command to specify the destination port.
    - Forward to Port: Specify. Put 22 in the input field or the listening port you have configured for SSH on the board. Since in my case the board is behind a router and not directly reachable from the internet, it is safe from brute force attacks on default ports. Therefore, I did not change the default port on the board. Whatever is specified under “Destination Ports” above, the router converts it to whatever is specified under “Forward to Port”.
  9. Finally Add the new port forwarding rule and wait for the router to restart.
  10. Now you should be able to connect with the board over SSH. Use the following command to connect to the board over SSH after replacing destination-port and router-ip with the appropriate values:
    ssh -p <destination-port> ubuntu@<router-ip>

Thank you for reading! Please leave a comment if you have questions or issues related to the steps above.

Security Researcher @ Stevens Institute of Technology

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store