Server Howto: PXE / UEFI network-boot

Pressing F12 during the POST boot cycle of most computers will produce a prompt asking which boot source you require. Some computers will default straight to network booting with F11. Selecting network booting will activate either the PXE function or the UEFI network stack, depending on what is configured in the BIOS. With a PXE / UEFI network boot function on your network, you can run rescue tools, partition tools, and install Linux distributions without needing to burn optical discs.

This howto describes how to set-up PXE and UEFI booting on RHEL+clones and assumes you have followed the howtos and set-up: DNS, DHCP, and an in-house mirror as all three of those are needed in order to set-up tftpboot.


Install

xinetd is dead and no longer needed. The Trivial File Transport Protocol daemon can be installed as a separate system that is controlled via systemd. Install the tftp-server with the following (as root): yum install tftp-server

You will need to enable the daemon with: systemctl enable tftp-server and start it with systemctl start tftp-server.

This is the first step, and difficult to test until we start to populate the directory. All data served by tftp-server comes from /var/lib/tftpboot and this directory is strictly locked to ensure tftp clients cannot wander off and try to grab files from other parts of the file-system, so do not try to symlink to other files/directories outside of /var/lib/tftpboot as it will not work!


PXE boot

From the DHCP set-up, you may remember the instruction to use pxelinux.0. So where is that?

In order to set-up a pxeboot function, we need to create a set of directories in /var/lib/tftpboot and populate them with files we can largely find on the working system. Go ahead and cd /var/lib/tftpboot, then inside that directory, create a bootmenu folder with: mkdir -p bootmenu/pxelinux.cfg

We will make use of the pxelinux.cfg directory later...

The files we need to add to the bootmenu directory are present in /usr/share/syslinux and they are owned by the syslinux package, which is not installed by default. Install it with: yum install syslinux. The files we need are: chain.c32, memdisk, pxelinux.0, vesamenu.c32, mboot.c32, and menu.c32. The simplest way to copy these files, and update them when a new syslinux package is released, is to create a script. As ever, this script is saved in /root/scripts.

#!/bin/bash
#
# Script to update pxeboot loader


# A path, a path!
#
BOOT=/var/lib/tftpboot/bootmenu/
SYS=/usr/share/syslinux

# Copy the required files
#
cp -f $SYS/chain.c32 $BOOT
cp -f $SYS/memdisk $BOOT
cp -f $SYS/pxelinux.0 $BOOT
cp -f $SYS/vesamenu.c32 $BOOT
cp -f $SYS/mboot.c32 $BOOT
cp -f $SYS/menu.c32 $BOOT


# Clean up
#
unset BOOT
unset SYS

exit 0

The script is called sync-pxeboot and has 755 permissions. It is run when needed; i.e. there is no need to use cron to run this script on a regular basis as these files rarely change.

In our DHCP configuration, we pointed to pxelinux.0 not bootmenu/pxelinux.0. To keep our system clean, simple, and make it work, we need to add a symlink to the file in the bootmenu directory. From within /var/lib/tftpboot run the command: ln -s bootmenu/pxelinux.0

If you ls -al (or ll if it is configured in bashrc) you will see a symlink for pxelinux.0 pointing at bootmenu/pxelinux.0

Now we need to create some PXE boot menu configuration files in bootmenu/pxeboot.cfg which are detailed below. To make things quicker to access the menus, go ahead and create a symlink to the folder from /var/lib/tftpboot with the command: ln -s bootmenu/pxelinux.cfg

If you ls -al (or ll if it is configured in bashrc) you will see a symlink for pxelinux.cfg pointing at bootmenu/pxelinux.cfg


sync-netboot

The set-up in this section is also needed for the UEFI set-up detailed below, so do not skip it.

The case and naming of the directories we are about to create are important as they will be referenced in both the PXE menu config files and the grub.cfg file used for UEFI, so remain consistent with how you create your directory layout.

As mentioned earlier, /var/lib/tftpboot is locked down to stop tftp clients from stealing important files, like /etc/passwd or /etc/shadow. We cannot symlink to the files we might find in the /mirror directory, assuming you followed the mirror howto, therefore we need to create a folder structure to contain files, such as vmlinuz and initrd.img, that are used to provide a network boot function. As these files tend to be different between versions and distributions, we need to create an array of containing directories.

For CentOS, I recommend creating a directory in /var/lib/tftpboot with: mkdir -p CentOS/7/x86_64

For Rocky Linux, I recommend creating a directory in /var/lib/tftpboot with: mkdir -p Rocky/8/x86_64

We now need to populate the x86_64 folders with the files used for network-booting. Assuming you followed the mirror howto, the simplest solution is to rsync the files lurking in /mirror. These files are updated each time there is a release; i.e. 7.8 to 7.9, so it is a good idea to create a script to do the heavy lifting. As ever, this script lives in /root/scripts

#!/bin/bash
#
# Script to rsync netboot images to PXE
#
# Variables
#
OPT=var

#################################################################
# CentOS
#################################################################

# 7
echo -e "\nCentOS 7\n"
rsync -$OPT --delete --exclude="README*" \
/mirror/mirror.centos.org/7/os/x86_64/images/pxeboot/ \
/var/lib/tftpboot/CentOS/7/x86_64/

#################################################################


#################################################################
# Rocky
#################################################################

# 8
echo -e "\nRocky 8\n"
rsync -$OPT --delete --exclude="README*" \
/mirror/rocky/8/BaseOS/x86_64/os/images/pxeboot/ \
/var/lib/tftpboot/Rocky/8/x86_64/

#################################################################

# Clean-up
unset OPT

exit 0

This script is called sync-netboot and has 755 permissions.

Below is a sample of an old script that synchronised Ubuntu 16 LTS. Note the paths in red split the 32-bit and 64-bit versions. Your script may need to go further if you are netbooting often-changing versions of Ubuntu or Fedora.

# 16.04 LTS
echo -e "\nUbuntu 16.04 LTS x86_64\n"
rsync -$OPT --delete --exclude-from=/root/scripts/sync-exclude \
/mirror/archive.ubuntu.com/ubuntu/dists/xenial/main/installer-amd64/current/images/netboot/ubuntu-installer/amd64/ \
/var/lib/tftpboot/Ubuntu/16.04-LTS/amd64/

echo -e "\nUbuntu 16.04 LTS i386\n"
rsync -$OPT --delete --exclude-from=/root/scripts/sync-exclude \
/mirror/archive.ubuntu.com/ubuntu/dists/xenial/main/installer-i386/current/images/netboot/ubuntu-installer/i386/ \
/var/lib/tftpboot/Ubuntu/16.04-LTS/i386/

/root/scripts/sync-exclude is a text file that contained the following to stop the included Ubuntu versions from over-riding ours:

boot-screens
pxelinux.0
pxelinux.cfg

As you can see, you will need to synchronise the required netboot files for each distribution you wish to use via PXE / UEFI network booting. You will also need to update this file for each new distribution you wish to add or remove, and you may need to run it via cron in order to automate the update process.


PXE Menu: default

We now need to create a file in /var/lib/tftpboot/bootmenu/pxelinux.cfg/ called default. Remember we created that symlink earlier? You can simply cd pxelinux.cfg from /var/lib/tftpboot to save on typing and/or remembering long paths.

There is considerable documentation available on the Internet regarding how to configure the PXE boot menus. The default file shown here is mine, and it is offered as a working example.

DEFAULT bootmenu/vesamenu.c32
PROMPT 0
TIMEOUT 0
ONTIMEOUT LOCAL
MENU BACKGROUND bootmenu/spectrum.jpg
MENU COLOR TITLE 7;30;47 #FF000000 #00000000 none
MENU COLOR UNSEL 30;47 #FF000000 #0000FFFF none
MENU COLOR SEL 7;37;40 #FF000000 #FF00FFFF none
MENU COLOR DISABLE 7;37;40 #FF000000 #00000000 none
MENU TITLE Gaztronics PXE Menu
MENU TABMSG
LABEL -
    MENU LABEL Exit PXEBOOT and boot local system
    MENU DEFAULT
    LOCALBOOT 0
LABEL -
    MENU LABEL Select distribution or tools:
    MENU DISABLE
LABEL -
    MENU INDENT 2
    MENU LABEL Rocky
    KERNEL bootmenu/vesamenu.c32
    APPEND pxelinux.cfg/rocky.menu
LABEL -
    MENU INDENT 2
    MENU LABEL CentOS
    KERNEL bootmenu/vesamenu.c32
    APPEND pxelinux.cfg/centos.menu
LABEL -
    MENU INDENT 2
    MENU LABEL Tools
    KERNEL bootmenu/vesamenu.c32
    APPEND pxelinux.cfg/tools.menu
LABEL -
    MENU INDENT 2
    MENU LABEL Testing (Here be Dragons!)
    KERNEL bootmenu/vesamenu.c32
    APPEND pxelinux.cfg/testing.menu

There is no count-down timer set in my default file. I assume I have booted to the network for a reason, and if a system has booted into PXE when it has an OS installed, I clearly need to re-set the BIOS boot order.

The line MENU BACKGROUND bootmenu/spectrum.jpg references a file I created back in the late 90s and have since converted to a JPEG for various annoying things. This is what it looks like:

spectrum

How are your eyeballs? The file is saved in /var/lib/tftpboot/bootmenu and is ye olde 640 x 480 pixels. You know when you are in the PXE system!!


PXE Menu: CentOS

With the above set and vmlinuz and initrd.img ready to go, we can now set-up the PXE menu to boot our CentOS installations. From the default file above, we can see a reference to pxelinux.cfg/centos.menu and this is my current centos.menu file:

MENU BACKGROUND bootmenu/spectrum-centos.jpg
MENU COLOR TITLE 7;30;47 #FF000000 #00000000 none
MENU COLOR UNSEL 30;47 #FF000000 #0000FFFF none
MENU COLOR SEL 7;37;40 #FF000000 #FF00FFFF none
MENU COLOR DISABLE 7;37;40 #FF000000 #00000000 none
MENU TITLE CentOS Install
MENU TABMSG
LABEL Main Menu
    MENU LABEL Return to Main Menu
    MENU DEFAULT
    KERNEL bootmenu/vesamenu.c32
    APPEND pxelinux.cfg/default
LABEL -
    MENU LABEL Select version to pxeboot:
    menu disable
LABEL CentOS 7 x86-64 Standard install
    MENU INDENT 2
    kernel CentOS/7/x86_64/vmlinuz
    append initrd=CentOS/7/x86_64/initrd.img ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp method=ftp://mirror.gaztronics.net/mirror.centos.org/7/os/x86_64
LABEL CentOS 7 x86-64 Rescue
    MENU INDENT 2
    kernel CentOS/7/x86_64/vmlinuz
    append initrd=CentOS/7/x86_64/initrd.img ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp method=ftp://mirror.gaztronics.net/mirror.centos.org/7/os/x86_64 rescue
LABEL CentOS 7 x86-64 Server install
    MENU INDENT 2
    kernel CentOS/7/x86_64/vmlinuz
    append initrd=CentOS/7/x86_64/initrd.img ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp ks=ftp://mirror.gaztronics.net/kickstart/CentOS-7-server.cfg

Now you can see the path references in kernel CentOS/7/x86_64/vmlinuz and how getting them wrong will result in failure to boot!

The other magic net.ifnames=0 biosdevname=0 ipv6.disable=1 reverts to eth0/eth1, disables eth0 being called something daft, and kills IPv6.

You may notice the method=ftp:// entry is pointing at our in-house mirror via FTP. You can of course use HTTP. I have used FTP for speed.

The last entry loses method in favour of ks= and the path is pointing at a kickstart directory on my mirror server. You can list a variety of kickstart installation files this way; e.g. if you want to install a custom desktop or custom laptop build. The kickstart file contains the path to use when installing packages. Here is an example:

#platform=x86, AMD64, or Intel EM64T
#version=DEVEL
# Install OS instead of upgrade
install
# Keyboard layouts
keyboard 'uk'
# Reboot after installation
reboot
# Root password
rootpw --iscrypted $1$...make your own!
# System timezone
timezone Etc/UTC
# Use network installation
url --url="ftp://mirror.gaztronics.net/mirror.centos.org/7/os/x86_64/"
# System language
lang en_GB
# Firewall configuration
firewall --disabled
# Network information
network --bootproto=dhcp --device=eth0 --onboot=on
network --bootproto=dhcp --device=eth1
network --bootproto=dhcp --device=eth2
network --bootproto=dhcp --device=eth3
# System authorization information
auth --useshadow --passalgo=sha512
# Use graphical install
graphical
# SELinux configuration
selinux --disabled
# Do not configure the X Window System
skipx

# System bootloader configuration
bootloader --location=mbr
# Clear the Master Boot Record
zerombr
# Partition clearing information
clearpart --all --initlabel
# Disk partitioning information
part /boot/efi --asprimary --fstype="vfat" --ondisk=sda --label EFI --size=1024
part /boot --asprimary --fstype="ext4" --ondisk=sda --label BOOT --size=512
part swap --asprimary --fstype="swap" --ondisk=sda --recommended
part / --asprimary --fstype="ext4" --grow --ondisk=sda --label ROOT --size=1

%post
echo "NOZEROCONF=yes" >> /etc/sysconfig/network
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
%end

%packages
@base
@console-internet
@mail-server
@system-admin-tools
deltarpm
dos2unix
ftp
gpm
screen
sendmail
sendmail-cf
symlinks
tree
unix2dos
-abrt*
-alsa*
-biosdevname
-cryptsetup-luks
-cpuspeed
-dmraid
-dosfstools
-dovecot
-elinks
-fprintd-pam
-ledmon
-lvm2
-mdadm
-pcmciautils
-postfix
-rdate
-rfkill
-spamassassin
-system-config-firewall-tui
-wireless-tools
-NetworkManager*
-ebtables
-firewalld

%end

The above example would install a very basic non-GUI CentOS 7 with the assumption that it was being installed on a rack-mount server with 4 NICs. Having completed the DNS and DHCP set-up, the MAC address(es) were already set in DHCP along with a DNS name.

The line MENU BACKGROUND bootmenu/spectrum-centos.jpg references a custom JPEG made with GIMP:

spectrum


PXE Menu: Rocky

My current rocky.menu file looks like this:

MENU BACKGROUND bootmenu/spectrum.jpg
MENU COLOR TITLE 7;30;47 #FF000000 #00000000 none
MENU COLOR UNSEL 30;47 #FF000000 #0000FFFF none
MENU COLOR SEL 7;37;40 #FF000000 #FF00FFFF none
MENU COLOR DISABLE 7;37;40 #FF000000 #00000000 none
MENU TITLE Rocky Linux Install
MENU TABMSG
LABEL Main Menu
    MENU LABEL Return to Main Menu
    MENU DEFAULT
    KERNEL bootmenu/vesamenu.c32
    APPEND pxelinux.cfg/default
LABEL -
    MENU LABEL Select version to pxeboot:
    menu disable
LABEL Rocky Linux Standard install
    MENU INDENT 2
    kernel Rocky/8/x86_64/vmlinuz
    append initrd=Rocky/8/x86_64/initrd.img ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.repo=ftp://mirror.gaztronics.net/rocky/8/BaseOS/x86_64/os
LABEL Rocky Linux Rescue
    MENU INDENT 2
    kernel Rocky/8/x86_64/vmlinuz
    append initrd=Rocky/8/x86_64/initrd.img ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.repo=ftp://mirror.gaztronics.net/rocky/8/BaseOS/x86_64/os rescue
LABEL Rocky Linux Server install
    MENU INDENT 2
    kernel Rocky/8/x86_64/vmlinuz
    append initrd=Rocky/8/x86_64/initrd.img ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.ks=ftp://mirror.gaztronics.net/kickstart/Rocky-8-server.cfg

Do not worry, I have not had the time to make a Rocky background ... yet!

Some notable differences in the way EL8 works. We now have to declare inst.repo= or inst.ks=.


PXE Menu: Testing

If you are working on new kickstart/preseed files that you do not want your staff to play with, you can hide them away in a testing menu, and even password protect it, if necessary. Here is an example of my testing.menu

MENU COLOR TITLE 7;30;47 #FF000000 #00000000 none
MENU COLOR UNSEL 30;47 #FF000000 #0000FFFF none
MENU COLOR SEL 7;37;40 #FF000000 #FF00FFFF none
MENU COLOR DISABLE 7;37;40 #FF000000 #00000000 none
MENU TITLE Testing
MENU TABMSG
LABEL Main Menu
    MENU LABEL Return to Main Menu
    MENU DEFAULT
    KERNEL bootmenu/vesamenu.c32
    APPEND pxelinux.cfg/default
LABEL -
    MENU LABEL Select version to pxeboot:
    menu disable
LABEL CentOS 7 x86-64 LUKS
    MENU INDENT 2
    kernel CentOS/7/x86_64/vmlinuz
    append initrd=CentOS/7/x86_64/initrd.img ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp ks=ftp://mirror.gaztronics.net/kickstart/CentOS-7-LUKS.cfg
MENU SEPARATOR
LABEL CentOS 7 x86-64 CentOS 7 build
    MENU INDENT 2
    kernel CentOS/7/x86_64/vmlinuz
    append initrd=CentOS/7/x86_64/initrd.img ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp ks=ftp://mirror.gaztronics.net/kickstart/CentOS-7-build.cfg
MENU SEPARATOR
LABEL Rocky Linux build install
    MENU INDENT 2
    kernel Rocky/8/x86_64/vmlinuz
    append initrd=Rocky/8/x86_64/initrd.img ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.ks=ftp://mirror.gaztronics.net/kickstart/Rocky-8-build.cfg
MENU SEPARATOR
LABEL Rocky Linux Desktop-LDAP-LUKS
    MENU INDENT 2
    kernel Rocky/8/x86_64/vmlinuz
    append initrd=Rocky/8/x86_64/initrd.img ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.ks=ftp://mirror.gaztronics.net/kickstart/Rocky-8-Desktop.cfg

No background picture with this one, although a tasty dragon picture might need to be found...


PXE Menu: Tools

A number of useful tools can be network booted: memtest, Clonezilla, Gparted, and some of the Linux distributions offer a "live" version, although these have become quite large in recent years, and have been failing to network boot any sense. As in the sync-netboot section above, you will need to create directories such as: memtest86+, clonezilla, and gparted in /var/lib/tftpboot into which you will unpack the necessary software. Here is my tools.menu

MENU BACKGROUND bootmenu/spectrum-tools.jpg
MENU COLOR TITLE 7;30;47 #FF000000 #00000000 none
MENU COLOR UNSEL 30;47 #FF000000 #0000FFFF none
MENU COLOR SEL 7;37;40 #FF000000 #FF00FFFF none
MENU COLOR DISABLE 7;37;40 #FF000000 #00000000 none
MENU TITLE Tools
MENU TABMSG
LABEL Main Menu
    MENU LABEL Return to Main Menu
    MENU DEFAULT
    KERNEL bootmenu/vesamenu.c32
    APPEND pxelinux.cfg/default
LABEL Memtest86+ v5.01
    MENU INDENT 2
    KERNEL memtest86+/memtest
LABEL Clonezilla (2.6.7-28) Plain
    MENU INDENT 2
    KERNEL clonezilla/live/vmlinuz
    APPEND initrd=clonezilla/live/initrd.img boot=live union=overlay config components quiet noswap edd=on nomodeset nodmraid locales="en_US.UTF-8" keyboard-layouts="gb" ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch=no net.ifnames=0 nosplash noprompt fetch=tftp://mirror.gaztronics.net/clonezilla/live/filesystem.squashfs
LABEL gparted Live (1.1.0-6)
    MENU INDENT 2
    KERNEL gparted/live/vmlinuz
    APPEND initrd=gparted/live/initrd.img boot=live union=overlay username=user config components quiet net.ifnames=0 vga=788 locales="en_US.UTF-8" keyboard-layouts="NONE" fetch=tftp://mirror.gaztronics.net/gparted/live/filesystem.squashfs

There are details for each of the above tools on how to set-up for network boot on their respective websites, so I will not repeat them here. As you can see, the Clonezilla APPEND line is rather long, and you have to be careful of line wraps in your text editor. A tip to follow is to list the version numbers of the tools in your PXE menu. You can then see when you need to update them...

The line MENU BACKGROUND bootmenu/spectrum-tools.jpg references a custom JPEG made with GIMP:

spectrum


UEFI boot

Setting up UEFI boot is far more complex than it should be. It is no-where near as easy as PXE. Progress, eh?!

From within /var/lib/tftpboot make a uefi directory with: mkdir uefi

The path to /var/lib/tftpboot/uefi is again referenced in dhcpd.conf, so the case needs to match.

To populate this directory on a system that is configured with the older BIOS boot requires yet another script:

#!/bin/bash
#
# Script to update /var/lib/tftpboot/uefi files


#---------------------------------------------------------------
# Paths
#
PACKAGES=/tmp/packages

#---------------------------------------------------------------

# Check directories exist, if not create them.
#
if [ ! -d $PACKAGES ]; then
        mkdir -p $PACKAGES
fi

# Change to working directory
#
cd $PACKAGES

#---------------------------------------------------------------
# Download required packages

yumdownloader shim-x64 grub2-efi-x64.x86_64

# Unpack locally

rpm2cpio shim-x64-* | cpio -dmi --quiet

rpm2cpio grub2-efi-x64-* | cpio -dmi --quiet

#---------------------------------------------------------------
# Copy required files

cp -f $PACKAGES/boot/efi/EFI/centos/shim.efi /var/lib/tftpboot/uefi
cp -f $PACKAGES/boot/efi/EFI/centos/grubx64.efi /var/lib/tftpboot/uefi

# Reset permissions
#
chmod 755 /var/lib/tftpboot/uefi/*.efi


#---------------------------------------------------------------
# Clean-up

rm -fr $PACKAGES

unset PACKAGES

exit 0

The script is called: sync-efi and lives in /root/scripts It is another script that should not need to be run all that often.

Your /var/lib/tftpboot/uefi directory should now contain grubx64.efi and shim.efi.

grub.cfg

You now need to create a grub.cfg file to provide the same sort of functions as the PXE menus.

This is my grub.cfg offered as a reference. It is not fully tested, and I have yet to work out how to make it work with a pretty background picture. More progress!

set default=0
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 timeout=-1

# Menu Colours
#
set menu_color_normal=white/black
set menu_color_highlight=white/cyan

submenu "Rocky -->" {
    menuentry "Rocky 8 x86-64 Rescue" --class fedora --class gnu-linux --class gnu --class os {
        linuxefi Rocky/8/x86_64/vmlinuz ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.repo=ftp://mirror.gaztronics.net/rocky/8/BaseOS/x86_64/os rescue
        initrdefi Rocky/8/x86_64/initrd.img
    }

    menuentry "Rocky 8 x86-64 Standard install" --class fedora --class gnu-linux --class gnu --class os {
        linuxefi Rocky/8/x86_64/vmlinuz ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.repo=ftp://mirror.gaztronics.net/rocky/8/BaseOS/x86_64/os
    initrdefi Rocky/8/x86_64/initrd.img
    }

    menuentry "Rocky 8 x86-64 Server install" --class fedora --class gnu-linux --class gnu --class os {
        linuxefi Rocky/8/x86_64/vmlinuz ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.ks=ftp://mirror.gaztronics.net/kickstart/Rocky-8-server.cfg
        initrdefi Rocky/8/x86_64/initrd.img
    }

}

submenu "CentOS -->" {
    menuentry "CentOS 7 x86-64 Rescue" --class fedora --class gnu-linux --class gnu --class os {
        linuxefi CentOS/7/x86_64/vmlinuz ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.repo=ftp://mirror.gaztronics.net/mirror.centos.org/7/os/x86_64 rescue
        initrdefi CentOS/7/x86_64/initrd.img
    }

    menuentry "CentOS 7 x86-64 Standard install" --class fedora --class gnu-linux --class gnu --class os {
        linuxefi CentOS/7/x86_64/vmlinuz ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.repo=ftp://mirror.gaztronics.net/mirror.centos.org/7/os/x86_64
        initrdefi CentOS/7/x86_64/initrd.img
    }

    menuentry "CentOS 7 x86-64 Server install" --class fedora --class gnu-linux --class gnu --class os {
        linuxefi CentOS/7/x86_64/vmlinuz ramdisk_size=10000 net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.repo=ftp://mirror.gaztronics.net/mirror.centos.org/7/os/x86_64 inst.ks=ftp://mirror.gaztronics.net/kickstart/CentOS-7-server.cfg
        initrdefi CentOS/7/x86_64/initrd.img
    }
}

submenu "Tools -->" {
    menuentry "Clonezilla (2.6.7-28) Plain" {
        linuxefi clonezilla/live/vmlinuz boot=live union=overlay config components quiet noswap edd=on nomodeset nodmraid locales="en_US.UTF-8" keyboard-layouts="gb" ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch=no net.ifnames=0 nosplash noprompt fetch=tftp://mail.gaztronics.net/clonezilla/live/filesystem.squashfs
        initrdefi clonezilla/live/initrd.img
    }

    menuentry "gparted Live (1.1.0-6 amd64)" {
    linuxefi gparted/live/vmlinuz boot=live union=overlay username=user config components quiet net.ifnames=0 vga=788 locales="en_US.UTF-8" keyboard-layouts="NONE" fetch=tftp://mirror.gaztronics.net/gparted/live/filesystem.squashfs
    initrdefi gparted/live/initrd.img
    }

}

submenu "Testing (Here be Dragons!) -->" {
    menuentry "CentOS 7 Live" {
    linuxefi CentOS/7/Live/vmlinuz0 rootflags=loop root=live:/CentOS-7-x86_64-LiveGNOME-2003.iso rootfstype=auto ro rd.live.image quiet rhgb rd.luks=0 rd.md=0 rd.dm=0
    initrdefi CentOS/7/Live/initrd0.img
    }

    menuentry "Fedora 32 Live" {
    linuxefi Fedora/Live/32/vmlinuz rootflags=loop root=live:/Fedora-MATE_Compiz-Live-x86_64-32-1.6.iso rd.live.image quiet
    initrdefi Fedora/Live/32/initrd.img
    }

    menuentry "memtest86+" {
    linuxefi memtest86+/memtest
    }

    menuentry "Rocky 8 x86-64 Desktop install" --class fedora --class gnu-linux --class gnu --class os {
    linuxefi Rocky/8/x86_64/vmlinuz ramdisk_size=10000 nomodeset net.ifnames=0 biosdevname=0 ipv6.disable=1 ip=dhcp inst.repo=ftp://mirror.gaztronics.net/rocky/8/BaseOS/x86_64/os inst.ks=ftp://mirror.gaztronics.net/kickstart/Rocky-8-Desktop.cfg
    initrdefi Rocky/8/x86_64/initrd.img
    }

}

As with the PXE menus, the APPEND line for Clonezilla is rather long and wraps. You have to keep a careful eye on your { and } as you can easily miss one and break your UEFI boot.

In theory, you are now the proud owner of a PXE / UEFI network boot server...


Page updated: 28th August 2021