Next Previous Contents

5. How the client boots

There are two methods for booting the client. The computer can boot from its network interface card (NIC) to receive the boot images via DHCP/TFTP or a suitable kernel as well as an initrd image is loaded from a floppy. Please refer to section Setting up the client's resources for details on how an appropriate initial ramdisk image is built and what is required of a feasible client-kernel.

Throughout this section let initrd.gz denote a gzipped initrd image and bzImage a client-kernel, just like mentioned above.

5.1 Booting from floppy

For testing/rescue purposes or because your NIC does not have a PROM (yet) you can build a boot floppy to use with NAIS. We will only describe how lilo(8) and syslinux may be used to achieve this. For detailed information see initrd.txt, ramdisk.txt, kernel-parameters.txt, and the Bootdisk-HOWTO as well as the documentation contained within both packages.


This Linux boot loader operates off an MS-DOS®/Windows® FAT filesystem. This makes it rather easy to maintain your boot floppies using standard MS-DOS® tools. Its second feature, which is more important to us, is the usability for booting Linux of a network server. To create a boot floppy type:

vermeer[/tmp]# superformat /dev/fd0u1440
vermeer[/tmp]# mount /dev/fd0u1440 /floppy/
vermeer[/tmp]# cp bzImage initrd.gz /floppy/
vermeer[/tmp]# cat <<EOF > /floppy/syslinux.cfg 
? DEFAULT bzImage
? APPEND $options
vermeer[/tmp]# umount /floppy/
vermeer[/tmp]# syslinux /dev/fd0u1440
Here $options means the kernel parameters that are passed to the kernel command line. In the above example we used options="rw ramdisk_size=10240 initrd=initrd.gz reboot=warm vga=normal". NOTE: All kernel parameters are case sensitive and the value of "ramdisk_size" MUST correspond to the size of your initrd. See section How to create the Initial RAM disk for details.


To build a lilo boot disk that contains a bzImage and an initrd.gz you have to supply a valid lilo.conf:

boot      = /dev/fd0u1440
install   = /boot/boot.b  # from your lilo-package
map       = /boot/map     # created when running /sbin/lilo
backup    = /dev/null
vga       = normal
image     = bzImage
label     = NAIS
root      = /dev/fd0u1440
initrd    = initrd.gz
append    = "ramdisk=10240 reboot=warm"
Now you can build your boot floppy by typing:
vermeer[/tmp]# mke2fs -i 8192 -m 0 /dev/fd0u1440
vermeer[/tmp]# mount /dev/fd0u1440 /floppy/
vermeer[/tmp]# rm -rf /floppy/lost+found/
vermeer[/tmp]# mkdir /floppy/{dev,boot}
vermeer[/tmp]# cp -a /dev/{fd0u1440,null} /floppy/dev/
vermeer[/tmp]# cp /boot/boot.b /floppy/boot/
vermeer[/tmp]# cp initrd.gz bzImage lilo.conf /floppy/
vermeer[/tmp]# lilo -v -C lilo.conf -r /floppy/

5.2 Booting from network card

For administrative purposes, booting from network card (NIC) is much more suitable than booting from floppy. In order to use this boot method, the client's NIC needs a boot PROM that is able to communicate with a DHCP server to receive communication-related configuration parameters such as network addresses and which is capable of communicating with a TFTP-server to get a boot image. Furthermore, it must be guaranteed that the transmitted boot image is executed properly in terms of what the boot PROM expects in a boot image.

Note: All described netbooting methods require that your DHCP server is properly set up. Please see section Setting up the server for details.

etherboot and netboot

etherboot and netboot are capable of creating a PROM binary (which must still be programmed onto a PROM) and a corresponding "tagged" TFTP boot image which includes a bzImage (and an optional initrd.gz). Some tools exist that help test a boot PROM image, in fact the support utilities are pretty much common to both etherboot and netboot.

The advantage of netboot is its ability to emulate just enough of a DOS environment such that unmodified DOS packet driver binaries -- these are usually provided with the NIC -- can be used for building a boot PROM. Thus, netboot supports a wider range of NICs. etherboot, on the other hand, creates smaller boot PROM images; the compressed versions will fit in 8 KB size (which all NIC's should support). Also etherboot does autoprobing of the hardware addresses while netboot only does autoprobing as long as the packet driver supports this feature. However, if you choose to use either one of these tools you should definitly read the documentation or take a look at the mailinglist; the Diskless-HOWTO might definitely be helpful as well. Here we will only give an example to get the idea how it works.


You probably do not need to compile netboot yourself, an apt-get install netboot or its equivalent for a rpm-based system should be sufficient. Once you have netboot running you have to get a working packet driver for the client's NIC. This MS-DOS®-program usually comes with your NIC, look at netboot's homepage for some links. The packet driver must fit into 32KB or 64KB to be programmed onto a PROM. If the driver is too big try using programs such as pkzip to decrease the size of the executable.

If you have the packet driver you can build your PROM-image by typing makerom. You will be asked a couple of questions, including where netboot can find your packet driver (e.g. if you have a 3Com® 3c90b) and the command line arguments (e.g. /I=96) for it. That means under DOS you would simply type

A:\> /I=96
to start the driver. This will create two files, image.flo and another file which is to be burned onto a PROM. Testing the boot PROM is done with cat image.flo > /dev/fd0; you can use this floppy to boot your netbootable client from.

The next task is to take the bzImage and initrd.gz and to turn them into a tagged image. Such an image has a special header that tells the network bootloader where the bytes go in memory and at what address to start the program. To make a network bootable image type:

vermeer[/tmp]# mknbi-linux -x -i rom -k bzImage -r initrd.gz \
   -a "ramdisk_size=10240" -o /tftpboot/clientnbi
Kernel image file name  = bzImage
Output file name        = /tftpboot/clientnbi
Ramdisk image file name = initrd.gz
Kernel command line     = "auto rw root=/dev/nfs nfsroot=kernel \
   nfsaddrs=rom ramdisk_size=10240"
vermeer[/tmp]# chmod a=r,u+w /tftpboot/clientnbi
Now a tagged image /tftpboot/clientnbi with the printed parameters was built. Most used options of mknbi-linux(8) are obvious; -x means verbose and -i rom means all necessary ip addresses for NFS root mounting will be determined at runtime using the BOOTP answer the bootrom got from the DHCP server. Although NAIS does not use a NFS root this option might be useful for other purposes. Note that you can use vendor tag 129 (option option-129) to pass additional parameters to the kernel at runtime. The string value given with this tag is appended verbatim to the command line by the boot loader.

Test your PROM image i.e. boot your client from that floppy:

Disk loader for net boot
Uncopressing... done
Found packet driver at int 60
Free memory: 31
BOOTP: Sending request (press ESC to abort): .ok
Local IP:
Server IP: (
File name: /tftpboot/clientnbi
Uncompressing Linux... Ok, booting the kernel.


The same works for etherboot like this:

vermeer[/tmp]# echo "Not done yet ..."
Testing the boot PROM works for etherboot pretty much the same (although mknbi-linux for etherboot is slightly different).
vermeer[/tmp]# echo "Please refer to the documentation meanwhile."

Using PXE boot-PROMs

Another option to etherboot and netboot is to use a PXE-compliant boot PROM. Different from the method mentioned above, when using Intel®'s PXE specification you have to distinguish two things. One is to obtain a PXE boot PROM the other is two get a PXE remote-boot processor that is able to load a bzImage and an initrd.gz.

There is a free tool that is oriented towards building PXE boot PROMs, nilo While this document is written, developments are made to the NILO project. Thus, we have not tested it yet, but give it a try!

Since many proprietary solutions are based upon PXE, you should not have any problems finding a suitable boot PROM. Take a look at for a list of some providers.


pxelinux is a syslinux derivative which is still beta but works well for us. If you are already familiar with syslinux you will see that pxelinux operates in many ways like syslinux does. Please see section Setting up the server for details on setting up your DHCP server for pxelinux.

First copy pxelinux.bin from the syslinux distribution to /tftpboot/ on your TFTP server, as well as bzImage and initrd.gz. Keep in mind that these files must be world readable!

vermeer[~]# cp /usr/lib/syslinux/pxelinux.bin /tftpboot/
vermeer[~]# cp bzImage initrd.gz /tftpboot/
vermeer[~]# chmod a+r /tftpboot/*
Then, create the directory /tftpboot/pxelinux.cfg/ with read/write permissions for your ${NAIS_USER}:
vermeer[/tftpboot]# mkdir pxelinux.cfg
vermeer[/tftpboot]# chgrp linuxadm pxelinux.cfg/
vermeer[/tftpboot]# chmod a+r,g+w pxelinux.cfg/
The configuration files (the equivalent of syslinux.cfg) will reside in this directory. pxelinux, unlike BpBatch, does not use additional vendor tags to determine which config file to use. Instead, the configuration file name depends on the IP address of the booting machine. pxelinux will search for its config file on the TFTP server in the following way:

First, it will search for the config file using its own IP address in upper case hexadecimal, e.g. -> /tftpboot/pxelinux.cfg/865F0AA0. If that file is not found, it will remove one hex digit and try again. For, if 865F0AA0 is not found, it will try 865F0AA, 865F0A, 865F0, 865F, 865, 86, and 8 in that order. Finally, it will try looking for a file named default (in lower case).

Note: This may not be as easily readable as host names, but using hexadecimal instead of decimal makes it easy to group alike clients together. Our 16 cluster clients have IP addresses from to Now, when we want to install the cluster, we simply delete/remove /tftpboot/pxelinux/865F0AA? while 865F0AA is a config file with defaults for installing a cluster client. When a client's installation is finished a file like e.g. 865F0AA0A for has to be created with this client's settings.

If you have problems setting up your client to work with pxelinux you should try to create a boot floppy with syslinux, like in section Booting from floppy. In most cases it should be sufficient to use exactly the same config file for pxelinux that you used for syslinux -- in fact we do not know of any cases where it did not work. ;)

vermeer[~]# mount /floppy/
vermeer[~]# cp /floppy/syslinux.cfg /tftpboot/pxelinux.cfg/865F0AA
vermeer[~]# chmod a+r /tftpboot/pxelinux.cfg/865F0AA
vermeer[~]# mv /tftpboot/pxelinux.cfg/865F0AA? /tmp/
In this case we use the seven-digit string 865F0AA, which to corresponds to hosts - 175, to install the whole cluster.

Booting pxelinux successfully should look like this:

CLIENT MAC ADDR: 00 10 5A 25 CB 73

PXELINUX 1.48 1999-09-26  Copyright (C) 1994-1999 H. Peter Anvin
PXE entry point found (we hope) at 9D98:00F6
My IP address seems to be 865F0AA0
TFTP prefix: /tftpboot/
Trying to load: pxelinux.cfg/865F0AA0
Trying to load: pxelinux.cfg/865F0AA
Loading bzImage...........
Loading initrd.gz.............

Ready to start kernel...
Uncompressing Linux... Ok, booting the kernel.


BpBatch is a non-free remote-boot processor that is free for personal use. This tool can perform a large variety of actions on a computer at boot-time before any operating system operation has started.

You have to set some vendor tags to make BpBatch work. Please see section Setting up the server for all details; BpBatch's webpage BpBatch Forum is also helpful as well the Remote-Boot mini-HOWTO.

First copy bpbatch.P (we call it bpbatch), bpbatch.ovl and bpbatch.hlp from the BpBatch distribution to /tftpboot/ on your TFTP server, as well as bzImage and initrd.gz. Please check at all times that the required files in /tftpboot/ are world readable!

vermeer[/tmp/bpb]# tar xfz /files/install/tars/bpb-exe.tar.gz 
vermeer[/tmp/bpb]# cp bpbatch.P /tftpboot/bpbatch
vermeer[/tmp/bpb]# cp bpbatch.ovl bpbatch.hlp /tftpboot/
vermeer[/tmp/bpb]# chmod a+r-w /tftpboot/bpbatch* /tftpboot/{bzImage,initrd.gz}

The role of the DHCP server is to give the client an IP address and to make it load the file named bpbatch from the TFTP server. Thus add an entry in the DHCP configuration file for your client, with the boot file set to "bpbatch". Define a vendor option tag 135 (decimal) set to client (on the ISC DHCP server, this is done by option option-135 "/tftpboot/client"). This batch script is interpreted an run by bpbatch, you may change the value of option-135 to "-i" for interactive mode. NOTE: BpBatch always appends the suffix .bpb to the basename of the value of option-135 (e.g. if you pass "/tftpboot/client.test" as option, BpBatch will try to get client.bpb).

You have to provide two different config files for use with BpBatch. The first, e.g. client-install.bpb, will be used to install your client, the second, e.g. client-run.bpb, will be used for running the client.

A feasible client-install.bpb with "options"="auto rw root=/dev/nfs ramdisk_size=10240 reboot=warm vga=normal" looks like:

set cachenever="on"
LinuxBoot "bzImage" "options" "initrd.gz"

Please note that BpBatch's special variable called "CacheNever" should always be turned on since we do not want BpBatch to try to cache the kernel image on the client's hard disk.

Now booting your client should look like this:

CLIENT MAC ADDR: 00 10 5A 25 CB 73

Starting BpBatch - PXE Boot ROM detected
BpBatch overlay loader v1.1 (Feb 11 2000)
Overlay file successfully loaded
- BootProm detected, using as standard TFTP server
- Advanced Power Management V1.2
- Using up to 368K of conventional memory for the heap
- Using up to 15296K of extended memory
- Direct disk write access enabled
Linux 2.2.15 (roott@vermeer) #6 SMP Fri May 12 11:19:05 CEST 2000
Loading linux ramdisk....................

Uncompressing Linux... Ok, booting the kernel.

Next Previous Contents