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:
-----------------------------------------------------------------------------------------
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 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:
sudo apt update && sudo apt install -y tftpd-hpa tftp-hpaReading 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.tftpdbackground 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-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 (
PUTrequests) 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:
sudo mkdir -p /var/lib/tftpboot && sudo chown -R tftp:tftp /var/lib/tftpboot && sudo chmod -R 777 /var/lib/tftpbootsudo 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 UTCIf UFW (Uncomplicated Firewall) is enabled on your Ubuntu host, open UDP port 69:
sudo ufw allow 69/udpRule 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:
echo "Hello Lynxbee TFTP" | sudo tee /var/lib/tftpboot/test.txt && tftp 127.0.0.1 -c get test.txt && cat test.txtHello Lynxbee TFTPWhat You Learned from Verification Step:
`-c get test.txt` Command: The
-coption executes thegetfile retrieval command non-interactively.Successful Transfer: Receiving
Hello Lynxbee TFTPconfirms 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:
# 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 - 0x88000000What You Learned from U-Boot Transfer Example:
`serverip` Environment Variable: Specifies the IP address of your Ubuntu host running
tftpd-hpa.RAM Target Address:
0x82000000is 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
serveripin U-Boot. Runsudo 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/tftpbootor missing--createinTFTP_OPTIONS.
Setting up tftpd-hpa on Ubuntu provides a reliable, fast network boot server for embedded Linux developers, kernel engineers, and router firmware developers.
Comments and corrections