diff options
Diffstat (limited to 'src/image')
| -rw-r--r-- | src/image/efi_image.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/src/image/efi_image.c b/src/image/efi_image.c index 437134035..104753a85 100644 --- a/src/image/efi_image.c +++ b/src/image/efi_image.c @@ -31,6 +31,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <ipxe/efi/efi_wrap.h> #include <ipxe/efi/efi_pxe.h> #include <ipxe/efi/efi_driver.h> +#include <ipxe/efi/efi_image.h> +#include <ipxe/efi/efi_shim.h> #include <ipxe/image.h> #include <ipxe/init.h> #include <ipxe/features.h> @@ -134,6 +136,8 @@ static int efi_image_exec ( struct image *image ) { EFI_LOADED_IMAGE_PROTOCOL *image; void *interface; } loaded; + struct image *shim; + struct image *exec; EFI_HANDLE handle; EFI_MEMORY_TYPE type; wchar_t *cmdline; @@ -150,6 +154,15 @@ static int efi_image_exec ( struct image *image ) { goto err_no_snpdev; } + /* Use shim instead of directly executing image if applicable */ + shim = ( efi_can_load ( image ) ? + NULL : find_image_tag ( &efi_shim ) ); + exec = ( shim ? shim : image ); + if ( shim ) { + DBGC ( image, "EFIIMAGE %s executing via %s\n", + image->name, shim->name ); + } + /* Re-register as a hidden image to allow for access via file I/O */ toggle = ( ~image->flags & IMAGE_HIDDEN ); image->flags |= IMAGE_HIDDEN; @@ -178,7 +191,7 @@ static int efi_image_exec ( struct image *image ) { } /* Create device path for image */ - path = efi_image_path ( image, snpdev->path ); + path = efi_image_path ( exec, snpdev->path ); if ( ! path ) { DBGC ( image, "EFIIMAGE %s could not create device path\n", image->name ); @@ -195,11 +208,20 @@ static int efi_image_exec ( struct image *image ) { goto err_cmdline; } + /* Install shim special handling if applicable */ + if ( shim && + ( ( rc = efi_shim_install ( shim, snpdev->handle, + &cmdline ) ) != 0 ) ){ + DBGC ( image, "EFIIMAGE %s could not install shim handling: " + "%s\n", image->name, strerror ( rc ) ); + goto err_shim_install; + } + /* Attempt loading image */ handle = NULL; if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, path, - user_to_virt ( image->data, 0 ), - image->len, &handle ) ) != 0 ) { + user_to_virt ( exec->data, 0 ), + exec->len, &handle ) ) != 0 ) { /* Not an EFI image */ rc = -EEFI_LOAD ( efirc ); DBGC ( image, "EFIIMAGE %s could not load: %s\n", @@ -289,6 +311,9 @@ static int efi_image_exec ( struct image *image ) { if ( rc != 0 ) bs->UnloadImage ( handle ); err_load_image: + if ( shim ) + efi_shim_uninstall(); + err_shim_install: free ( cmdline ); err_cmdline: free ( path ); |
