iPXE discussion forum
Detect if bios or uefi possible? - Printable Version

+- iPXE discussion forum (https://forum.ipxe.org)
+-- Forum: iPXE user forums (/forumdisplay.php?fid=1)
+--- Forum: General (/forumdisplay.php?fid=2)
+--- Thread: Detect if bios or uefi possible? (/showthread.php?tid=7879)



Detect if bios or uefi possible? - layzer253 - 2015-12-04 01:46

Is there a function similar to how you can check if you are booted via BIOS or UEFI in a menu simliar to how you can check cpu architecture? My current setup is 2 different static menus, one for each boot mode as certain options dont work in UEFI. I am using dual boot usb sticks via syslinux>ipxe.lkrn and ipxe renamed to BOOTX64.EFI so that way I can support as many different models of computers as possible.


RE: Detect if bios or uefi possible? - silver310 - 2016-01-02 08:34

(2015-12-04 01:46)layzer253 Wrote:  Is there a function similar to how you can check if you are booted via BIOS or UEFI in a menu simliar to how you can check cpu architecture? My current setup is 2 different static menus, one for each boot mode as certain options dont work in UEFI. I am using dual boot usb sticks via syslinux>ipxe.lkrn and ipxe renamed to BOOTX64.EFI so that way I can support as many different models of computers as possible.

You can use the 'platform' function/command to test if a client is booted in Legacy or EFI, http://ipxe.org/cfg/platform
Code:
iseq ${platform} efi && goto is_efi || goto not_efi

I also had separate menus for both types, but got tired of updating two files whenever i make a simple change or added something, so now i have one menu, and if a certain program needs doesn't support EFI or needs some special option i use, IMO this is batter then having separate files.
Here's an example:

Code:
:rhel67
iseq ${platform} efi && goto rhel67_efi || goto rhel67_legacy

    :rhel67-efi
    echo Starting RHEL 6.7 Server x64 (EFI)
    chain ${tftp-server}/grub2-efi/rhel67server/bootx64.efi || goto rhel67-efi

    :rhel67-legacy
    echo Starting RHEL 6.7 Server x64 (EFI)
    set repo ${http-images}/iso_images/rhel/rhel67_server
    kernel ${repo}/isolinux/vmlinuz || goto rhel67-legacy
    initrd ${repo}/isolinux/initrd.img
    boot || goto failed



RE: Detect if bios or uefi possible? - MultimediaMan - 2016-01-02 14:12

But as far as the iPXE Binary goes, you need to go up one level to the DHCP server, otherwise, if the machine attempts to boot an incompatible iPXE binary, it will bring things to a halt:

DHCP Server Settings (ISC DHCPd -compliant):
Robinsmidrod has an excellent example on his githhub page: https://gist.github.com/robinsmidsrod/4008017

Relevant Excerpt:
Code:
# Make sure the iPXE we're loading supports what we need,
# if not load a full-featured version
if    exists ipxe.http
  and exists ipxe.menu
  and exists ipxe.nfs
  and ( ( exists ipxe.pxe
      and exists ipxe.bzimage
      and exists ipxe.elf
      and exists ipxe.comboot
      and exists ipxe.iscsi
  ) or (
      exists ipxe.efi
  ) ) {
    filename "nfs://nas.smidsrod.lan/raid/boot/boot.ipxe";
    #filename "http://boot.smidsrod.lan/boot.ipxe";
}
elsif exists user-class and option user-class = "iPXE" {
    # We're already using iPXE, but not a feature-full version,
    # and possibly an out-of-date version from ROM, so load a more
    # complete version with native drivers
    # Allow both legacy BIOS and EFI architectures
    if option arch = 00:06 {
        filename "ipxe-x86.efi";
    } elsif option arch = 00:07 {
        filename "ipxe-x64.efi";
    } elsif option arch = 00:00 {
        filename "ipxe.pxe";
    }
}
elsif exists user-class and option user-class = "gPXE" {
    # If someone has an old version of gPXE burned into their ROM,
    # load a more recent iPXE
    filename "ipxe.pxe";
}
elsif option arch = 00:06 {
    # EFI 32-bit
    # I like to use iPXE-provided drivers, so therefore give ipxe.efi
    # to all non-iPXE clients, use snponly.efi if you have unsupported
    # or misbehaving NICs
    filename "ipxe-x86.efi";
    #filename "snponly-x86.efi";
}
elsif option arch = 00:07 {
    # EFI 64-bit
    # I like to use iPXE-provided drivers, so therefore give ipxe.efi
    # to all non-iPXE clients, use snponly.efi if you have unsupported
    # or misbehaving NICs
    filename "ipxe-x64.efi";
    #filename "snponly-x64.efi";
}
elsif option arch = 00:00 {
    # Legacy BIOS x86 mode
    # I like to use iPXE-provided drivers, so therefore give ipxe.pxe
    # to all non-iPXE clients, use undionly.kpxe if you have unsupported
    # or misbehaving NICs
    filename "ipxe.pxe";
    #filename "undionly.kpxe";
}
else {
    # Unsupported client architecture type, so do nothing
}

As far as platform detection goes in scripts, there are a couple of ways to do it which allow for minimal repetition of code; it is also important to preserve the iPXE environment in the event of a failure for either another boot attempt or an alternate path of action:

Code:
cpuid --ext 29 && set arch x86_64 || set arch i386 ; echo ${platform} ${arch}
set CentOS67path ${17}/Media-Depot/linux/CentOS/6.7/EL/${arch}/OEM/os

goto CentOS67-${platform}

:CentOS67-efi
chain ${CentOS67path}/EFI/BOOT/BOOTX64.efi || goto failed

:CentOS67-pcbios
initrd ${CentOS67path}/images/pxeboot/initrd.img || goto failed
chain ${CentOS67path}/images/pxeboot/vmlinuz || goto failed

:failed
chain -ar ${17}/NetBoot/iPXE/ipxelinux.cfg/default/default.ipxe