Chris Fallin
(author)
Homepage:
http://www.cfallin.org/
$Date: 2003/02/08 00:07:57 $
$Revision: 1.4 $
Sometimes it's very convenient to be able to boot your OS over a network,
without ever having to transfer any disks between the development and test PCs.
1. Introduction
2. Overview
3. Setting up GRUB
4. The TFTP Server
5. Test It
6. Optional: Installing Etherboot
7. Optional: Diskless GRUB
8. Optional: The DHCP Server
9. Test It (this time with Etherboot)
Most of the time, hobby OSes are loaded from a floppy. In fact, most hobby OSes start with a floppy boot sector. Floppies have the advantage that they will work with nearly any PC. However, it can be quite time-consuming writing a new version of your OS to a floppy, moving it to the test PC, and waiting for it to load every time you change something. There is a better way, though - you can set your test machine up to automatically load the newest version of your OS every time it boots, making it much easier to test new changes.
Network booting (sometimes known as diskless booting) really isn't too hard to set up, and once it is set up there is practically no maintenance involved.
You will need two PCs to network-boot - a server (your development machine) and a client (your test machine). Linux, FreeBSD and Win2k Server have all been successfully used by the author on the server. Using the simple netbooting method (loading GRUB off a floppy), any OS with a TFTP server can be used; that includes basically all Unices and Win32's. The client may be any PC with an Etherboot- and GRUB-compatible network card.
There are two ways to boot a PC off a network that will be covered in this document. The first is to boot GRUB like normal off a floppy, give it a static IP, and download the kernel and modules from a TFTP server. The second way is to use Etherboot to load GRUB itself from the network. This has the advantage of faster load times and keeping menu.lst and GRUB on the server, for easy updating; however, it's slightly harder to set up.
One or two protocols (depending on how you set it up) are used to boot a machine off the network. The first, DHCP, is a protocol to allow hosts to automatically configure their network parameters from a server, and is commonly used on networks to make IP address allocation and network administration easier. You'll only need to set this up if you use Etherboot. The second, TFTP, is a stripped down FTP protocol, commonly used in bootloaders where a full FTP client would be too large. The server machine must run servers for at least TFTP, and DCHP too if you want to load GRUB off the network.
The more complex and flexible method uses two software packages before it gets to your OS. The first of these is Etherboot, a network bootloader capable of running from a floppy as well as a boot ROM on a network card. Etherboot, when run, uses DHCP to get an IP address, a TFTP server address and a boot image filename. It then downloads the boot image and transfers control.
This boot image, in our case, will be GRUB. When compiled with the right options, a network boot image (NBI image) is produced suitable for Etherboot. GRUB then loads its menu.lst file according to a special option in the DHCP reply packet. The menu.lst file specifies your kernel and modules, which will be downloaded using TFTP when you boot your OS.
To simplify things we can bypass Etherboot and DHCP altogether and load GRUB from a floppy. This is the recommended method for newbies, and is covered first in this document. However, loading GRUB and menu.lst from the server does have advantages - faster load times, and all configuration is on the server side.
Note that because GRUB is used to boot your OS, any Multiboot-compatible OS should work. If you can use GRUB to boot your OS off a floppy, you can boot it off a network. No modifications are needed to your OS. It just works.
GRUB has built-in support for basic networking; this makes network booting extremely easy. Unfortunately the pre-built binaries don't have this support compiled in; you will need to compile GRUB for your specific network card.
Compiling GRUB with network support isn't too hard. First, you need the source: GRUB's homepage. Now unpack it:
| Code listing 1 |
$ tar zxvf grub-x.yz.tar.gz $ cd grub-x.yz |
Like Etherboot, this requires a GNU i386 toolchain. The compilation goes like this:
| Code listing 2 |
$ ./configure --enable-<NIC name> $ make |
<NIC name> is the name of your client's NIC - see the output of "./configure --help" for a full list of options, including NIC names.
There have been reports of GRUB not compiling on Cygwin; there is a problem with objcopy. For now, if all you have is Cygwin, ask a friend with a *nix box to compile it for you.
Once GRUB is compiled, you will have 'stage1/stage1' and 'stage2/stage2'. Install these to a floppy like you would for any other GRUB install.
The TFTP server is the only server software you need to make the entire setup work if you're loading GRUB off a floppy. It is what serves boot files to the client. distributions come with a TFTP daemon. There are also a few freewware TFTP servers for Win32; I have not used any myself, but they should work.
If the TFTP daemon isn't installed already on your Linux box, look on the install CD for a tftpd package; on Debian, try "apt-get install tftpd". you might need to uncomment a line in /etc/inetd.conf too. Make sure the command line that inetd is passing to tftpd specifies /tftpboot as a root. Create this directory on your filesystem.
Now put your kernel in /tftpboot. Make sure that the paths you specified in GRUB's menu.lst start with "/tftpboot"; even though this is the server's root, you still need to specify it. In menu.lst, the syntax for the TFTP driver is "(nd)/tftpboot/file". Here's a sample menu.lst (this goes on your GRUB floppy):
| Code listing 3 |
title yourOS ifconfig --address=192.168.0.2 --server=192.168.0.1 tftpserver 192.168.0.1 kernel=(nd)/tftpboot/yourOS/kernel module=(nd)/tftpboot/yourOS/driver1 |
You'll want to set up your Makefile(s) to automatically copy your OS binaries to the TFTP server's root every time you compile new ones. This will make the required work minimal to test a new version of your code.
With all this software set up, you should be ready to network-boot your system. Make sure your TFTP server is running, then boot your client off the GRUB floppy you made. If it loads correctly, you should see GRUB present you with a list of entries in your menu.lst; hit 'Enter' after selecting the one you want. Your OS shouldn't take any significant time to load over 100Mbps Ethernet; it's certainly faster than a floppy!
This isn't the end of the road, however; if you'd like to set up GRUB to load off the network, to ease maintenance and speed up load times, read on.
Etherboot, as mentioned earlier, is the piece of software that loads off of a floppy or boot EPROM and loads the GRUB, the second-stage loader, off the server. It is a freely-available, open source package.
Etherboot may be obtained at etherboot.sourceforge.net. Be sure to grab the latest version.
You will need a GNU compiler environment to compile Etherboot. Linux works, as does FreeBSD. Cygwin would probably work too. Unpack the tarball:
| Code listing 4 |
$ tar zxvf etherboot-x.y.z.tar.gz $ cd etherboot-x.y.z/src |
Now compile a floppy image:
| Code listing 5 |
$ make bin32/<NIC name>.fd0 |
Where <NIC name> is the name of your NIC's driver - for example, 3c90x (3Com 3c90x) or tulip (DEC Tulip chipset). This will write a bootable image to /dev/fd0. If your floppy drive isn't /dev/fd0, then:
| Code listing 6 |
$ cat bin/boot1a.bin bin32/<NIC name>.rom > floppy.img |
This will create floppy.img, a floppy image.
Once you have a bootable floppy, test-boot it. You should receive a prompt asking whether to boot from (L)ocal or (N)etwork. Choose network. As you haven't set up a DHCP server yet, it should hang - but at least Etherboot works.
In order to load from the network, GRUB must be compiled with a special option. Follow the directions for compiling GRUB above, except for the configure line:
| Code listing 7 |
$ ./configure --enable-diskless --enable-<NIC name> $ make |
Note the --enable-diskless option. This will build a file 'stage2/nbgrub'; copy this to your TFTP server directory.
You'll also need a menu.lst file in the TFTP directory. Here's a sample:
| Code listing 8 |
title yourOS kernel (nd)/tftpboot/yourOS/kernel module (nd)/tftpboot/yourOS/module1 |
As you can see, it's basically the same as the one above, except that because we'll be using DHCP we don't need to give static IPs.
The DHCP server is what allocates an address to your netboot client and gives it the parameters it needs to load the rest of the software. Because you need to pass DHCP options to the client, not any DHCP server will work. ISC DHCP (packaged with Linux and FreeBSD) and Win2K Server's DHCP have both been used successfully. For other Win32's, I have been pointed to Weird Solutions' software. This has not been tested by the author; but if it can pass options, it should work.
To successfully netboot a client, you need to pass three DHCP options. The first, boot server, specifies the IP or hostname of the TFTP server. The second, boot filename, is the TFTP filename path to the 'nbgrub' file you saved earlier. The last, option-150, is not specified in any DHCP RFC but is used by GRUB to specify the TFTP path to menu.lst (GRUB's menu/configuration file).
Under Linux, ISC DHCP is standard. It uses a text file configuration format, which is fairly simple to write. I'll let you dive right in to my /etc/dhcpd.conf (for dhcpd v2):
| Code listing 9 |
# cfallin.org internal dhcp
option domain-name "int.cfallin.org";
option domain-name-servers 10.0.0.1;
subnet 12.0.0.0 netmask 255.0.0.0 {
# attbi cable modem - ignore
}
subnet 10.0.0.0 netmask 255.255.255.0 {
range 10.0.0.128 10.0.0.192;
option routers 10.0.0.1;
option broadcast-address 10.0.0.255;
# GRUB network boot stuff
filename "/tftpboot/nbgrub";
server-name "10.0.0.1";
option option-150 "(nd)/tftpboot/menu.lst";
}
|
It's pretty easy, really. Note that you have to have a subnet declaration for each network your server is on - in this case, my server is on my cable modem and my internal network. To ignore a subnet (I wouldn't want to serve DHCP on ATTBI's cable modem network - that would conflict with their servers), just leave the declaration empty. The "range" keyword gives a range of IPs from which to allocate. The rest is self explanatory.
Note that the above is for dhcpd version 2. I have not used version 3; however, through feedback I know that the following should work:
| Code listing 10 |
option space netboot;
option netboot.grub-menu code 150 = text;
< ... rest of global settings ... >
subnet ... {
...
option netboot.grub-menu "(nd)/tftpboot/menu.lst";
...
}
|
Under Win2K server, setup is slightly more tedious, due to the GUI, but not any harder. Note that I currently don't have a Win2K server set up, so this is from memory - if it doesn't work, play around with it. First, create a DHCP scope, and set it up with your parameters (IP range, etc.) Do this from Start > Programs > Administrative Tools > DHCP. Then go to Scope Options, and add the boot filename and server. Then you'll need to customize the available DHCP options (I think you right-click on the scope); add option 150, of type "string", and call it something like "GRUB menu.lst". Now add this option to the Scope Options, setting it to whatever the TFTP server filename for menu.lst is. That should be it.
Now that you have Etherboot, DHCP, and diskless GRUB set up, you are ready to test the setup. Boot off your Etherboot floppy, and when prompted, press 'N' to boot off the network. GRUB should load, and should display the entries in your menu.lst. If not, you can use a packet sniffer, such as Ethereal, to debug. If it works, select your OS's entry and press enter. Have fun with your new setup!