The hard drive in my Linux workstation started getting a bit noisy. The computer is in the center of the house and I quickly tired of listening to the high-pitched whine. Rather than replace the drive, I decided I'd finally figure out how to net boot the machine, eliminating the need to have a hard drive running at all. The machine conveniently had a network card capable of PXE [Pre-boot eXecution Environment (Intel site, a great intro white paper from 3Com)], a 3Com 3C905 which I added an MBA chip to. Most recent 3Com and Intel cards come with the PXE feature built-in so there's no need to add a boot ROM like the MBA.
I didn't want to give up any functionality. I wanted to continue to run a full featured Linux distro (Red Hat in my case). I also wanted something that would be easy to upgrade in the future. (I.e. an upgrade from RH 7.2 to 7.3 should hopefully not be too much more painful than if I just ran it off a local disk.) My experience has been that things that require a lot of disk access (a kernel compile for example) are noticably slower, but general activity (surfing the web, etc.) is pretty much unchanged. (My home directory and most applications already came in over NFS before, so if you have everything local the difference might be more noticable.)
You need a kernel with the following features above and beyond whatever you normally need.
With Red Hat 7.2 I accomplish this step as follows:
In my case I had a perfectly reasonable Red Hat installation on the workstation, and the drive was still working (just noisy). So I just tar'd the root and /var filesystems over to a directory on the NFS server. If you want to net boot a client with no disk at all, you'll have to do something fancier. Once the filesytem was on the server, I made only two changes. The first change was to /etc/fstab to reflect the new location of the root filesytem, and to comment out /var (which was now part of the root filesystem). The second change was to add the following two lines to /etc/rc.d/rc.local to set a spin-down timeout on the hard drive and to actually spin the drive down. I wanted to leave the drive in the system for future upgrades.
hdparm -S 6 /dev/hda hdparm -y /dev/hda
The directory containing the root filesystem must be shared back to the client read/write with root access. The syntax for this varies depending on the server OS. Here are some examples:
The syslinux distribution contains a PXE boot loader called pxelinux. Red Hat comes with a syslinux RPM, but it does not include pxelinux. You can grab syslinux here. The necessary file from the distribution is pxelinux.0. We'll discuss what to do with it in a second.
You need a TFTP server that implemnts the tsize option for pxelinux. In my case my server is running FreeBSD and the bundled TFTP server does not implment tsize, so I replaced it with this one. Red Hat already comes with this TFTP server, you just need to change the disable option to no in /etc/xinetd.d/tftp and run /etc/init.d/xinetd reload.
Place pxelinux.0 in the base directory that is shared by your TFTP server (generally /tftpboot). Also create a directory there called pxelinux.cfg. Copy the kernel you compiled earlier to pxelinux.cfg/. The filename doesn't matter, I use the more or less standard vmlinuz-version. You also need to create a configuration file for pxelinux named after the IP address of your client in hexadecimal. syslinux comes with a handy tool called gethostip to do the conversion for you. A basic config file just needs an entry with the filename of the kernel and a couple of kernel flags to indicate that we're booting from the network, here's a sample. You can specify the path to the root filesystem in this config file or via DHCP, whichever works better for your environment.
The main thing that needs to be configured in DHCP (presuming it is already otherwise configured for your environment) is a pointer to the pxelinux boot loader (pxelinux.0). Here's a sample entry for an ISC DHCP server:
next-server server.example.com; filename "/tftpboot/pxelinux.0";
If you also want to specify the path to the root filesystem via DHCP, you should also add an entry like the following:
option root-path "/export/rootfs";
At this point things should be ready to go. In my case, I have the PXE loader on the NIC configured to prompt for 3 seconds about booting from the net, otherwise it tries to boot from disk. So select net booting. PXE should then go searching for a DHCP server. Presuming it gets an IP address it will next try to grab (via TFTP) the file specified by the filename entry in the DHCP configuration. At this point you should see some information from pxelinux, and then it will go try to get its configuration file. Presuming that succeeds it should download the kernel and execute it. The kernel will go through it's usual routine, then try to configure the network. You will probably find the ability to scroll back up with Shift-PageUp very handy here (a very neat Linux trick that other OSs would do well to implement). The kernel should then mount the root filesystem and proceed to boot just like normal.
Most of the error messages make it fairly obvious what is wrong. If not, tcpdump/snoop/ethereal/etc. can be very handy. I also find it handy to have the TFTP server configured to log a little more verbosely than the default. A -v on the command line does the trick for the TFTP server mentioned above, it will then log all file requests to syslog.