Install PXE server on Raspberry Pi 4
This approach works fine for Legacy (BIOS) PXE Boot. But UEFI PXE Boot appeared to be an advanced topic. Get ready to dive deep.
To setup a PXE Server we will need the following dependencies:
dnsmasq
NFS
Network boot is possible due to TFTP. Usually TFTP server has the same IP address as DHCP server, but we will use dnsmasq to configure some kind of relay for our goal. It is called proxy DHCP to be more precise. This way our setup will work in any local network even with grandma's router.

We will setup a NFS (Network File System) server, which will allow computers to access files on PXE server over the network. Using TFTP the client only receives crucial parts of the system important to load, like kernel and initramfs, but the rest files like other additional software and user files will stay on the server, though the client will see these files locally, but all magic is done by NFS.
Note: This tutorial assumes you are the root user, if not, please add sudo
for all the commands.
Install and configure
The following command will install required packages on Raspberry OS:
apt install -y dnsmasq pxelinux syslinux-common nfs-kernel-server
Once downloading is complete, stop the dnsmasq for now
systemctl stop dnsmasq
PXELINUX
Create directory where all transferable operating system files will reside
mkdir /srv/tftpboot
Take important boot modules (pxelinux.0, ldlinux.c32, libutil.c32, menu.c32, poweroff.c32, reboot.c32 and vesamenu.c32) and place them into /srv/tftpboot
cp /usr/lib/PXELINUX/pxelinux.0 \
/usr/lib/syslinux/modules/bios/{ldlinux.c32,libcom32.c32,libutil.c32,menu.c32,poweroff.c32,reboot.c32,vesamenu.c32} \
/srv/tftpboot/
Create directory for the PXE configuration file.
Important: this directory must be called pxelinux.cfg
mkdir -p /srv/tftpboot/pxelinux.cfg
Prepare boot menu design
nano /srv/tftpboot/pxelinux.cfg/default
with this content
MENU TITLE Network Boot Menu
UI vesamenu.c32
MENU INCLUDE pxelinux.cfg/pxe.conf
LABEL next
MENU LABEL Load local bootloader
MENU DEFAULT
localboot
# Separator
MENU SEPARATOR
LABEL reboot
MENU LABEL Reboot
COM32 reboot.c32
LABEL poweroff
MENU LABEL Power Off
COM32 poweroff.c32
And styles separately
nano /srv/tftpboot/pxelinux.cfg/pxe.conf
MENU BACKGROUND pxelinux.cfg/logo.png
MENU RESOLUTION 1024 768
NOESCAPE 1
ALLOWOPTIONS 0
PROMPT 0
menu width 32
menu rows 5
MENU MARGIN 0
MENU VSHIFT 10
MENU HSHIFT 46
menu color title 1;37;40 #ffffffff #00000000 std
menu color border 36;40 #c00090f0 #00000000 std
menu color sel 30;47 #00000000 #ffffffff all
menu color unsel 37;40 #ffffffff #00000000 std
And the background /srv/tftpboot/pxelinux.cfg/logo.png

Check PXELINUX configuration syntax here: https://wiki.syslinux.org/wiki/index.php?title=Config
We will add real entries in the Test section.
dnsmasq
Update the content of /etc/dnsmasq.conf. By default this file full of comments above each option. You can read through and tweak settings to your liking (online manpages), but I already know what I put into:
mv /etc/dnsmasq.conf /etc/dnsmasq.conf.example
nano /etc/dnsmasq.conf
#Disable DNS Server
port=0
#Enable DHCP logging
log-dhcp
#Respond to PXE request for the specified network;
#Run as DHCP proxy
dhcp-range=192.168.0.0,proxy,255.255.255.0
dhcp-boot=pxelinux.0
#Flag forces "simple and safe" behavior
dhcp-no-override
#Provide network boot option called "Network Boot"
pxe-service=x86PC,"Network Boot", pxelinux
#Turn tftp ON
enable-tftp
#Set tftp root
tftp-root=/srv/tftpboot
Add the following line to the /etc/default/dnsmasq file
DNSMASQ_EXCEPT=lo
NFS
In order to give access to specific files to NFS clients add the following line to the /etc/exports file
/srv/tftpboot 192.168.0.0/24(rw,sync,no_root_squash,no_subtree_check)
Then make this change live:
exportfs -a
Test
For tests we are going to run Kali Linux and custom Buildroot build (here can be another article about it, but here we'll assume that you already have output/images/rootfs.tar.gz)
Kali
Download an ISO image from official website and transfer it to Raspberry Pi (when I was writing this tutorial the last version was 2021.2 and ISO name correspondingly kali-linux-2021.2-live-amd64.iso)
scp kali-linux-2021.2-live-amd64.iso pi@192.168.0.11:~
Then extract it to /srv/tftpboot/kali
mkdir -p /srv/tftpboot/kali
mount kali-linux-2021.2-live-amd64.iso kali
Add to boot menu an entry
LABEL kali
MENU vesamenu.c32
MENU LABEL Kali Linux Live
KERNEL /kali/live/vmlinuz
APPEND root=/dev/nfs rw nfsroot=192.168.0.11:/srv/tftpboot/kali,tcp,vers=4 ip=dhcp rootfstype=ext4 --
Buildroot
Do not forget to enable in kernel configuration
CONFIG_IP_PNP_DHCP=y
NFS filesystem support (CONFIG_NFS_FS).
Root file system on NFS (CONFIG_ROOT_NFS).
Transfer rootfs archive to Raspberry Pi
scp rootfs.tar.gz pi@192.168.0.11:~
Then extract it to /srv/tftpboot/buildroot
mkdir -p /srv/tftpboot/buildroot
tar xvpf ~/rootfs.tar.gz -C /srv/tftpboot/buildroot
Add to boot menu an entry
LABEL buildroot
MENU vesamenu.c32
MENU LABEL Custom Buildroot build
KERNEL /buildroot/boot/bzImage
APPEND root=/dev/nfs rw nfsroot=192.168.0.11:/srv/tftpboot/buildroot,tcp,vers=4 ip=dhcp rootfstype=ext4 --
Last updated
Was this helpful?