Adding EFI support to our PXE server

In this post I’m going to cover the process needed to add UEFI support to our PXE server.
Up until this point, we’ve only been able to boot and access our PXE server on BIOS devices, Gen 1 Hyper-V VMs, and BIOS mode VMWare VMs.

This post assumes you’ve either followed or have a similar setup to the one mentioned in my first post on this, HERE.

Getting started

As mentioned above, we’re going to add EFI support to our PXE server. We’re going to accomplish this with a few files and resources:
– grubx64.efi (found online or within an ISO)
– grubia32.efi (found online or within an ISO)
– grub.cfg (created by us, more on this later)

To begin, we want to obtain the grubia32.efi and grubx64.efi files and put it in the /var/lib/tftpboot location.
In the first post in this series, you’ll remember we copied the AlmaLinux install files to our /srv/networkboot location – I’m going to copy the files from that location:

[root@COLO-PXE ~]# cp -v /srv/networkboot/almalinux/8.5/EFI/BOOT/{grubia32.efi,grubx64.efi} /var/lib/tftpboot/
'/srv/networkboot/almalinux/8.5/EFI/BOOT/grubia32.efi' -> '/var/lib/tftpboot/grubia32.efi'
'/srv/networkboot/almalinux/8.5/EFI/BOOT/grubx64.efi' -> '/var/lib/tftpboot/grubx64.efi'

Prepare router for EFI booting

When we initially built our PXE server, I ran through how to set the DHCP options to enable PXE booting, however this was only for BIOS/Legacy clients. To enable PXE booting for EFI clients, we’ll need to do the following:

On PFSense, we’re going to want to navigate to Services DHCP Server > <Network name>.
Scroll to the bottom of the page and find Network Booting. Click Display Advanced.
In the UEFI 32 bit file name box, enter grubia32.efi
In the UEFI 64 bit file name box, enter grubx64.efi
Scroll to the bottom of the page and Save the changes we’ve made. We’re now ready to continue.

Building grub.cfg

At this point, we’ve copied our efi bootloaders, but we now need to build our grub.cfg file – unfortunately our pxelinux menu files won’t work with EFI.
First, we need to create the grub.cfg file and then open it, I’m using vi in this example:

[root@COLO-PXE ~]# touch /var/lib/tftpboot/grub.cfg
[root@COLO-PXE ~]# vi /var/lib/tftpboot/grub.cfg

In this example, I’m going to provide a simple grub.cfg that lets us boot the AlmaLinux installation media, and also Gparted, both over EFI:

set default=0
set timeout=30


menuentry 'Boot from next volume' {
        exit
}

menuentry 'Boot AlmaLinux 8.5 x64 with Network Repo'{
        linuxefi almalinux/8.5/pxeboot/vmlinuz inst.repo=ftp://10.179.1.10/almalinux/8.5 devfs=nomount
        initrdefi almalinux/8.5/pxeboot/initrd.img
}

menuentry 'GParted Live'{
        linuxefi gparted/vmlinuz boot=live config components union=overlay username=user noswap noeject locales=en_US keyboard-layouts=en_US.UTF-8 fetch=ftp://10.179.1.10/gparted/filesystem.squashfs
        initrdefi gparted/initrd.img
}

So what’s actually happening?

This took me some time to work out and understand. We’re basically doing the following:
– Setting our default boot option number
– Setting our menu timeout
– Adding an exit option (which is our default boot option)
– Adding a menu entry for our first bootable item (AlmaLinux 8.5 media)
– Setting the EFI equivalent of the PXELINUX APPEND line
– Setting the EFI equivalent of the PXELINUX KERNEL line
– Adding a menu entry for our second bootable item (GParted Live)
– Setting the EFI equivalent of the PXELINUX APPEND line
– Setting the EFI equivalent of the PXELINUX KERNEL line

You’ll notice that the linuxefi and initredfi lines are similar to what I initially set up in my post about adding more entries to our boot menu, HERE. We can reuse most of these lines but some will need some changing to follow the above format.

Now that we’ve got this, we can try booting:

AlmaLinux
GParted Live

Adding more entries to grub.cfg

Now that we understand the basics of the grub.cfg menu, we can add some more entries and customise it a little. Sources are HERE and HERE – these two links massively helped with this process.
Below is a copy of a menu that contains a couple of submenus with more bootable options. This also has some colours set for the text:

set default=0
set timeout=20
function load_video {
  insmod efi_gop
  insmod efi_uga
  insmod video_bochs
  insmod video_cirrus
  insmod all_video
}

load_video
set gfxpayload=keep
insmod net
insmod efinet
insmod tftp
insmod gzio
insmod part_gpt
insmod ext2


set menu_color_normal=white/black
set menu_color_highlight=white/cyan

menuentry 'Boot from next volume' {
	echo "System booting to next volume..."
    exit
}

menuentry "Shutdown system" {
	echo "System shutting down..."
	halt
}
 
menuentry "Reboot system" {
	echo "System rebooting..."
	reboot
}

submenu "AlmaLinux -->" {
	menuentry 'Boot AlmaLinux 8.5 x64 with Network Repo'{
        linuxefi almalinux/8.5/pxeboot/vmlinuz inst.repo=ftp://10.179.1.10/almalinux/8.5 devfs=nomount
        initrdefi almalinux/8.5/pxeboot/initrd.img
	}
}

submenu "Tools -->" {
    menuentry "NT Password and Registry Editor"{
        linuxefi ntpasswd/vmlinuz rw vga=1
		initrdefi ntpasswd/initrd.cgz,ntpasswd/scsi.cgz
    }

    menuentry "GParted Live"{
        linuxefi gparted/vmlinuz boot=live config components union=overlay username=user noswap noeject locales=en_US keyboard-layouts=en_US.UTF-8 fetch=ftp://10.179.1.10/gparted/filesystem.squashfs
        initrdefi gparted/initrd.img
    }

    menuentry "Clonezilla Live"{
        linuxefi clonezilla/vmlinuz boot=live username=user union=overlay config components quiet noswap edd=on nomodeset nodmraid keyboard-layouts=en locales=en_US.UTF-8 ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch=no net.ifnames=0 nosplash noprompt fetch=ftp://10.179.1.10/clonezilla/filesystem.squashfs
        initrdefi clonezilla/initrd.img
    }

    menuentry "Rescuezilla Live"{
        linuxefi rescuezilla/vmlinuz boot=casper quiet splash fastboot toram root=/dev/ram0 ramdisk_size=15000000 ip=dhcp url=http://10.179.1.10/networkboot/rescuezilla/rescuezilla-2.3.1-64bit.impish.iso
        initrdefi rescuezilla/initrd.lz
    }
}

So what’s actually happening? Part 2

Much the same as our first menu, I’m not 100% sure what’s going on here and it’s taken me some time to sort of understand, however for the parts I do know:
– Setting our default boot option number
– Setting our menu timeout
– Creating a module group, and then inserting the dynamic modules to support different video types
– Inserting more dynamic modules (not 100% what these are but I presume they’re important!)
– Setting menu colours for normal text and highlighted text
– Adding menu entries for boot to next volume, shutdown and reboot
– Creating submenu for AlmaLinux containing it’s boot entry
– Creating submenu for Tools and their entries

That was lots of text, so let’s test our menu and see if we can boot from it successfully:

AlmaLinux
Rescuezilla
Reboot + shutdown

Wrapping up

In this post I’ve covered the process of enabling UEFI PXE booting on our router, copying the files to allow for UEFI booting, and creating a couple of grub menus to allow us to select and boot from our stored images, with submenu support to allow us to keep our menu tidy and organised.
In the next post, I’m going to cover adding Windows support to both the legacy PXELINUX and grub.cfg menu.

Danny Written by: