• Tutorials
  • Booting Linux Kernel and Root Filesystem over Ethernet with Yocto (TFTP + NFS)

    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 (zImage or Image)
    • 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

    profile image of Martin Mitkov

    Martin Mitkov

    Martin is a founder and CEO of Mitkov Systems GmbH.

    More posts from Martin Mitkov