PXEBoot (X86+EFI)

Any OS can support PXE/EFI boot possibilities to other systems booting. This post will focus on creating a X86/EFI boot environment using Debian for booting various other systems. The post will primarily focus on booting other Linux environments, there will be additional posts supporting Windows and other platforms.

Step 1: Basic Details

The three components that make up a PXE boot environment are:

  • DHCP provisioning: DHCP provisions the system with IP address and details on where to boot from.
  • TFTP : provides the system with files to boot from

Step 2: DHCP Details

Provision a DHCP server in the environment that is coupled to your network. In the following example will focus primarily on linux DHCP, but any DHCP service will suffice. The following DHCP server configuration extract contains the option entries to have the system choose a boot file for x86 of EFI systems.

# DHCP Server Example Configuration File

allow bootp;
allow booting;
next-server 192.168.0.40;

option arch code 93 = unsigned integer 16;

if option arch = 00:07 or option arch = 00:09 {
      filename "bootnetx64.efi";
} else {
      filename "pxelinux.0";
}

subnet 192.168.2.0 netmask 255.255.255.0 {
   option routers 192.168.2.1;
   option subnet-mask 255.255.255.0;
   option broadcast-address 192.168.2.255;
   range 192.168.2.2 192.168.2.254;
}

Step 2: TFTP Server

Install a tftp server:

# apt install tftpd-hpa

Configure the default TFTP configuration file /etc/default/tftpd-hpa

# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure"

Create TFTP directory structure:

# mkdir /srv/tftp
# mkdir /srv/tftp/boot-screens
# mkdir /srv/tftp/pxelinux.cfg
# mkdir /srv/tftp/grub
# mkdir -p /srv/tftp/debian-installer/amd64
# mkdir -p /srv/tftp/images/debian
# mkdir -p /srv/tftp/images/ubuntu

Restart the TFTP server

# systemctl restart tftpd-hpa.service

Step 3: Install Debian Netboot

Install the Debian netboot files, these contain the basic files for creating a Debian boot PXE environment and memdisk (to boot alternative images in X86 mode):

# apt install debian-installer-11-netboot-amd64
# apt install grub-imageboot

Copy the various netboot files to the tftp directory and create basic structure:

# cd /usr/lib/debian-installer/images/11/amd64/text/debian-installer/amd64

# cp pxelinux.0 /srv/tftp/
# cp bootnetx64.efi /srv/tftp/
# cp grubx64.efi /srv/tftp/
# cp boot-screens /srv/tftp/boot-screens

# cd /srv/tftpboot
# ln -s boot-screens/ldlinux.c32 ldlinux.c32
# cp /boot/memdisk /srv/tftpboot/images/memdisk

< Debian EFI boot links to grub.cfg in debian-installer directory, create symbolic link to root>
# cd /srv/tftp/debian-installer/amd64
# ln -s ../../grub grub

Copy the Debian boot files to the TFTP  Debian image directory:

# cd /usr/lib/debian-installer/images/11/amd64/text/debian-installer/amd64

# cp initrd.gz /srv/tftp/images/debian
# cp linux /srv/tftp/images/debian

Step 4: Configure X86 Netboot

x86 netboot uses the pxelinux.0 format to boot from, this file uses /srv/tftp/pxelinux.cfg/default for its details, edit the file and place the following values to let it use a boot-screen:

path boot-screens/
include boot-screens/menu.cfg
default boot-screens/vesamenu.c32
prompt 0
timeout 0

Configure the /srv/tftp/boot-screens/menu.cfg to reflect your boot requirements, in the following example it was customized to support for various options:

menu hshift 7
menu width 61
timeout 50

menu title ^GMy PXE Boot System
include boot-screens/stdmenu.cfg
default debian
menu begin debian
    menu label ^Debian
    menu title Debian
    include boot-screens/stdmenu.cfg
    label mainmenu
        menu label ^Back..
        menu exit
    include boot-screens/debian-auto.cfg
    include boot-screens/debian-manual.cfg
menu end

Configure the Debian auto-installer menu  /srv/tftp/boot-screens/debian-auto.cfg to reflect your boot requirements, in the following example it was customized to support for various options. The boot line contains a url=??? entry, which should point to your Debian preseed file.

label debian-auto-install-text
        menu label ^Debian [auto-install-text]
        menu default
        kernel images/debian/text/linux
        append vga=788 auto=true priority=critical ramdisk_size=14984 locale=en_US.UTF-8 kdb-chooser/method=us console-setup/layoutcode=en_GB interface=eth0 netcfg/get_hostname= console-keymaps-at/keymap=us url=http://nas.mydomain.org/preseed-debian.txt vga=normal initrd=images/debian/text/initrd.gz -- quiet

Configure the Debian regular menu  /srv/tftp/boot-screens/debian-manual.cfg to reflect your boot requirements,

label debian-manual-install
        menu label ^Debian [manual-install]
        kernel images/debian/linux-amd64
        append vga=788 initrd=images/debian/initrd-amd64.gz --- quiet

Step 5: Configure EFI Netboot

EFI netboot uses the bootnetx64.efi format to boot from, this file uses  /debian-installer/amd64/grub/x86_64-efi/grub.cfg for its details. As we created a symoblic link you can edit /srv/tftp/grub/x86_64-efi/grub.cfg  the file and place the following values to let it load the generic modules and the main grub.cfg file:

insmod part_acorn
insmod part_amiga
insmod part_apple
insmod part_bsd
insmod part_dfly
insmod part_dvh
insmod part_gpt
insmod part_msdos
insmod part_plan
insmod part_sun
insmod part_sunpc
source /grub/grub.cfg

Configure the /srv/tftp/grub/grub.cfg to reflect your boot requirements, in the following example it was customized to support for various options. The following example does contain a theme.txt file, you can use any of the available grub themes to customize this loader:

if loadfont $prefix/font.pf2 ; then
  set gfxmode=800x600
  set gfxpayload=keep
  insmod efi_gop
  insmod efi_uga
  insmod video_bochs
  insmod video_cirrus
  insmod gfxterm
  insmod png
  terminal_output gfxterm
fi

insmod loopback


background_image /boot-screens/background.png

set theme=/grub/theme.txt

set menu_color_normal=cyan/blue
set menu_color_highlight=white/blue

insmod play
play 480 440 1

submenu "Debian" --class debian {

set theme=/grub/theme.txt

menuentry 'Debian Auto-Install' --class debian {
    set background_color=black
    linux    images/debian/text/linux vga=normal auto=true priority=critical ramdisk_size=14984 locale=en_US.UTF-8 kdb-chooser/method=us console-setup/layoutcode=en_GB interface=eth0 netcfg/get_hostname= console-keymaps-at/keymap=us url=http://filer.ops.cyberfront.org/preseed-debian-efi.txt vga=normal initrd=images/debian/text/initrd.gz quiet
    initrd   images/debian/text/initrd.gz
}

menuentry 'Debian Manual-Install' --class debian {
    set background_color=black
    linux    images/debian/text/linux vga=normal quiet
    initrd   images/debian/text/initrd.gz
}
}

menuentry 'Reboot' --class restart {
    reboot
}

menuentry 'Shutdown' --class shutdown {
    halt
}

Step 6: Test Test Test

Create a Virtual Machine with X86 boot or EFI Settings, when creating a Virtual Machine, just edit it settings and set BIOS type to BIOS or EFI. Boot the VM and start checking if it receives the proper DHCP settings, boots from the TFTP server, etc.