Loading Linux Images via Ethernet and TFTP Print


This note explains how to load images via Ethernet from U-Boot. With an Ethernet connection available, U-Boot can load Linux images from a TFTP host quickly and easily. This is the development and software manufacturing option that is preferable with U-Boot and Linux.

The download procedure is based on the tftpboot command provided by the U-Boot command interface. tftboot implements a download capability over Ethernet using the TFTP protocol and has the following synopsis:

tftpboot <file> [<load_addr>]

If you do not specify a load address, then the value will be taken from the loadaddr environment variable. On the STM32F4 SOM, loadaddr is set as follows, placing the download buffer into the on-module SDRAM:

STM32F4X9-SOM> print loadaddr
loadaddr=0xC0007FB4 
STM32F4X9-SOM>

The MAC address of the Ethernet interface is defined by the ethaddr environment variable.The IP address of the board is defined by the ipaddr U-Boot environment variable. The TFTP server IP address is defined by the serverip U-Boot environment variable. Make sure you define these environment variables to values that make sense for your LAN and save them in the on-module NOR Flash:

STM32F4X9-SOM>  setenv ipaddr 172.17.6.136
STM32F4X9-SOM>  setenv serverip 172.17.0.1
STM32F4X9-SOM>  saveenv
Saving Environment to Flash...
. done
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... done
. done
Protected 1 sectors
STM32F4X9-SOM>

Note that the ethaddr variable is preset by Emcraft to a unique MAC address at the factory. To avoid possible conflicts in a LAN, we do not recommend updating ethaddr although you have this option in case you require it for some reason:

STM32F4X9-SOM> printenv ethaddr
ethaddr=C0:B1:3C:88:88:85
STM32F4X9-SOM> setenv ethaddr C0:B1:3C:88:88:86
STM32F4X9-SOM> saveenv
Saving Environment to Flash...
...
STM32F4X9-SOM>

Once the transmission using tftpboot finishes, the file will be in memory at the specified load address. The loadaddr environment variable will automatically be set to the address the tftpboot command used. The filesize environment variable will automatically be set to the number of bytes transferred during the load operation.

Then you are free to do whatever you like with the loaded image. You can boot Linux from the image (assuming it is a bootable Linux file), copy it to some other place (for instance, NOR Flash), display the memory, etc.

One typical command sequence involving tftpboot is defined in the netboot environment variable, which by default is set in U-Boot as follows:

STM32F4X9-SOM> print netboot
netboot=tftp ${image};run args addip;bootm
STM32F4X9-SOM>

What netboot does is load from a TFTP host a file defined by image (the tftp command), then add the TCP/IP related parameters to the kernel command string (the args and addip commands), and finally boot Linux from the just loaded image (the bootm command).

Let's use netboot to boot Linux via TFTP from the sample Linux image (rootfs.uImage) included in the Emcraft software distribution. Copy rootfs.uImage to the TFTP directory on the host and then from U-Boot on the target set the image environment variable to point to the Linux file:

STM32F4X9-SOM> set image vlad/rootfs.uImage
STM32F4X9-SOM> saveenv
Saving Environment to Flash...
...
STM32F4X9-SOM> run netboot
Auto-negotiation...completed.
STM32_MAC: link UP (100/Half)
Using STM32_MAC device
TFTP from server 172.17.0.1; our IP address is 172.17.4.206
Filename 'vlad/rootfs.uImage'.
Load address: 0xc0007fb4
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##
done
Bytes transferred = 4794223 (49276f hex)
## Booting kernel from Legacy Image at c0007fb4 ...
Image Name:   Linux-4.2.0-00175-g21f52b5-dirty
Image Type:   ARM Linux Multi-File Image (uncompressed)
Data Size:    4794159 Bytes =  4.6 MB
Load Address: c0008000
Entry Point:  c0008001
Contents:
Image 0: 4776496 Bytes =  4.6 MB
Image 1: 17651 Bytes = 17.2 kB
Verifying Checksum ... OK
## Flattened Device Tree from multi component Image at C0007FB4
Booting using the fdt at 0xc0496230
Loading Multi-File Image ... OK
OK
Loading Device Tree to c1ff8000, end c1fff4f2 ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.2.0-00175-g21f52b5-dirty (vlad @ocean.emcraft.com) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-189) ) #26 Sun Mar 20 15:35:11 +0400 2016
...
init started: BusyBox v1.17.0 (2016-03-09 16:27:43 +0400)
...
/ # ls
bin    etc    init   mnt    mnt2   mnt4   root   sys    usr
dev    httpd  lib    mnt1   mnt3   proc   sbin   tmp    var
/ #

You must set up a TFTP server on the development host to allow downloading images to the target over Ethernet. The procedure is extensively documented in the Internet. Just google for "how to set up a tftp server" and follow the advice from some top articles.

Here are some troubleshooting tips, in case tftpboot does not work for you from U-Boot:

  1. As trivial as it sounds make sure that the board is connected to the LAN with an Ethernet cable.
  2. Make sure you have copied a file you are trying to download to the TFTP server directory on the host.
  3. Disable the firewall on the host. If a firewall is enabled, it will block TFTP requests from the target.
  4. On the target, make sure that you have set ipaddr and serverip correctly. Check ethaddr and make sure that you don't have another embedded board (eg. another STM32F4 SOM) configured for the same MAC address (this shouldn't be the case unless you have changes the ethaddr variable on some of your STM32F4 modules).