How to boot the kernel via TFTP from U-Boot

This page explains how to boot the Linux kernel from U-Boot through a TFTP server (trivial file transfer protocol[1]) installed on a host PC, based on the U-Boot command pxe.

1 Documentation[edit]

The documentation is available in the U-Boot source:

2 tftp server installation on host PC[edit]


3 tftp server configuration[edit]

U-Boot follows pxelinux's rules[2] to download from the tftp server a #PXE configuration file located in the #pxelinux.cfg directory.
See details in

3.1 PXE configuration file[edit]

Each PXE configuration file has same format as the extlinux.conf file generated by yocto distribution.

To fully boot on a network (kernel and rootfs), you can define the ramfs option.
For example for an ev1 board:

menu title Select the boot mode
LABEL ramfs
	KERNEL uImage
	FDT stm32mp157c-ev1.dtb
	INITRD uInitrd
	APPEND rootwait rw earlyprintk console=ttyS3,115200

Another solution for network boot is to use rootfs as nfs with modified Linux bootargs (APPEND: rootfstype=nfs nfsroot=... see kernel bootargs).

You be can also use rootfs on a device (e•MMC, SDCard, NAND, and so on) by adding other labels and TIMEOUT (selection needs user action on the U-Boot console).

menu title Select the boot mode
LABEL ramfs
	KERNEL uImage
	FDT stm32mp157c-ev1.dtb
	INITRD uInitrd
	APPEND rootwait rw earlyprintk console=ttySTM0,115200
LABEL sdcard
	KERNEL uImage
	FDT stm32mp157c-ev1.dtb
	APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttySTM0,115200
	KERNEL uImage
	FDT stm32mp157c-ev1.dtb
	APPEND root=/dev/mmcblk1p6 rootwait rw earlyprintk console=ttySTM0,115200

3.2 pxelinux.cfg directory[edit]

Because more than one board may be booted from the same server, the PXE configuration file name depends on U-boot parameters (hardware address/IP address).
U-Boot looks in the pxelinux.cfg directory for a PXE configuration file name in this order:

  1. UUID comes from "pxeuuid" variable [3]
  2. hardware type and address: Ethernet (ARP[4] type "1") with MAC address[5] (ethaddr env variable)
  3. IP address of the board and each subnet mask
  4. at the end, the file named "default-$CONFIG_SYS_ARCH-$CONFIG_SYS_SOC"

You need to provide at least one file on the server for your board.

Each file of the pxelinux.cfg directory can share the the same content (or can be a symbolic link to a default one).

For example, for an stm32mp1 target, when:

  • UUID is not defined
  • ethaddr=00:80:e1:01:2d:6f
  • IP = (hexa coding=0A30008D)
  • ARCH=arm and SOC=stm32mp

U-Boot searches the configuration file is this order:

  1. "01-00-80-e1-01-2d-6f"
  2. 0A30008D then subnet 0A30008, 0A3000, 0A300 ...
  3. default-arm-stm32mp

With ethaddr=00:80:e1:01:2d:6f, the tftp directory (for example /tftpboot) may look like:

├── pxelinux.cfg
│   ├── 01-00-80-e1-01-2d-6f
├── stm32mp157c-ev1.dtb
├── uImage
├── uInitrd

An other example with

  • different boards (identified by a MAC address)
    each pxe file selects a different device tree (ed1, ev1, dk1, dk2) or kernel file
  • fallback with the IP address submask (symbolic link to default-arm-stm32mp)
  • default-arm-stm32mp (final fallbackup file)
├── pxelinux.cfg
│   ├── 01-00-80-e1-01-2d-6f
│   ├── 01-00-80-e1-42-42-8c
│   ├── 01-00-80-e1-42-42-cd
│   ├── 01-00-80-e1-42-46-76
│   ├── 0A300 -> default-arm-stm32mp
│   ├── 0A30001 -> default-arm-stm32mp
│   ├── 0A30004 -> default-arm-stm32mp
│   ├── 0A30008 -> default-arm-stm32mp
│   └── default-arm-stm32mp
├── stm32mp157c-ed1.dtb
├── stm32mp157c-ev1.dtb
├── stm32mp157a-dk1.dtb
├── stm32mp157c-dk2.dtb
├── uImage
├── uInitrd

4 Board command in U-boot console[edit]

You can execute the DISTRO bootcmd for PXE:

 Board $> env set serverip <you PC address>
 Board $> run bootcmd_pxe

5 References[edit]

Trivial File Transfer Protocol


former spelling for e•MMC ('e' in italic)