It was my turn to take care of the garbage the other day (yeah, I have to do it every once in a while but this time I was glad it was my turn) and realized someone left pieces of old computer equipment. There was some Pentium and Pentium II motherboards, memory and network cards, etc. Undoubtedly it is all obsolete equipment nowadays for the average brainwashed consumer who believes you can't browse the web with less than 512Mb of RAM and a 3Ghz processor...

Well, while staring at those computer parts I started thinking all the things I could do with them. The first thing that crossed my mind was that I had a couple of old quickcam cameras in my basement. I thought these motherboards would be great for capturing images and doing motion detection, so I grabbed them all : ) 

All motherboards where in perfect condition. The first thing to resolve was: storage, as I just can't have noisy hard drives spinning all over the house. I had to come up with a better solution, and that is either a high capacity flash drive or ... a remote filesystem. Some of the network cards were PXE enabled, and therefore I decided to go that way. It was fun to get all this stuff together. In case someone else is interested in doing this, here is my HOWTO:

In order to boot linux on a diskless computer using a remote filesystem, two pieces of equipment are required:

Client: A PC computer with a PXE-enabled NIC (network card). No hard drive required (and no video required once you know it all works fine). Most of the cheap Realtek RTL8139 based network cards do not include this feature, but pretty much all PCI 3Com cards do. If you don't know if your card features PXE, simply remove all boot drives from your PC and power it up. It will give up trying to find a boot drive and then the network card will kick in. Your NIC will display some information and then it will try to find a DHCP server. If this doesn't happen, most likely you will have to find another card.

Server: A linux computer featuring: DHCP Server, TFTP Server, NFS Server and the PXELINUX linux loader.

The way it all works and interacts is as follows:

1- Your network card obtains an IP address from your server, along with the location of a TFTP server and an initial file to be downloaded (your bootloader)
2- Your network card initiates a TFTP connection to your server and downloads the boot loader (pxelinux)
4- Your network card executes pxelinux
5- pxelinux downloads via TFTP its configuration, where the linux kernel location and its parameters are specified
6- Your linux kernel loads (with pre-compiled nfsboot support)
7- Your linux kernel configures an IP address in your computer and connects to the NFS server, as specified in the kernel parameters. Your root filesystem is mounted on the remote NFS server.
8- Your linux system boots up.

From the client side, all you need is the computer booting and the network card looking for a DHCP. If you've gotten this far, your client PC is ready.

As far as the server, there are quite a few things to do. I will start assuming you are using a Debian-based linux distribution. If you are not, maybe is time to think about it ; ) . Get ready:

DHCP Server

Install your DHCP Server from a root console with:

apt-get install dhcp


That it is, your server is up and running but is not yet configured properly. Replace the contents of your /etc/dhcpd.conf file with:

allow booting;
allow bootp;
server-identifier 192.168.0.1;

subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.10 192.168.0.20;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.0.255;
default-lease-time 600;
max-lease-time 7200;
}

group {
next-server localhost;
filename "/tftpboot/pxelinux.0";

host hostname {
hardware ethernet 00:32:23:55:68:7A;
fixed-address 192.168.0.122;
}
}


And restart your dhcp server with:

/etc/init.d/dhcp restart


In this example, we are using 192.168.0.1 for the server IP address. Make sure your server IP matches your server-identifier. Also, make sure localhost resolves with the same IP. In my case I have remarked the 127.0.0.1 entry in my /etc/hosts and I left instead an entry:

192.168.0.1 localhost


I'm sure there is a better way to address this issue, but I'm too lazy. If you fail to do this, your client computer will try to connect to the TFTP server in 127.0.0.1 (which will never happen).

Also, you must define a fixed-address for your client NIC's MAC address. In this case the MAC address is (let's say) 00:32:23:55:68:7A and the IP address we will assign for it is 192.168.0.122.

If your DHCP server is configured correctly, you will see something like this:

PXELINUX boot screenshot

Make sure your DHCP IP shows the right IP address. Of course, the PXE section will only work when you complete the following steps.


LINUX KERNEL

I'm not going to go through the details of how to compile your kernel. I have already explained that in previous articles:

http://julian.coccia.com/article-68.html

First, make sure your compile the kernel for the right processor on your client PC:

Processor type and features -> Subarchitecture Type ->


Then, compile support for the network card in your client computer. For example:

Device Drivers -> Networking support ---> Ethernet (10 or 100Mbit)
[*] 3COM cards
< *> 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support (NEW) ->

Enable automatic IP address configuration:

[*] Networking support
Networking options --->
< *> Unix domain sockets
[*] TCP/IP networking
[*] IP: kernel level autoconfiguration
[*] IP: DHCP support
[*] IP: BOOTP support
[*] IP: RARP support


(make sure you are not compiling anything as kernel modules, use < *>)

Next, compile NFS support as follows:

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


Exit and compile your kernel with: make

Create a directory named /tftpboot and place your kernel in there:

mkdir /tftpboot
cp arch/i386/boot/bzImage /tftpboot


PXELINUX

Download and uncompress the latest copy of SYSLINUX at: http://syslinux.zytor.com/pxe.php. You will find there a file called pxelinux.0. Place a copy of this file in your /tftpboot directory:

cp pxelinux.0 /tftpboot


Now, create a pxelinux configuration directory:

mkdir /tftboot/pxelinux.cfg


Now, a configuration file must be created for each client PC. The file will be named 01- followed by the client's MAC address. In my case it will be:

/tftboot/pxelinux.cfg/01-00-32-23-55-68-7A


The file contents follow below:

display display.txt
prompt 1
default L
timeout 50
label L
kernel vmlinuz
append rw root=/dev/nfs nfsroot=192.168.0.1:/linespa ip=192.168.0.55:192.168.0.1:192.168.0.1:255.255.255.0:CAMERA1:eth0


In the example above, a display.txt file will be displayed, followed by a "boot:" prompt that will wait for 5 seconds and then will boot up the vmlinuz kernel image along with a bunch of parameters. Pay special attention to all these parameters.

root=/dev/nfs tells the kernel to use the directory specified in the NFS server as the root filesystem.

nfsroot= defines the IP address and the directory where the root filesystem is located.

ip= defines (in this order) the local IP address, the server IP address, the gateway IP address, the netmask, the hostname and the network device. If you don't know what to do here, my example would be a good start.

Last, create a display.txt file. This text will be prompted when booting up. In my case the file contains:

PXELINUX IS WORKING !!!


TFTP Server

We are done with the contents of the TFTP Server, but we haven't installed the TFTP server yet. There are a number of TFTP Servers around and they all should work as long as they support the TSIZE option. If your TFTP server does not support the TSIZE option, pxelinux will let you know when it tries to boot up.

In my case, I have followed Peter Anvin's suggestion and installed tftpd-hpa as follows:

apt-get install tftp-hpa tfpd-hpa


Note that this installs the server and the client. We want to use the client to test the server locally before trying to connect from the client PC. Now, edit your /etc/inetd.conf file and look for tftp. In my case this is what it looks like:

tftp dgram udp wait root /usr/sbin/in.tftpd /usr/sbin/in.tftpd -s -v -v -v -v /


And restart your inet daemon with:

/etc/init.d/inetd restart


Test your tftp server:

$ tftp localhost
tftp> get /tftpboot/pxelinux.0
tftp> quit


Linux Filesystem

Now we have to set up the Linux Filesystem that we will load on the client PC. In my case, I'm using a LinEspa (Debian) partition already existing in my PC, mounted as /linespa. You can either use your current filesystem or prepare a special one. This is totally up to you. In my case, this is what I have:

$ ls /linespa
bin cdrom etc home lib mnt proc ram1.tar.gz ram2.tar.gz sbin tmp var
boot dev floppy initrd lost+found opt ram1 ram2 root sys usr


NFS Server

The last step is to set up the NFS server and configure the export (shared directory) so that our client PC can access and mount the filesystem.

apt-get install nfs-user-server


Configure your exports in your /etc/exports file:

# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
/linespa (rw)


and restart your NFS daemon with:

/etc/init.d/nfs-user-server restart


In theory, your system is now ready to go. Boot up your client PC and cross your fingers : ) 
If you have any questions, feel free to email me.


All knowledge and software published in this website is released under the GNU General Public License (GPL)