Single iPXE Menu Entry for Both BIOS/UEFI
-
FOG version: 1.5.2
As I have been learning and using FOG I realized some options can only be used when the host has been booted BIOS or UEFI. For example, the included Memtest86+ can only run when the host was BIOS booted. Trying the menu option when UEFI booted results in errors. Alternatively, as per this post here, ESXi would only be supported out of the box when UEFI booted. I am sure there are many other examples of this.
It may also be that the parameters under BIOS and UEFI are just different. In other words the OS/Installer can run under either, but requires different parameters.
What I have found is its possible to use a single iPXE menu entry to cover using different parameters depending on how the host was booted. This is all done via the web GUI under Settings | iPXE Menu Item Settings (or for new entries ‘iPXE New Menu Entry’.
I altered the default fog.memtest entry, parameters field for example to the following:
iseq ${platform} pcbios && goto mem_bios || goto no_mem :mem_bios kernel memdisk initrd=memtest.bin iso raw initrd memtest.bin boot || goto MENU :no_mem prompt --timeout 30000 Host must be BIOS (not UEFI) booted for this option. Press any key to return to the menu... && goto MENU || goto MENU
The first line tests if the host was BIOS booted, if so it jumps to the ‘mem_bios’ label and executes the commands under that label, otherwise it goes to the ‘no_mem’ label and instead displays a prompt explaining why its not an option and then returning to the menu thus avoiding the error.
This results in 1 menu entry that changes behavior based on how the host was booted. I might even go as far as including in my entry descriptions some syntax/indicator of its compatibility, IE: “Memtest86+ (BIOS only)” so that its obvious to users without selecting it that it can only be used when BIOS booted.
Another example is my ESXi entry:
iseq ${platform} efi && goto esxi_efi || goto esxi_bios :esxi_efi kernel http://${fog-ip}/fog/os/esxi65/efi/boot/bootx64.efi -c http://${fog-ip}/fog/os/esxi65/efi/boot/boot.cfg boot || goto MENU :esxi_bios prompt --timeout 30000 Host must be UEFI booted for this option. Press any key to return to the menu... && goto MENU || goto MENU
Similar to the above but the 1st line does the reverse test, is the host UEFI booted. The ‘:esxi_bios’ label and its commands could be altered as seen below if, for example, you compiled the ipxe kernel to include IMG_COMBOOT to support BIOS booting ESXi:
iseq ${platform} efi && goto esxi_efi || goto esxi_bios :esxi_efi kernel http://${fog-ip}/fog/os/esxi65/efi/boot/bootx64.efi -c http://${fog-ip}/fog/os/esxi65/efi/boot/boot.cfg boot || goto MENU :esxi_bios kernel http://${fog-ip}/fog/os/esxi65/mboot.c32 -c http://${fog-ip}/fog/os/esxi65/boot.cfg boot || goto MENU
In the above, we load ESXi one way if the host is UEFI booted and another if it was BIOS booted.
[Moderators Note]: I want to restate again that the mboot.c32 syslinux script will not boot using FOG Project supplied iPXE boot loaders (i.e. undionly.kpxe) since they are not complied by default with COM_BOOT enabled. YOU must compile the iPXE boot loader if you want syslinux support -Geo
I have so far only tried this with memtest and ESXi.
I also would love to see an option for a menu to be displayed or not based on this variable, IE: show the memtest86+ entry only when BIOS booted but not when UEFI booted, but have not found a way this is possible yet. Maybe the devs have some ideas as to if this is feasible?
I think that could really help make the menus a bit more flexible/dynamic. It could potentially be a set of check-boxes in the GUI for the menu entry: “BIOS”, “UEFI” or “Both” which would dictate if the menu entry is included for a host given how it was booted. Alternatively, maybe somehow tied into the ‘Menu Show With’ option.
In any case hopefully others find this useful.
-
As an additional note: each label you use must be unique across all of your menu entries.
IE: If you make a menu entry for ESXi 6.5 and another for 6.7, then these lines:
iseq ${platform} efi && goto esxi_efi || goto esxi_bios :esxi_efi ... :esxi_bios ...
must have unique labels, for example esxi65_efi vs esxi67_efi instead of both having esxi_efi (or esxi_bios).
If you use the same label in 2 different menu entries than iPXE will go to whichever is listed first in your boot.php.