OS Deployment

Configuring DHCP and Basic PXELinux Setup

Note: these instructions assume that you have setup a TFTP server using the instructions in my previous post. You might want to go read that first.

Configuring your DHCP server to support PXE booting is pretty straight-forward, especially for Microsoft DHCP servers. I’ll describe how to setup ISC DHCPD as well.

With either server, you need to add two options, typically referred to as the boot server and boot filename.

In a hurry? Take a look at the DHCP summary instead.

DHCP Configuration Warning

Keep in mind that you should only have a single DHCP server running on a given network. If you setup an additional DHCP server on a single network, it is extremely likely that you will break DHCP for ALL systems on that network. Make sure that you know your network’s layout, and whether or not there’s an existing DHCP server running.

If you just want to experiment with this stuff, get yourself a hefty workstation with lots of RAM (2-4GB), a decent processor (anything current will do), and a lot of disk space (a typical Fedora Core installation requires about 4GB of disk, and you’ll want some extra room to store your installation media, so at least 15GB should do the trick), and use VirtualBox (or VMWare Workstation/Fusion/Server) to setup a virtual machine running Linux. This system can then be used as a DHCP and TFTP server for a private network within VirtualBox, thus isolating your environment from the rest of the network. You can then create a second virtual machine that can be used as your PXE client.

If you’re looking to implement this on a corporate network, be sure to ask your network administrator(s) for permission beforehand. In addition to ensuring that it’s ok to implement, your network administrator will very likely have good advice for how to set this sort of thing up – and, even if they don’t, at least they’ll know what’s going on when all hell breaks loose because the DHCP server has stopped responding or has started handing out invalid leases… 😉

Microsoft DHCP

  • open the DHCP MMC console
  • if you have more than one DHCP scope defined, expand the one that you want to allow PXE booting in, and select the Scope Options folder; otherwise, simply select the global Server Options folder
  • right-click the main pane, and select Configure Options
  • scroll through the available options until you find 066 Boot Server Host Name, and select the checkbox alongside the option
  • enter your TFTP server’s IP address in the Data Entry -> String Value field (even though the option says “Host Name”, keep in mind that when PXE booting name resolution services are typically not available until after the TFTP server has been contacted)
  • select the checkbox for 067 Bootfile Name in the Available Options list
  • enter pxelinux.0 in the Data Entry -> String Value field


  • edit the dhcpd.conf file (typically in /etc/dhcp/ on Gentoo), and add the following to the appropriate scope (again, you could just put this in the global scope; it all depends on what you want to do):
    if substring ( option vendor-class-identifier, 0, 9 ) = "PXEClient" {
       next-server <TFTP server's IP address>;
       filename "pxelinux.0";
  • restart DHCP (/etc/init.d/dhcpd restart on Gentoo)

The really cool thing about ISC DHCPD is that you can do WAY more with it than you can with Microsoft’s DHCP server. For example, you could do PXE client architecture detection at boot, and direct x86 clients to one TFTP server and x64 clients to another with something like the following:

if substring (option vendor-class-identifier, 20, 3) = "x64" {
   next-server <x64 TFTP server>;
} else {
   next-server <x86 TFTP server>;
filename "pxelinux.0";
– modified from examples found here

(I have yet to find a way to do something similar with Microsoft’s DHCP server. Since we’re using MS DHCP at work, I’d love to find a way to do this, so if anyone knows, please feel free to share!)


In a hurry? Take a look at the PXELINUX summary instead.

PXELinux’s documentation is sketchy at best – at least, it was for me. It took me a while to get my head around it, but once I did, it turned out I had been over-complicating the whole thing: it’s actually surprisingly easy to configure, but describing how to configure it is awkward. Remember that you created the /var/lib/tftpboot/pxelinux.cfg/ folder and copied a bunch of files into /var/lib/tftpboot/ last time? Well, now you actually get to create the configuration files for PXELinux. First, we’ll create a default configuration file for all PXE clients to use. Later, I’ll show you how to create a configuration file for a specific host, or for an entire subnet.

The default configuration file for PXELinux is /var/lib/tftpboot/pxelinux.cfg/default. This file consists of a list of boot images that can be selected by a PXE client, as well as global options that apply to all boot images. The boot images can be Linux kernels, floppy disk images, or other boot loaders.

Installing Linux Using PXELinux

Since PXE booting is really good for installing operating systems over the network, we’ll start with setting up PXELinux to boot the Fedora Core installer in rescue mode. Later, I’ll describe how to automate the installation of FC, Ubuntu, and Windows XP/Vista/2003/2008. We’ll also start with a simple boot: prompt; later, I’ll show you how to make it into a proper menu system, with help text, fancy colors, and arrow-key selection of the boot option.

These instructions will work with any RedHat-based Linux distribution, including RHEL 4 and Fedora Core. Before you start, make sure that you have a copy of the the installation media handy, such as the Fedora Core 10 installation DVD. You’ll need a couple of files from the disc for this to work.

  • open /var/lib/tftpboot/pxelinux.cfg/default in your favorite editor
  • add the following lines:
    default fc
    timeout 100
    prompt 1
    label fc
      kernel linux/vmlinuz
      append initrd=linux/initrd.img text
  • save and close the file
  • create a folder to store the boot kernel and initrd: mkdir -p /var/lib/tftpboot/linux/
  • mount the installation media ISO or DVD, and copy images/pxeboot/vmlinuz and images/pxeboot/initrd.gz to /var/lib/tftpboot/linux/

At this point, you should be able to PXE boot, and have the Fedora Core (or whatever Linux distribution’s installation media you used) installer start up in text-mode. When you PXE boot using the above configuration file, you’ll be presented with a boot: prompt. You can either wait 10 seconds, press ENTER, or type fc and press ENTER to start the installer.

Here’s what the configuration file does:

  • default fc: sets the default boot image label. The boot image label must match one of the label lines that comes later in the configuration file.
  • timeout 100: sets how long PXELinux waits at the boot: prompt for user input, in tenths of a second (e.g. 100 = 10 seconds; 200 = 20 seconds; 600 = one minute)
  • prompt 1: shows the boot: prompt. If this is set to 0, the boot: prompt will not be displayed
  • label fc: a name for this boot image; in this case fc is the name for this boot image. The default fc line above tells PXELinux to use this section by default (i.e. when the timeout occurs, or when you just press ENTER at the boot: prompt)
  • kernel linux/vmlinuz: this is the path to the boot image. Note that I’ve used a relative path here; the path is relative to the TFTP server’s root directory (the folder specified after the -s parameter in the tftpd-hpa command line)
  • append initrd=linux/initrd.img text: values to append to the boot image command line. In this case, we’re telling the Linux kernel to use linux/initrd.img as the initial RAMdisk, and to boot into text mode (i.e. the non-graphical installer). The exact values that can be appended depend entirely on the boot image you are using, and are almost always documented by the provider. For Fedora Core/Redhat derivatives, check here.

Every label in the configuration file should be followed by a corresponding kernel entry. Multiple labels can be specified in a configuration file. To use a given label, enter the label at the boot: prompt and press ENTER.

So let’s make this a little more complicated: let’s say you want to use the graphical installer by default, but you have a few systems where the video card misbehaves (or, more accurately, the video card driver misbehaves) and the installer locks up. You can configure PXELinux to boot into the graphical installer by default, but if you type the word text at the boot: prompt, it’ll launch the text-mode installer.

Here’s what you need to do: open /var/lib/tftpboot/pxelinux.cfg/default in your favorite editor, and use the following contents:

default graphics
timeout 100
prompt 1
label graphics
  kernel linux/vmlinuz
  append initrd=linux/initrd.gz

label text
  kernel linux/vmlinuz
  append initrd=linux/initrd.gz text

Now, when you PXE boot a client, you’ll be presented with the boot: prompt still. If you don’t press any key, the graphical installer will launch after 10 seconds; if you press any key (except ENTER, of course, which will launch the default boot image – in this case, the graphical installer) within 10 seconds, you must specify the boot label you want. In other words, you have ten seconds after the boot: prompt is displayed to type text and press ENTER to start the text-mode installer.

Host-specific PXELinux Configuration

If you get tired of always having to type text at the boot: prompt for a specific system, you can always create a system-specific configuration file for PXELinux. When PXELinux starts, it will scan the TFTP server’s pxelinux.cfg/ directory for the first filename that matches the following:

  • system UUID
  • MAC address
  • or IP address (in hexadecimal, not the usual decimal – I’ll explain why in a minute…)

If it doesn’t find a filename matching any of the above, PXELinux loads the file pxelinux.cfg/default – which is why I had you create that file first. 😉

To be honest, I’ve never used the system UUID to target a specific host, as I’ve never bothered trying to figure out how the UUID is determined. If you’ve turned on verbose logging (-v -v option) in tftpd-hpa, you’ll be able to see the client’s UUID, but it’s usually easier just to use the client’s MAC address instead. However, if the network adapter is moved from one system to another, the system-specific PXELinux configuration will follow, and you may end up with an improper configuration for the new client. Which option you go with will be determined by your needs. The following instructions apply to either method, so I’ll describe how to use the MAC address version, since it’s probably more common.

First, you’ll need to know your client’s MAC address. If you have a running OS on the client, there’s always a command that you can run to determine the network card’s MAC address:

  • Linux, and other UNIX derivatives: open a terminal, and run ifconfig -a as root
  • Windows XP/Vista/2003/2008: open a command prompt, and run ipconfig /all

Running ifconfig -a on Linux produces output similar to the following:

eth0      Link encap:Ethernet  HWaddr 00:15:c5:ed:e7:dd
         inet addr:  Bcast:  Mask:
         RX packets:308065197 errors:0 dropped:0 overruns:0 frame:0
         TX packets:349111118 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000
         RX bytes:882076130 (841.2 MB)  TX bytes:2924579095 (2.7 GB)
         Interrupt:16 Memory:f8000000-f8012100

The part we care about is the HWaddr (in this case, 00:15:c5:ed:e7:dd).

Let’s assume that this system won’t run the graphical installer, and we need to use the text-mode installer. To create a host-specific PXELinux configuration file for this system, all we need to do is copy our existing /var/lib/tftpboot/pxelinux.cfg/default file to /var/lib/tftpboot/pxelinux.cfg/01-00-15-c5-ed-e7-dd, and customize the configuration as we see fit.

Notice the filename: it’s simply the system’s MAC address, prefixed by 01-, and with all of the colons (:) replaced with hyphens (-). The contents of this configuration file are identical to the default configuration file: any number of boot images can be specified, and they must be in the same format as the default configuration file, but these boot images will only be available to the system with that specific MAC address.

So, since we want this system to always boot into the text-mode installer, open /var/lib/tftpboot/pxelinux.cfg/01-00-15-c5-ed-e7-dd in your favorite editor, get rid of the graphics section, and change the default to text:

default text
timeout 100
prompt 0

label text
  kernel linux/vmlinuz
  append initrd=linux/initrd.img text

Since we only have the one boot image, it also makes sense to change the prompt option so that the boot: prompt is not displayed. This is accomplished by changing the prompt 1 line to prompt 0 (shocking, huh? :).


You now have a working PXE boot environment, and you can almost install Linux over the network. Next time, I’ll discuss how to make PXELinux’s boot: prompt user-friendly, and how to setup an NFS server so that you can actually finish that Linux install… 😉