Poky NFS Root

From Yocto Project
Jump to: navigation, search


HOWTO: Booting poky images on hardware from network


Booting from network is a common practice when developing embedded system on real hardware. It avoids the time consuming process of downloading the kernel and root filesystem to a hard drive or flash to make developer's life easier.

The general idea is to use a bootloader to get the kernel image (using TFTP, mostly) and specifying nfsroot in the kernel command line to mount rootfs via a remote NFS server. In the case of x86 systems, the bootloader is usually PXE (Preboot Execution Environment), either provided by BIOS or other PXE implementations like gPXE.

This HOWTO walks through the process of setting everything for eMenlow, with NFS-root, you can:

  • boot a diskless and flashless target
  • avoid downloading kernel/rootfs after a rebuild
  • change files on the fly even on read-only fs (jffs2, squashfs, etc.)
  • boot on different boards or boxen

Target bootloading with gPXE

TODO: integrate gPXE into yocto

The traditional method of bootloading is the PXE stack provided in BIOS. However, that often requires DHCP cooperation, which is not viable in many circumstances. Here we use gPXE, an open-source PXE implementation, to get around this DHCP restriction.

It can function as a standalone bootloader or be chainloaded by grub. Since it's less than 500kB in size, it can fit in a small USB flash drive very well.

First, build it from source. Suppose your development machine has the hostname of <hostname>:

$ git clone git://git.etherboot.org/scm/gpxe.git
$ cd gpxe
$ cat > chainload.gpxe <<EOF
dhcp net0
kernel tftp://<hostname>/boot.gpxe
$ cd src
$ EMBEDDED_IMAGE=../chainload.gpxe make bin/gpxe.usb

The EMBEDDED_IMAGE is the builtin script as gPXE starts. The script above chainloads another gPXE script on the remote tftp server (your development machine) to get actual kernel and rootfs image location.

After that, bin/gpxe.usb can be written to an empty USB stick to bootload the image on any box that has a network connection:

warning: the content of the usb device will be wiped out!

# dd if=bin/gpxe.usb of=</dev/sdX>

Alternatively, there are also other targets available, for example, bin/gpxe.lkrn can be built to be chainloaded by grub, please refer to gPXE docs.

Development box preparation

TODO: integrate nfs server and tftpd into yocto

To set up tftp and nfs server on debian/ubuntu, simply:

# apt-get install nfs-kernel-server atftpd

tftpd-hpa can be used as well instead of atftpd.

Target system changes

There are two additional requirements for the target system, however:

  1. the kernel needs to have the network driver built in, not as a module
  2. the network init scripts needs to be disabled or patched to avoid collision with nfsroot

For 1, just change the config file of the target kernel, i.e for qemux86 on eMenlow, change meta/packages/linux/linux-rp-2.6.29/defconfig-qemux86 to add CONFIG_E1000E=y.

(note: status of initramfs is unknown at the moment)

For 2, there are many possible solutions, a relative generic patch can be found here:


Besides, you may also:

  • remove /etc/init.d/networking altogether
  • remove "auto eth0" in /etc/network/interfaces

Setting up after image build

TODO: avoid using sudo

The following patch provides a script to automatically set up tftp and nfsroot after image build completes.


Simply run the following in the poky build directory, assuming your machine type is qemux86:

$ prepare-nfsroot qemux86 -g

And everything is done. Now just insert the USB stick into the target machine, power it on, and see if the target image is booting.

External references

Personal tools