Skip to content

Commit

Permalink
xilzcu102-boot-from-jtag: rebased to v0.2.0
Browse files Browse the repository at this point in the history
Changelog:
- Fixed #94
- Fixed !186
- Moved remaining `tools` content to `util` folder
- Update boog_jtag.sh. Added `NO_IIS` environment option
- Update reset_jtag.sh. Added `NO_IIS` environment option
- Fix after code review (!186)
- Fixed boot with NFS Rootfs and DHCP
- Fixed major issue on buildroot network configuration in case of usage of NFS rootfs and DHCP.
- Fixed also minor problem related to local.cfg file parsing. Petalinux build was not able to skip commented (\#) configurations.
- Fix #114
- Fixed petalinux script for booting in different configurations (SD and
JTAG mainly
  • Loading branch information
Alessandro Capotondi committed Jun 21, 2023
1 parent 57d1129 commit 48cfb9b
Show file tree
Hide file tree
Showing 9 changed files with 425 additions and 9 deletions.
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

0 comments on commit 48cfb9b

Please sign in to comment.