Setting up Network Booting using PXE / BOOTP / TFTP

Home

Problem

I want to be able to "boot" a system without the need for disks / CDs or any other removal media. Therefore booting over the network is desirable (and cool!). This on its own constitutes the initial phase of a larger development effort...

Investigation

The test environment for this is a Virtual Machine, specifically VMWare Workstation 5.5.3 build-34685 [1]. This is beneficial as it allows for rapid experimentation. After setting up the VM, I proceed to boot it for the first time...

Well the above image indicates the starting point of our investigation; the VM searching via DHCP.

DHCP / BOOTP

I have on my local server (192.168.0.10) a DHCP/BOOTP server running in the form of ISC DHCP Server V3.0.3-Gentoo-r5 [2]. Therefore I will add the "host" construct representing the VM (testbox).
option domain-name "d";
option domain-name-servers 192.168.0.10,192.168.0.1;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.0.255;
option routers 192.168.0.1;

host testbox {
  hardware ethernet 00:0c:29:20:63:ad;
  fixed-address 192.168.0.88;
}
After restarting my DHCP/BOOTP server I booted the VM and saw the following in my logs;
dhcpd: DHCPDISCOVER from 00:0c:29:20:63:ad via eth0
dhcpd: DHCPOFFER on 192.168.0.88 to 00:0c:29:20:63:ad via eth0
Therefore DHCP is working, and offering the machine the specified IP. Now we just need to configure the bootstrap, or BOOTP, element. After some investigating in the man pages I found the following section:
BOOTP Support
       Each BOOTP client must be explicitly declared in the dhcpd.conf file.   A very basic client declaration will  specify  the  client
       network  interface's hardware address and the IP address to assign to that client.   If the client needs to be able to load a boot
       file from the server, that file's name must be specified.   A simple bootp client declaration might look like this:

            host haagen {
              hardware ethernet 08:00:2b:4c:59:23;
              fixed-address 239.252.197.9;
              filename "/tftpboot/haagen.boot";
            }
OK, we need to provide the boot file via the "filename" argument. This raises two questions;
  1. How do we serve the file?
  2. What type of file do we serve?
A hint to the first answer is given with the sample file, specifically the '/tftpboot/' component. After some googling to confirm, the file is served via a TFTP server [3].

TFTP

I chose atftp [4] for no particular reason, emerged it, configured it and started it up on my server. The only real option of interest is its root directory.
TFTPD_ROOT="/var/tftp"
Put simply all files are served from this location. Ok, solved question 1, now question 2. This proved to be a bit more involved. After reading over a Wikipedia article on PXE [5] I found that I was in need of a "Network Bootstrap Program" or NBP. A quick browse of the external links led to my next investigation - PXELINUX [6].

PXELINUX

To cut to the chase, PXELINUX can be used and a NBP for booting linux and other OS's. There are five things that need to be done;
  1. Download and compile
  2. Copy "pxelinux.0" to my TFTP directory and update my DHCP settings.
  3. Create the appropriate TFTP directory structure for the configuration file.
  4. Create the configuration file.
  5. Copy the required kernel files to the TFTP directory.
The first step is fairly painless and instructions are provided with the downloaded file. The second step involved copying the resulting "pxelinux.0" file from the PXELINUX directory to my TFTP root directory ("/var/tftp") and altering my DHCP file to:
host testbox {
  hardware ethernet 00:0c:29:20:63:ad;
  fixed-address 192.168.0.88;
  filename "/pxelinux.0";
  next-server 192.168.0.10;
}
The third is also pretty trivial in accordance with that shown below; From "{ How do I Configure PXELINUX? }"
First, it will search for the config file using the hardware type (using its ARP type code) and address, all in lower case hexadecimal with dash separators; for example, for an Ethernet (ARP type 1) with address 88:99:AA:BB:CC:DD it would search for the filename 01-88-99-aa-bb-cc-dd.
Next, it will search for the config file using its own IP address in upper case hexadecimal, e.g. 192.0.2.91 -> C000025B (you can use the included progam gethostip to compute the hexadecimal IP address for any host.)
If that file is not found, it will remove one hex digit and try again. Ultimately, it will try looking for a file named default (in lower case). As an example, if the boot file name is /mybootdir/pxelinux.0, the Ethernet MAC address is 88:99:AA:BB:CC:DD and the IP address 192.0.2.91, it will try:

	/mybootdir/pxelinux.cfg/01-88-99-aa-bb-cc-dd
	/mybootdir/pxelinux.cfg/C000025B
	/mybootdir/pxelinux.cfg/C000025
	/mybootdir/pxelinux.cfg/C00002
	/mybootdir/pxelinux.cfg/C0000
	/mybootdir/pxelinux.cfg/C000
	/mybootdir/pxelinux.cfg/C00
	/mybootdir/pxelinux.cfg/C0
	/mybootdir/pxelinux.cfg/C
	/mybootdir/pxelinux.cfg/default
 
... in that order. 
Therefore for my specific installation I created the following file:
/var/tftp/pxelinux.cfg/01-00-0c-29-20-63-ad
For step four I populated this file after quickly looking over the "{ How do I Configure SYSLINUX? }" section [7]. Because this is to be used for further development I only really wanted a "dummy" configuration. Therefore I used the following:
SAY Welcome......

DEFAULT helloworld

label helloworld
  kernel hello.c32

The kernel "hello.c32" comes with PXELINUX under the "samples" directory. It can be used in accordance with the following:
The "kernel" doesn't have to be a Linux kernel; it can be a boot sector or a COMBOOT file
Therefore step five required placing "hello.c32" in my TFTP root directory ("/var/tftp") resulting in the following files and directory structure:
/var/tftp
/var/tftp/pxelinux.cfg/01-00-0c-29-20-63-ad
/var/tftp/pxelinux.0
/var/tftp/hello.c32

Testing it all...

Now, the million dollar question, does it all work?

Success! Obviously you would alter your configuration file to do a more meaningful task like boot a linux kernel etc. For me however this is all I require at this stage. Hope it helps.

References

  1. VMware http://www.vmware.com
  2. ISC Dynamic Host Configuration Protocol http://www.isc.org/products/DHCP
  3. "Trivial File Transfer Protocol" http://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol
  4. atftp ftp://ftp.mamalinux.com/pub/atftp/
  5. "Preboot Execution Environment" http://en.wikipedia.org/wiki/Preboot_Execution_Environment
  6. PXELINUX http://syslinux.zytor.com/pxe.php
  7. SYSLINUX http://syslinux.zytor.com/faq.php

Last updated: 28th March 2007