aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-05-22 13:54:19 +0100
committerMichael Brown <mcb30@ipxe.org>2023-05-22 13:54:19 +0100
commit89c75c3c19468a21fdf7f16f8a0a4c74275ff5a9 (patch)
tree8776309e422a91eda1fe8fa349ad080381cf1892
parent57f3fcee5ebcae6f0ca0df36cc9774b805a65005 (diff)
downloadipxe-shim3.zip
ipxe-shim3.tar.gz
ipxe-shim3.tar.bz2
WIP - refactoredshim3
-rw-r--r--src/hci/commands/shim_cmd.c17
-rw-r--r--src/image/efi_image.c4
-rw-r--r--src/include/ipxe/efi/efi_shim.h3
-rw-r--r--src/interface/efi/efi_shim.c46
4 files changed, 60 insertions, 10 deletions
diff --git a/src/hci/commands/shim_cmd.c b/src/hci/commands/shim_cmd.c
index 54ed2b2..1667e03 100644
--- a/src/hci/commands/shim_cmd.c
+++ b/src/hci/commands/shim_cmd.c
@@ -38,22 +38,26 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** "shim" options */
struct shim_options {
- /** Always download shim */
- int always;
/** Download timeout */
unsigned long timeout;
/** Crutch image name or URI */
char *crutch;
+ /** Require third party loader */
+ int require_loader;
+ /** Allow PXE base code protocol */
+ int allow_pxe;
};
/** "shim" option list */
static struct option_descriptor shim_opts[] = {
- OPTION_DESC ( "always", 'a', no_argument,
- struct shim_options, always, parse_flag ),
OPTION_DESC ( "timeout", 't', required_argument,
struct shim_options, timeout, parse_timeout ),
OPTION_DESC ( "crutch", 'c', required_argument,
struct shim_options, crutch, parse_string ),
+ OPTION_DESC ( "require-loader", 'l', no_argument,
+ struct shim_options, require_loader, parse_flag ),
+ OPTION_DESC ( "allow-pxe", 'p', no_argument,
+ struct shim_options, allow_pxe, parse_flag ),
};
/** "shim" command descriptor */
@@ -82,7 +86,7 @@ static int shim_exec ( int argc, char **argv ) {
/* Decide whether or not to download images */
kernel = find_image_tag ( &selected_image );
- download = ( ( kernel && efi_can_load ( kernel ) ) ? opts.always : 1 );
+ download = ( ! ( kernel && efi_can_load ( kernel ) ) );
/* Parse name/URI string */
name_uri = argv[optind];
@@ -102,7 +106,8 @@ static int shim_exec ( int argc, char **argv ) {
}
/* (Un)register as shim */
- if ( ( rc = shim ( image, crutch ) ) != 0 )
+ if ( ( rc = shim ( image, crutch, opts.require_loader,
+ opts.allow_pxe ) ) != 0 )
goto err_shim;
err_shim:
diff --git a/src/image/efi_image.c b/src/image/efi_image.c
index 039ac8f..104753a 100644
--- a/src/image/efi_image.c
+++ b/src/image/efi_image.c
@@ -209,7 +209,9 @@ static int efi_image_exec ( struct image *image ) {
}
/* Install shim special handling if applicable */
- if ( shim && ( ( rc = efi_shim_install ( snpdev->handle ) ) != 0 ) ) {
+ 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;
diff --git a/src/include/ipxe/efi/efi_shim.h b/src/include/ipxe/efi/efi_shim.h
index 4a44a4f..bf35adc 100644
--- a/src/include/ipxe/efi/efi_shim.h
+++ b/src/include/ipxe/efi/efi_shim.h
@@ -17,7 +17,8 @@ extern int efi_shim_allow_pxe;
extern struct image_tag efi_shim __image_tag;
extern struct image_tag efi_shim_crutch __image_tag;
-extern int efi_shim_install ( EFI_HANDLE handle );
+extern int efi_shim_install ( struct image *shim, EFI_HANDLE handle,
+ wchar_t **cmdline );
extern void efi_shim_uninstall ( void );
#endif /* _IPXE_EFI_SHIM_H */
diff --git a/src/interface/efi/efi_shim.c b/src/interface/efi/efi_shim.c
index 673b2d8..42faaa6 100644
--- a/src/interface/efi/efi_shim.c
+++ b/src/interface/efi/efi_shim.c
@@ -24,9 +24,11 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
+#include <stdlib.h>
#include <errno.h>
#include <ipxe/image.h>
#include <ipxe/efi/efi.h>
+#include <ipxe/efi/efi_strings.h>
#include <ipxe/efi/efi_shim.h>
#include <ipxe/efi/Protocol/PxeBaseCode.h>
#include <ipxe/efi/Protocol/ShimLock.h>
@@ -175,12 +177,47 @@ static int efi_shim_inhibit_pxe ( EFI_HANDLE handle ) {
}
/**
+ * Update command line
+ *
+ * @v shim Shim image
+ * @v cmdline Command line to update
+ * @ret rc Return status code
+ */
+static int efi_shim_cmdline ( struct image *shim, wchar_t **cmdline ) {
+ wchar_t *shimcmdline;
+ int len;
+ int rc;
+
+ /* Construct new command line */
+ len = ( shim->cmdline ?
+ efi_asprintf ( &shimcmdline, "%s %s", shim->name,
+ shim->cmdline ) :
+ efi_asprintf ( &shimcmdline, "%s %ls", shim->name,
+ *cmdline ) );
+ if ( len < 0 ) {
+ rc = len;
+ DBGC ( &efi_shim, "SHIM could not construct command line: "
+ "%s\n", strerror ( rc ) );
+ return rc;
+ }
+
+ /* Replace command line */
+ free ( *cmdline );
+ *cmdline = shimcmdline;
+
+ return 0;
+}
+
+/**
* Install UEFI shim special handling
*
- * @v handle EFI handle
+ * @v shim Shim image
+ * @v handle EFI device handle
+ * @v cmdline Command line to update
* @ret rc Return status code
*/
-int efi_shim_install ( EFI_HANDLE handle ) {
+int efi_shim_install ( struct image *shim, EFI_HANDLE handle,
+ wchar_t **cmdline ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
int rc;
@@ -195,8 +232,13 @@ int efi_shim_install ( EFI_HANDLE handle ) {
goto err_inhibit_pxe;
}
+ /* Update command line */
+ if ( ( rc = efi_shim_cmdline ( shim, cmdline ) ) != 0 )
+ goto err_cmdline;
+
return 0;
+ err_cmdline:
err_inhibit_pxe:
bs->GetMemoryMap = efi_shim_orig_map;
return rc;