7 minutes
WIP: Building a PetaLinux image for the EBAZ4205 board
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.
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”.
At the next screen, click “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.
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.
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.
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:
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.
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).
Loop the FPGA clock output to the clock input of the processor.
Then, run the block automation.
After the diagram design is complete, right click the design source and select “Create HDL wrapper”.
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
.
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.