When developing embedded Linux systems, constant flashing of SD cards or eMMC devices quickly becomes tedious.
A much faster and more flexible approach is to boot your device entirely over Ethernet — loading the kernel via TFTP and mounting the root filesystem via NFS.
This network-based setup is ideal during development and testing, especially when working with Yocto, because every change made on the host system is immediately visible on the target board.
#Why Boot Over Ethernet
Using TFTP and NFS for booting provides several major advantages:
- ⚡ Instant updates: Edit files or rebuild the rootfs without reflashing storage
- 🧩 Separation of kernel and rootfs: Test different kernel versions easily
- 🧠 Easy debugging: Logs and files remain on the host
- 💾 No flash wear: Protect limited write-endurance devices
- 🔁 Rapid iteration: Perfect for development and continuous testing setups
#1. Preparing the Yocto Build Output
After building your Yocto image (for example, core-image-minimal), locate the generated files:
1$BUILDDIR/tmp/deploy/images/<machine>/
You’ll need:
- The kernel image (
zImageorImage) - The device tree blob (
.dtb) - The root filesystem archive (
.rootfs.tar.xz)
#2. Setting Up the Workstation (TFTP + NFS Server)
Install the required services:
1sudo apt update
2sudo apt install nfs-kernel-server tftpd-hpa
#Configure the NFS export
1sudo mkdir -p /nfs
2sudo chmod 777 /nfs
Add this line to /etc/exports:
1/nfs *(rw,sync,no_root_squash,no_subtree_check)
Apply the export configuration:
1sudo exportfs -r
#Configure the TFTP server
1sudo mkdir -p /tftpboot
2sudo chmod 777 /tftpboot
3sudo cp zImage /tftpboot/
4sudo cp board.dtb /tftpboot/
Verify /etc/default/tftpd-hpa contains:
1TFTP_DIRECTORY="/tftpboot"
2TFTP_ADDRESS=":69"
3TFTP_OPTIONS="--secure"
Restart the service:
1sudo systemctl restart tftpd-hpa
#3. Configure the Host Ethernet Interface
Assign a static IP to your workstation that will act as both the TFTP and NFS server.
For example:
1nmcli con add type ethernet ifname eth0 ip4 192.168.0.1/24
If it already exists:
1nmcli con mod eth0 ipv4.addresses 192.168.0.1/24 ipv4.method manual
2nmcli con up eth0
#4. Deploy the Yocto Root Filesystem
Extract the root filesystem archive into the exported NFS directory:
1sudo tar xpf $BUILDDIR/tmp/deploy/images/<machine>/core-image-minimal-<machine>.rootfs.tar.xz -C /nfs
Now your board can mount /nfs as its root filesystem.
#5. Configure U-Boot for Network Boot
At the U-Boot prompt, set the necessary environment variables:
1setenv serverip 192.168.0.1
2setenv ipaddr 192.168.0.100
3setenv bootfile zImage
4setenv fdtfile board.dtb
5setenv bootargs "console=ttyS0,115200 root=/dev/nfs rw nfsroot=${serverip}:/nfs,v3,tcp ip=dhcp"
6
7tftp ${loadaddr} ${bootfile}
8tftp ${fdtaddr} ${fdtfile}
9bootz ${loadaddr} - ${fdtaddr}
If configured correctly, you’ll see output similar to:
1IP-Config: eth0 hardware address ...
2Looking up 192.168.0.1
3Sending DHCP requests ...
4VFS: Mounted root (nfs filesystem)
Your board is now running completely from the network.
#6. Adding Packages to the Root Filesystem
To extend your rootfs, modify your Yocto configuration file:
1$BUILDDIR/conf/local.conf
Append the desired package, for example:
1IMAGE_INSTALL:append = " dropbear"
Rebuild the image:
1bitbake core-image-minimal
Extract the updated rootfs again to /nfs and reboot your board.
You can now connect via SSH:
1ssh root@192.168.0.100
#7. Choosing Kernel Variants in Yocto
Yocto uses virtual package providers, meaning different kernel recipes can fulfill virtual/kernel.
To see which kernel is currently used:
1bitbake -vn virtual/kernel
If you want to switch to a different kernel:
1PREFERRED_PROVIDER_virtual/kernel = "linux-custom"
Then verify again:
1bitbake -vn virtual/kernel
#8. Useful BitBake Commands
Here are some helpful Yocto commands for everyday work:
| Purpose | Command |
|----------|----------|
| List available tasks | bitbake -c listtasks virtual/kernel |
| Run a specific task | bitbake -c menuconfig virtual/kernel |
| Force rebuild | bitbake -f virtual/kernel |
| Fetch all sources | bitbake --runall=fetch world |
| List available packages | bitbake -s |
Explore more recipes at layers.openembedded.org.
#9. Summary
Booting over Ethernet using TFTP and NFS is a cornerstone of efficient embedded development:
- No local storage needed
- Immediate updates and faster iterations
- Centralized kernel and rootfs management
This setup is the foundation of most professional embedded Linux workflows — including our own at Mitkov Systems GmbH, where fast iteration and reliable testing environments are key to high-quality product development.
#💡 Next Steps
In future articles, we’ll show how to:
- Automate U-Boot network booting
- Use Yocto SDKs for seamless application development directly on NFS-mounted root filesystems
Stay tuned — or contact us at mail@mitkov-systems.de if you’d like to discuss how we can help accelerate your embedded Linux development.
Mitkov Systems GmbH
Specialists in Embedded Systems, IoT, and Industrial Connectivity