Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • secbus secbus
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Renaud Pacalet
  • secbussecbus
  • Wiki
  • zedboard tftp nfs

Last edited by Renaud Pacalet Nov 30, 2018
Page history

zedboard tftp nfs

Running a Debian distribution on the ZedBoard using tftp and NFS

This page explains how to run a regular Debian distribution on the ZedBord with:

  • A minimal boot image on the SD card, containing only the First Stage Boot Loader (FSBL) and U-Boot
  • Loading the kernel image and the device tree blob from a remote tftp server
  • Mounting the root file system from a remote NFS server

This is not specific to SecBus and can be used for any development project on the ZedBoard.

This setup is extremely convenient as it almost completely avoids SD card manipulations. The Linux kernel and its device tree blob can be re-built any time, copied on the tftp server and re-loaded by the ZedBoard through its Ethernet link at the price of a single reboot. The Debian root file system can also be updated from the NFS server (thanks to Qemu and chroot) using the regular Debian tools. The changes are immediately reflected on the ZedBoard and, in most cases, without rebooting.

In the following we assume that:

  • <host> is the hostname of the workstation we will use and to which the UART USB cable of the ZedBoard is attached
  • The Xilinx tool chain is installed on <host> and it is on the PATH
  • <bistream>.bit is the bistream file used to configure the Programmable Logic (PL), if any
  • <server> is the hostname of the remote tftp and NFS server (can be the same as <host>)
  • <server_ip_address> is the IP address of <server>
  • <zedboard_mac_address> is the Ethernet MAC address of the ZedBoard
  • <zedboard_ip_address> is the IP address of the ZedBoard
  • <gateway_ip_address> is the IP address of the gateway through which the ZedBoard connects to <server> (if it connects directly <gateway_ip_address> = <server_ip_address>)
  • <tftproot> is the absolute path on <server> of the root directory of the tftp server
  • <tftproot>/<tftpdir> is the absolute path on <server> of the directory containing the tftp-served files
  • <nfsdir> is the absolute path on <server> of the directory containing the NFS-served file systems
  • We are root on <server> which runs a Debian variant, has access to Internet and has Qemu installed

Note: there are several ways to configure the Programmable Logic (PL). In the following we present three of them:

  • Copy the bitstream somewhere in the NFS share on <server> and send it to the /dev/xdevcfg device after the Linux kernel booted. This method is very convenient because it allows to reconfigure the PL at run time without rebooting. On the other hand, it cannot be used when the PL must be configured before booting the Linux kernel.
  • Let U-Boot download the bitstream from the tftp server and configure the PL. This method is less flexible because the system must be rebooted to change the PL configuration. However, it can be used when the PL must be configured prior booting the Linux kernel.
  • Include the bitstream in the boot image on the SD card and let the First Stage Boot Loader (FSBL) do the job. This method is the less flexible of all because changing the PL configuration not only requires to reboot but also to regenerate the boot image and store it on the SD card. But it is the only one that can be used if U-Boot needs the PL to be already configured when it boots.

Please adapt the following instructions to your own settings.

On <server>, the NFS server, prepare the root file system

Create an empty image for the Debian root file system and mount it

server> cd <nfsdir>
server> dd if=/dev/zero of=debianrootfs4zynq.img bs=1024 count=1MB
server> sudo mkfs.ext3 -F debianrootfs4zynq.img
server> mkdir debianrootfs4zynq
server> sudo mount -o loop debianrootfs4zynq.img debianrootfs4zynq

Install a minimal Debian distribution

server> sudo debootstrap --verbose --arch armhf --variant=minbase --foreign wheezy debianrootfs4zynq http://ftp.fr.debian.org/debian
server> sudo modprobe binfmt_misc
server> sudo cp /usr/bin/qemu-arm-static debianrootfs4zynq/usr/bin
server> sudo mkdir debianrootfs4zynq/dev/pts
server> sudo mount -t devpts devpts debianrootfs4zynq/dev/pts
server> sudo mount -t proc proc debianrootfs4zynq/proc

Chroot into the file system and continue the Debian install

server> sudo chroot debianrootfs4zynq /bin/bash
server-chrooted> /debootstrap/debootstrap --second-stage
server-chrooted> cat <<! >> /etc/apt/sources.list
deb http://security.debian.org/ wheezy/updates main
deb-src http://security.debian.org/ wheezy/updates main
deb http://ftp.fr.debian.org/debian/ wheezy main 
deb-src http://ftp.fr.debian.org/debian/ wheezy main
!
server-chrooted> apt-get update
server-chrooted> apt-get upgrade
server-chrooted> export LANG=C
server-chrooted> apt-get install apt-utils dialog locales
server-chrooted> dpkg-reconfigure locales
server-chrooted> export LANG=en_US.UTF-8
server-chrooted> apt-get install udev netbase ifupdown iproute openssh-server iputils-ping wget net-tools ntpdate nano less module-init-tools

Configure file systems, hostname, root password and serial console

server-chrooted> cat <<! >> /etc/fstab
/dev/nfs /    nfs   defaults 0 1
tmpfs    /tmp tmpfs defaults 0 0
!
server-chrooted> echo "MyZedBoard" > /etc/hostname
server-chrooted> passwd
...

Comment out the tty1 to tty6 specifications in /etc/inittab and add the serial console (use nano to edit the file):

#1:2345:respawn:/sbin/getty 38400 tty1
#2:23:respawn:/sbin/getty 38400 tty2
#3:23:respawn:/sbin/getty 38400 tty3
#4:23:respawn:/sbin/getty 38400 tty4
#5:23:respawn:/sbin/getty 38400 tty5
#6:23:respawn:/sbin/getty 38400 tty6
T0:23:respawn:/sbin/getty -L ttyPS0 115200 vt100

Allow the root user to log in through the serial console:

server-chrooted> cat <<! >> /etc/securetty
ttyPS0
!

Escape from the chroot and export the NFS share

server-chrooted> exit
server> sudo mkdir <nfsdir>/debianrootfs4zynq/opt/bitstreams
server> sudo cat <<! >>  /etc/exports
<nfsdir>/debianrootfs4zynq <zedboard_ip_address>/32(rw,sync,no_root_squash,no_subtree_check,insecure)
!
server> sudo exportfs -v <zedboard_ip_address>/32:<nfsdir>/debianrootfs4zynq

On <host> build U-Boot, the Linux kernel, the device tree blob and generate the boot image

Clone the U-Boot and Linux git repositories by Xilinx

host> export ROOTDIR=<some-path>
host> mkdir -p $ROOTDIR
host> cd $ROOTDIR
host> git clone http://github.com/Xilinx/u-boot-xlnx.git
host> git clone https://github.com/Xilinx/linux-xlnx.git

Configure and build U-Boot

host> cd $ROOTDIR/u-boot-xlnx
host> export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
host> make O=build zynq_zed_config
host> make O=build
host> cp build/u-boot build/u-boot.elf
host> export PATH=$PATH:$ROOTDIR/u-boot-xlnx/build/tools

Configure and build the Linux kernel, compile the device tree blob, copy the image and the blob on the tftp server

Note: when configuring the Linux kernel do not forget to enable the NFS support if it is not already.

host> cd $ROOTDIR/linux-xlnx
host> make ARCH=arm xilinx_zynq_defconfig
host> make ARCH=arm menuconfig
host> make ARCH=arm UIMAGE_LOADADDR=0x8000 uImage
host> ./scripts/dtc/dtc -I dts -O dtb -o $ROOTDIR/devicetree.dtb arch/arm/boot/dts/zynq-zed.dts
host> scp arch/arm/boot/uImage $ROOTDIR/devicetree.dtb <server>:<tftproot>/<tftpdir>
host> ssh <server> chmod a+r <tftproot>/<tftpdir>/uImage <tftproot>/<tftpdir>/devicetree.dtb

Compile the kernel modules and install them in the NFS share on <server>

host> cd $ROOTDIR/linux-xlnx
host> make ARCH=arm INSTALL_MOD_PATH=$ROOTDIR/debianrootfs4zynq modules modules_install
host> cd $ROOTDIR
host> tar -pzcvf - debianrootfs4zynq | ssh root@<server> 'cd <nfsdir>; tar -pzxvf -'

To configure the PL from a running Linux kernel, copy the bistream file on the NFS server:

host> scp <bitstream>.bit <server>:<nfsdir>/debianrootfs4zynq/opt/bitstreams

To configure the PL with U-Boot copy the bistream file on the tftp server:

host> scp <bitstream>.bit <server>:<tftproot>/<tftpdir>
host> ssh <server> chmod a+r <tftproot>/<tftpdir>/<bitstream>.bit

Create and build the Board Support Package (BSP) and the FSBL, generate the boot image

Note: we use the zed_hw_platform template provided with the Xilinx SDK.

Note: delete the <bitstream>.bit line if the PL is not configured by the FSBL.

host> cd $ROOTDIR
host> cat <<! > fsbl.tcl
set_workspace ./fsbl
create_project -type app -name fsbl -app "Zynq FSBL" -proc ps7_cortexa9_0 -hwproject zed_hw_platform
build -name fsbl
quit
!
host> xsdk -batch -source fsbl.tcl
host> cat <<! > boot.bif
the_ROM_image:
{
  [bootloader]./fsbl/fsbl/Debug/fsbl.elf
  <bitstream>.bit
  ./u-boot-xlnx/build/u-boot.elf
}
!
host> bootgen -image ./boot.bif -o ./boot.bin -w on
host> cp boot.bin /media/SDCARD
host> sync

On the ZedBoard, set U-Boot environment variables and boot the Linux kernel

Unmount the SD card, insert it in the SD card slot of the ZedBoard, configure the jumpers to boot from the SD Card, connect the Ethernet cable, the USB UART cable, the power cable and power on. Launch minicom (or equivalent) on <host>:

host> minicom -D /dev/ttyACM0

and stop U-Boot by pressing a key before the end of the countdown.

Set the following U-Boot environment variables (please pay attention to the simple and double quotes):

zynq-uboot> setenv ethaddr  <zedboard_mac_address>
zynq-uboot> setenv ipaddr   <zedboard_ip_address>
zynq-uboot> setenv serverip <server_ip_address>
zynq-uboot> setenv nfsdir   <nfsrootdir>/debianrootfs4zynq
zynq-uboot> setenv tftpdir  <tftpdir>
zynq-uboot> setenv netboot  'tftpboot ${kernel_load_address} ${tftpdir}/${kernel_image} && tftpboot ${devicetree_load_address} ${tftpdir}/${devicetree_image} && bootm ${kernel_load_address} - ${devicetree_load_address}'
zynq-uboot> setenv bootargs "console=ttyPS0,115200 root=/dev/nfs rw nfsroot=${serverip}:${nfsdir} ip=${ipaddr}:${serverip}:${serverip}:255.255.255.0:zynq:eth0:off nfsrootdebug earlyprintk"

If the PL must be configured by U-Boot add the following netboot variable redefinition:

setenv netboot  "tftpboot 0x4000000 ${tftpdir}/<bitstream>.bit && fpga loadb 0 0x4000000 4045671 && ${netboot}"

Save the environment variables in the SPI flash memory of the ZedBoard:

zynq-uboot> saveenv
zynq-uboot> run netboot
...
Debian GNU/Linux 7 MyZedBoard ttyPS0

MyZedBoard login: root
Password: 
Last login: Thu Jan  1 00:01:57 UTC 1970 on ttyPS0
Linux MyZedBoard 3.18.0-xilinx-06524-gd51de5a #1 SMP PREEMPT Fri Apr 10 14:39:03 CEST 2015 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@MyZedBoard:~# df
Filesystem                                    1K-blocks   Used Available Use% Mounted on
rootfs                                           967864 373036    544828  41% /
<server_ip_address>:<nfsdir>/debianrootfs4zynq   967864 373036    544828  41% /
devtmpfs                                         248100      0    248100   0% /dev
tmpfs                                             51284    132     51152   1% /run
tmpfs                                              5120      0      5120   0% /run/lock
tmpfs                                            102560      0    102560   0% /run/shm
tmpfs                                            256400      0    256400   0% /tmp
root@MyZedBoard:~#

If the PL must be configured from the running Linux kernel, this can be done with:

root@MyZedBoard:~# cat /opt/bistreams/<bitstream>.bit > /dev/xdevcfg

To avoid leaving your NFS root file system in an unstable state, always shut down properly:

root@MyZedBoard:~# poweroff
...
[info] Will now halt.
reboot: System halted

before turning the power off. Remember that the root file system is on <server> and that resetting the ZedBoard or powering it off without a proper shut down can definitively compromise your NFS share.

Maintaining the NFS share

If the NFS share on <server> still appears busy after the client ZedBoard has been properly shut down, as happens sometimes, it can be unmounted with:

server> sudo exportfs -u <zedboard_ip_address>/32:<nfsdir>/debianrootfs4zynq
server> sudo umount -l <nfsdir>/debianrootfs4zynq

To re-mount and re-export the NFS share on <server>:

server> cd <nfsdir>
server> sudo mount -o loop debianrootfs4zynq.img debianrootfs4zynq
server> sudo mount -t devpts devpts debianrootfs4zynq/dev/pts
server> sudo mount -t proc proc debianrootfs4zynq/proc
server> sudo exportfs <zedboard_ip_address>/32:<nfsdir>/debianrootfs4zynq

To chroot in the NFS share:

server> sudo chroot debianrootfs4zynq /bin/bash
server-chrooted> apt-get update
...
Clone repository
  • Home
  • axi bridge
  • axi simple bridge
  • disabling zynq caches
  • downloads
  • hsm as a bridge
  • secure boot
  • sharing laptop wireless connnection with zedboard
  • trescca demo
  • virtual prototype
  • zedboard linux uboot dtb buildroot
  • zedboard tftp nfs