The UEFI boot managers reads its configuration from EFI variables (that are stored in NVRAM). Depending on the configured entries and the configured boot boot order it might very well search for a ESP on each storage device.
For example, if you have - say - 2 storage devices and for each a generic entry like
PciRoot(0x0)/Pci(0x5,0x0) # or
PciRoot(0x0)/Pci(0x1,0x1)/Ata(1,0,0)
and they are both referenced in the boot order then the UEFI boot manager probes them both for ESPs.
Also, the UEFI specification doesn't forbid the firmware to auto-add some generic entries on each boot for each newly detected storage device. Thus, depending on your system you might end up with it auto-detecting an ESP on any detected storage device, by default.
The UEFI specification also allows the firmware to discover an ESP that doesn't use the EFI system parition GUID (C12A7328-F81F-11D2-BA4B-00A0C93EC93B
). Instead it might just probe for a GPT partition with a FAT filesystem and the expected file under EFI/BOOT
(e.g. BOOTX64.EFI
on a x86 64 bit system):
UEFI does not impose a restriction on the number or location of System Partitions that can exist on
a system. System Partitions are discovered when required by UEFI firmware by examining the
partition GUID and verifying that the contents of the partition conform to the FAT file system as
defined in Section 13.3.1.1. Further, UEFI implementations may allow the use of conforming FAT
partitions which do not use the ESP GUID. Partition creators may prevent UEFI firmware from
examining and using a specific partition by setting bit 1 of the Partition Attributes (see 5.3.3) which
will exclude the partition as a potential ESP.
(UEFI specification version 2.7 errata A, Section 13.3.3 Number and Location of System Partitions, page 516)
For example, the Supermicro and Qemu UEFI firmware do this.
Here are my eventual findings and solution, with lots of help from the comments!
- Syslinux doesn't support ARM
- Even if it did,
pxelinux.0
only applied to BIOS, not UEFI
- Use GRUB2 instead of Syslinux
Assuming the PXE (DHCP + TFTP) server(s) are already setup according to many guides,
- Copy your kernel and initramfs to your TFTP root dir (commonly
/var/lib/tftpboot
)
- Copy
grubaa64.efi
from /boot/efi/EFI/centos/
to your TFTP root dir (or ./boot/
subdir)
Create a config file, grub.cfg
, in the same directory
(GRUB treats /
as your TFTP root dir. Change linux
& initrd
as needed)
menuentry 'Shared CentOS (4.5.0-23.el7.aarch64)' {
linux /vmlinuz-4.5.0-23.el7.aarch64 rw root=/dev/nfs ip=dhcp nfsroot=/netboot/CentOS_7.3 enforcing=0
initrd /initramfs-nfs-only.img
}
menuentry 'Refresh GRUB menu' {
configfile /boot/grub.cfg
}
Point your DHCP server to grubaa64.efi
instead of pxelinux.0
- That's it! Try editing
grub.cfg
on the TFTP server, then choosing "Refresh GRUB menu" to see that it pulls in the new config
Best Answer
The UEFI specification describes an API that a firmware may expose. This API can be used by applications and drivers loaded by the firmware.
The open source firmware Das U-Boot contains a partial implementation of the UEFI specification. A complete open source implementation is offered by TianoCore EDK II. Companies like Phoenix offer closed source UEFI firmware.
On the 64-bit ARM architecture the Linux distributions Suse and Fedora use U-Boot to load GRUB as a UEFI application from U-Boot which in turn loads and starts the Linux kernel via UEFI API calls. Linux itself has an UEFI stub so it can be started as a UEFI application.
The UEFI specification defines a runtime that stays in memory until the system is rebooted. The UEFI runtime offers services including changing UEFI variables, uploading new firmware, and rebooting the system. Compliant to the UEFI specification U-Boot also contains a UEFI runtime. But as of today the functionality is limited to rebooting the system.