Network-Mounting the root Filesystem
tbdevarm's root filesystem, generated by the buildrootfilesystem script, contains the cross-compiled version of helloworld and gdbserver. Changing the helloworld source code would require completely rebuilding the root filesystem, rebooting the MediaEngine, and then downloading the kernel and root filesystem again. Even though the MediaEngine boots quickly, taking this approach over time would become tedious and time-consuming.
Instead of transferring the root filesystem, you can mount it over the Ethernet network by using NFS. With a network-mounted root filesystem, you can generate the ARM cross-compiled version of helloworld.c on tbdev1. Then you can directly execute it or remotely debug it without regenerating the MediaEngine root filesystem or rebooting. The buildrootfilesystem script creates the minimum root filesystem in the /tftpboot directory and can be NFS-mounted directly.
The Unix world commonly uses NFS to mount hard disks on remote computers. For example, a server can share its /home directory for user workstations or the /tftpboot directory for diskless workstations to mount their root filesystem. (Note that diskless workstations and the Project Trailblazer target platforms use TFTP, not NFS, to download their kernels.) The Linux kernel itself contains NFS code, which allows the kernel to mount its own root filesystem during the boot process.
In this section, you'll learn how to configure tbdev1 to act as an NFS server and configure the target board's kernel options for network-mounting their root file systems.
Configuring the NFS Server
tbdev1 serves as the Project Trailblazer target root filesystem NFS server. You can configure it to serve the i386 files to the i386 target (MZ104 and COTS PC), the ARM files to the ARM target (MediaEngine), and the PowerPC files to the PowerPC target (RPX-CLLF). As you can tell, it's important to serve the correct files to each architecture. Figure 5.2 shows the Project Trailblazer development computers and their IP addresses.
Figure 5.2. The Project Trailblazer development stations and their IP addresses.
Here are the steps to install, configure, and run the NFS server on tbdev1:
Install the NFS server on tbdev1:
root@tbdev1: apt-get install nfs-server
Configure tbdev1's NFS server by adding an entry to its configuration file, /etc/exports, for each target platform. Each entry contains a directory, an IP address, and mounting permission options. To do so, add these lines to /etc/exports:
/tftpboot/arm-rootfs 192.168.1.21(rw,no_root_squash) /tftpboot/powerpc-rootfs 192.168.1.22(rw,no_root_squash) /tftpboot/i386-rootfs 192.168.1.23(rw,no_root_squash) /tftpboot/i386-rootfs 192.168.1.24(rw,no_root_squash)
The mounting permissions shown here are rw and no_root_squash. rw allows the clients (the target boards) to mount their root filesystems with read and write permissions. The no_root_squash option allows the clients to mount their root filesystems as user root on tbdev1. See the exports man page for more information.
Line 1 of the /etc/exports configuration file says that the MediaEngine with an ARM processor at IP address 192.168.1.21 now has NFS read and write mounting access to the /tftpboot/arm-rootfs directory. Similarly, the RPX CLLF with a PowerPC processor at IP address 192.168.1.22 has NFS read and write mount access to the /tftpboot/powerpc-rootfs directory. Finally, the Tri-M and COTS PC with i386 processor at IP addresses 192.168.1.23 and 192.168.1.24 have NFS read and write access to the /tftpboot/i386-rootfs directory.
Make /etc/exports readable by all:
root@tbdev1: chmod 444 /etc/exports
The NFS server reads the /etc/exports configuration file at startup, so you need to tell it to reload its configuration:
root@tbdev1: /etc/init.d/nfs-server reload
The NFS server is now configured and ready for NFS mounting by the targets.
Configuring the Target Kernels
During the boot process, the bootloader passes the root filesystem location to the kernel, using the boot prompt mechanism. The ARM and PowerPC bootloaders are configured during the kernel configuration process. On x86 platforms, the Linux loader (lilo) is configured to pass the root filesystem location to the kernel.
lilo is configured using the /etc/lilo.conf file. Both kernel compilation and lilo configuration result in the root filesystem location being passed to the kernel. Without root filesystem location information, the kernel can't mount its root filesystem and stops, with a "kernel panic."
You can supercede the root filesystem location by entering new location information at the Linux boot: prompt. See the Linux BootPrompt HOWTO6 for more information. This section does not use the boot prompt because of the length of the NFS server root filesystem location information.
In the following steps, you'll compile the MediaEngine ARM kernel for NFS mounting of the ARM root filesystem; the other platforms are similarly configured, except that their IP addresses and root filesystem paths are different:
Change directory to the ARM kernel source and run make menuconfig:
root@tbdev1: cd /usr/src/arm-linux/ root@tbdev1: make menuconfig
Scroll and select General setup, and scroll and select Default kernel command string:. Then, enter the following string in the dialog box (as all one string, with no returns):
root=/dev/nfs nfsaddrs=192.168.1.21:192.168.1.11::255.255.255.0:tbdevarm:eth0:off nfsroot=192.168.1.11:/tftpboot/arm-rootfs,rw
The Linux BootPrompt HOWTO 6 fully explains the nfsaddrs parameters.
Select OK. Continue to select exit until you're asked to save your configuration; then save it.
Make a new kernel by using make zImage:
root@tbdev1: make zImage
Copy the new kernel image to /tftpboot/arm-zImage-NFS and make it readable by all:
root@tbdev1: cp arch/arm/boot/zImage /tftpboot/arm-zImage-NFS root@tbdev1: chmod 444 /tftpboot/arm-zImage-NFS root@tbdev1: ls -l /tftpboot/arm-zImage* -r--r--r-- 1 root root 646240 Aug 24 15:16 /tftpboot/arm-zImage -r--r--r-- 1 root root 646308 Aug 28 22:19 /tftpboot/arm-zImage-NFS
Rebuild the arm-rootfs directory, using the buildrootfilesystem script:
root@tbdev1: cd /root/cross/ root@tbdev1: ./buildrootfilesystem arm
Check for the arm-rootfs directory. It should be located in /tftpboot:
root@tbdev1: cd /tftpboot/ root@tbdev1: ls -l total 6972 -r--r--r-- 1 root root 1705333 Aug 24 16:16 arm-ramdisk.gz drwxr-xr-x 10 root root 4096 Aug 24 16:13 arm-rootfs/ -r--r--r-- 1 root root 646240 Aug 24 15:16 arm-zImage -r--r--r-- 1 root root 646308 Aug 28 22:19 arm-zImage-NFS
All the pieces are in place to boot the MediaEngine by using NFS mounting of its root filesystem:
/tftpboot/arm-zImage-NFS the ARM kernel with NFS mounting exists /tftpboot/arm-rootfs the ARM root filesystem exists /etc/exports the NFS Server on tbdev1 configured
Reboot the MediaEngine, tbdevarm. Use minicom on tbdev1 to download the arm-zImage-NFS kernel file via TFTP, and then boot the arm-zImage-NFS kernel:
root@tbdev1: minicom Boot: BSE 2001 R1.0 SN# 00:50:15:03:00:19 >load arm-zImage-NFS c0008000 loading ... 646308 bytes loaded cksum 00007361 done >go c0008000 Uncompressing Linux............................ done, booting the kernel. Linux version 2.4.2-rmk1-np2-bse (root@tbdev1) (gcc version 2.95.3 20010315 (release)) #4 Tue Aug 28 22:31:45 MST 2001 Processor: Intel StrongARM-1110 revision 6 Architecture: BSE nanoEngine On node 0 totalpages: 8192 zone(0): 8192 pages. zone(1): 0 pages. zone(2): 0 pages. Kernel command line: root=/dev/nfs nfsaddrs=192.168.1.21:192.168.1.11:: 255.255.255.0: tbdevarm:eth0:none nfsroot=192.168.1.11: /tftpboot/arm-rootfs,rw . . . VFS: Mounted root (nfs filesystem) readonly. Freeing init memory: 52K INIT: version 2.78 booting INIT: Entering runlevel: 2 Starting Network bash-2.04#
You are now back at the bash prompt from tbdevarm, whose kernel network mounted the ARM root filesystem. How can you tell this? At tbdevarm's bash prompt, use echo to generate a file in the /tmp directory. Remember that tbdevarm's /tmp directory is the same as tbdev1's /tftpboot/arm-rootfs/tmp directory:
bash-2.04# echo "This is a NFS root filesystem test" > /tmp/test
Switch to the tbdev1 console, change into the directory /tftpboot/arm-rootfs, and look for the file called test:
root@tbdev1: cd /tftpboot/arm-rootfs/tmp root@tbdev1: ls helloworld-arm-linux helloworld.c test root@tbdev1: cat test This is a NFS root filesystem test
tbdevarm successfully network-mounted its root filesystem with read and write access.
Change helloworld.c on tbdev1, cross-compile it, and execute it on tbdevarm:
root@tbdev1: cd /tftpboot/arm-rootfs/tmp root@tbdev1: cp /root/cross/builds/helloworld.c helloworld5.c
Edit helloworld5.c and change the for loop to count to 5 instead of 10. Cross-compile helloworld5.c, and then verify the cross-compile by using the file program:
root@tbdev1: arm-linux-gcc -g -o helloworld5 helloworld5.c root@tbdev1: ls -l total 60 -rwxr-xr-x 1 root root 22266 Aug 28 23:05 helloworld-arm-linux -rw-r--r-- 1 root root 120 Aug 28 23:05 helloworld.c -rwxr-xr-x 1 root root 22272 Aug 28 23:22 helloworld5 -rw-r--r-- 1 root root 120 Aug 28 23:21 helloworld5.c -rw-r--r-- 1 root root 35 Aug 28 23:16 test root@tbdev1: file helloworld5 helloworld5: ELF 32-bit LSB executable, Advanced RISC Machines ARM, version 1, dynamically linked (uses shared libs), not stripped
Switch back to the minicom console, look for the new helloworld5.c source file and the cross-compiled helloworld5. Now execute helloworld5:
bash-2.04# cd /tmp bash-2.04# ls -l total 60 -rwxr-xr-x 1 0 0 22266 Aug 29 2001 helloworld-arm-linux -rw-r--r-- 1 0 0 120 Aug 29 2001 helloworld.c -rwxr-xr-x 1 0 0 22272 Aug 29 2001 helloworld5 -rw-r--r-- 1 0 0 120 Aug 29 2001 helloworld5.c -rw-r--r-- 1 0 0 35 Aug 29 2001 test bash-2.04# ./helloworld5 Hello world 1 times! Hello world 2 times! Hello world 3 times! Hello world 4 times! bash-2.04#
You can now run the cross-compiler and gdb on the host, tbdev1. The target, with an NFS-mounted root filesystem, can run gdbserver and then execute cross-compiled programs. With this combination, you can dramatically reduce development time by decreasing the compile/run/debug cycle time.