Thursday, December 18, 2008

Gumstix NFS boot

After a long time, I've had a chance to pick up the pieces of my project again. So this time, I was trying to get the stix to boot off the network. This saves tremendous time over manual transferring the kernel and rootfs over serial. Manual process also requires several steps and is therefore a wasteful process as one can't leave the stix and do something else.

Anyhoo... so booting a device off the network requires a few fundamental things:

1. a server hosting the kernel image (typically bootp or tftp). I chose tftp because it seemed to be the easy thing to do
2. server hosting the root file system. this is typically over nfs
3. setting arguments in boot loader so that the kernel may be started with the proper settings
4. configuring the rootfs so that it knows it is being booted off the network.

Before going any further, READ THESE first:
1. Gumstix wiki on NFS root
2. Gumstix UBoot wiki
3. http://www.denx.de/wiki/view/DULG/UBoot">Uboot wiki

I installed the following in Ubuntu:
tftp tftpd nfs nfsd portmap
wireshark (formerly known as Ethereal)

for nfs setup follow guidelines here http://nfs.sourceforge.net/nfs-howto/ar01s02.html

my hosts.allow looks as below (found in /etc/ = NFSROOT_ETC):


portmap: 192.168.1.100 , 192.168.1.101 , 192.168.1.104
lockd: 192.168.1.100 , 192.168.1.101 , 192.168.1.104
mountd: 192.168.1.100 , 192.168.1.101 , 192.168.1.104
statd: 192.168.1.100 , 192.168.1.101 , 192.168.1.104


192.168.1.100 = gumstix
192.168.1.101 = laptop (ubuntu 7.1)
192.168.1.104 = server (ubuntu 8.1)

these were setup static ip in my router set up (details follow later in the blog)

my hosts.deny looks as below (NFSROOT_ETC/hosts.deny):


lockd:ALL
mountd:ALL
rquotad:ALL
statd:ALL


NFSROOT_ETC/exports looks as below. this sets up the nfs share

/home/hypo/gumstix/nfsroot 192.168.1.100(rw,sync,no_root_squash) 192.168.1.101(rw,sync) 192.168.1.104(rw,sync)


This directory is different from the gumstix root folder (~/gumstix/gumstix-buildroot-1614/build_arm_no_fpu/root = GUMSTIX_ROOT) because i don't want any inadvertent modifications on the stix to ruin all later builds. This was any changes are localized to the stix (till I overwrite the root fs).

Command for copying over the root folder:

cp -a /build_arm_no_fpu/root/* ~/gumstix/nfsroot


Tftp boot is started (on host machine, not gumstix) with the following command:

sudo in.tftpd -l -s /tftpboot/ -r blksize -r blksize2 -v -v -v -v -v -B 1024


this starts up tftpd in standalone mode (more later on how to launch this at startup). The "-B 1024" option limits blocksize to 1024. -r blksize and -r blksize2 prevent negotiation on the block size. I did this because I was initially seeing some problems getting tftp to work reliably. The repeated -v options increase verbosity on the server (though I couldn't figure out where syslog goes). -s /tftpboot/ tells the server to change root systems to indicated path. This is the location where uImage must be copied to.

UBoot variables need to be set to ensure it boots from tftp as follows. Remember to printenv and save off default UBoot environment in case you need to flip back.

To enable TFTP boot and root over NFS

-------------------------------------
setenv bootargs 'console=ttyS0,115200n8 root=/dev/nfs rw nfsroot=192.168.1.101:/home/hypo/gumstix/nfsroot,nolock,rsize=1024,wsize=1024 ip=192.168.1.100:192.168.1.101:::::off\; tftpb a2000000 uImage && bootm a2000000'
setenv bootcmd 'tftpb a2000000 uImage; bootm a2000000'
setenv serverip 192.168.1.101
setenv ipaddr 192.168.1.100
-------------------------------------


Some options in the commands above are different from those specified in the Gumstix NFS Root wiki. In particular.

rsize=1024,wsize=1024 specify that the nfs server must limit packet sizes to 1024 bytes. As before, this is to prevent IP fragmentation and associated problems (Gumstix maynot be able to assemble packets correctly). Typically router sizes are 1500 (=MTU).

To revert back

-------------------------------------
setenv bootargs 'console=ttyS0,115200n8 root=1f01 rootfstype=jffs2 reboot=cold,hard'
setenv bootcmd 'icache on; setenv stderr nulldev; setenv stdout nulldev; if pinit on && fatload ide 0 a2000000 gumstix-factory.script; then setenv stdout serial; setenv stderr serial; echo Found gumstix-factory.script on CF...; autoscr; else if mmcinit && fatload mmc 0 a2000000 gumstix-factory.script; then setenv stdout serial; setenv stderr serial; echo Found gumstix-factory.script on MMC...; autoscr; else setenv stdout serial; setenv stderr serial; katload 100000 && bootm; fi; fi'
-------------------------------------


remember to 'saveenv' after chaning environment variables.

Changes in Gumstix root fs / kernel

Follow Gumstix NFS Root wiki to change fstab and init.d/ dirs. Also do the following, which aren't mentioned in the wiki:

For netmicroSD boards, ethernet chip is SMC911x. Ensure that this is enabled in the kernel (not module, built in) and SMC91x is NOT.

/build_arm_nofpu/linux-2.6.21gum/.config contains the following section. Follow instructions in Gumstix NFS Root wiki to change these options using make ARCH=arm menuconfig


#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
CONFIG_SMC911X=y
CONFIG_SMC911X_GUMSTIX=y


If the above isn't set correctly, Gumstix won't be able to mount NFS correctly.

Edit GUMSTIX_ROOT/etc/network/interfaces and comment out anything that brings up / tears down eth0. If this isn't done, then typically dhcp kicks in and it is good bye NFS. Then the system just hangs waiting for NFS ROOT (NFS Root 192.168.1.101 time out. Still trying)

GUMSTIX_ROOT/etc/network/intefaces now looks like

# Configure Loopback
auto lo
iface lo inet loopback

iface usb0 inet dhcp

iface bnep0 inet dhcp

#auto eth0 # commented out because eth0 is setup at boot time
iface eth0 inet dhcp

iface eth1 inet dhcp

iface wlan0 inet dhcp



edit GUMSTIX_ROOT/etc/modules and comment out anything that loads ethernet modules, e.g. smc91x, smc911x (as these would already be compiled in the kernel. see below).


# MMC support -- comment the next two lines to enable using CF
#mmc_block
#pxamci

# Compact Flash support -- Must load smc91x or smc911x first!!
#smc91x # comment out modules already loaded in kernel
#smc911x
#pcmcia


# Load USB host driver
ohci-hcd



The above will prevent "-EEXIST module already exists (owned by kernel)" failures when booting up.

Make the kernel and copy over uImage to /tftpboot/ and build_arm_no_fpu/root/* to ~/gumstix/nfsroot.

Copying over rootfs and uImage maybe automated as part of the build/make process. Remember to modify on the GUMSTIX_ROOT/etc/fstab according to the gumstix NFS Root wiki (comment out line for /) before copying over rootfs to nfsroot.


#!/bin/bash
#script to make and copy over images
#place this in ~/gumstix/, e..g ~/gumstix/gumstix-buildroot-1614/makencopy.sh

make
if [ -f uImage ]; then
cp uImage /tftpboot/
fi

if [ -f rootfs.arm_nofpu.jffs2 ]; then
cp -a build_arm_no_fpu/root/* ~/gumstix/nfsroot
fi

No comments: