Setting up a PXE install for Linux

Installing Linux via PXE boot over a network can be a really nice way to do it and it is especially useful, if your client machine doesn’t have a CD / DVD drive. However, it can be a bit tricky to understand how it all works, so this post will hopefully explain what is going on, as well as show you how to set it up.

You will need:

  • A DHCP server
  • A TFTP server (tftpd-hpa)
  • vmlinuz and initrd.img from your distribution of choice
  • The PXELINUX.0 boot loader and a suitable config file

Install the TFTP server

Ensure you use the tftpd-hpa package, as PXELINUX requires that the boot server has a TFTP server which supports the “tsize” TFTP option. If you don’t use tftpd-hpa you will most likely see an error such as ‘TFTP server does not support the tsize option’

sudo apt-get install tftpd-hpa tftp-hpa xinetd

Configure xinetd to load TFTP

Create a new file called /etc/xinetd.d/conf/tftp and add the following contents:

service tftp
protocol        = udp
port            = 69
socket_type     = dgram
wait            = yes
user            = root
server          = /usr/sbin/in.tftpd
server_args     = /tftpboot
disable         = no

Create the /tftpboot folder, and ensure it is world readable. Then restart xinetd, and then test you can connect using tftp.

Set up the DHCP server

Add the following config to your /etc/dhcpd.conf file:

host pxeinstall {
# specify your client's MAC address
hardware ethernet 00:13:21:1F:F1:82; 
# give it an IP
#If the tftp server is on a different host to the DHCP server, specify its IP.
# path of the bootloader file, with tftpd-hpa it must be the absolute path
filename "/tftpboot/linux-install/pxelinux.0";

Then reboot dhcpd.

Setting up PXELINUX

PXELINUX is a SYSLINUX derivative, for booting Linux off a network server. Essentially, it is used to load a linux kernel of your choice on to your machine. You specify which kernel to load in a config file. You can download the latest pxelinux.0 file from You will need to extract it from the syslinux archive .

You are going to be creating a folder structure that will eventually look like this:


So, create a linux-install folder inside the /tftpboot folder. Inside this directory you should copy in pxelinux.0 (the PXE network boot loader) and create another folder called pxelinux.cfg. Inside pxelinux.cfg, create a file called default and copy in something like the following code:


Make a folder called pxelinux.cfg inside /tftboot/linux-install and then inside that create a file called default, with the following contents:

DISPLAY menu.msg


LABEL linux
        localboot 0

LABEL centos5.1
        KERNEL distros/centos5.1/vmlinuz
        APPEND initrd=distros/centos5.1/initrd.img ramdisk_size=6454 ip=dhcp

LABEL ubuntu8.04
        KERNEL distros/ubuntu8.04/linux
        APPEND initrd=distros/ubuntu8.04/initrd.gz ramdisk_size=6454 ip=dhcp

What this does is set up a boot prompt where you can choose to load any of the specified labels (kernels). In my example, I have used centos 5.1 and Ubuntu 8.04.

There is a 20 second timeout (200=20 seconds) and after this, it will load the default label.

The options we specify after each label direct the boot loader to the location of the kernel and the initrd files for that particular distro. NB: You must specify the path relative to the PXELINUX.0 file.

We have also specified menu.msg file – this just shows an ASCI menu to let people know what options they have. Unfortunately we could find a way to auto-generate a boot menu, so you need to edit the menu.msg manually every time you change the pxe config.

Linux Kernel and Initial Ram Disk

The only two files that are really needed to begin installing a distribution after PXELINUX loads are the compressed linux kernel and initial ram disk of your choice. You can define these as shown above in the pxelinux config. For ubuntu 8.04 they are called linux and initrd.gz, and can be found in the netboot folder of the ubuntu archive. For centos 5.1 they are called initrd.img and vmlinuz and can be found in the pxeboot images folder on any Centos Mirror. Once you have downloaded whichever ones you want to use, put them into your linux-install folder as shown in the directory structure above.


This is a really simple ASCII file that will be displayed as the boot menu. The one we use is as follows:

                          .-=-.          .--.
              __        .'     '.       /  " )
      _     .'  '.     /   .-.   \     /  .-'0c\0a
     ( \   / .-.  \   /   /   \   \   /  /    0c^0a
      \ `-` /   \  `-'   /     \   `-`  /
       `-.-`     '.____.'       `.____.'
  __ _ _ __   __ _  ___ ___  _ __   __| | __ _ 
 / _` | '_ \ / _` |/ __/ _ \| '_ \ / _` |/ _` |
| (_| | | | | (_| | (_| (_) | | | | (_| | (_| |
 \__,_|_| |_|\__,_|\___\___/|_| |_|\__,_|\__,_|


Choose one of the following labels in order to boot:
- linux (localboot)
- centos5.1
- ubuntu8.04