Network Booting a Linux STB with PXE

Summary

PXE (Preboot eXecution Environment) is, in one persons words, Intel's attempt at making PCs work more like SUNs ( ref). PXE outlines a protocol for enabling the BIOS to retrieve the operating system over standard network protocols.

This document outlines the process of setting up an Allwell STB to use a PXE enabled BIOS to load and run a Linux kernel and root file system

Contents

Introduction and Prerequisites

This document steps through the process of setting up the appropriate servers, creating the client code, and enabling the client to boot. It is assumed that the reader has a fundamental grasp of networking concepts. DHCP, Linux Kernel, TFTP, and BIOS concepts will be covered here, as well, and some knowledge of those topics is required.

Also, you'll need a kernel and root file system setup. I think the easiest way to do all of that is to follow the instructions in the Bootdisk HOWTO (part of the standard LDP HOWTO documents) as if you were making a two-disk floppy bootdisk set. I have been told that some distributions (Slackware?) come with boot/root images. I have also heard that there is a set on the FTP site at kernel.org. That may be a faster way to the goal then the Bootdisk HOWTO.

The client used in this case was a GCT-Allwell 3036 with the PXE BIOS extension. The servers were just clunky old PCs with Trustix or Mandrake loaded on them.

Conceptual Overview

In the case presented in this document, PXE works like this:

  1. The client is booted.
  2. The BIOS portion of the client (or the Network Card firmware) makes a DHCP request.
  3. The DHCP server responds with the usual information (IP, netmask, gateway, etc.), but in addition provides information about the location of a TFTP server.
  4. When the client receives the information, it contacts the TFTP server asking for whatever file the DHCP server told it to ask for (in this casse, the PXELINUX bootloader).
  5. The TFTP server sends the file (PXELINUX), and the client executes it.
  6. PXELINUX searches for a configuration file on the TFTP server, and boots a kernel according to that configuration file. In our case, the config file instructs PXE to load the kernel and a filesystem.
  7. The client downloads all the files it needs (kernel and root file system) and then loads them.
  8. If all goes well, the system boots.

Setting Up DHCP

I used the ISC DHCP server (v. 2.0), as it was highly recommended, is easy to configure, and came with Trustix the - Linux distro I use. If you use the DHCP 3.0 version, check the man pages for changes to syntax. The content should be about the same.

Set up the DHCP server to handle PXE client requests. /etc/dhcp.conf is the main file on my machine for configuring the DHCP server. A very generic dhcp.conf would look something like this:

	  allow booting;
	  allow bootp;
	  option routers [gateway address];
	  option subnet-mask [subnet mask];
	  option domain name [domain name];
	  option domain-name-servers [list of dns servers];
	  default-lease-time 21600;
	  max-lease-time 43200;

	  group {
	  	next-server [ip or hostname of tftp server];
	  	#This is the pxe bootloader file
		filename "pxelinux.0";
		# One host block per client. This network only has one.
		host stb1 {
			hardware ethernet [MAC address, in format nn:nn:nn:nn:nn:nn]
			fixed-address [ip address that will be assigned to client]
		}
       	}

All the values in square brackets should be filled in with the correct values for your setup. The man page for dhcp.conf is very good. If you get stuck on this step, try consulting it. The really important parts of the example are those in the "group" block. These are the parameters specific to TFTP booting clients. Mainly, the configuration specifies what tftp server has boot images (next-server), what file they should try to get from the next server (filename) and then there is a section defining every host on the network that should be TFTP booted. That section tells the DHCP server to send the host with the specified hardware address the fixed-address and all other fields in the group section.

Start (or restart) DHCP to make the changes take effect.

Installing the TFTPD Server

The TFTPD server serves the booting images to the client. Because of the various nonconformities in PXE implementations, some network cards may require specific TFTPD servers. In this case, though, I used the one written by H. Peter Anvin, author of SYSLINUX, and it worked without a hitch.

Many distros come with TFTP servers, and they may work equally well, but I've never tried them. If you are planning on using the TFTP-HPA server, ensure that you do not already have a TFTP server running. Often times, inetd or xinetd handles the tftpd server, so check their config files, too.

Get the source code for TFTP-HPA, uncompress it, and CD into the tftp-hpa directory that was created. There is nothing unusual about the compilation (though there are no INSTALL notes).

	  $ ./configure
	  $ make
	  # as root
	  $ make install
  

I ran into a configuration problem with the location of my man pages, so I edited the MCONFIG file. I suspect that I could have rerun configure with a flag set, but "laziness is a virtue," so I did what was easiest.

Once the install is complete, cd (as root) to the location where you want to put your TFTP boot files. Traditionally, this is in /tftpboot. However, I detest cluttering my root directory when there are so many other places to put things, so I created /var/tftpboot. Rather than start tftpd now, we'll configure the PXELINUX client software, first.

A note about files in /var/tftpboot: They should all have permissions that allow global reading of the file.

Moving Kernel and Root FS Images

Remember how I said in the introduction that you would need a kernel and root file system? Well, here's where you need it. I have a 2.4 kernel named bzImage and a compressed ext2 root filesystem named rootfs.gz. I use them as images to make bootdisks. Now, I'm going to copy both of them to the tftpboot directory.

	  $ ls
	  bzImage   rootfs.gz
	  $ cp bzImage /var/tftpboot
	  $ cp rootfs.gz /var/tftpboot
  

Setting Up PXELINUX

PXELINUX is one of the bootloaders included in H. Peter Anvin's SYSLINUX package. PXELINUX presents a configurable PXE client that looks enough like LILO to make it pretty intuitive to configure and use.

Get the SYSLINUX package and untar it. cd into the newly created directory. The SYSLINUX package comes with both the source and binary files. Unless you have some weird desire to compile the assembly file, I recommend using the binary, called 'pxelinux.0'. Copy pxelinux.0 into the tftpboot directory ('/var/tftpboot').

cd to the /var/tftpboot directory. Make a directory called pxelinux.cfg.

	  $ cd /var/tftpboot
	  $ ls
	  pxelinux.0
	  $ mkdir pxelinux.cfg
  

Using the editor of your choice, create a file in /var/tftpboot/pxelinux.cfg called 'default'. It should look like this:

	  # This is the default pxelinux config file.
	  LABEL test
	  	KERNEL bzImage
		APPEND initrd=rootfs.gz
		IPAPPEND 1
	

Lines that begin with '#' are comments. LABEL identifies the name of the boot image. KERNEL indicates the first file to get, which in most cases is the Linux kernel. APPEND appends kernel parameters. Here, I'm appending the name of the initrd image -- my bootdisk rootfs. IPAPPEND, if greater than zero, tells PXELINUX to generate and append the IP information to the boot request. In almost every case, you want this.

This is about the most generic, unspecific way of setting up the PXELINUX bootloader. There are a number of other options, including setting up specific config files for specific clients, including boot messages, and loading a default image (without showing the "boot:" menu). The pxelinux.doc and syslinux.doc documents explain these other options.

Once this configuration is done, start the tftp server:

	  # as root...
	  $ in.tftpd -v -l -s /var/tftpboot
  

The '-v' option will increase verbosity. It's useful for testing. If things go wrong, you can use -vv to increase debugging output. Messages are logged to syslog. '-l' sets the server to run in standalone. If you are running the server in inetd, don't use the -l option. '-s /var/tftpboot' makes the tftpd server use /var/tftpboot as it's root directory (e.g. chroots it).

Configuring the Client

Allwell specific configuration can be found in the HOWTO section at GCTGLOBAL's site.

Once the PXE BIOS is setup, power cycle the client. It should give feedback about it's DHCP status. When the pxelinux client is loaded, it will search for various configuration files (based on it's IP address), and hopefully eventually find default. When default is loaded, it will look for a default entry (linux), which is not there. It will then prompt for input. Type 'test' (the value of LABEL in the config file) and hit enter.

	  boot: test
	  getting bzImage.....
	  getting rootfs.gz..........
  

If all goes well, it should boot!

Troubleshooting

If you find any errors in this document, please email me.

Links


Author: Matt Butcher (mbutcher [at] aleph-null [dot] tv)
Copyright © 2001 Aleph-Null, Inc.

Linux is a trademark of Linus Torvalds.

This document may be reproduced for personal use without permission. Commercial use or publication without permission is strictly forbidden.

All material herein is provided as is with absolutely no warranty.