]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Split out autoexec script portions of efi_autoboot.c
authorMichael Brown <mcb30@ipxe.org>
Wed, 17 Feb 2021 16:57:19 +0000 (16:57 +0000)
committerMichael Brown <mcb30@ipxe.org>
Wed, 17 Feb 2021 17:14:19 +0000 (17:14 +0000)
The "autoboot device" and "autoexec script" functionalities in
efi_autoboot.c are unrelated except in that they both need to be
invoked by efiprefix.c before device drivers are loaded.

Split out the autoexec script portions to a separate file to avoid
potential confusion.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/efi/efi_autoboot.h
src/include/ipxe/efi/efi_autoexec.h [new file with mode: 0644]
src/include/ipxe/errfile.h
src/interface/efi/efi_autoboot.c
src/interface/efi/efi_autoexec.c [new file with mode: 0644]
src/interface/efi/efiprefix.c

index 1d5ddc8c31b4d496501db9783e2b32efd483d488..706885e28d882effe6d18b01fcee20e127a8742a 100644 (file)
@@ -9,6 +9,8 @@
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
-extern void efi_set_autoboot ( void );
+#include <ipxe/efi/efi.h>
+
+extern int efi_set_autoboot_ll_addr ( EFI_HANDLE device );
 
 #endif /* _IPXE_EFI_AUTOBOOT_H */
diff --git a/src/include/ipxe/efi/efi_autoexec.h b/src/include/ipxe/efi/efi_autoexec.h
new file mode 100644 (file)
index 0000000..1f93b41
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _IPXE_EFI_AUTOEXEC_H
+#define _IPXE_EFI_AUTOEXEC_H
+
+/** @file
+ *
+ * EFI autoexec script
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/efi/efi.h>
+
+extern int efi_autoexec_load ( EFI_HANDLE device );
+
+#endif /* _IPXE_EFI_AUTOEXEC_H */
index 4c1c334d81d6d4eef681508c7cca954948dbc335..a0b7618cc1fc711767b0c984ae64220ac2c51158 100644 (file)
@@ -385,6 +385,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define ERRFILE_ntlm                 ( ERRFILE_OTHER | 0x00510000 )
 #define ERRFILE_efi_veto             ( ERRFILE_OTHER | 0x00520000 )
 #define ERRFILE_efi_autoboot         ( ERRFILE_OTHER | 0x00530000 )
+#define ERRFILE_efi_autoexec         ( ERRFILE_OTHER | 0x00540000 )
 
 /** @} */
 
index f7993b06829b24520415ba6270ce6869e539bb2f..08d67f761fcdc7ccb7bd471d012b7d1b93890253 100644 (file)
@@ -25,40 +25,24 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <string.h>
 #include <errno.h>
-#include <ipxe/image.h>
-#include <ipxe/init.h>
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/efi_autoboot.h>
 #include <ipxe/efi/Protocol/SimpleNetwork.h>
-#include <ipxe/efi/Protocol/SimpleFileSystem.h>
-#include <ipxe/efi/Guid/FileInfo.h>
 #include <usr/autoboot.h>
 
 /** @file
  *
- * EFI automatic booting
+ * EFI autoboot device
  *
  */
 
-/** Autoexec script filename */
-#define AUTOEXEC_FILENAME L"autoexec.ipxe"
-
-/** Autoexec script image name */
-#define AUTOEXEC_NAME "autoexec.ipxe"
-
-/** Autoexec script (if any) */
-static void *efi_autoexec;
-
-/** Autoexec script length */
-static size_t efi_autoexec_len;
-
 /**
  * Identify autoboot device
  *
  * @v device           Device handle
  * @ret rc             Return status code
  */
-static int efi_set_autoboot_ll_addr ( EFI_HANDLE device ) {
+int efi_set_autoboot_ll_addr ( EFI_HANDLE device ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        union {
                EFI_SIMPLE_NETWORK_PROTOCOL *snp;
@@ -93,172 +77,3 @@ static int efi_set_autoboot_ll_addr ( EFI_HANDLE device ) {
 
        return 0;
 }
-
-/**
- * Load autoexec script
- *
- * @v device           Device handle
- * @ret rc             Return status code
- */
-static int efi_load_autoexec ( 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] ) ];
-       } info;
-       EFI_FILE_PROTOCOL *root;
-       EFI_FILE_PROTOCOL *file;
-       UINTN size;
-       VOID *data;
-       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,
-                                         &u.interface, efi_image_handle,
-                                         device,
-                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
-               rc = -EEFI ( efirc );
-               DBGC ( device, "EFI %s has no filesystem instance: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
-               goto err_filesystem;
-       }
-
-       /* Open root directory */
-       if ( ( efirc = u.fs->OpenVolume ( u.fs, &root ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( device, "EFI %s could not open volume: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
-               goto err_volume;
-       }
-
-       /* Open autoexec script */
-       if ( ( efirc = root->Open ( root, &file, name,
-                                   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 ) );
-               goto err_open;
-       }
-
-       /* Get file information */
-       size = sizeof ( info );
-       if ( ( efirc = file->GetInfo ( file, &efi_file_info_id, &size,
-                                      &info ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( device, "EFI %s could not get %ls info: %s\n",
-                      efi_handle_name ( device ), name, strerror ( rc ) );
-               goto err_getinfo;
-       }
-       size = info.info.FileSize;
-
-       /* Ignore zero-length files */
-       if ( ! size ) {
-               rc = -EINVAL;
-               DBGC ( device, "EFI %s has zero-length %ls\n",
-                      efi_handle_name ( device ), name );
-               goto err_empty;
-       }
-
-       /* Allocate temporary copy */
-       if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, size,
-                                         &data ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( device, "EFI %s could not allocate %ls: %s\n",
-                      efi_handle_name ( device ), name, strerror ( rc ) );
-               goto err_alloc;
-       }
-
-       /* Read file */
-       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 ) );
-               goto err_read;
-       }
-
-       /* Record autoexec script */
-       efi_autoexec = data;
-       efi_autoexec_len = size;
-       data = NULL;
-       DBGC ( device, "EFI %s found %ls\n",
-              efi_handle_name ( device ), name );
-
-       /* Success */
-       rc = 0;
-
- err_read:
-       if ( data )
-               bs->FreePool ( data );
- err_alloc:
- err_empty:
- err_getinfo:
-       file->Close ( file );
- err_open:
-       root->Close ( root );
- err_volume:
-       bs->CloseProtocol ( device, &efi_simple_file_system_protocol_guid,
-                           efi_image_handle, device );
- err_filesystem:
-       return rc;
-}
-
-/**
- * Configure automatic booting
- *
- */
-void efi_set_autoboot ( void ) {
-       EFI_HANDLE device = efi_loaded_image->DeviceHandle;
-
-       /* Identify autoboot device, if any */
-       efi_set_autoboot_ll_addr ( device );
-
-       /* Load autoexec script, if any */
-       efi_load_autoexec ( device );
-}
-
-/**
- * Register automatic boot image
- *
- */
-static void efi_autoboot_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 */
-       if ( ! efi_autoexec )
-               return;
-
-       /* Create autoexec image */
-       image = image_memory ( 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 );
-               return;
-       }
-       DBGC ( device, "EFI %s registered %s\n",
-              efi_handle_name ( device ), name );
-
-       /* Free temporary copy */
-       bs->FreePool ( efi_autoexec );
-       efi_autoexec = NULL;
-}
-
-/** Automatic boot startup function */
-struct startup_fn efi_autoboot_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
-       .name = "efi_autoboot",
-       .startup = efi_autoboot_startup,
-};
diff --git a/src/interface/efi/efi_autoexec.c b/src/interface/efi/efi_autoexec.c
new file mode 100644 (file)
index 0000000..88eb379
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <string.h>
+#include <errno.h>
+#include <ipxe/image.h>
+#include <ipxe/init.h>
+#include <ipxe/efi/efi.h>
+#include <ipxe/efi/efi_autoexec.h>
+#include <ipxe/efi/Protocol/SimpleFileSystem.h>
+#include <ipxe/efi/Guid/FileInfo.h>
+
+/** @file
+ *
+ * EFI autoexec script
+ *
+ */
+
+/** Autoexec script filename */
+#define AUTOEXEC_FILENAME L"autoexec.ipxe"
+
+/** Autoexec script image name */
+#define AUTOEXEC_NAME "autoexec.ipxe"
+
+/** Autoexec script (if any) */
+static void *efi_autoexec;
+
+/** Autoexec script length */
+static size_t efi_autoexec_len;
+
+/**
+ * Load autoexec script
+ *
+ * @v device           Device handle
+ * @ret rc             Return status code
+ */
+int efi_autoexec_load ( 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] ) ];
+       } info;
+       EFI_FILE_PROTOCOL *root;
+       EFI_FILE_PROTOCOL *file;
+       UINTN size;
+       VOID *data;
+       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,
+                                         &u.interface, efi_image_handle,
+                                         device,
+                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
+               rc = -EEFI ( efirc );
+               DBGC ( device, "EFI %s has no filesystem instance: %s\n",
+                      efi_handle_name ( device ), strerror ( rc ) );
+               goto err_filesystem;
+       }
+
+       /* Open root directory */
+       if ( ( efirc = u.fs->OpenVolume ( u.fs, &root ) ) != 0 ) {
+               rc = -EEFI ( efirc );
+               DBGC ( device, "EFI %s could not open volume: %s\n",
+                      efi_handle_name ( device ), strerror ( rc ) );
+               goto err_volume;
+       }
+
+       /* Open autoexec script */
+       if ( ( efirc = root->Open ( root, &file, name,
+                                   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 ) );
+               goto err_open;
+       }
+
+       /* Get file information */
+       size = sizeof ( info );
+       if ( ( efirc = file->GetInfo ( file, &efi_file_info_id, &size,
+                                      &info ) ) != 0 ) {
+               rc = -EEFI ( efirc );
+               DBGC ( device, "EFI %s could not get %ls info: %s\n",
+                      efi_handle_name ( device ), name, strerror ( rc ) );
+               goto err_getinfo;
+       }
+       size = info.info.FileSize;
+
+       /* Ignore zero-length files */
+       if ( ! size ) {
+               rc = -EINVAL;
+               DBGC ( device, "EFI %s has zero-length %ls\n",
+                      efi_handle_name ( device ), name );
+               goto err_empty;
+       }
+
+       /* Allocate temporary copy */
+       if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, size,
+                                         &data ) ) != 0 ) {
+               rc = -EEFI ( efirc );
+               DBGC ( device, "EFI %s could not allocate %ls: %s\n",
+                      efi_handle_name ( device ), name, strerror ( rc ) );
+               goto err_alloc;
+       }
+
+       /* Read file */
+       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 ) );
+               goto err_read;
+       }
+
+       /* Record autoexec script */
+       efi_autoexec = data;
+       efi_autoexec_len = size;
+       data = NULL;
+       DBGC ( device, "EFI %s found %ls\n",
+              efi_handle_name ( device ), name );
+
+       /* Success */
+       rc = 0;
+
+ err_read:
+       if ( data )
+               bs->FreePool ( data );
+ err_alloc:
+ err_empty:
+ err_getinfo:
+       file->Close ( file );
+ err_open:
+       root->Close ( root );
+ err_volume:
+       bs->CloseProtocol ( device, &efi_simple_file_system_protocol_guid,
+                           efi_image_handle, device );
+ err_filesystem:
+       return rc;
+}
+
+/**
+ * Register autoexec script
+ *
+ */
+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 */
+       if ( ! efi_autoexec )
+               return;
+
+       /* Create autoexec image */
+       image = image_memory ( 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 );
+               return;
+       }
+       DBGC ( device, "EFI %s registered %s\n",
+              efi_handle_name ( device ), name );
+
+       /* Free temporary copy */
+       bs->FreePool ( efi_autoexec );
+       efi_autoexec = NULL;
+}
+
+/** Autoexec script startup function */
+struct startup_fn efi_autoexec_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
+       .name = "efi_autoexec",
+       .startup = efi_autoexec_startup,
+};
index 3273b79d842fd03f24a76a7999e28838610a8d0f..928f41c729f3e42056b758f76d8ddfbee9a9226d 100644 (file)
@@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/efi/efi_driver.h>
 #include <ipxe/efi/efi_snp.h>
 #include <ipxe/efi/efi_autoboot.h>
+#include <ipxe/efi/efi_autoexec.h>
 #include <ipxe/efi/efi_watchdog.h>
 #include <ipxe/efi/efi_veto.h>
 
@@ -48,8 +49,11 @@ EFI_STATUS EFIAPI _efi_start ( EFI_HANDLE image_handle,
        if ( ( efirc = efi_init ( image_handle, systab ) ) != 0 )
                goto err_init;
 
-       /* Record autoboot device (if any) */
-       efi_set_autoboot();
+       /* Identify autoboot device, if any */
+       efi_set_autoboot_ll_addr ( efi_loaded_image->DeviceHandle );
+
+       /* Load autoexec script, if any */
+       efi_autoexec_load ( efi_loaded_image->DeviceHandle );
 
        /* Claim SNP devices for use by iPXE */
        efi_snp_claim();