]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Allow for autoexec scripts that are not located in a filesystem
authorMichael Brown <mcb30@ipxe.org>
Mon, 17 Jan 2022 16:11:56 +0000 (16:11 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 18 Jan 2022 13:16:12 +0000 (13:16 +0000)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/interface/efi/efi_autoexec.c

index 88eb379bb813b34636f7e707778a29e76351638a..881c30c7e71dbdb8dc1cf5c9c7d7a734d34d5249 100644 (file)
@@ -39,10 +39,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  */
 
 /** Autoexec script filename */
-#define AUTOEXEC_FILENAME L"autoexec.ipxe"
+static wchar_t efi_autoexec_wname[] = L"autoexec.ipxe";
 
 /** Autoexec script image name */
-#define AUTOEXEC_NAME "autoexec.ipxe"
+static char efi_autoexec_name[] = "autoexec.ipxe";
 
 /** Autoexec script (if any) */
 static void *efi_autoexec;
@@ -51,21 +51,21 @@ static void *efi_autoexec;
 static size_t efi_autoexec_len;
 
 /**
- * Load autoexec script
+ * Load autoexec script from filesystem
  *
  * @v device           Device handle
  * @ret rc             Return status code
  */
-int efi_autoexec_load ( EFI_HANDLE device ) {
+static int efi_autoexec_filesystem ( EFI_HANDLE device ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       static wchar_t name[] = AUTOEXEC_FILENAME;
        union {
                void *interface;
                EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *fs;
        } u;
        struct {
                EFI_FILE_INFO info;
-               CHAR16 name[ sizeof ( name ) / sizeof ( name[0] ) ];
+               CHAR16 name[ sizeof ( efi_autoexec_wname ) /
+                            sizeof ( efi_autoexec_wname[0] ) ];
        } info;
        EFI_FILE_PROTOCOL *root;
        EFI_FILE_PROTOCOL *file;
@@ -74,10 +74,6 @@ int efi_autoexec_load ( EFI_HANDLE device ) {
        EFI_STATUS efirc;
        int rc;
 
-       /* Sanity check */
-       assert ( efi_autoexec == NULL );
-       assert ( efi_autoexec_len == 0 );
-
        /* Open simple file system protocol */
        if ( ( efirc = bs->OpenProtocol ( device,
                                          &efi_simple_file_system_protocol_guid,
@@ -99,11 +95,12 @@ int efi_autoexec_load ( EFI_HANDLE device ) {
        }
 
        /* Open autoexec script */
-       if ( ( efirc = root->Open ( root, &file, name,
+       if ( ( efirc = root->Open ( root, &file, efi_autoexec_wname,
                                    EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
                rc = -EEFI ( efirc );
                DBGC ( device, "EFI %s has no %ls: %s\n",
-                      efi_handle_name ( device ), name, strerror ( rc ) );
+                      efi_handle_name ( device ), efi_autoexec_wname,
+                      strerror ( rc ) );
                goto err_open;
        }
 
@@ -113,7 +110,8 @@ int efi_autoexec_load ( EFI_HANDLE device ) {
                                       &info ) ) != 0 ) {
                rc = -EEFI ( efirc );
                DBGC ( device, "EFI %s could not get %ls info: %s\n",
-                      efi_handle_name ( device ), name, strerror ( rc ) );
+                      efi_handle_name ( device ), efi_autoexec_wname,
+                      strerror ( rc ) );
                goto err_getinfo;
        }
        size = info.info.FileSize;
@@ -122,7 +120,7 @@ int efi_autoexec_load ( EFI_HANDLE device ) {
        if ( ! size ) {
                rc = -EINVAL;
                DBGC ( device, "EFI %s has zero-length %ls\n",
-                      efi_handle_name ( device ), name );
+                      efi_handle_name ( device ), efi_autoexec_wname );
                goto err_empty;
        }
 
@@ -131,7 +129,8 @@ int efi_autoexec_load ( EFI_HANDLE device ) {
                                          &data ) ) != 0 ) {
                rc = -EEFI ( efirc );
                DBGC ( device, "EFI %s could not allocate %ls: %s\n",
-                      efi_handle_name ( device ), name, strerror ( rc ) );
+                      efi_handle_name ( device ), efi_autoexec_wname,
+                      strerror ( rc ) );
                goto err_alloc;
        }
 
@@ -139,7 +138,8 @@ int efi_autoexec_load ( EFI_HANDLE device ) {
        if ( ( efirc = file->Read ( file, &size, data ) ) != 0 ) {
                rc = -EEFI ( efirc );
                DBGC ( device, "EFI %s could not read %ls: %s\n",
-                      efi_handle_name ( device ), name, strerror ( rc ) );
+                      efi_handle_name ( device ), efi_autoexec_wname,
+                      strerror ( rc ) );
                goto err_read;
        }
 
@@ -148,7 +148,7 @@ int efi_autoexec_load ( EFI_HANDLE device ) {
        efi_autoexec_len = size;
        data = NULL;
        DBGC ( device, "EFI %s found %ls\n",
-              efi_handle_name ( device ), name );
+              efi_handle_name ( device ), efi_autoexec_wname );
 
        /* Success */
        rc = 0;
@@ -169,6 +169,26 @@ int efi_autoexec_load ( EFI_HANDLE device ) {
        return rc;
 }
 
+/**
+ * Load autoexec script
+ *
+ * @v device           Device handle
+ * @ret rc             Return status code
+ */
+int efi_autoexec_load ( EFI_HANDLE device ) {
+       int rc;
+
+       /* Sanity check */
+       assert ( efi_autoexec == NULL );
+       assert ( efi_autoexec_len == 0 );
+
+       /* Try loading from file system, if supported */
+       if ( ( rc = efi_autoexec_filesystem ( device ) ) == 0 )
+               return 0;
+
+       return -ENOENT;
+}
+
 /**
  * Register autoexec script
  *
@@ -176,7 +196,6 @@ int efi_autoexec_load ( EFI_HANDLE device ) {
 static void efi_autoexec_startup ( void ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        EFI_HANDLE device = efi_loaded_image->DeviceHandle;
-       const char *name = AUTOEXEC_NAME;
        struct image *image;
 
        /* Do nothing if we have no autoexec script */
@@ -184,15 +203,16 @@ static void efi_autoexec_startup ( void ) {
                return;
 
        /* Create autoexec image */
-       image = image_memory ( name, virt_to_user ( efi_autoexec ),
+       image = image_memory ( efi_autoexec_name,
+                              virt_to_user ( efi_autoexec ),
                               efi_autoexec_len );
        if ( ! image ) {
                DBGC ( device, "EFI %s could not create %s\n",
-                      efi_handle_name ( device ), name );
+                      efi_handle_name ( device ), efi_autoexec_name );
                return;
        }
        DBGC ( device, "EFI %s registered %s\n",
-              efi_handle_name ( device ), name );
+              efi_handle_name ( device ), efi_autoexec_name );
 
        /* Free temporary copy */
        bs->FreePool ( efi_autoexec );