PXE Beginnings

Introduction

Today's subject is PXE - in my world, that stands for "Preboot eXecution Environment" and it's usually pronounced "pixie." This is a specification that uses a limited network stack on network card (before the OS is booted) to A) get itself a network setup from a local DHCP server, B) discover a local PXE/TFTP server (address provided by the DHCP server), and C) download and boot an OS from the TFTP server. (This is considerably simplified.) This is useful for diskless workstations (not common anymore, but they do still exist), network OS installation, and diagnostic disks to examine a damaged system.

PXE has been a standard nearly two decades, and while it's not something most computer users are aware of, it's alive and thriving in network centres - and occasionally in the homes of dedicated enthusiasts. The use of PXE has mutated over time to allow for considerably more flexibility than was originally envisioned when the specification was crafted. syslinux was used to create a menu system to select your OS, and more recently the open source firmware iPXE allows not only a menu system, but booting a machine from anywhere on the Internet (not just your local LAN as with the original PXE).

The first example given on the OpenWRT page (link in the Bibliography) is excessively complex: several steps are required, but instead of using a single binary (the simplest possible case) they use an Ubuntu ISO and then start explaining how to set up NFS so it will work. A single binary doesn't need NFS, so let's start there.

The simplest case for me was to use my primary router which runs OpenWRT (version Chaos Calmer) - this means modifying the DHCP server to point to a TFTP server, but - again going with the simplest case - the TFTP server will also be hosted on the router. Again for simplicity, I'm going to start with syslinux and worry about iPXE later (or not at all if syslinux serves my purposes).

Basic Setup

You'll need to set up a folder from which to serve your binaries and/or ISO images. I got into quite an adventure with USB storage on OpenWRT because I thought I was going to need room for several ISOs. If you're just starting out, you can work through my example with a copy of the Memtest86+ binary hosted on a folder on the router's internal storage: the Memtest86+ binary is only 150Kb, and the bits of syslinux you need will require another 416Kb. Most routers shouldn't have any trouble storing this.

Setting Up the Folder

I used the folder /mnt/usb1/images/ as the TFTP folder. You'll need to unpack the latest syslinux: I'd recommend doing the downloading and unpacking on a regular computer, not on the router itself. After you've done that:

$ mkdir syslinux-6.03
$ cd syslinux-6.03
$ unzip ../syslinux-6.03.zip
...
$ mkdir tftp
$ cp -vi bios/core/pxelinux.0 bios/com32/elflink/ldlinux/ldlinux.c32 bios/com32/menu/vesamenu.c32 bios/com32/lib/libcom32.c32 bios/com32/libutil/libutil.c32  tftp/
$ scp tftp/* root@192.168.0.1:/mnt/usb1/images/

You can do this any number of ways (potentially not extracting the whole zip file, and my intermediate 'tftp' directory was entirely unnecessary but convenient). The point is, get that set of files from syslinux and put them in the TFTP directory.

Now get our binary: go to http://www.memtest.org/#downiso and download the "Pre-Compiled Bootable Binary." Extract the memtest86+-5.01.bin file that's the only file in the archive, and get it over to the same folder on your router. Sean Madden's wiki ("Memtest over PXEBoot" in the Bibliography) insists that it needs to be renamed to remove the ".bin". To be on the safe side (no dots or special characters of any kind) I called it memtest86501.

Setting up the syslinux Menu

Create a subfolder of your main TFTP folder called 'pxelinux.cfg/'. Create and edit a new file in that folder, 'pxelinux.cfg/default':

DEFAULT vesamenu.c32
PROMPT 0
MENU TITLE OpenWRT CC PXE-Boot Menu

label Memtest86
        MENU LABEL Memtest86+ v5.01
        KERNEL memtest86501
        TEXT HELP
                Starts the Memtest86+ memory tester on most machines - crashes on a few ...
        ENDTEXT

Setting Up DHCP and TFTP

I had spent some time researching how to set up a TFTP server. As it turned out, this was unnecessary. OpenWRT has a TFTP package, but I never installed it and this worked anyway, which suggests that the 'dnsmasq' package - already the main driver of our router by providing DNS and DHCP - is also capable of providing TFTP. All I did was modify the /etc/config/dhcp file with the following changes:

config dnsmasq  # this section should already exist
    # ...
    # add the following two lines at the end of the section
    option enable_tftp '1'
    option tftp_root '/mnt/usb1/images'  # your TFTP folder

config boot linux  # I had to add this section
    option filename 'pxelinux.0'
    option serveraddress '192.168.0.1'  # the IP address of your router
    option servername 'OpenWRT'  # this seems to be renameable?

Finally, I ran /etc/init.d/dnsmasq restart . And at this point, it worked for me.

The Fine Print

This is only useful if your computer(s) can boot from PXE. Nearly all can: get into your BIOS, and reset the boot order so that PXE comes before everything else.