Step-by-step NFS-mounted Root File System
This tutorial is for Developers. It is written to work with the odroidu2-ubuntu or odroidu2-debian SD-Card images [is this specific enough?]
It is not for Android developers.
Contents
Introduction
A common technique for embedded development is to NFS-mount your root file system. This means that all files are actually on a host. The host is configured to export the filesystem. The target (odroid) mounts the filesystem at boot time and uses it as its own. All files are visible on the host.
As targets have increased in storage capacity and speed, the need for NFS-mounting root file systems will decrease. The technique is still useful when bringing up a new port or you have a lot of files that need to change together.
It is common to check in a whole root file system into a source control system for quality control.
Prerequisites
Overview
We are going to:
Steps
Power-up the odroid and abort the boot at u-boot console
Exynos4412 #
Copy/paste the following text to a text editor. You need to make changes. See the comments for an explaination
# replace the ip address below with the ip address of the host you want to NFS-mount # This address must be on the same subnet as your odroid -- no routes are in place # so early in the boot, and neither is DNS. set nfsserverip 10.4.124.93 # replace home/karlo/targetrfs with the host absolute path of the directory you mean to # use for the odroid root file system. This can be a symlink, but it must NFS must be # able to resolve it (it must be on the same filesystem) set rfspath home/karlo/targetrfs # We will use this macro as 'run setnfs' at the u-boot prompt to turn on NFS mounting set setnfs 'set bootdev root=/dev/nfs rw nfsroot=${nfsserverip}:/${rfspath}; saveenv;' # We will use this macro as 'run unsetnfs' at the u-boot prompt to turn off NFS mounting set unsetnfs 'set bootdev;' # this step saves the u-boot environment variables we just set saveenv
Now boot the odroid, nothing we did so far is going to change the boot.
run bootcmd
Mount the boot partition read-write, if it is not already mounted. The Debian images do not mount the boot partition (at this time)
mount /dev/mmcblkp1 /boot cd /boot <pre> This is the current boot.scr (yours may be different): <pre> setenv initrd_high "0xffffffff" setenv fdt_high "0xffffffff" setenv bootcmd "fatload mmc 0:1 0x40008000 zImage; fatload mmc 0:1 0x42000000 uInitrd; bootm 0x40008000 0x42000000" setenv bootargs "console=tty1 console=ttySAC1,115200n8 root=UUID=e139ce78-9841-40fe-8823-96a304a09859 rootwait ro mem=2047M" boot
Copy the existing boot script:
cp boot.scr boot-nfs.scr
Edit boot-nfs.scr. Insert ${bootdev} text to give the following:
setenv initrd_high "0xffffffff" setenv fdt_high "0xffffffff" setenv bootcmd "fatload mmc 0:1 0x40008000 zImage; fatload mmc 0:1 0x42000000 uInitrd; bootm 0x40008000 0x42000000" setenv bootargs "${bootdev} console=tty1 console=ttySAC1,115200n8 root=UUID=e139ce78-9841-40fe-8823-96a304a09859 rootwait ro mem=2047M" boot
Compile to a u-boot script like this:
mkimage -T script -A arm -C none -n 'odroid-u2.Boot NFS-mounted RFS' -d boot-nfs.txt boot-nfs.scr
If that works, replace your existing script with the one just made. If not, you do not have the prerequisites to build a kernel. mkimage comes from a u-boot package, listed in prerequisites for kernel building.
mv boot.scr boot.scr.orig cp boot-nfs.scr boot.scr
Now we need a kernel configured to be able to NFS-mount the root file system and the network driver needs to be built-in, not a kernel module. Maybe it is easiest to just pick up the configuration I used... Or you could look at the patch. Browse here: Example files
You need to somehow get the configuration to the area you are building the kernel. If it is on the target, it would be /usr/src/linux.
cd /usr/src/linux wget http://odroid.us/odroid/users/osterluk/nfs-mounting/odroidu2_ubuntu_nfs_defconfig mv odroidu2_ubuntu_nfs_defconfig arch/arm/configs # now use the new configuration make odroidu2_ubuntu_nfs_defconfig # build the kernel make -j8 zImage # copy it out to the boot partition cp arch/arm/boot/zImage /boot
At this point, you can still boot normally. The capability to NFS mount the kernel will not stop from mounting the flash-located root file system.
Setting up Target Root File System
# go home cd ~ # make a place to hold the target root file system mkdir targetrfs chmod 777 targetrfs cd targetrfs # You need to expand the RFS image as root, or you will lose the required device nodes sudo tar -xvzf ../odroidu2_20130104-debian-wheezy-2-rootfs.tgz cd ..
Setting up NFS export
# configure to export the target root file system with no restrictions sudo echo "/home/$USER/targetrfs *(rw,no_root_squash,no_subtree_check)" >> /etc/exports # On Debian/Ubuntu host: sudo /etc/init.d/nfs-kernel-server restart # On a SuSE 11.4 host, it looks like this: # sudo /etc/init.d/nfsserver restart
Testing NFS Export
# go home cd ~ # create a mount point and set permissions mkdir mnt chmod 777 mnt sudo mount -t nfs localhost:/home/$USER/targetrfs mnt # test to make sure we have write access echo xyx > mnt/test.txt sudo umount mnt
Selecting NFS-mount
Abort booting at the u-boot console
# select the nfs-mounted RFS configuration. You would use run unsetnfs to go back to normal mount run setnfs <pre> === Testing NFS-mounted RFS === Reboot the target and watch the boot progress. You can power-cycle or do 'run bootcmd' at the u-boot prompt. Once you see the IP-Config lines, you know you succeeded. <pre> Begin: Loading essential drivers ... done. Begin: Running /scripts/init-premount ... done. Begin: Mounting root file system ... Begin: Running /scripts/nfs-top ... done. [ 5.399441] ADDRCONF(NETDEV_UP): eth0: link is not ready [ 6.975337] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready [ 6.976319] smsc95xx 1-2:1.0: eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1 IP-Config: eth0 hardware address ce:dd:54:19:96:0b mtu 1488 DHCP RARP IP-Config: no response after 2 secs - giving up IP-Config: eth0 hardware address ce:dd:54:19:96:0b mtu 1488 DHCP RARP IP-Config: eth0 guessed broadcast address 10.4.127.255 IP-Config: eth0 complete (dhcp from 10.1.0.219): address: 10.4.124.209 broadcast: 10.4.127.255 netmask: 255.255.128.0 gateway: 10.4.0.1 dns0 : 10.1.0.83 dns1 : 10.1.0.84 domain : echelon.echcorp.com rootserver: 10.1.0.41 rootpath: filename : k2000.0 Begin: Running /scripts/nfs-premount ... done. Begin: Running /scripts/nfs-bottom ... done. done. Begin: Running /scripts/init-bottom ... done. INIT: version 2.88 booting
Here is more proof:
root@odroidu2-1:~# mount sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) udev on /dev type devtmpfs (rw,relatime,size=10240k,nr_inodes=168964,mode=755) devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620) tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=203124k,mode=755) '''10.4.124.93:/home/karlo/targetrfs on / type nfs (rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,proto=tcp,port=2049)''' tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k) tmpfs on /run/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=406240k) root@odroidu2-1:~#