Booting UEFI only devices with USB network adapters - problem and solution
-
Hi all,
We’ve just hit a problem that I think has been coming for a while. The problem is as follows:
When network booting a UEFI only device via a USB network adapter, after downloading the initial NBP file (snponly.efi) the PXE shell can’t see any network devices.
We tried forcing these devices to load ipxe.efi instead but the problem persisted.
After some digging it seems the reason is FOGs use of USB_HCD_USBIO instead of USB_EFI. We built our own ipxe.efi with USB_EFI instead and it got further but then hit permission errors - turns out this is because we weren’t trusting the ssl certificate.
Anyway, long story short, we modded the buildipxe.sh to add in a usb.h config file and we removed the sed commands forcing USB_HCD_USBIO instead of USB_EFI and then we changed the dhcpd.conf to direct all efi devices to snp.efi instead of snponly.efi.
This has now fixed the issue and our UEFI only devices can now network boot from USB network adapters.
For reference here are the changes to the build files:
The new buildipxe.sh:
#!/bin/bash if [[ -r $1 ]]; then cert=$1 elif [[ -r /opt/fog/snapins/ssl/CA/.fogCA.pem ]]; then cert="/opt/fog/snapins/ssl/CA/.fogCA.pem" fi BUILDOPTS="CERT=${cert} TRUST=${cert}" IPXEGIT="https://github.com/ipxe/ipxe" # Change directory to base ipxe files SCRIPT=$(readlink -f "$BASH_SOURCE") FOGDIR=$(dirname $(dirname $(dirname "$SCRIPT") ) ) BASE=$(dirname "$FOGDIR") if [[ -d ${BASE}/ipxe ]]; then cd ${BASE}/ipxe git clean -fd git reset --hard git pull cd src/ # make sure this is being re-compiled in case the CA has changed! touch crypto/rootcert.c else git clone ${IPXEGIT} ${BASE}/ipxe cd ${BASE}/ipxe/src/ fi # Get current header and script from fogproject repo echo "Copy (overwrite) iPXE headers and scripts..." cp ${FOGDIR}/src/ipxe/src/Makefile.housekeeping . cp ${FOGDIR}/src/ipxe/src/ipxescript . cp ${FOGDIR}/src/ipxe/src/ipxescript10sec . cp ${FOGDIR}/src/ipxe/src/config/general.h config/ cp ${FOGDIR}/src/ipxe/src/config/settings.h config/ cp ${FOGDIR}/src/ipxe/src/config/console.h config/ # For BIOS builds, disable USB_HCD_USBIO as it's EFI-specific sed -i 's+#define USB_HCD_USBIO+//#define USB_HCD_USBIO+g' config/usb.h # Build the files make -j$(nproc) EMBED=ipxescript bin/ipxe.iso bin/{undionly,ipxe,intel,realtek}.{,k,kk}pxe bin/ipxe.lkrn bin/ipxe.usb ${BUILDOPTS} [[ $? -eq 0 ]] || exit 40 # Copy files to repo location as required cp bin/ipxe.iso bin/{undionly,ipxe,intel,realtek}.{,k,kk}pxe bin/ipxe.lkrn bin/ipxe.usb ${FOGDIR}/packages/tftp/ cp bin/ipxe.lkrn ${FOGDIR}/packages/tftp/ipxe.krn # Build with 10 second delay make -j$(nproc) EMBED=ipxescript10sec bin/ipxe.iso bin/{undionly,ipxe,intel,realtek}.{,k,kk}pxe bin/ipxe.lkrn bin/ipxe.usb ${BUILDOPTS} [[ $? -eq 0 ]] || exit 48 # Copy files to repo location as required cp bin/ipxe.iso bin/{undionly,ipxe,intel,realtek}.{,k,kk}pxe bin/ipxe.lkrn bin/ipxe.usb ${FOGDIR}/packages/tftp/10secdelay/ cp bin/ipxe.lkrn ${FOGDIR}/packages/tftp/10secdelay/ipxe.krn # Change to the efi layout if [[ -d ${BASE}/ipxe-efi ]]; then cd ${BASE}/ipxe-efi/ git clean -fd git reset --hard git pull cd src/ # make sure this is being re-compiled in case the CA has changed! touch crypto/rootcert.c else git clone ${IPXEGIT} ${BASE}/ipxe-efi cd ${BASE}/ipxe-efi/src/ fi # Get current header and script from fogproject repo echo "Copy (overwrite) iPXE headers and scripts..." cp ${FOGDIR}/src/ipxe/src-efi/Makefile.housekeeping . cp ${FOGDIR}/src/ipxe/src-efi/ipxescript . cp ${FOGDIR}/src/ipxe/src-efi/ipxescript10sec . cp ${FOGDIR}/src/ipxe/src-efi/config/general.h config/ cp ${FOGDIR}/src/ipxe/src-efi/config/settings.h config/ cp ${FOGDIR}/src/ipxe/src-efi/config/console.h config/ cp ${FOGDIR}/src/ipxe/src-efi/config/usb.h config/ # Build the files make -j$(nproc) EMBED=ipxescript bin-{i386,x86_64}-efi/{snp{,only},ipxe,intel,realtek}.efi ${BUILDOPTS} [[ $? -eq 0 ]] || exit 80 # Apply USB configuration for ARM64 build make -j$(nproc) CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 EMBED=ipxescript bin-arm64-efi/{snp{,only},ipxe,intel,realtek}.efi ${BUILDOPTS} [[ $? -eq 0 ]] || exit 82 # Copy the files to upload cp bin-arm64-efi/{snp{,only},ipxe,intel,realtek}.efi ${FOGDIR}/packages/tftp/arm64-efi/ cp bin-i386-efi/{snp{,only},ipxe,intel,realtek}.efi ${FOGDIR}/packages/tftp/i386-efi/ cp bin-x86_64-efi/{snp{,only},ipxe,intel,realtek}.efi ${FOGDIR}/packages/tftp/ # Build with 10 second delay make -j$(nproc) EMBED=ipxescript10sec bin-{i386,x86_64}-efi/{snp{,only},ipxe,intel,realtek}.efi ${BUILDOPTS} [[ $? -eq 0 ]] || exit 91 make -j$(nproc) CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 EMBED=ipxescript10sec bin-arm64-efi/{snp{,only},ipxe,intel,realtek}.efi ${BUILDOPTS} [[ $? -eq 0 ]] || exit 93 # Copy the files to upload cp bin-arm64-efi/{snp{,only},ipxe,intel,realtek}.efi ${FOGDIR}/packages/tftp/10secdelay/arm64-efi/ cp bin-i386-efi/{snp{,only},ipxe,intel,realtek}.efi ${FOGDIR}/packages/tftp/10secdelay/i386-efi/ cp bin-x86_64-efi/{snp{,only},ipxe,intel,realtek}.efi ${FOGDIR}/packages/tftp/10secdelay/
And usb.h:
#ifndef CONFIG_USB_H #define CONFIG_USB_H /** @file * * USB configuration * */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <config/defaults.h> /* * USB host controllers (enable all) */ #define USB_HCD_XHCI /* xHCI USB 3.0 host controller */ #define USB_HCD_EHCI /* EHCI USB 2.0 host controller */ #define USB_HCD_UHCI /* UHCI USB 1.1 host controller */ //#undef USB_HCD_USBIO /* Very slow EFI USB host controller */ /* * USB peripherals */ #define USB_KEYBOARD /* USB keyboards */ //#undef USB_BLOCK /* USB block devices */ /* * USB external interfaces */ #define USB_EFI /* Provide EFI_USB_IO_PROTOCOL interface */ #include <config/named.h> #include NAMED_CONFIG(usb.h) #include <config/local/usb.h> #include LOCAL_NAMED_CONFIG(usb.h) #endif /* CONFIG_USB_H */