summaryrefslogtreecommitdiffstats
path: root/src/image
diff options
context:
space:
mode:
authorMichael Brown2015-09-01 22:23:34 +0200
committerMichael Brown2015-09-02 14:45:12 +0200
commit3376fa520b0ce4ba3f0d9bad626617acf88908df (patch)
treec1887ddd09315c71eaf92efacf62976e24ed3359 /src/image
parent[uri] Generalise tftp_uri() to pxe_uri() (diff)
downloadipxe-3376fa520b0ce4ba3f0d9bad626617acf88908df.tar.gz
ipxe-3376fa520b0ce4ba3f0d9bad626617acf88908df.tar.xz
ipxe-3376fa520b0ce4ba3f0d9bad626617acf88908df.zip
[efi] Implement the EFI_PXE_BASE_CODE_PROTOCOL
Many UEFI NBPs expect to find an EFI_PXE_BASE_CODE_PROTOCOL installed in addition to the EFI_SIMPLE_NETWORK_PROTOCOL. Most NBPs use the EFI_PXE_BASE_CODE_PROTOCOL only to retrieve the cached DHCP packets. This implementation has been tested with grub.efi, shim.efi, syslinux.efi, and wdsmgfw.efi. Some methods (such as Discover() and Arp()) are not used by any known NBP and so have not (yet) been implemented. Usage notes for the tested bootstraps are: - grub.efi uses EFI_PXE_BASE_CODE_PROTOCOL only to retrieve the cached DHCP packet, and uses no other methods. - shim.efi uses EFI_PXE_BASE_CODE_PROTOCOL to retrieve the cached DHCP packet and to retrieve the next NBP via the Mtftp() method. If shim.efi was downloaded via HTTP (or other non-TFTP protocol) then shim.efi will blindly call Mtftp() with an HTTP URI as the filename: this allows the next NBP (e.g. grubx64.efi) to also be transparently retrieved by HTTP. shim.efi can also use the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL to retrieve files previously loaded by "imgfetch" or similar commands in iPXE. The current implementation of shim.efi will use the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL only if it does not find an EFI_PXE_BASE_CODE_PROTOCOL; this patch therefore prevents this usage of our EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. This logic could be trivially reversed in shim.efi if needed. - syslinux.efi uses EFI_PXE_BASE_CODE_PROTOCOL only to retrieve the cached DHCP packet. Versions 6.03 and earlier have a bug which may cause syslinux.efi to attach to the wrong NIC if there are multiple NICs in the system (or if the UEFI firmware supports IPv6). - wdsmgfw.efi (ab)uses EFI_PXE_BASE_CODE_PROTOCOL to retrieve the cached DHCP packets, and to send and retrieve UDP packets via the UdpWrite() and UdpRead() methods. (This was presumably done in order to minimise the amount of benefit obtainable by switching to UEFI, by replicating all of the design mistakes present in the original PXE specification.) The EFI_DOWNGRADE_UX configuration option remains available for now, until this implementation has received more widespread testing. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/image')
-rw-r--r--src/image/efi_image.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/image/efi_image.c b/src/image/efi_image.c
index b7d8f9c6..89d57bbd 100644
--- a/src/image/efi_image.c
+++ b/src/image/efi_image.c
@@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/efi/efi_utils.h>
#include <ipxe/efi/efi_strings.h>
#include <ipxe/efi/efi_wrap.h>
+#include <ipxe/efi/efi_pxe.h>
#include <ipxe/image.h>
#include <ipxe/init.h>
#include <ipxe/features.h>
@@ -159,6 +160,13 @@ static int efi_image_exec ( struct image *image ) {
goto err_file_install;
}
+ /* Install PXE base code protocol */
+ if ( ( rc = efi_pxe_install ( snpdev->handle, snpdev->netdev ) ) != 0 ){
+ DBGC ( image, "EFIIMAGE %p could not install PXE protocol: "
+ "%s\n", image, strerror ( rc ) );
+ goto err_pxe_install;
+ }
+
/* Install iPXE download protocol */
if ( ( rc = efi_download_install ( snpdev->handle ) ) != 0 ) {
DBGC ( image, "EFIIMAGE %p could not install iPXE download "
@@ -266,6 +274,8 @@ static int efi_image_exec ( struct image *image ) {
err_image_path:
efi_download_uninstall ( snpdev->handle );
err_download_install:
+ efi_pxe_uninstall ( snpdev->handle );
+ err_pxe_install:
efi_file_uninstall ( snpdev->handle );
err_file_install:
err_no_snpdev: