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:


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:



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.