FPGA Zero to Hero Vol 5 EBAZ4205 Chronicles #
In my previous blog Link I created a basic Verilog module and used the JTAG to test it. It was great demonstration for testing the board but first I did not fully utilized the powerful Zync FPGA and second I glossed over many details. I will fix that in this blog. As I told you that this board had multiple quirks and need some soldering work to use all the features. I will discuss some of the hardware changes needed to use it to its full potential. Also depending on the seller you might be missing some components and you need to change the software accordingly. In this blog post I will cover only hardware tweaks, FPGA Software to run Linux and Petalinux configuration and compilation to boot up the Linux.
NOTE: My current system configuration is:
- OS: Ubuntu 22.04
- VIVADO Version: Vivado v2024.2 (64-bit)
- PETALINUX Version: Petalinux 2024.2
So if you are using any other version then everything described here might or might not work. Also there are some changes from Petalinux older version to current 2024.2 version. So you might need to different commands if you are using older version .
Hardware #
- Powering the Board:
Powering this board is not as easy as it seems to be as some of the components lik Diode
D24
is missing from most board. If you have this Diode mounted on the board then you can use J4 connector to power the board else you need to use12v
andGND
pins on port markedDATA1
orDATA2
orDATA3
.

- SD Card Boot: By default most boards come with NAND FLash boot config registers. You need to check the Resister R2577 and Resistor R2584. If the resistor R2584 is present and resistor 2577 is not present then the hardware is configured to boot from NAND. You need to remove resistor R2584 and solder it on silkscreen marked with resistor R2577.
The configuration is done using resistors combination and can be checked in schematic as shown below:

Shown above in the schematic is config for NAND, SD and JTAG boot. That is MIO5
that is Multiplexed Input/Output 5
connected to GND
and MIO4
that is Multiplexed Input/Output 4
connected to VCC
. To configure boot from SD Card we need to connect both MIOs
to VCC
.

Vivado HW Description and Synthesis #
From my last blog you already know how to create a new project. We will use it as base for our further development. We need to configure the Xilinx® Integrated PS (Processing System) to use the Ethernet, DRAM and other Peripherals.
Enable Ethernet PHY #
EBAZ4205 uses IP101GA chip as Ehernet PHY. See schematic. In the schematic you can see the Xilinx IO ports that are connected to the PYH. Shown below is part of PHY pins and its connections to Xilinx IO:

Now we will continue to connect the PHY to the Vivado® Ethernet IP in the Xilinx® Vivado® Design Software. Double click on Zynq7 Processing System IP and it should open Re-customize IP following window:

As you can see the Ethernet PHY is connected to EMIO. In Xilinx’s Zynq UltraScale+ devices, EMIO (Extended Multiplexed I/O) refers to a set of I/O pins on the Processing System (PS) that can be routed to the Programmable Logic (PL) for extended peripheral access. EMIO provides a way to connect peripherals to the PS when the number of available MIO pins is insufficient. More Details Link
Now as the ports are routed through EMIO we need to connect them in the constraints file and also create ports both RX & TX from and to IP101GA. To create a port on Vivado block design Right click and Create a port/bus as shown below:

For clock you should define it as Clock for input clock port as shown below:

But there is a catch in the software side that needs to be considered. The catch is GMII interface is has 8 bit wide bus for both RX and TX but the chip IP101GA supports only 4 bit wide RX and TX. So we use only lower 4 bits of the GMII Interface. That means this chip doesnt support full bandwidth of GMII interface: Read more here. To use lower nibble of the port we need to use Slice
and Concat
IP blocks provided by Vivado.
From Ethernet PS IP i.e. ENET0_GMII_TXD[7:0] we need to reduce the number of ports so we use Slice
IP. Right click on the block diagram. Add IP and search for Slice. Configure the IP as shown below:

Similarly for the ENET0_GMII_RXD[7:0] expects 8 bit bus input so we use Concat to make 4 bit RX input into a 8 bit bus as shown below:

Now as I told you this board has some quirks. One of it is the Crystal Occilator for the Ethernet PHY. In some boars the two capacitors are missing and the Zynq PL is used to create the Clock Signal. You can easily create a clock out as described in my previous blog. We need 25 MHz clock for the PHY

Finally the complete design should look something like shown below:

Enable SD card and UART #
To enable SD card and UART we need to select SD0 and UART1 and select the appropriate GPIO Numbers which should match the Hardware connection as described in Schematic.

Enable DDR3 controller #
Select the MT41K128M16 HA-15E Memory part to configure the DRAM

Create a constraints file #
We now need to create the constraints file that maps all the Output and Input soft ports to the real GPIOs on the Zynq Chip. The process was described in my earlier blog. I will just provide the contraints file this time.
# Clocks
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports FCLK_CLK3_0]
set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports CLOCK_OUT]
# Ethernet GMII clocks
set_property -dict {PACKAGE_PIN U14 IOSTANDARD LVCMOS33} [get_ports ENET0_GMII_RX_CLK_0]
set_property -dict {PACKAGE_PIN U15 IOSTANDARD LVCMOS33} [get_ports ENET0_GMII_TX_CLK_0]
# Ethernet GMII RX data[3:0]
set_property -dict {PACKAGE_PIN Y17 IOSTANDARD LVCMOS33} [get_ports {enet0_gmii_rxd[3]}]
set_property -dict {PACKAGE_PIN V17 IOSTANDARD LVCMOS33} [get_ports {enet0_gmii_rxd[2]}]
set_property -dict {PACKAGE_PIN V16 IOSTANDARD LVCMOS33} [get_ports {enet0_gmii_rxd[1]}]
set_property -dict {PACKAGE_PIN Y16 IOSTANDARD LVCMOS33} [get_ports {enet0_gmii_rxd[0]}]
# Ethernet GMII RX_DV
set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports ENET0_GMII_RX_DV_0]
# Ethernet GMII TX enable + data[3:0]
set_property -dict {PACKAGE_PIN W19 IOSTANDARD LVCMOS33} [get_ports ENET0_GMII_TX_EN_0]
set_property -dict {PACKAGE_PIN Y19 IOSTANDARD LVCMOS33} [get_ports {enet0_gmii_txd[3]}]
set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports {enet0_gmii_txd[2]}]
set_property -dict {PACKAGE_PIN Y18 IOSTANDARD LVCMOS33} [get_ports {enet0_gmii_txd[1]}]
set_property -dict {PACKAGE_PIN W18 IOSTANDARD LVCMOS33} [get_ports {enet0_gmii_txd[0]}]
# MDIO interface
set_property -dict {PACKAGE_PIN W15 IOSTANDARD LVCMOS33} [get_ports MDIO_ETHERNET_0_0_mdc]
set_property -dict {PACKAGE_PIN Y14 IOSTANDARD LVCMOS33} [get_ports MDIO_ETHERNET_0_0_mdio_io]
# LEDs
set_property -dict {PACKAGE_PIN W13 IOSTANDARD LVCMOS33} [get_ports {LED[1]}]
set_property -dict {PACKAGE_PIN W14 IOSTANDARD LVCMOS33} [get_ports {LED[0]}]
With this we are ready for our Petalinux build just Run Synthesis , Run Implemention and Generate Bitstream.
Go to File -> Export -> Export Hardware -> Include bitstream.
This will generate design file with .xsa extension that Petalinux can use to configure the Device Tree
Petalinux configuration and Compilation #
Once we have the design we can use it to configure the Petalinux.
Installing Petalinux #
Here is the complete guide to install Petalinux by Xilinx with troubleshooting Link
Once you have installed Petalinux you can source the toolchain setting script from the folder using following command considering you installed it in your HOME folder under /xilinx/petalinux
source ~/xilinx/petalinux/setting.sh
This should have following output on terminal
PetaLinux environment set to '/home/phnx/xilinx/petalinux'
[WARNING] This is not a supported OS
[INFO] Checking free disk space
[INFO] Checking installed tools
[INFO] Checking installed development libraries
[INFO] Checking network and other services
[WARNING] No tftp server found - please refer to "UG1144 2024.2 PetaLinux Tools Documentation Reference Guide" for its impact and solution
Creating a New Project #
A new petalinux project for Zynq series of FPGA can be created using following command on terminal
petalinux-create -t project --name ebaz4205 --template zynq
This should show following output on terminal:
[INFO] Create project: ebaz4205
[INFO] New project successfully created in /home/phnx/projects/petalinux/ebaz4205
Configuring Project with Design file for first time #
Use following command to configure the Petalinux project for the first time.
cd ebaz4205
petalinux-config --get-hw-description=/home/YOUR_USERNAME/ebaz4205
Note: The path is where you exported the .xsa file. I have created the project in my ~/ebaz4205 folder in my HOME folder path.
In my case I run
petalinux-config --get-hw-description=/home/phnx/ebaz4205
This should open a configuration menuconfig window like shown below:

Now we need to configure a very important parameter in u-boot Configuration. As we have only 256 MB of DDR RAM we need to configure our u-boot such that it search for the Linux Kernel Image within this RAM space but by default its set to way higher the RAM address. You can set a lower RAM address by setting following config::
u-boot Configuration --->
u-boot script configuration --->
JTAG/DDR image offsets --->
(0x10000000) Fit image offset
As you can see it is currently set to way above 256 MB address space. We need to set it to 0x06000000
. <Select>
the (0x10000000) Fit image offset
and Se it to (0x06000000) Fit image offset
. After the change it should look like this:
u-boot Configuration --->
u-boot script configuration --->
JTAG/DDR image offsets --->
(0x100000) Devicetree offset
(0x200000) Kernel offset
(0x4000000) Ramdisk image offset
(0x6000000) Fit image offset
(0x3000000) Boot script offset
Another configuration that we need to change at this point is Image Packaging Configuration ---> Root filesystem type
This need to be changed to SD Card
Image Packaging Configuration --->
Root filesystem type (INITRAMFS) --->
( ) INITRAMFS
( ) INITRD
( ) UBI/UBIFS
( ) NFS
(X) EXT4 (SD/eMMC/SATA/USB)
( ) other
Configuring the u-boot #
This is the first component that you need to run a linux embedded system. It is a bootloader that is used to load the Linux kernel.
To configure the u-boot bootloader we need to run following
petalinux-config -c u-boot
But it seems there is a bug in the build system for verisons Petalinux 2024.1 that I am using and the configuration fails at parsing the device tree system.dtsi* file. This might lead to failed build like shown below:
petalinux-config -c u-boot
[INFO] Bitbake is not available, some functionality may be reduced.
[INFO] Using HW file: /home/phnx/projects/petalinux/ebaz4205/project-spec/hw-description/system.xsa
[INFO] Getting Platform info from HW file
[INFO] Silentconfig project
[INFO] Silentconfig rootfs
[INFO] Generating configuration files
[INFO] Generating workspace directory
NOTE: Starting bitbake server...
...
...
ERROR: device-tree-xilinx-v2024.2+git-r0 do_compile: Error executing a python function in exec_func_python() autogenerated:
...
File: 'exec_func_python() autogenerated', lineno: 2, function: <module>
0001:
*** 0002:devicetree_do_compile(d)
...
...
0573: return CompletedProcess(process.args, retcode, stdout, stderr)
...
...
Subprocess output:
Error: /home/phnx/projects/petalinux/ebaz4205/components/plnx_workspace/device-tree/device-tree/system-conf.dtsi:25.1-12 Label or path ps7_nand_0 not found
FATAL ERROR: Syntax error parsing input tree
ERROR: Logfile of failure stored in: /home/phnx/projects/petalinux/ebaz4205/build/tmp/work/
...
NOTE: Tasks Summary: Attempted 945 tasks of which 889 didn't need to be rerun and 1 failed.
Summary: 1 task failed:
/home/phnx/projects/petalinux/ebaz4205/components/yocto/layers/meta-xilinx/meta-xilinx-core/recipes-bsp/device-tree/device-tree.bb:do_compile
Summary: There was 1 WARNING message.
Summary: There was 1 ERROR message, returning a non-zero exit code.
[ERROR] Command bitbake virtual/bootloader -c menuconfig failed
To fix it we need to rename the &ps7_nand_0
to &nfc0
or if you dont need the nand controller just remove it out completly the complete &ps7_nand_0
block as shown below
vim /home/phnx/projects/petalinux/ebaz4205/components/plnx_workspace/device-tree/device-tree/system-conf.dtsi
&ps7_nand_0 {
nand@0 {
partition@0 {
label = "nand-boot";
reg = <0x0 0x00000000 0x00500000>;
};
partition@1 {
label = "nand-kernel";
reg = <0x0 0x00500000 0x00a80000>;
};
partition@2 {
label = "nand-bootenv";
reg = <0x0 0x00f80000 0x00020000>;
};
};
};
Change it to by changing ps7_nand_0
to nfc0
as shown below:
&nfc0{
nand@0 {
partition@0 {
label = "nand-boot";
reg = <0x0 0x00000000 0x00500000>;
};
partition@1 {
label = "nand-kernel";
reg = <0x0 0x00500000 0x00a80000>;
};
partition@2 {
label = "nand-bootenv";
reg = <0x0 0x00f80000 0x00020000>;
};
};
};
And Re-run
petalinux-config -c u-boot
After this fix you should see this menuconfig window
Note: IF you still dont see the window then check this Technical FAQs

One thing we need to update is boot option and boot media.
<Select>
the following path
Boot options --->
Boot media --->
[*] Support for booting from NAND flash
[*] Support for booting from SD/EMMC
and once both items are selected <Exit>
all menu till you see
then press
<Yes>
to save the new configuration.
If you dont want specific Linux config or some rootfs packages. Now we can build the u-boot kernel and rootfs using following command
petalinux-build
We need to package all into a boot BOOT.bin image file. The BOOT.BIN file typically includes the First Stage Boot Loader (FSBL), Platform Management Unit (PMU) firmware, Trusted Firmware (TF-A), and the Second Stage Boot Loader (U-Boot). Run this on the shell to generate the file:
petalinux-package boot --force --fsbl ./images/linux/zynq_fsbl.elf --fpga ./project-spec/hw-description/ebaz4205_wrapper.bit
Petalinux has powerful suit of commands and I have just scrached the surface. You can learn more here Link
If the build succeed without any errors you can see all the gnerated files in PROJECT_PATH/images/linux
folder
phnx@phnx:~/projects/petalinux/ebaz4205/images/linux$ ls
boot.scr pxelinux.cfg rootfs.cpio.gz.u-boot rootfs.qemuboot.conf rootfs.testdata.json u-boot.bin u-boot.elf zImage
config rootfs.cpio rootfs.ext4 rootfs.spdx.tar.zst system.bit u-boot-dtb.bin uImage zynq_fsbl.elf
image.ub rootfs.cpio.gz rootfs.manifest rootfs.tar.gz system.dtb u-boot-dtb.elf vmlinux
Partion the SD Card #
We need two partition in the SD Card to run the Petalinux succesfully.
Now how to partition a SD Card is also a few step process and described beautifully in Xilinx documentation in this Link
Once you have partitioned the SD card we need to transfer the boot.scr,BOOT.bin, system.dtb and image.ub to the boot partition.
cd to this mount point in your system via shell. Copy the rootfs.tar.gz compressed rootfile system to the other partition using cp
command this (need root access):
sudo cp ~projects/petalinux/ebaz4205/images/linux/rootfs.tar.gz .
sync
In the shell just run the following command to decompress and unzip the rootfile system. It need root access too.
sudo tar -xvpf rootfs.tar.gz
sync
Remove the SD card and insert into the board.
Serial Kernel Boot Log #
Connect a Serial-2-USB converter to log the boot process. I use Cp2102 based cheap 3 bucks USB to TTL converter shown below:
Please make sure it works at 3.3v TTL as higher level like 5v will destroy the GPIO. And DO NOT USE RS232 USB coverters.
Connect RXD
on the converter to TX
on the board and TXD
on converter to RX
on the board. Also connect the ground GND
together.
Go to the shell on computer and find out where it is attached on the /dev/
folder. You can check it with sudo dmesg
and it should show up like this on the logs (mine is attached on ttyUSB0):
[19128.317021] usb 1-5: SerialNumber: 0001
[19128.326421] cp210x 1-5:1.0: cp210x converter detected
[19128.327354] usb 1-5: cp210x converter now attached to ttyUSB0
Install minicom
using sudo apt-get install minicom
and run following command:
minicom -D /dev/ttyUSB0
Connect to the power supply as described before. And If all steps were successful there should be a boot log like one shown below:
U-Boot 2024.01 (Oct 24 2024 - 10:42:51 +0000)
CPU: Zynq 7z010
Silicon: v3.1
DRAM: ECC disabled 256 MiB
Core: 19 devices, 14 uclasses, devicetree: board
Flash: 0 Bytes
NAND: 0 MiB
MMC: mmc@e0100000: 0
U-Boot 2024.01 (Oct 24 2024 - 10:42:51 +0000)
CPU: Zynq 7z010
Silicon: v3.1
DRAM: ECC disabled 256 MiB
Core: 19 devices, 14 uclasses, devicetree: board
Flash: 0 Bytes
NAND: 0 MiB
MMC: mmc@e0100000: 0
In: serial@e0001000
Out: serial@e0001000
Err: serial@e0001000
Net:
ZYNQ GEM: e000b000, mdio bus e000b000, phyaddr 0, interface gmii
eth0: ethernet@e000b000
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
3830 bytes read in 19 ms (196.3 KiB/s)
## Executing script at 03000000
Trying to load boot images from mmc0
4919919 bytes read in 435 ms (10.8 MiB/s)
## Loading kernel from FIT Image at 06000000 ...
...
...
Starting kernel ...
Log in using username as petalinux and it should prompt you to create a new password. And we have succesfully booted a Linux kernel on a EBAZ4205 board. I will continiue our journey in my later blog post where I will access the SPI Peripheral that I created in my earlier blog from within the running Petalinux system