In this tutorial, we will take the design from the last tutorial and built on top of it by adding an Embedded OS to the PS side to handle data transfer between Host Machine and Zybo board in order to have our MicroBlaze-V have access to large amounts of data very quickly, before we were bottlenecked by the slow speeds of JTAG to transfer Data to DDR. We will take advantage of the out of the box network drivers on PetaLinux to transfer the data.
Note: This tutorial uses elements from the other tutorials on my account page
RequirementsWe will need to have the following to install PetaLinux on our board
- PetaLinux (Match Vivado Install, e.g. 2025.2)
- Linux Machine – Ubuntu 20.04 is recommended (Can use VM or WSL if on Windows)
- MicroSD Card (Formatted with FAT32 + EXT4)
First, we need to reconfigure our design to include Ethernet Port and the SD card port on the PS side, we can configure this by double clicking the Zynq IP and entering Peripheral I/O Pins. Ensure MDIO under Ethernet is also selected.
Once that is done, regenerate the bitstream and export the hardware to get our new XSA File. We can now move on to Linux Development.
Linux DevelopmentI will be using WSL with Ubuntu 20.04 for this tutorial; a Linux machine of some kind is required to build the Linux kernel. You can install PetaLinux here, scroll down till you find the PetaLinux Installer. Before installing PetaLinux, ensure you have all the dependencies required.
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install -y build-essential gcc g++ xterm autoconf libtool texinfo zlib1g-dev gcc-multilib libncurses5-dev libncursesw5-dev zlib1g:i386Once that’s done, you can install PetaLinux by running the following commands
chmod +x petalinux-v2025.2-11160223-installer.run
./petalinux-v2025.2-11160223-installer.runOnce PetaLinux is installed, we want to run a script that will give us some PetaLinux commands we can use. (Note name of PetaLinux folder might be different depending on what you called it).
source /petalinux/settings.shWe now what to create the project :
petalinux-create --type project --template zynq --name zybo_petalinux_buildSystem ConfigurationWe now want to take our xsa file we generated in Vivado and copy this to our new project directory, once its copied over, we start configuring the build
petalinux-config --get-hw-description .When this command is run, it will open a configuration menu in your terminal, where you can configure the system, here we can check If Hardware settings are set up correctly, they should be all okay by default. One setting to disable would be the ‘Copy final images to tftpboot’ as we won’t be using that.
We also want to ensure that we are using a static IP when the board connects
So go into the Ethernet settings to set up the IP, here are my settings that you can copy, ensure that the host machine is set up in the same sub net.
Once we are happy with that, we can exit the system config and me setting up the kernel configuration.
Kernel Configurationpetalinux-config -c kernelThis will open a separate window where we can mess with the kernal, we won’t be changing anything in this menu but still have to run the command. Ensure ‘network support is marked with an ‘*’.
We run the following command to set up our boot files to run off an SD-Card
petalinux-config -c u-bootThis will open a similar window to before, where from here we want to go into ‘Boot Options -> Boot media’ and configure boot support for SD Cards.
Once this is enabled, we can save Uboot configuration.
The final Configuration we must set up our root files, here we will install extra programs such as python and the ‘packagegroup-core-buildessential’ so we can build and run c and python programs, to enter the config, simply type
petalinux-config -c rootfsFrom here we can navigate to ‘File System Packages -> misc’ and scroll down till we find what we need, select all the packages you might need.
Note: ensure that ssh-server-OpenSSH is enabled in the ‘Image Features’ section as we will be using this to control Petalinux from our host machine and to transfer data.
The final step of the configuration is setting up the device tree that tells the kernel how our hardware is set up, here we will configure the Ethernet port as well as reserve memory for the MicroBlaze-V that PetaLinux can’t touch by default.
Here is the config file named ‘system-user.dtsi’ located in ‘/zybo_petalinux_build/project-spec/meta-user/recipes-bsp/device-tree/files’
/include/ "system-conf.dtsi"
/ {
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
mb_v_memory: buffer@10000000 {
no-map;
reg = <0x10000000 0x10000000>;
};
};
reserved-driver@0 {
compatible = "xlnx,reserved-memory";
memory-region = <&mb_v_memory>;
};
};
&gem0 {
status = "okay";
phy-mode = "rgmii-id";
phy-handle = <ðernet_phy>;
mdio {
#address-cells = <1>;
#size-cells = <0>;
ethernet_phy: ethernet-phy@1 {
reg = <1>;
device_type = "ethernet-phy";
compatible = "ethernet-phy-id001c.c915";
};
};
};From here we can now build the image using the command:
petalinux-buildThis will take quite some time (12 hours +), so dedicate a time for this process, rebuilds will only take a few minutes if changes need to be made.
Sd Card FormatYour MicroSD Card will need to be formatted the following way:
The first Partition will contain your boot files (BOOT.BIN image.ub boot.scr) and the second Partition will be your root files (rootfs.tar.gz)
To partition your card, you will need Linux, as Windows does not support ext4 formats, I used a tool called gparted live that can be loaded on to a USB and ran from there
Once the build process is complete, you can prepare your boot files, to do this we run the following:
This will package the boot files and have them ready to run on our board. As mentioned in the last part, we will transfer BOOT.BIN, image.ub and boot.scr to Parition 0 and the rootfs.tar.gz to Parition 1, rootfs.tar.gz will have to be extracted (sudo tar -xvf root.tar.gz)
Once that is done, we can insert the Sd card into the zybo board and changing the jumper to be on SD instead of JTAG. Open up a terminal in Putty and you should be able to see PetaLinux booting up
You will then be prompted to login, you have to use the username ‘petalinux’, you will then be asked to create a password.
Once logged in, we can check to see if our ethernet port is up by using ifconifg and pinging the IP Address on our host machine. Ensure it is plugged in via ethernet and set up on the same subnet.
ping 192.168.1.10
Pinging 192.168.1.10 with 32 bytes of data:
Reply from 192.168.1.10: bytes=32 time<1ms TTL=64
Reply from 192.168.1.10: bytes=32 time<1ms TTL=64
Reply from 192.168.1.10: bytes=32 time<1ms TTL=64
Reply from 192.168.1.10: bytes=32 time<1ms TTL=64
Ping statistics for 192.168.1.10:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0msWe can see that the interface is up, Note: if it says the link is down or there is no IPv4 address, then you may have to manually bring it up, there is plenty of tutorials online on how to do that.
Now that we have our PetaLinux set up, we can move onto the software development section
Software DevelopmentWith the Network interface set up, we should now be able to SSH into the Zybo board. The login credentials we will be used that were created earlier. To transfer the input.bin file to the Zybo board, we will use the SCP protocol build into the ssh client application. One thing to note is that if we want to set up an automated script, we must set up ssh key authentication so the password log in can be skipped, to do this we do the following steps: Note: The host machine in this case is running windows. IP of Zybo board may be different also.
On your host machine, generate an SSH key pair:
ssh-keygen -t rsa -b 4096This will create the two files, a private and public key, the public key will go the Zybo Board. Copy the public key over:
type $env:USERPROFILE\.ssh\id_rsa.pub | ssh petalinux@192.168.1.10 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"Next, we will ssh into the Zybo Board and run the following commands to set the permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keysNow we can log in without setting a password.
When the input file is on the Zybo board, we now need a way to transfer the data to DDR, I found the easiest way to do this was to use a python script to do this:
import mmap
import os
MEM_ADDR = 0x10000000
FILE_PATH = "input.bin"
def load_to_ddr(file_path, target_addr):
if not os.path.exists(file_path):
print(f"Error: {file_path} not found.")
return
file_size = os.path.getsize(file_path)
print(f"Input file size: {file_size} bytes")
fd = os.open("/dev/mem", os.O_RDWR | os.O_SYNC)
try:
mem = mmap.mmap(fd, file_size, flags=mmap.MAP_SHARED,
prot=mmap.PROT_READ | mmap.PROT_WRITE,
offset=target_addr)
with open(file_path, "rb") as f:
data = f.read()
mem.write(data)
print(f"SUCCESS: Loaded {file_size} bytes to physical address {hex(target_addr)}")
finally:
mem.close()
os.close(fd)
if __name__ == "__main__":
load_to_ddr(FILE_PATH, MEM_ADDR)This script is run with sudo, so to get this to run, we must allow the petalinux user to enter sudo without a password. To do this we go into /etc/sudoers and add this line to end of the file:
petalinux ALL=(ALL) NOPASSWD: ALLNext, we will change the TCL script to no longer transfer the message via JTAG, since this is being done via Linux. We change the flash_and _run.tcl file we made in the last tutorial to this:
set mb_elf_path "C:/Path/to/Vitis/Project/SHA256Project/Sha256/build/Sha256.elf"
catch {connect}
targets -set -filter {name =~ "Hart*"}
rst -processor
dow $mb_elf_path
conWith all our scripts made, we can combine them into one script that can be run from the host machine:
import subprocess
import sys
# Config
BOARD_IP = "192.168.1.10"
TARGET = f"petalinux@{BOARD_IP}"
try:
xsdb_process = subprocess.Popen(
["xsdb"],
stdin=subprocess.PIPE,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
text=True,
shell=True
)
xsdb_process.stdin.write("connect\n")
print("Prepping data...")
subprocess.run(["python.exe", "prep_data.py"], check=True)
print("Transferring input.bin...")
subprocess.run(["scp", "./input.bin", f"{TARGET}:/home/petalinux"], check=True)
print("Executing remote script...")
subprocess.run(["ssh", TARGET, "sudo python3 /home/petalinux/send_data_ddr.py"], check=True)
print("Flashing elf to MicroBlaze-V...")
xsdb_process.communicate("source flash_and_run.tcl\nexit\n")
print("XSDB closed.")
except subprocess.CalledProcessError as e:
print(f"\nError during step: {e.cmd}")
sys.exit(1)When we run this script, we should get the same output as from the last tutorial:









Comments