Main Content

Build Custom Linux Image for HDL Coder IP Core Workflow

This example shows the basic steps involved in using the Mathworks® Buildroot environment to build a custom Zynq® Linux® image for a Digilent™ Zybo Z7-10 Zynq board. The same steps can be followed to create an image for the Digilent Zybo Z7-20 Zynq board or other Zynq platforms.

This examples also talks about the process to setup your build environment before starting the building of Linux image for Zynq paltforms

Requirements

  • Debian-9 Linux operating system.

  • Xilinx® Vivado® Design Suite, the supported version listed in the HDL Coder™ documentation

  • AMD® Vitis® Unified Software Platform

  • MathWorks build system - Buildroot

  • Digilent Zybo Z7-10 Zynq development board with the accessory kit

Zynq Configuration

The Zynq boot process involves the processor system (PS), loading and executing Zynq boot image which consists of a First stage bootloader (FSBL), a bitstream to configure the programmable logic (PL), and user applications.

Boot Process

Stage 0

After the board is switched ON or the Zynq processor is reset, BootROM, a read-only code executes from (CPU0) one of the processor from processing system (PS). Based on the boot mode pin settings (JP5) in Zybo Z7-10 from available boot mode options, such as QSPI Flash, NAND Flash, SD Card, it copies the BootROM to on-chip memory (OCM). Then OCM executes the BootROM. Post-execution, the BootROM transfers execution to FSBL in the OCM.

Stage 1

The FSBL enables by configuring PS components, such as DDR memory controller and I/O components then it looks for the bitstream file in the boot device. The FSBL loads application binaries and data files into memory until the complete image has been read from the boot device then FSBL initializes the external RAM and loads the second stage bootloader or stand alone application.

Stage 2

The user application loaded in the previous stage will be executed like U-Boot. It runs in CPU0 to initialize and setup the environment in which OS will boot. Initialization includes configuring the memory management unit.

Stage 3

The bootloader then fetches the kernel image and boots the embedded Linux operating system. In case of Linux, the OS detects and enables the second processor core CPU1, configures and activates the MMU and data caches and performs other actions to make a complete system available to applications.

This example is verified in Debian-9 Linux operating system. If you have the supported OS installed, you can directly Build a Zynq Linux image by using the Mathwork Build System section. Otherwise, please do install Debian-9 by following below installation process

Installation of Debian-9 Linux Operating System

Step 1

Download the Debian-9 iso cdimage file from the official website using the link

Step 2

Install the Debian-9 OS using above iso file. During the installation process, you may be asked to configure the package manager. Provide the mentioned debian archive mirror manually as shown below.

Do following settings as shown below and Click on continue.

Step 3

In the next step, you should ignore the error saying security.debian.org could not be accessed as there are no security updates for debian Lenny and follow further installation process to complete Debian 9 installation.

Mathworks Build System

Mathworks Buildroot is a tool you can use to generate custom linux images through cross-compilation. The MathWorks build system wraps Buildroot in pre and post-processing scripts to automate the generation of system images for various platforms. The build system is based on scripts that take as input the target board, platform or image description file and output a complete system image, including bootloaders, kernel, and user space. This repository hosts the buildroot framework that creates the Xilinx® Zynq platform and Altera® SoC SD Card images for use with MathWorks tools. To start with the build process, there is some pre-work which need to be carried out to generate handoff files. This can be done using the Xilinx Vivado and AMD Vitis tools as shown in further sections.

Generate Handoff Files

To generate handoff files, you should create a reference design using Xilinx Vivado project for your application. The settings applied in Zynq processing system IP such as address mapping of memory and peripherals, are exported from the Xilinx Vivado project. For more information, see the Create and Export a Custom Reference Design by Using Xilinx Vivado section in Define Custom Board and Reference Design for AMD Workflow. Although the example targets for Zybo Z7-10 board in creating custom reference design, the same workflow can be used for Zybo Z7-20 or other Zynq based boards. Export the hardware platform from the Vivado block design project and unzip the .xsa(Xilinx Source Archive) file to get ps7_init_gpl.c, ps7_init_gpl.h as shown.

Step-1: After successful creation of Vivado project, open the block design in Vivado and export the hardware as shown and follow the corresponding steps to generate .xsa file

Step-2: Once the .xsa file is created, open it through Vitis tool to extract the processor configured header files as shown

You can also run the below command in MATLAB command window to extract the handoff files from the exported .xsa file after navigating to the exported .xsa file path

>> unzip design_led_wrapper.xsa

With the extraction of .xsa file and generating handoff files, pre-work is completed and you can start building the linux image using MathWorks build system

Build a Zynq Linux image by Using the Mathworks Build System

1. Setup Cross compiler

Setup the cross compiler by Installing the Linaro ARM toolchain on your Linux machine. You can install the corresponding tarball using the link Linaro Toolchain

Unzip the tarball and copy the contents into specified folder on your Linux machine: /opt/linaro/aarch32-6.3.1-2017.02

2. Sync MathWorks Buildroot from Git Hub

Get the buildroot from the GitHub - MathWorks Buildroot repository using git clone

>> git clone https://github.com/mathworks/buildroot.git

Now checkout the branch using latest tag

>> git checkout xilinx-next

3. Replace/Copy the handoff files into buildroot directrory

Replace/Copy the generated ps7_init_gpl.c, ps7_init_gpl.h files into handoff folder in the zyboz710 buildroot directory buildroot/board/mathworks/boards/zynq/zyboz710/handoff on your Debian-9 Linux machine as shown in below image

Now you are set to initiate the build process using the Python commands

4. Run Build Script

Using the following build script, we can initiate the Linux SD image build for the specific board. Note that you may need to install additional packages like gcc, make, g++ etc., using sudo commands as and when required for successfully building the image

>> ./build.py -c board/mathworks/zynq/boards/zyboz710/catalog.xml

Otherwise use this command to provide the different toolchain path manually to build.

>> ./build.py -p zynq -b zyboz710 --brconfig BR2_TOOLCHAIN_EXTERNAL_PATH='/opt/linaro/aarch32-6.3.1-2017.02'

Once the build is successful, you should be able to see the image generated as a zip file with name <board_name>_sdcard_hdlcoder_<build_date>.zip under /buildroot/output/<board_name>_linux_linaro/images folder

5. Unzip the image file into SD card

Unzip the image file to see the contents inside it as shown below.

Copy the contents into the SD card and insert the SD card on Zybo Z7-10 board and make sure to put the board in SD boot mode. It can be done by using JP5 jumper switch. To learn more about board connections, see Define Custom Board and Reference Design for AMD Workflow.

Once the board is powered ON, you can see the successful boot log in external console as shown below.

This completes the process of building image and booting up the board successfully.

Device Tree Source and Defconfig Files

This section gives infomation about the devicetree and defconfig files which are used by buildroot while building the image. We do not need to provide or add these files manually anywhere in the buildroot directory. The automated Python build script will fetch these files from other MathWorks github repositories whenever required.

1. Device Tree Source

Device tree is a data structure that describes the hardware which is readable by an operating system like Linux so that it doesn't need to hard code any details of the machine. A device tree source (DTS) file contains plain text data that describes a list of nodes, properties and child nodes for platform identification, run-time configuration like bootargs. DTS files are compiled using device tree compiler into device tree blob (DTB) which is a binary file that the hardware uses during the boot process.

Below code is the sample code of the Zybo Z7-10 Device tree source file.

#include "zynq-7000.dtsi"
#include <dt-bindings/gpio/gpio.h>

/ {
    model = "Digilent Zybo Z7 board";
    compatible = "digilent,zynq-zybo-z7", "xlnx,zynq-7000";


    aliases {
        ethernet0 = &gem0;
        serial0 = &uart1;
    };


    memory@0 {
        device_type = "memory";
        reg = <0x0 0x40000000>;
    };


    chosen {
        bootargs = "";
        stdout-path = "serial0:115200n8";
    };


    gpio-leds {
        compatible = "gpio-leds";


        ld4 {
            label = "zynq-zybo-z7:green:ld4";
            gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
        };
    };


    usb_phy0: phy0 {
        #phy-cells = <0>;
        compatible = "usb-nop-xceiv";
        reset-gpios = <&gpio0 46 GPIO_ACTIVE_LOW>;
    };
};


&clkc {
    ps-clk-frequency = <33333333>;
};


&gem0 {
    status = "okay";
    phy-mode = "rgmii-id";
    phy-handle = <&ethernet_phy>;


    ethernet_phy: ethernet-phy@0 {
        reg = <0>;
        device_type = "ethernet-phy";
    };
};


&sdhci0 {
    status = "okay";
};


&uart1 {
    status = "okay";
};


&usb0 {
    status = "okay";
    dr_mode = "host";
    usb-phy = <&usb_phy0>;
};

2. Zynq Defconfig

The platform defconfig contains the Linux kconfig settings required to properly configure the kernel build. This file is the zynq_zybo_defconfig file used for building the Z7-10 and Z7-20 Images.

###########################################

# Zybo Options

###########################################

BR2_TARGET_UBOOT_BOARD_DEFCONFIG="zynq_zybo"

BR2_PACKAGE_XILINX_BOOTLOADER_UBOOT_TARGET_DIR="board/xilinx/zynq/zynq-zybo"

Summary

This example shows step by step process of building a Linux image by using the Mathworks Buildroot system. You can build a Linux image for other Zynq platforms by using the MathWorks build system. Using this example you can create Xilinx Zynq Linux image for the custom Zynq boards by including the required files in the Mathworks buildroot folder and setting up the linaro cross-compiler.