From Segfault
Jump to: navigation, search


We'll need the following components to allow for PXE booting:

  1. a DHCP server will set up networking and will point to a PXE bootfile
  2. the TFTP server will provide a PXE bootfile, containing a minimal boot environment
  3. NFS server, for serving the actual operating system.

Let's install the software first:

apt-get install isc-dhcp-server tftpd-hpa tftp-hpa nfs-kernel-server

The TFTP client was installed as well, so that we can test if the TFTP server is working correctly. Syslinux will provide the bootfiles:

wget https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-5.01.tar.{bz2,sign}
bzip2 -d syslinux*tar.bz2
gpg --recv-keys 8D233D55
gpg --verify syslinux*.tar.sign

The following modules[1] need to be copied to our PXE boot environment:

tar --wildcards -xvf syslinux*.tar syslinux*/core/pxelinux.0 syslinux*/com32/elflink/ldlinux/ldlinux.c32 \
          syslinux*/com32/libutil/libutil.c32 syslinux*/com32/menu/menu.c32
mkdir -p /tftpboot/pxe/pxelinux.cfg
find syslinux*/ -type f | while read f; do mv -v "$f" /tftpboot/pxe; done

The PXE configuration will be located in pxe/pxelinux.cfg. Each PXE client can have its own configuration file, where the file name is derived from the client's MAC address, with "01-" as a prefix:

$ cd /tftpboot/pxe/pxelinux.cfg
$ ls
01-00-50-56-01-02-03       # MAC address: 00:50:56:01:02:03

The default file will be used if no other configuration file matches.


In this example we'll be able to boot a VMware installation or the GRML rescue system:

$ cd /tftpboot/pxe/pxelinux.cfg
$ cat 01-00-50-56-01-02-03
serial 0 115200 0

default menu.c32
menu title PXE Boot Menu
timeout 3000

label VMWARE
menu label VMware ESX Kickstart
kernel vmware/vmlinuz
append initrd=vmware/initrd.img mem=512M vmkopts=debugLogToSerial:1 console=ttyS0,115200n8 \
       text ks=nfs://

label VMWARE
menu label VMware ESX Interactive
kernel vmware/vmlinuz
append initrd=vmware/initrd.img mem=512M vmkopts=debugLogToSerial:1 console=ttyS0,115200n8 \
       text askmedia

label GRML64
kernel grml64/vmlinuz
append initrd=grml64/initrd.img console=ttyS0,115200n8 root=/dev/nfs \
nfsroot= live-media-path=/live/grml64-full boot=live noeject nocolor noquick

Don't put any actual line breaks in the file, this was just done for readability. To elaborate a bit more on these examples:

  • The VMware ESX installer would not start on a serial console when the text parameter was missing. Booting alsways hung at:
[05:32:23.924504] * weasel ... [ !! ]
init started: BusyBox v1.9.1-VMware-esx-624
  • After booting GRML and logging in, a "Quickhelp" menu came up, totally screwing up the (screen) console. Adding noquick supressed the menu and login is now less painful.

Next, we'll copy the kernel and the initrd into our PXE boot environment.


Mount the ESX ISO and copy the kernel & initrd to the PXE root:

mount -o loop,ro esx-4.0.0.iso /mnt/cdrom

mkdir -p /tftpboot/pxe/vmware
cp /mnt/cdrom/isolinux/vmlinuz /mnt/cdrom/isolinux/initrd.img /tftpboot/pxe/vmware


wget http://download.grml.org/grml_netboot_package_grml64-full_2013.02.tar.bz2{,.sha1,.sha1.asc}
gpg --recv-keys --keyserver hkp://pgp.mit.edu:11371 37E272E8
gpg --verify grml_netboot*.sha1.asc

tar --wildcards -xvjf grml_netboot_package*.tar.bz2 */tftpboot/{vmlinuz,initrd.img}

mkdir -p /tftpboot/pxe/grml64
mv grml*/tftpboot/* /tftpboot/pxe/grml64

We still need the GRML root filesystem[2]:

wget http://download.grml.org/grml64-full_2013.02.iso{,.sha1,sha1.asc}
gpg --verify grml*.sha1.asc

We can just loop-mount the ISO image, no need to copy anything:

mount -t iso9660 -o loop,ro grml64-full_2013.02.iso /mnt/cdrom/

Don't forget to re-export the NFS mountpoint:

$ exportfs -v -r



Create a separate stanza for the PXE client (the host that will boot via PXE):

$ cat /etc/dhcp/dhcpd.conf
host node1 {
       hardware ethernet 00:50:56:01:02:03;
       fixed-address node1;
       filename "pxe/pxelinux.0";

The filename directive specifies the file which will be served via tftp. The filename is relative to the document root of the tftp server.

Note: it may be possible to assign a single IP address to more than one hardware address. That might be useful because in our setup the (virtual) NICs got a different hardware address in each installation.


We're using tftp-hpa which will chroot on startup.[3]

$ grep tftp /etc/inetd.conf 
tftp    dgram   udp   wait  root    /usr/sbin/in.tftpd  /usr/sbin/in.tftpd -s /tftpboot

By now, the absolute path of pxe/pxelinux.0 will be /tftpboot/pxe/pxelinux.0. Once in.tftpd is running, we can see if it's working properly:

$ cd /tmp
$ tftp localhost
tftp> verbose
tftp> get pxe/pxelinux.0
getting from localhost:pxe/pxelinux.0 to pxelinux.0 [netascii]
Received 26840 bytes in 0.4 seconds [599978 bit/s]
tftp> ^D

$ diff pxelinux.0 /tftpboot/pxe/pxelinux.0

No output from diff, good :-)


While the kernel and its initrd are being served via PXE, the operating system will be served via NFS. On Linux, NFS shares are configured via /etc/exports:

$ cat

After rexporting the shares (exportfs -vr), we should be good to go.

On Solaris, exporting NFS shares can be done as such:

$ cat /etc/dfs/dfstab
share -F nfs -o ro    /data/tftpboot
share -F nfs -o ro    /mnt/cdrom

$ shareall -F nfs

Pay attention to the /mnt/cdrom share: when something (an actual CD-ROM or an ISO image) is mounted (locally) on /mnt/cdrom its NFS share has to be re-exported!