TFTP server (tftpd-hpa) on Ubuntu 14.04 LTS
Install the tftpd-hpa on the host:$ sudo apt-get install tftpd-hpaThe default configuration file (/etc/default/tftpd-hpa) just needs some tweaks (my changes highlighted):
RUN_DAEMON="yes"
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/var/lib/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure --ipv4"
For reasons I cannot recall now, I ran the TFTP as its own daemon instead of through inetd. Because I have bigger fish to fry, I am moving on. Serving all interfaces on the host is fine because my development box only has 1 NIC. I originally allowed IPv6 to run on my server, but got fed up with apt-get taking forever to time out against canonical servers and turned off IPv6 on my desktop with this command, by appending the following to my /etc/sysctl.conf,
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
and then running
$ sudo sysctl -p
But turning off IPv6 requires IPv6 to be turned off in the TFTP config file, by changing TFTP_ADDRESS to the value shown above; note that the port number does not change.
The server must serve up the kernel image and device tree, which I put in TFTP_DIRECTORY defined in the config file above.
/var/lib/tftpboot$ sudo cp ~/work/zynq/buildroot/output/images/uImage zedImage
/var/lib/tftpboot$ sudo cp ~/work/zynq/buildroot/output/images/zynq-zed-adv7511.dtb .
No, I still cannot make the ftp server follow symbolic link, sigh... For sanity test, install tftp on the host, and try "get"-ting one of the above files into your home folder. So here is a post-build script to ease the pain; change the folders according to your own setup:
sudo rm -rf /export/root/zed/; sudo mkdir /export/root/zed/
sudo tar -C /export/root/zed -xf /mnt/work/zynq/buildroot/output/images/rootfs.tar
sudo cp /mnt/work/zynq/buildroot/output/images/uImage /var/lib/tftpboot/zedImage
No, I still cannot make the ftp server follow symbolic link, sigh... For sanity test, install tftp on the host, and try "get"-ting one of the above files into your home folder. So here is a post-build script to ease the pain; change the folders according to your own setup:
sudo rm -rf /export/root/zed/; sudo mkdir /export/root/zed/
sudo tar -C /export/root/zed -xf /mnt/work/zynq/buildroot/output/images/rootfs.tar
sudo cp /mnt/work/zynq/buildroot/output/images/uImage /var/lib/tftpboot/zedImage
Troubleshooting
If TFTP suddenly stops working when you have not changed the target side, then suspect the TFTP server--it often does not start or crashes. To check,
$ sudo service tftpd-hpa status
ftpd-hpa start/running, process 5930
It should show print a PID if it's really running, as in the above example. If not, try stopping and restarting
$ sudo service tftpd-hpa restart
Manually boot off TFTP
Logically, U-Boot needs to know 2 things to boot:- What files to download over TFTP, and which memory to stick them.
- ipaddr and serverip U-Boot environment variables stay the same as the NFS root file system case.
- Leveraging the knowledge gained from the previous post, I will continue to mount the root file system over NFS, so I only need to download the kernel image (uImage) and DTB (because my eval board is ARM). Copied for convenience, the kernel image should be at 0x3000000, and the device tree image should be at 0x2A00000.
- The boot command specifying the memory address containing the kernel. From previous post, I already have a working boot command. If I keep the memory addresses the same, I do NOT have to modify the boot command.
So let's focus on downloading the uImage and DTB files to the target. I stop U-Boot in the serial console during the 3 second wait. The U-Boot command to download a file from the TFTP server is (surprise!) "tftpboot". So first, the device tree blob:
zynq-uboot> tftpboot 0x2A00000 192.168.1.2:zynq-zed-adv7511.dtb
The the kernel image itself:
zynq-uboot> bootm
...
Welcome to Zeboard!
zed login:
zynq-uboot> tftpboot 0x3000000 192.168.1.2:zedImageThen we can simply boot from memory:
zynq-uboot> bootm
...
Welcome to Zeboard!
zed login:
Codify the success as U-Boot sdboot script
Remember that the FSBL is still necessary to program the FPGA bitstream and kick off U-Boot (the 2nd stage boot loader). All these files are still on the SD card, so when U-Boot loads, it will find itself in sdboot mode. There is a matching environment variable "sdboot" which I configured in the previous post to load the uImage and the DTB files from SD's BOOT partition, and kick off the bootm command (used above). So for TFTP boot, I just have to modify this sdboot environment variable to what worked above:
setenv serverip 192.168.1.2
setenv ipaddr 192.168.1.9
setenv kernel_image "zedImage"
setenv devicetree_image "zynq-zed-adv7511.dtb"
setenv sdboot 'if mmcinfo; then run uenvboot; echo Copying files over TFTP to RAM && tftpboot 0x2A00000 ${serverip}:${devicetree_image} && tftpboot 0x3000000 ${serverip}:${kernel_image} && bootm 0x3000000 - 0x2A00000; fi'
saveenv
boot