Difference between revisions of "Step-by-step NFS-mounted Root File System"

From odroid US
Jump to: navigation, search
Line 123: Line 123:
  
 
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.
 
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 ===
 +
<pre>
 +
# 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 ..
 +
</pre>
  
 
=== Setting up NFS export ===
 
=== Setting up NFS export ===
 +
<pre>
 +
# 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
 +
</pre>
  
 
=== Testing NFS Export ===
 
=== Testing NFS Export ===
 +
<pre>
 +
# 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
 +
</pre>
  
 
=== Selecting NFS-mount ===
 
=== Selecting NFS-mount ===
 +
Abort booting at the u-boot console
 +
<pre>
 +
# select the nfs-mounted RFS configuration.  You would use run unsetnfs to go back to normal mount
 +
run setnfs
 +
<pre>
  
=== Testing NFS-mount ===
+
=== 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
 +
</pre>
  
 +
Here is more proof:
 +
<pre>
 +
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:~#
 
</pre>
 
</pre>

Revision as of 22:36, 17 January 2013

THIS TOPIC ACTIVELY BEING EDITED. IT IS NOT COMPLETE

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.

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

  • You MUST have access to the serial console -- use the USB/Serial adapter [check actual Hardkernel name]
  • You need to be able to edit files on the odroid, or how to move them to a host and back for editing
  • You need to know how to build a kernel. There are many ways to do it. This tutorial walks through a native kernel build: Kernel Compiling
  • You need to know how to abort booting at the u-boot console. [http://odroid.us/mediawiki/index.php?title=U-boot_Topics&action=view&section=5 Abort boot at u-boot console]
  • You will need some patience... NFS exporting and mounting can be frustrating

    Overview

    We are going to:

  • Add some u-boot environment variables to steer the boot process
  • Mount the boot partition read/write
  • Compile a custom u-boot script to add parameters to the kernel command line
  • Replace the standard boot.scr with our custom one
  • Setup the root file system directory
  • Configure NFS-exports
  • Test the NFS server
  • reboot and see that we actually are running from files living on the host

    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:~#