How to Create a Diskless Linux Target

When developing for an Embedded Linux target it is always desirable to shorten your development cycle. The following article explains about how to use an x86 machine (AMD Duron) as a diskless embedded target and use a virtual machine running Linux to setup this development environment. The virtual machine running Linux listens on TFTP and NFS servers to provide a bootable kernel image and a mounted root file system respectively for the diskless client. The development time is reduced as we need not reinstall the kernel and/or root file system every time on the target. We develop device drivers and kernel code on the host and simply reboot the target to load and test.


TARGET @ IP adderess :
x86 target machine with :
+ AMD Duron processor (800 MHz)
+ 128 MB RAM
+ Intel Pro100 LAN Card
+ floppy drive

HOST @ IP address :
+ linux virtual machine running RHEL4
+ linux kernel 2.6.26
+ grub 0.95
+ tftp server
+ NFS server


The target board is booted via grub floppy, the menu to select the kernel to load will be downloaded via the tftp server on the target. The menu selection provides list of linux kernels to boot which will in turn be downloaded from the same tftp server. Also the root file system for the kernel will be mounted as NFS residing on the host. So lets get started ...

As a general convention we need to create a world read/writable directory /tftpboot/ which holds the Root file system.

# cd /
# mkdir tftpboot
# mkdir /tftpboot/
# mkdir /tftpboot/


GRUB stands for GRand Unified Boot Loader which is a boot loader used to fetch the linux kernel via the TFTP server running on the host virtual machine.

Download GRUB from ftp://alpha.gnu.org/gnu/grub/

Extract grub for e.g. grub-0.95.tar.gz on the host

# tar zxvf grub-0.95.tar.gz
# cd grub-0.95

Have a look at /grub-0.95/netboot/README.netboot to get a list of supported network cards.

We need to configure the grub for network booting with the lan card i.e. Intel Pro 100 support in built so that it can transfer files using the LAN card. Also note that we hardcoded the IP addresses of target and host and do not use DHCP in this setup.

# echo "ifconfig --address= --server=" >mypreset
# ./configure --enable-eepro100 --enable-preset-menu=mypreset
# make

Copy the /boot/message and /boot/menu.lst files to target root file system as follows :

# cp -av /boot/message /tftpboot/
# cp -av /boot/menu.lst /tftpboot/

Edit the target root filesystem menu.lst as follows :

# cat /tftpboot/

gfxmenu (nd)/boot/message
color white/blue black/light-gray
default 1
timeout 8

title Linux 2.6.26 test - linux virtual machine
root (nd)
kernel /boot/linux-2.6.26 rw ip= root=/dev/nfs nfsroot=

This menu.lst file will provide a graphical selection of list of available kernels to boot.

Creating GRUB Boot Floppy

The make command above generates stage1 and stage2 file in /stage1 and /stage2 directories respectively.
Next put a formatted floppy in to floppy disk drive of the host and run following commands (assuing you are @ ../grub-0.95/)

# cd stage1
# dd if=stage1 of=/dev/fd0
# cd ..
# cd stage2
# dd if=stage2 of=/dev/fd0 seek=1

Try the floppy by booting the target with the floppy. If the floppy is OK you should get a grub prompt like :

GNU GRUB version 0.95 (640K lower / 3072K upper memory)

[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename. ]


As the name suggests the boot floppy provides initial boot screen and grub prompt which will be used to get the menu.lst file from TFTP server so that we get to select the kernel image to boot.

Try 'help' command on the grub> prompt to see the supported commands by grub.

Compiling the linux kernel

Next step is preparing the kernel.

Download the linux kernel from http://www.kernel.org

for e.g. linux-2.6.26.tar.bz2 and extract it.

# tar zxvf linux-2.6.26.tar.bz2
# cd linux-2.6.26

Configure the kernel using following commands :

# make mrproper
# make i386_defconfig
# make menuconfig

We need to build the kernel with inbuilt support for the ethernet card i.e. Intel Pro 100 and NFS. Select following from the menuconfig and include them as built into (showing *) the kernel rather than as modules (showing M).
Network device support --->
Ethernet (10 or 100Mbit) --->
EtherExpressPro/100 support (eepro100, original Becker driver)
Intel(R) PRO/100+ support

File systems --->
Network File Systems --->
NFS file system support
[*] Provide NFSv3 client support
[*] Root file system on NFS

Save the kernel configuration and compile the kernel as follows :

# make all

be patient it will take a while....

This creates compressed kernel image @ ../linux-2.6.26/arch/x86/boot/bzImage. Copy it to our root file system.

# cp -av arch/x86/boot/bzImage /tftpboot/

Preparing the root file system

Now as we have the kernel compiled, let's prepare the root file system for the kernel. Create the directories of the root file system :

# mkdir /tftpboot/
# mkdir /tftpboot/
# mkdir /tftpboot/
# mkdir /tftpboot/
# mkdir /tftpboot/
# mkdir /tftpboot/
# mkdir /tftpboot/
# mkdir /tftpboot/
# mkdir /tftpboot/
# mkdir /tftpboot/

We are using the host root file system as a base to create root file system for target and thus copy the required minimal set to files to the target root file system from host file system.


Copy following /dev entries :

# cp -dpRv /dev/fd[01]* /tftpboot/
# cp -dpRv /dev/tty[0-6] /tftpboot/
# cp -Rv /dev/console /tftpboot/
# cp -Rv /dev/kmem /tftpboot/
# cp -Rv /dev/mem /tftpboot/
# cp -Rv /dev/null /tftpboot/
# cp -Rv /dev/ram0 /tftpboot/


Copy following /etc entries :

# cp -av /etc/fstab /tftpboot/
# cp -av /etc/group /tftpboot/
# cp -av /etc/inittab /tftpboot/
# cp -av /etc/mtab /tftpboot/
# cp -av /etc/nsswitch.conf /tftpboot/
# cp -av /etc/passwd /tftpboot/
# cp -av /etc/protocols /tftpboot/
# cp -av /etc/rc /tftpboot/
# cp -av /etc/services /tftpboot/
# cp -av /etc/shadow /tftpboot/
# cp -av /etc/termcap /tftpboot/
# cp -av /etc/fstab /tftpboot/
# mkdir /tftpboot/
# cp -dpR /etc/rc.d /tftpboot/

Edit target root file system /etc/fstab as follows :

# cat /tftpboot/
/dev/ram0 / ext2 defaults 0 0
/dev/fd0 / ext2 defaults 0 0
none /proc proc defaults 0 0 / nfs defaults 1 1

This will mount the NFS filesystem as the root filesystem everytime the target is rebooted.

Edit target root file system /etc/initab as follows :

# cat /tftpboot/

The inittab sets the runlevel to 2 and calls the /etc/rc script to setup the system.

Edit target root file system /etc/rc as follows :

# cat /tftpboot/
#! /bin/bash
mount -n -t proc /proc /proc
[ -d /proc/bus/usb ] && mount -n -t usbfs /proc/bus/usb /proc/bus/usb
mount -n -t sysfs /sys /sys >/dev/null 2>&1

This rc srcipt mounts the proc file system to /proc and sets the shell as bash at the end of initialization.

Be sure it is executable, be sure it has a "#!" line at the top, and be sure any absolute filenames are correct.

Edit target root file system /etc/nsswitch.conf as follows :

# cat /tftpboot/
passwd: files
shadow: files
group: files
hosts: files
services: files
networks: files
protocols: files
rpc: files
ethers: files
netmasks: files
bootparams: files
automount: files
aliases: files
netgroup: files
publickey: files

The file is used to configure which services are to be used to determine information such as hostnames, password files, and group files.


# cp -av /lib/ld* /tftpboot/
# cp -av /lib/libc.* /tftpboot/
# cp -av /lib/libutil.* /tftpboot/
# cp -av /lib/libncurses.* /tftpboot/
# cp -av /lib/libdl.* /tftpboot/
# cp -av /lib/libnss_dns* /tftpboot/
# cp -av /lib/libnss_files* /tftpboot/
# cp -av /lib/libresolv* /tftpboot/
# cp -av /lib/libproc* /tftpboot/
# cp -av /lib/librt* /tftpboot/
# cp -av /lib/libpthread* /tftpboot/
# cp -av /lib/libm* /tftpboot/
# cp -av /lib/libselinux* /tftpboot/
# cp -av /lib/libattr* /tftpboot/
# cp -av /lib/tls/lib* /tftpboot/

ldd command will list the library dependencies for a command

# ldd /bin/ls
librt.so.1 => /lib/tls/librt.so.1 (0x0040c000)
libacl.so.1 => /lib/libacl.so.1 (0x005f3000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00cb9000)
libc.so.6 => /lib/tls/libc.so.6 (0x0049b000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x006f6000)
/lib/ld-linux.so.2 (0x0047d000)
libattr.so.1 => /lib/libattr.so.1 (0x00cc9000)

The libraries on the RHS of => needs to be copied to the host root file system to enable the command to run on the target.

[root@purnendurhel4 lib]# ldd /sbin/mke2fs
libext2fs.so.2 => /lib/libext2fs.so.2 (0x00cd9000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x00dd2000)
libblkid.so.1 => /lib/libblkid.so.1 (0x005cf000)
libuuid.so.1 => /lib/libuuid.so.1 (0x00496000)
libe2p.so.2 => /lib/libe2p.so.2 (0x005c8000)
libc.so.6 => /lib/tls/libc.so.6 (0x0049b000)
/lib/ld-linux.so.2 (0x0047d000)
[root@purnendurhel4 lib]# cp -av /lib/libcom* /tftpboot/
cp: overwrite `/tftpboot/'? n
cp: overwrite `/tftpboot/'? n
[root@purnendurhel4 lib]# cp -av /lib/libblk* /tftpboot/
`/lib/libblkid.so.1' -> `/tftpboot/'
`/lib/libblkid.so.1.0' -> `/tftpboot/'
[root@purnendurhel4 lib]# cp -av /lib/libuuid* /tftpboot/
`/lib/libuuid.so.1' -> `/tftpboot/'
`/lib/libuuid.so.1.2' -> `/tftpboot/'
[root@purnendurhel4 lib]# cp -av /lib/libe2p* /tftpboot/
`/lib/libe2p.so.2' -> `/tftpboot/'
`/lib/libe2p.so.2.3' -> `/tftpboot/'

TFTP server

The TFTP server provides the menu selection and the linux kernel to the target machine.

Download and install TFTP server as follows :

# rpm -ivh tftp-server-0.39-3.el4.i386.rpm

This will install the TFTP server in /usr/sbin/in.tftpd

we need to run the tftp server in standalone mode using following command.

#/usr/sbin/in.tftpd -l -vv -p -s /tftpboot/

-l standalone mode
-vv verbose log messages
-p ignore permissions on the file/directory
-s start the tftpd @ this directory as root

NFS server

Make sure that NFS server is installed and running by :

# service nfs status
Shutting down NFS mountd: rpc.mountd (pid 2628) is running...
nfsd (pid 2622 2621 2620 2619 2618 2617 2616 2615) is running...
rpc.rquotad (pid 2602) is running...

Edit /etc/exports on the host to enable the root file system we created available as an NFS share.

# cat /etc/exports

Once all the configuration mentioned above is done, now it is time to check the system working.Boot the target using the grub boot floppy we created earlier. On the grub prompt :

grub> configfile (nd)/boot/menu.lst

You will get the menu showing the list options. Select the entry you want to boot and press enter !! You should see a bash prompt on the target.

This tutorial can be viewed at www.techtutorials.net

Quote this article in website Print Send to friend Related articles

Users' Comments (3) RSS feed comment

Posted by Gavin Nottage, on 02-10-2008 15:02,
1. ...
If you want to add a menu to the grub boot from floppy, then concatenate the ifconfig line with your grub.conf or menu.lst file and pass the resulting file as the value for --enable-preset-menu.
» Report this comment to administrator

Posted by Gavin Nottage, on 03-09-2008 14:46,
2. ...
The menu.lst file may actually be in /boot/grub rather than just /boot
» Report this comment to administrator

Posted by Ed Liversidge, on 27-08-2008 15:43,
3. ...
Great article!
» Report this comment to administrator

Add your comment

mXcomment 1.0.8 © 2007-2015 - visualclinic.fr
License Creative Commons - Some rights reserved