Poky NFS Root

= HOWTO: Booting poky images on hardware from network =
== Overview ==
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
 #!gpxe
 dhcp net0
 kernel tftp://<hostname>/boot.gpxe
 boot
 EOF
 $ 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:
# the kernel needs to have the network driver built in, not as a module
# 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:
http://git.pokylinux.org/cgit.cgi/poky-contrib/commit/?h=qhe/nfsroot&id=95c6536d33677f177a3aec14f61589702b96cbb7
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.
http://git.pokylinux.org/cgit.cgi/poky-contrib/commit/?h=qhe/nfsroot&id=fd51f44f07e1f07d0891082d488a969844bccb2f
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 ==
* etherboot.org - The Etherboot/gPXE Wiki
* nfsroot reference in kernel/Documentation
* NFS-Root mini-HOWOTO (not maintained)