Skip to content
This repository was archived by the owner on Nov 28, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Config.in
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,23 @@ config BR2_HERO_EXT_MOUNT
Binds system to the filesystem. Options can be specified
before (with -o) as the options are completely forwarded to
mount. Leave empty to not mount external partition.

config BR2_HERO_ETH_IP_ADDR
string "Optional static IP address for the Host"
help
Static IP address. Leave empty to use DHCP.

config BR2_HERO_ETH_NETMASK
string "Optional static IP netmask"
help
Static netmask. Only considered when static IP address is set.

config BR2_HERO_ETH_GATEWAY
string "Optional static IP gateway"
help
Static gateway. Only considered when static IP address is set.

config BR2_HERO_ETH_DNS
string "Optional static IP DNS"
help
Static DNS server. Only considered when static IP address is set.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,10 @@ insmod /run/media/mmcblk0p2/lib/modules/4.19.0/extra/pulp.ko
```
after every reboot. The kernel messages on the serial terminal will inform you about the outcome (it should end with `PULP: Device registered.` if successful).

Finally, to develop applications for this setup, initialize the environment on your development workstation with `source env/exilzcu102.sh`. Afterwards applications can be built with the provided `Makefile`s and transferred to the board with `scp`.
Users can enable NFS-based RootFS by configuring in `local.cfg` the following variables: `PT_NFSSERVER_IP="<server_ip>"`, `PT_ROOTFS_NFS="y"`, `PT_NFSROOT_DIR="</path/to/nfs/rootfs>"`. The configurations will be propagated in the Petalinux build process, thus such variables must be set before the `make br-har-exilzcu102` command execution.
Additional information about IP configuration, and about to how to boot Linux without SD card (using JTAG) can be found [here](doc/BootZCU102WithoutSDCard.md).

To develop applications for this setup, initialize the environment on your development workstation with `source env/exilzcu102.sh`. Afterwards applications can be built with the provided `Makefile`s and transferred to the board with `scp` or using NFS.

##### QEMU RISC-V

Expand Down
6 changes: 5 additions & 1 deletion board/common/overlay/etc/network/interfaces
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@ auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
iface eth0 inet dhcp
pre-up /etc/network/nfs_check
wait-delay 15
hostname $(hostname)

37 changes: 37 additions & 0 deletions board/common/post_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,40 @@ if [ ! -z "$AUTH_KEYS" ]; then
mkdir -p ${TARGET_DIR}/root/.ssh/
cp $AUTH_KEYS ${TARGET_DIR}/root/.ssh/authorized_keys
fi

echo "Setup Networking ${BR2_CONFIG}"
IP_ADDR=$(grep BR2_HERO_ETH_IP_ADDR ${BR2_CONFIG} | sed -e 's/.*=//' -e 's/^"//' -e 's/"$//')
if [ ! -z "$IP_ADDR" ]; then
IP_NETMASK=$(grep BR2_HERO_ETH_NETMASK ${BR2_CONFIG} | sed -e 's/.*=//' -e 's/^"//' -e 's/"$//')
IP_GATEWAY=$(grep BR2_HERO_ETH_GATEWAY ${BR2_CONFIG} | sed -e 's/.*=//' -e 's/^"//' -e 's/"$//')
IP_DNS=$(grep BR2_HERO_ETH_DNS ${BR2_CONFIG} | sed -e 's/.*=//' -e 's/^"//' -e 's/"$//')

echo " IP........$IP_ADDR"
echo " Netmask...$IP_NETMASK"
echo " Gateway...$IP_GATEWAY"
echo " DNS.......$IP_DNS"

rm -rf ${TARGET_DIR}/etc/network/interfaces
echo "
# configure eth0 with static IP
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address $IP_ADDR
netmask $IP_NETMASK
gateway $IP_GATEWAY
pre-up /etc/network/nfs_check
wait-delay 15
hostname $(hostname)

" > ${TARGET_DIR}/etc/network/interfaces

rm -rf ${TARGET_DIR}/etc/resolv.conf
echo "nameserver $IP_DNS" > ${TARGET_DIR}/etc/resolv.conf

else
echo " IP........DHCP"
fi

119 changes: 119 additions & 0 deletions doc/BootZCU102WithoutSDCard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# HERO Boot from JTAG+TFTPBOOT+NFS (w/o SDCard)

## Intro
This tutorial shows how to boot the HERO ecosystem on the ZCU102 instance without the usage of SDCard. JTAG will be used to boot FSBL and U-Boot. Linux kernel, which is quite bigger, is loaded through TFTP, while RootFS is exported using NFS. This tutorial will use also static IP for the HERO board.

## 1. Prerequisite
### 1.1. Setup JTAG Boot
Setup the switch on the ZCU102 for JTAG boot (See [https://www.xilinx.com/support/answers/68682.html](https://www.xilinx.com/support/answers/68682.html)).


### 1.2. Setup TFTPBOOT and NFS Server
First, you need to set up your TFT and NFS server. If you have already a TFTP and NFS server installed you can skip this pass.
#### 1.2.1 Install TFTPBOOT and NFS Server packages (Ubuntu)
```
sudo apt update
sudo apt install -y tftpd-hpa nfs-kernel-server
```

#### 1.2.2 Setup NFS Folder
Edit the file `/etc/exports` adding the following line to export an NFS folder (i.e. `/opt/hero/rootfs`) to the HERO board:
```
/opt/hero/rootfs <hero_ip>(rw,nohide,insecure,no_subtree_check,async,no_root_squash)

```
After the file modification, you should execute the command `sudo exportfs -ra` to activate the new configuration.

#### 1.2.3. Setup TFTP Folder
By default, the tftpboot shared folder is located at `/var/lib/tftpboot`. You can select another folder changing in the file `/etc/default/tftpd-hpa` the value of `TFTP_DIRECTORY` (i.e. `TFTP_DIRECTORY="/opt/tftpboot"`). You need also to setup the `--create` to `TFTP_OPTIONS`.

Here an example of `/etc/default/tftpd-hpa`:
```
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/opt/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure --create"
```

Then we create the target folder for HERO and we restart the service to update the configuration.
```
sudo mkdir -p /opt/tftpboot
sudo chown root:nogroup /opt/tftpboot
sudo chmod 777 /opt/tftpboot
sudo systemctl restart tftpd-hpa
```
## 2. Setup and Build Custom Configuration of HERO
### 2.1 Setup custom local.cfg
You should modify the `local.cfg` as follow:
```
#
# Buildroot Custom Configurations
#
BR2_HERO_BITSTREAM="<path/to/hero/bistream.bit>"
BR2_HERO_ETH_IP_ADDR="<hero_ip>"
BR2_HERO_ETH_NETMASK="<netmask>"
BR2_HERO_ETH_GATEWAY="<gateway_ip>"
BR2_HERO_ETH_DNS="<dnsserver_ip>"

#
# Petalinux Custom Configurations
#
PT_NFSSERVER_IP="<server_ip>"
PT_ROOTFS_NFS="y"
PT_NFSROOT_DIR="/opt/rootfs"
PT_TFTPBOOT_DIR="/opt/tftpboot"
```
All the `BR2_HERO_ETH_*` values are optional in case you want to use DHCP.

### 2.2 Build HERO Environment
In case it is your first build you can build all you need using the following command:
```
make har-exilzcu102
```

Otherwise, if you had already built all toolchain and the auxiliary environment, you can execute the following command to re-build only the Linux Kernel and the RootFS:
```
make br-har-exilzcu102
```

After the build you need to install the generated files into the NFS and TFTP shared folders:
```
cp output/br-har-exilzcu102/images/Image $PT_TFTPBOOT_DIR
cp output/br-har-exilzcu102/images/system.dtb $PT_TFTPBOOT_DIR
tar -xf output/br-har-exilzcu102/images/rootfs.tar -C $PT_NFSROOT_DIR
```

Note, you can automatically install the generated files executing the following command:
```
util/xsdb/install_tftp_nfs_rootfs.sh
```

### 2.3 Boot U-Boot from JTAG
You can boot FSBL and U-Boot using the following Petalinux command:
```
cd petalinux/zcu102
petalinux-boot --jtag --U-Boot --fpga --bitstream <path/to/hero-bistream.bit> -v --hw_server-url <hwserver_ip>:<hwserver_port>
```
Or you can use the following command:
```
util/xsdb/boot_jtag.sh -i <hwserver_ip> -p <hwserver_port>
```

The boot process takes around 5 minutes. After that, you can access to the U-Boot prompt connecting to the UART port of the board.


### 2.4 Setting U-Boot Bootargs and Boot Linux Kernel (Finally!)
From the U-Boot prompt you need to fix the `bootargs` (due to some problem of petalinux to generate a correct configuration). Here the comand you should execute inside the prompt of U-Boot (adjust with your local configuration):
```
setenv tftpblocksize 512
setenv bootargs console=ttyPS0,115200n8 earlycon clk_ignore_unused ip=<hero_ip>:<server_ip>:<gateway_ip>:<netmask>::eth0:off root=/dev/nfs rootfstype=nfs nfsroot=<server_ip>:/opt/hero/rootfs,tcp,nolock,nfsvers=3 rw
```

Now you are able to boot Linux triggering the following list of commands inside the U-Boot prompt:
```
tftpb 0x200000 Image
tftpb 0x7000000 system.dtb
booti 0x200000 - 0x7000000 ${bootargs}
```
82 changes: 75 additions & 7 deletions petalinux/zcu102.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ python3.6 -m venv .venv
ln -sf python3.6 .venv/bin/python3
source .venv/bin/activate

# Read Petalinux name
if [ -n "$NO_IIS" ]; then
PETALINUX_VER=''
else
Expand Down Expand Up @@ -58,19 +59,86 @@ cd linux-xlnx
git checkout tags/xilinx-v2019.2.01

cd ../../../
sed -i 's|CONFIG_SUBSYSTEM_COMPONENT_LINUX__KERNEL_NAME_LINUX__XLNX||' project-spec/configs/config
sed -i 's|CONFIG_SUBSYSTEM_ROOTFS_INITRAMFS||' project-spec/configs/config
echo 'CONFIG_SUBSYSTEM_ROOTFS_SD=y' >> project-spec/configs/config
sed -i 's|CONFIG_SUBSYSTEM_COMPONENT_LINUX__KERNEL_NAME_LINUX__XLNX.*||' project-spec/configs/config
echo 'CONFIG_SUBSYSTEM_COMPONENT_LINUX__KERNEL_NAME_EXT__LOCAL__SRC=y' >> project-spec/configs/config
echo 'CONFIG_SUBSYSTEM_COMPONENT_LINUX__KERNEL_NAME_EXT_LOCAL_SRC_PATH="${TOPDIR}/../components/ext_sources/linux-xlnx"' >> project-spec/configs/config
echo 'CONFIG_SUBSYSTEM_SDROOT_DEV="/dev/mmcblk0p2"' >> project-spec/configs/config
sed -i 's|CONFIG_SUBSYSTEM_MACHINE_NAME.*||' project-spec/configs/config
echo 'CONFIG_SUBSYSTEM_MACHINE_NAME="zcu102-revb"' >> project-spec/configs/config

if [ -f "$LOCAL_CFG" ] && grep -q PT_ETH_MAC "$LOCAL_CFG"; then
sed -e 's/PT_ETH_MAC/CONFIG_SUBSYSTEM_ETHERNET_PSU_ETHERNET_3_MAC/;t;d' "$LOCAL_CFG" >> project-spec/configs/config
# Cleanup All RootFS Options
sed -i 's|CONFIG_SUBSYSTEM_ROOTFS_INITRAMFS.*||' project-spec/configs/config
sed -i 's|CONFIG_SUBSYSTEM_ROOTFS_INITRD.*||' project-spec/configs/config
sed -i 's|CONFIG_SUBSYSTEM_ROOTFS_JFFS2.*||' project-spec/configs/config
sed -i 's|CONFIG_SUBSYSTEM_ROOTFS_JFFS2.*||' project-spec/configs/config
sed -i 's|CONFIG_SUBSYSTEM_ROOTFS_NFS.*||' project-spec/configs/config
sed -i 's|CONFIG_SUBSYSTEM_ROOTFS_OTHER.*||' project-spec/configs/config

# Select RootFS Option (Default: SD_CARD)
nfsrootfs="$("$HERO_ROOT/util/configfile/get_value" -s "$LOCAL_CFG" PT_ROOTFS_NFS \
| tr -d '"')";
if ! [[ $nfsrootfs == "y" ]]; then
# SD-CARD
echo 'CONFIG_SUBSYSTEM_ROOTFS_SD=y' >> project-spec/configs/config
echo 'CONFIG_SUBSYSTEM_SDROOT_DEV="/dev/mmcblk0p2"' >> project-spec/configs/config
else
# NFS ROOTFS
nfsrootdir="$("$HERO_ROOT/util/configfile/get_value" -s "$LOCAL_CFG" PT_NFSROOT_DIR)";
if [ -z $nfsrootdir ]; then
>&2 echo "Error: PT_NFSROOT_DIR is not defined in '$LOCAL_CFG'!"
exit 1
fi
nfsserverip="$("$HERO_ROOT/util/configfile/get_value" -s "$LOCAL_CFG" PT_NFSSERVER_IP \
| tr -d '"')";
if [ -z $nfsserverip ]; then
>&2 echo "Error: PT_NFSSERVER_IP is not defined in '$LOCAL_CFG'!"
exit 1
fi
set -e
echo "CONFIG_SUBSYSTEM_ROOTFS_NFS=$nfsrootfs" >> project-spec/configs/config
echo "CONFIG_SUBSYSTEM_NFSROOT_DIR=$nfsrootdir" >> project-spec/configs/config
echo "CONFIG_SUBSYSTEM_NFSSERVER_IP=$nfsserverip" >> project-spec/configs/config
fi

$PETALINUX_VER petalinux-config --oldconfig --get-hw-description "$HERO_ROOT/hardware/fpga/hero_exil$TARGET/hero_exil$TARGET.sdk"
# Ethernet Settings

# Set MAC address if specified
sed -i 's|CONFIG_SUBSYSTEM_ETHERNET_PSU_ETHERNET_3_MAC.*||' project-spec/configs/config
eth_mac="$("$HERO_ROOT/util/configfile/get_value" -s "$LOCAL_CFG" PT_ETH_MAC \
| tr -d '"')";
if ! [ -n $eth_mac ]; then
echo "CONFIG_SUBSYSTEM_ETHERNET_PSU_ETHERNET_3_MAC=$eth_mac" >> project-spec/configs/config
else
echo "CONFIG_SUBSYSTEM_ETHERNET_PSU_ETHERNET_3_MAC=\"ff:ff:ff:ff:ff:ff\"" >> project-spec/configs/config
fi

# Set IP Configuration
sed -i 's|CONFIG_SUBSYSTEM_ETHERNET_PSU_ETHERNET_3_USE_DHCP=y||' project-spec/configs/config
ip="$("$HERO_ROOT/util/configfile/get_value" -s "$LOCAL_CFG" BR2_HERO_ETH_IP_ADDR \
| tr -d '"')";
if [ -z $ip ]; then
# DHCP
echo 'CONFIG_SUBSYSTEM_ETHERNET_PSU_ETHERNET_3_USE_DHCP=y' >> project-spec/configs/config
else
# Static IP Configuration
echo '# CONFIG_SUBSYSTEM_ETHERNET_PSU_ETHERNET_3_USE_DHCP is not set' >> project-spec/configs/config
set +e
netmask="$("$HERO_ROOT/util/configfile/get_value" -s "$LOCAL_CFG" BR2_HERO_ETH_NETMASK \
| tr -d '"')";
if [ -z $netmask ]; then
>&2 echo "Error: BR2_HERO_ETH_NETMASK is not defined in '$LOCAL_CFG'!"
exit 1
fi
gateway="$("$HERO_ROOT/util/configfile/get_value" -s "$LOCAL_CFG" BR2_HERO_ETH_GATEWAY \
| tr -d '"')";
if [ -z $gateway ]; then
>&2 echo "Error: BR2_HERO_ETH_GATEWAY is not defined in '$LOCAL_CFG'!"
exit 1
fi
set -e
echo "CONFIG_SUBSYSTEM_ETHERNET_PSU_ETHERNET_3_IP_ADDRESS=$ip" >> project-spec/configs/config
echo "CONFIG_SUBSYSTEM_ETHERNET_PSU_ETHERNET_3_IP_NETMASK=$netmask" >> project-spec/configs/config
echo "CONFIG_SUBSYSTEM_ETHERNET_PSU_ETHERNET_3_IP_GATEWAY=$gateway" >> project-spec/configs/config
fi

echo "
/include/ \"system-conf.dtsi\"
Expand Down
61 changes: 61 additions & 0 deletions util/xsdb/boot_jtag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash

this_dir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
hero_root_dir="${this_dir}/../.."

hero_config_file=${hero_root_dir}/local.cfg # HERO Config File
hero_petalinux_dir=${hero_root_dir}/petalinux/zcu102 # HERO Petalinux Folder

usage () {
echo "Usage: $0 [-h | -i <hw_server_ip> | -p <hw_server_port>] -- Boot u-boot from XSDB/JTAG"
echo "Arguments:"
echo " -h Show this help text"
echo " -i <hw_server_ip> Xilinx HW Server IP (default: 127.0.0.1)"
echo " -p <hw_server_port> Xilinx HW Server Port (default: 3121)"
exit 0
}

# HW Server Default Configuration
hw_server_ip=127.0.0.1
hw_server_port=3121

while getopts "hi:p:" option; do
case "$option" in
i) hw_server_ip="$OPTARG" ;;
p) hw_server_port="$OPTARG" ;;
h) # it's always useful to provide some help
usage
exit 0
;;
:) echo "Error: -$OPTARG requires an argument"
usage
exit 1
;;
?) echo "Error: unknown option -$OPTARG"
usage
exit 1
;;
esac
done

if [ -n "$NO_IIS" ]; then
PETALINUX_VER=''
else
if [ -z "$PETALINUX_VER" ]; then
PETALINUX_VER="vitis-2019.2"
fi
fi
readonly PETALINUX_VER

# Boot HERO from JTAG
eval hero_bitstream=$(grep BR2_HERO_BITSTREAM ${hero_config_file} | sed 's/.*=//' | tr -d '"')
if [ -z "${hero_bitstream}" ]; then
echo "ERROR: please set BR2_HERO_BITSTREAM in local.cfg file"
else
cd ${hero_petalinux_dir}
echo "Booting Petalinux project: ${hero_petalinux_dir}"
echo "HW Server: ${hw_server_ip}:${hw_server_port} Bitstream: ${hero_bitstream}"
$PETALINUX_VER petalinux-boot --jtag -v --hw_server-url tcp:${hw_server_ip}:${hw_server_port} --u-boot --fpga --bitstream ${hero_bitstream}
fi

# That's all folks!!
26 changes: 26 additions & 0 deletions util/xsdb/install_tftp_nfs_rootfs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
THIS_DIR=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")

CONFIG_FILE=$THIS_DIR/../../local.cfg
OUTPUT_DIR=$THIS_DIR/../../output

if [ -f ${CONFIG_FILE} ] && grep -q PT_TFTPBOOT_DIR ${CONFIG_FILE}; then
eval TFTPBOOT_DIR=$(grep PT_TFTPBOOT_DIR ${CONFIG_FILE} | sed 's/.*=//' | tr -d '"')
echo "Installing Boot Files: ${OUTPUT_DIR}/br-har-exilzcu102/images/ -> $TFTPBOOT_DIR"
cp ${OUTPUT_DIR}/br-har-exilzcu102/images/Image $TFTPBOOT_DIR
cp ${OUTPUT_DIR}/br-har-exilzcu102/images/system.dtb $TFTPBOOT_DIR
else
echo "Installing Boot Files: SKIPPED (PT_TFTPBOOT_DIR is not set in local.cfg)"
fi

if [ -f ${CONFIG_FILE} ] && grep -q PT_NFSROOT_DIR ${CONFIG_FILE}; then
eval NFSROOT_DIR=$(grep PT_NFSROOT_DIR ${CONFIG_FILE} | sed 's/.*=//' | tr -d '"')
echo "Installing Host RootFS: ${OUTPUT_DIR}/br-har-exilzcu102/images/rootfs.tar -> $NFSROOT_DIR"
tar -xf ${OUTPUT_DIR}/br-har-exilzcu102/images/rootfs.tar -C $NFSROOT_DIR
echo "Installing HERO RootFS: ${OUTPUT_DIR}/har-rootfs.tar -> $NFSROOT_DIR/mnt"
tar -xf ${OUTPUT_DIR}/har-rootfs.tar -C $NFSROOT_DIR/mnt
else
echo "Installing RootFS: SKIPPED (PT_NFSROOT_DIR is not set in local.cfg)"
fi

# That's all folks!!
Loading