Loading Linux Kernel Images via Ethernet and TFTP Print


This note explains how to load kernel and device tree images to the target via Ethernet. It is assumed that the Root Filesystem is already installed in a partition on the SD Card or eMMC as specified in the root= parameter in the bootargs U-Boot variable. With an Ethernet connection available, U-Boot can load 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 [<load_addr><file>

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

u-boot=> print loadaddr
loadaddr=0xc1000000
u-boot=>

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 persistent storage:

u-boot=> setenv ethaddr 3C:FB:96:44:44:02
u-boot=> setenv ipaddr 192.168.1.151
u-boot=> setenv serverip 192.168.1.65
u-boot=> saveenv
Saving Environment to MMC...
Writing to MMC(1)... done

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), display the memory, etc.

One typical command sequence involving tftpboot could be defined in the netboot environment variable as follows:

u-boot=> print netboot
## Error: "netboot" not defined
u-boot=> setenv args 'setenv bootargs root=/dev/mmcblk1p4 rootwait rw console=ttySTM0,115200'
u-boot=> setenv netboot 'tftp 0xc1fffff4 ${image} && tftp 0xc1000000 ${dtbimage} && run args && bootm 0xc1fffff4 - 0xc1000000'
u-boot=> saveenv

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

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

u-boot=> setenv image psl/stmp1/Image u-boot=> setenv dtbfile psl/stmp1/stm32mp1-som.dtb u-boot=> saveenv Saving Environment to MMC... Writing to MMC(1)... done u-boot=> run netboot STM32MP1-SOM> run netboot Using ethernet@5800a000 device TFTP from server 172.17.0.1; our IP address is 172.17.11.14 Filename 'psl/stmp1/uImage'. Load address: 0xc1fffff4 Loading: ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ####################### 3.8 MiB/s done Bytes transferred = 6059440 (5c75b0 hex) Using ethernet@5800a000 device TFTP from server 172.17.0.1; our IP address is 172.17.11.14 Filename 'psl/stmp1/stm32mp1-som.dtb'. Load address: 0xc1000000 Loading: ####### 3.2 MiB/s done Bytes transferred = 96881 (17a71 hex) ## Booting kernel from Legacy Image at c1fffff4 ... Image Name: Linux-4.14.48 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 6059376 Bytes = 5.8 MiB Load Address: c2000040 Entry Point: c2000040 Verifying Checksum ... OK ## Flattened Device Tree blob at c1000000 Booting using the fdt blob at 0xc1000000 Loading Kernel Image ... OK Using Device Tree in place at c1000000, end c101aa70 SF: unrecognized JEDEC id bytes: 00, 00, 00 Starting kernel ... ... stm32mp1-som login: root (automatic login) root@stm32mp1-som:~#

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. Suppose you are still not getting your file from the TFTP server. It is possible that the problem is on the host side - you must set up a TFTP server correctly. Just google for "how to set up a tftp server" and follow the advice from some top articles.
  3. Make sure you have copied a file you are trying to download to the TFTP server directory on the host.
  4. Disable the firewall on the host since get enabled, it will block TFTP requests from the target.
  5. 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 Emcraft STM32MP1 SOM) configured for the same MAC address.