This work in progress post describes how a PetaLinux image can be built for the EBAZ4205 FPGA board. There are already some great tutorials online, which explain how to run a verilog project on the Xilinx Zynq 7000 FPGA. This blogpost takes snippets of the existing tutorials, with the goal of creating a new PetaLinux image for the board.

What is the EBAZ4205?

The EBAZ4205 is a cheap FPGA-board, available on sites like AliExpress. These boards were used for cryptomining and are now sold for around $20 per piece. When a board arrives, the PetaLinux firmware containing cryptomining software may still be installed. To make sure the board works, the steps in this post can be followed.

picture of the board goes here

The FPGA can be programmed to act as digital logic gates using verilog. This is well documented in this post. If you want to learn verilog without having to deal with PetaLinux, I would recommend getting a JTAG programmer for the board and following the steps in this post.

Software used

I wanted to know how to create a new PetaLinux image for the board, to replace all the cryptomining software. This post gives some useful information, but there are some pitfalls when combining the steps from this and this post. This blogpost will loosely follow the steps from this post, but with some differences. Instead of uploading a bitstream using JTAG, the goal of this project is to create a bootable PetaLinux image for the EBAZ4205 board and starting it from an SD-card.

Before any Linux firmware can be used on the FPGA, it has to be configured to act as a CPU. This can be done in a program called Vivado. When the FPGA is configured, a tool called PetaLinux can be used to build Linux firmware for the FPGA. PetaLinux can read the hardware configuration of the FPGA and create Linux firmware for the board.

In this project, Ubuntu 24.04 was used. Even though it is not a supported OS, it worked fine for my purposes.

Installing Vivado

First, download Vivado from AMD’s website. I chose to download the web installer, since the offline installer has a size of 100GB. At the time of writing, version 2024.1 was the latest version. This is the version of Vivado that was used in this project.

After downloading, I chose to run the Vivado installer with superuser rights, to make sure the installed software would be able to communicate with the Xilinx JTAG device. I think the software can be installed and used without superuser rights, but I have not tested this.

Starting the Vivado installer with superuser rights

Most of the installation is straightforward; insert username and password, click “Next” a few times, etc. At some point in the installation, the installer will ask what software needs to be installed. Click on “Vivado”.

Select Vivado instead of Vitis

At the next screen, click “Vivado ML standard”.

Select Vivado ML standard

The installer will then ask what software modules should be installed. I chose to install everything from Vitis, just to be sure no software is missing. Under “SoC’s”, all other boards, except the Z7000 series were unchecked, because I don’t have these boards.

Selected software modules

At the end, the installer will (at least for me) hang at “Generating installed device list”. If this happens, leave it running for 10 minutes and then terminate the installer using sudo xkill. The reason for this, is that Ubuntu is not a supported OS.

The installer hangs

Starting Vivado for the first time

If Vivado is installed in the (default) /tools/Xilinx directory, it can be started with the following command:

sudo /tools/Xilinx/Vivado/2024.1/bin/vivado

It is possible that application fails to start, because the correct ncurses version cannot be found. This is because Ubuntu 24.04 is newer than the supported OS and has a newer version of ncurses.

The version of ncurses is too new

This ncurses error can be fixed by creating a (questionable) symbolic link:

sudo ln -s /usr/lib/x86_64-linux-gnu/libtinfo.so.6 /usr/lib/x86_64-linux-gnu/libtinfo.so.5

After this, Vivado should start.

Installing the EBAZ4502 board files

After starting Vivado, the board files for the EBAZ4205 board have to be added to the Vivado installation. This is as simple as copying the files into the correct folder:

# Download board files from github
git clone https://github.com/XyleMora/EBAZ4205.git

# Create a "board_files" directory, in case it doesn't exist yet
sudo mkdir /path/to/vivado/installation/Vivado/2024.1/data/boards/board_files/

# Copy the board files into the correct location
sudo cp -r EBAZ4205/Documents/Board\ files/ebaz4205/ /path/to/vivado/installation/Vivado/2024.1/data/boards/board_files/

Installing PetaLinux

Installing PetaLinux is more straightforward than Vivado. The installer does not have to be started with superuser rights. PetaLinux was installed using the following settings:

Selected software modules

Creating an FPGA configuration using Vivado

After placing the board files into the correct location, Vivado can be started. In Vivado, a minimal hardware configuration will be created. Instead of creating an AND-gate, as explained in this post, the FPGA will be configured as a minimal CPU.

First, create a new project. This post will say that the option “This is an extensible Vitis project” needs to be enabled. However, for this project, this option needs to remain unchecked. Instead of uploading the bitstream via JTAG, the bitstream needs to be exported to an .XSA file. Vivado will refuse to export the bitstream if the project is not configured properly.

Leave the default options as they are

After the project has been created, click on “Create block design” and give the design a nice name.

In the block design, Add an IP (ZYNQ7 processing system).

Add a new ZYNQ7 processing system

Loop the FPGA clock output to the clock input of the processor.

Use the FPGA clock output as clock input for the processing system

Then, run the block automation.

A minimal working example of a processing system

After the diagram design is complete, right click the design source and select “Create HDL wrapper”.

A minimal working example of a processing system

Then, click on generate bitstream. This will create a hardware design. To export the hardware design, click File->Export->Export hardware and export the bitstream file.

Creating a Linux firmware using PetaLinux

The exported .XSA file (the FPGA bitstream) can now be given to PetaLinux. PetaLinux can use this bitstream file to generate a Linux firmware for the EBAZ4205 board. To create a minimal working example of a linux firmware, the following commands were executed:

source /path/to/petalinux/installation/settings.sh
petalinux-create --type project --template zynq --name ebaz4205_petalinux_build
cd ebaz4205_petalinux_build
petalinux-config --get-hw-description /path/to/hardware_design.xsa
petalinux-build

Editing the .dtsi

Because the hardware design is very minimal, it does not know what a “NAND storage” is. If petalinux-build fails with the message Label or path ps7_nand_0 not found, open the .dtsi file and comment out the &ps_7_nand_0 block. After that, petalinux-build should work again.

Creating BOOT.BIN

Although petalinux creates a lot of useful files, it didn’t create BOOT.BIN. This is the one file that makes sure everything boots properly: It contains the bitstream, bootloader and kernel.

petalinux-config

Subsystem Hardware Settings -> Flash Settings -> [*] Advanced Flash Autoconfiguration
Subsystem Hardware Settings -> Flash Settings -> (0x1000000) size (for nand-boot)

petalinux-build
# Ignore any errors about image.ub not being correctly aligned, it will not be used.
petalinux-package --boot --uboot --kernel --dtb --fsbl --format MCS --fpga --force
bootgen -arch zynq -image images/linux/bootgen/bif -w -o images/linux/BOOT.BIN

Now, insert an SD card into the computer and format it as FAT32 with a size of around 512MiB. Then, copy the required boot files onto the SD card:

sudo cp images/linux/boot.scr /path/to/boot/partition
sudo cp images/linux/BOOT.BIN /path/to/boot/partition
sudo cp images/linux/uImage /path/to/boot/partition
sudo cp images/linux/rootfs.cpio.gz.u-boot /path/to/boot/partition

When the SD card is inserted into the board, it should succesfully load the kernel and init system. The default login is username petalinux.

The system boots

TODO: add more hardware using Vivado

Until this point, the project is very minimal. It can start, but that is about it. Before it can be any useful, more hardware should be added to the bitstream files. This is yet to be done.

TODO: make the rootfs permanent

Petalinux boots into a minimal rootfs, that is loaded into ram. After every shutdown, any stored information is gone. Instead of directly loading the rootfs.cpio.gz.u-boot file, linux should mount another (ext4) partition, containing the petalinux rootfs. This is yet to be done.