Trivial File Transfer Protocol (TFTP) is a lightweight, unauthenticated UDP file transfer protocol operating on port 69. In embedded Linux development, network engineering, and SRE infrastructure, TFTP is the industry-standard mechanism used by bootloaders (like U-Boot) to load Linux kernel images (zImage/uImage), Device Tree Blobs (.dtb), and PXE network boot payloads into target hardware RAM.

Quick Reference: /etc/default/tftpd-hpa Configuration Parameters

The tftpd-hpa daemon service configuration resides in /etc/default/tftpd-hpa. Below is the complete parameter breakdown for production setups:

Configuration Parameter Lookup Tabletext
-----------------------------------------------------------------------------------------
Parameter                 | Value                   | Description
-----------------------------------------------------------------------------------------
TFTP_USERNAME             | "tftp"                  | System user running the daemon process
TFTP_DIRECTORY            | "/var/lib/tftpboot"     | Root directory storing downloadable files
TFTP_ADDRESS              | ":69"                   | Bind address (":69" listens on all interfaces)
TFTP_OPTIONS              | "--secure --create"     | Security jail root and allow file creation
-----------------------------------------------------------------------------------------

Visual Architecture: U-Boot to Ubuntu TFTP Transfer Sequence

Understanding how an embedded target board downloads kernel binaries from an Ubuntu TFTP server during early boot:

Embedded Network Boot Sequence Diagramtext
+---------------------------------------------------------------------------------+
| EMBEDDED TARGET BOARD (U-Boot Bootloader)                                       |
+---------------------------------------------------------------------------------+
| U-Boot Command: tftp 0x82000000 zImage                                          |
| Sends Read Request (RRQ) -> Destination IP: UDP Port 69                         |
+---------------------------------------------------------------------------------+
                                |
                                v (Ethernet LAN / Local Subnet)
+---------------------------------------------------------------------------------+
| UBUNTU HOST SERVER (tftpd-hpa Daemon)                                           |
+---------------------------------------------------------------------------------+
| 1. Receives RRQ on UDP Port 69                                                  |
| 2. Spawns ephemeral UDP socket (e.g. Port 52143) for data transfer              |
| 3. Reads /var/lib/tftpboot/zImage                                              |
| 4. Streams 512-byte DATA packets back to target RAM                             |
+---------------------------------------------------------------------------------+

1. Installing and Configuring tftpd-hpa on Ubuntu

First, install the tftpd-hpa daemon and the tftp-hpa command-line test client using apt:

Terminalbash
sudo apt update && sudo apt install -y tftpd-hpa tftp-hpa
Reading package lists... Done
Building dependency tree... Done
Setting up tftpd-hpa (5.2+20150408-2)...

What You Learned from Installation Step:

  • `tftpd-hpa` Package: Provides the in.tftpd background daemon managed by systemd (tftpd-hpa.service).

  • `tftp-hpa` Package: Provides the CLI client executable (tftp) used for local testing.

Next, configure /etc/default/tftpd-hpa to enable secure root directory isolation and file creation flags:

/etc/default/tftpd-hpabash
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/var/lib/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure --create"

What You Learned from Configuration Step:

  • `--secure` Flag: Restricts file accesses strictly within /var/lib/tftpboot (chroot), preventing clients from reading system files like /etc/passwd.

  • `--create` Flag: Allows incoming TFTP uploads (PUT requests) to create new files on the server (requires write permissions on the directory).

2. Setting Directory Permissions and Service Restart

Create the TFTP root directory, set appropriate ownership and permissions, and restart the tftpd-hpa systemd service:

Terminalbash
sudo mkdir -p /var/lib/tftpboot && sudo chown -R tftp:tftp /var/lib/tftpboot && sudo chmod -R 777 /var/lib/tftpboot
Terminalbash
sudo systemctl restart tftpd-hpa && sudo systemctl status tftpd-hpa
● tftpd-hpa.service - LSB: HPA's tftp server
   Loaded: loaded (/etc/init.d/tftpd-hpa; generated)
   Active: active (running) since Wed 2026-08-12 22:45:00 UTC

If UFW (Uncomplicated Firewall) is enabled on your Ubuntu host, open UDP port 69:

Terminalbash
sudo ufw allow 69/udp
Rule added
Rule added (v6)

3. Verifying File Transfers with TFTP Client

To test the setup locally, create a test file in /var/lib/tftpboot/ and download it using the tftp CLI client:

Terminalbash
echo "Hello Lynxbee TFTP" | sudo tee /var/lib/tftpboot/test.txt && tftp 127.0.0.1 -c get test.txt && cat test.txt
Hello Lynxbee TFTP

What You Learned from Verification Step:

  • `-c get test.txt` Command: The -c option executes the get file retrieval command non-interactively.

  • Successful Transfer: Receiving Hello Lynxbee TFTP confirms the daemon is active, listening on UDP 69, and reading from /var/lib/tftpboot/.

4. Downloading Kernel Images in U-Boot

On an embedded target running the U-Boot bootloader connected via Ethernet to your Ubuntu host, configure network IP addresses and download kernel images:

U-Boot Serial Console Promptbash
# Set Target IP and Server IP in U-Boot
setenv ipaddr 192.168.1.50
setenv serverip 192.168.1.100
 
# Download zImage into target RAM at address 0x82000000
tftp 0x82000000 zImage
 
# Download Device Tree Blob into RAM at address 0x88000000
tftp 0x88000000 am335x-boneblack.dtb
 
# Boot Linux Kernel from RAM
bootz 0x82000000 - 0x88000000

What You Learned from U-Boot Transfer Example:

  • `serverip` Environment Variable: Specifies the IP address of your Ubuntu host running tftpd-hpa.

  • RAM Target Address: 0x82000000 is the physical RAM location where U-Boot writes incoming 512-byte TFTP kernel data blocks.

Gotchas and Troubleshooting Checklist

  • `Transfer timed out.` Error - Usually caused by UFW firewall blocking UDP 69 or ephemeral response ports, or an incorrect serverip in U-Boot. Run sudo ufw allow 69/udp.

  • `Error code 1: File not found` - Verify the requested filename matches exact case in /var/lib/tftpboot/. TFTP is case-sensitive.

  • `Error code 2: Access violation` - Occurs when trying to upload a file (PUT) without write permissions on /var/lib/tftpboot or missing --create in TFTP_OPTIONS.

Setting up tftpd-hpa on Ubuntu provides a reliable, fast network boot server for embedded Linux developers, kernel engineers, and router firmware developers.