summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2024-03-29 14:03:38 +0100
committerMichael Brown2024-04-03 01:03:49 +0200
commit165995b7e917a94533799fe43d14f5e3b1fef285 (patch)
tree5cab20918fc7471b8b911ed9dbf8b520970249ca
parent[cachedhcp] Allow cached DHCPACK to apply to temporary network devices (diff)
downloadipxe-165995b7e917a94533799fe43d14f5e3b1fef285.tar.gz
ipxe-165995b7e917a94533799fe43d14f5e3b1fef285.tar.xz
ipxe-165995b7e917a94533799fe43d14f5e3b1fef285.zip
[efi] Restructure handling of autoexec.ipxe script
We currently attempt to obtain the autoexec.ipxe script via early use of the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or EFI_PXE_BASE_CODE_PROTOCOL interfaces to obtain an opaque block of memory, which is then registered as an image at an appropriate point during our startup sequence. The early use of these existent interfaces allows us to obtain the script even if our subsequent actions (e.g. disconnecting drivers in order to connect up our own) may cause the script to become inaccessible. This mirrors the approach used under BIOS, where the autoexec.ipxe script is provided by the prefix (e.g. as an initrd image when using the .lkrn build of iPXE) and so must be copied into a normally allocated image from wherever it happens to previously exist in memory. We do not currently have support for downloading an autoexec.ipxe script if we were ourselves downloaded via UEFI HTTP boot. There is an EFI_HTTP_PROTOCOL defined within the UEFI specification, but it is so poorly designed as to be unusable for the simple purpose of downloading an additional file from the same directory. It provides almost nothing more than a very slim wrapper around EFI_TCP4_PROTOCOL (or EFI_TCP6_PROTOCOL). It will not handle redirection, content encoding, retries, or even fundamentals such as the Content-Length header, leaving all of this up to the caller. The UEFI HTTP Boot driver will install an EFI_LOAD_FILE_PROTOCOL instance on the loaded image's device handle. This looks promising at first since it provides the LoadFile() API call which is specified to accept an arbitrary filename parameter. However, experimentation (and inspection of the code in EDK2) reveals a multitude of problems that prevent this from being usable. Calling LoadFile() will idiotically restart the entire DHCP process (and potentially pop up a UI requiring input from the user for e.g. a wireless network password). The filename provided to LoadFile() will be ignored. Any downloaded file will be rejected unless it happens to match one of the limited set of types expected by the UEFI HTTP Boot driver. The list of design failures and conceptual mismatches is fairly impressive. Choose to bypass every possible aspect of UEFI HTTP support, and instead use our own HTTP client and network stack to download the autoexec.ipxe script over a temporary MNP network device. Since this approach works for TFTP as well as HTTP, drop the direct use of EFI_PXE_BASE_CODE_PROTOCOL. For consistency and simplicity, also drop the direct use of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL and rely upon our existing support to access local files via "file:" URIs. This approach results in console output during the "iPXE initialising devices...ok" message that appears while startup is in progress. Remove the trailing "ok" so that this intermediate output appears at a sensible location on the screen. The welcome banner that will be printed immediately afterwards provides an indication that startup has completed successfully even absent the explicit "ok". Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/core/main.c3
-rw-r--r--src/include/ipxe/efi/efi_autoexec.h5
-rw-r--r--src/interface/efi/efi_autoexec.c489
-rw-r--r--src/interface/efi/efiprefix.c11
4 files changed, 124 insertions, 384 deletions
diff --git a/src/core/main.c b/src/core/main.c
index 638dea9c..3db83649 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -32,9 +32,8 @@ __asmcall int main ( void ) {
initialise();
/* Some devices take an unreasonably long time to initialise */
- printf ( "%s initialising devices...", product_short_name );
+ printf ( "%s initialising devices...\n", product_short_name );
startup();
- printf ( "ok\n" );
/* Attempt to boot */
if ( ( rc = ipxe ( NULL ) ) != 0 )
diff --git a/src/include/ipxe/efi/efi_autoexec.h b/src/include/ipxe/efi/efi_autoexec.h
index 08ddf583..18bc4200 100644
--- a/src/include/ipxe/efi/efi_autoexec.h
+++ b/src/include/ipxe/efi/efi_autoexec.h
@@ -9,9 +9,6 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-#include <ipxe/efi/efi.h>
-
-extern int efi_autoexec_load ( EFI_HANDLE device,
- EFI_DEVICE_PATH_PROTOCOL *path );
+extern int efi_autoexec_load ( void );
#endif /* _IPXE_EFI_AUTOEXEC_H */
diff --git a/src/interface/efi/efi_autoexec.c b/src/interface/efi/efi_autoexec.c
index fb12cef0..d9ad3b99 100644
--- a/src/interface/efi/efi_autoexec.c
+++ b/src/interface/efi/efi_autoexec.c
@@ -24,16 +24,16 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
-#include <stdlib.h>
#include <errno.h>
+#include <ipxe/timer.h>
#include <ipxe/image.h>
-#include <ipxe/init.h>
-#include <ipxe/in.h>
+#include <ipxe/netdevice.h>
#include <ipxe/efi/efi.h>
+#include <ipxe/efi/efi_utils.h>
#include <ipxe/efi/efi_autoexec.h>
-#include <ipxe/efi/Protocol/PxeBaseCode.h>
-#include <ipxe/efi/Protocol/SimpleFileSystem.h>
-#include <ipxe/efi/Guid/FileInfo.h>
+#include <ipxe/efi/mnpnet.h>
+#include <usr/imgmgmt.h>
+#include <usr/sync.h>
/** @file
*
@@ -41,413 +41,160 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
*/
-/** Autoexec script filename */
-static wchar_t efi_autoexec_wname[] = L"autoexec.ipxe";
+/** Timeout for autoexec script downloads */
+#define EFI_AUTOEXEC_TIMEOUT ( 2 * TICKS_PER_SEC )
/** Autoexec script image name */
-static char efi_autoexec_name[] = "autoexec.ipxe";
-
-/** Autoexec script (if any) */
-static void *efi_autoexec;
-
-/** Autoexec script length */
-static size_t efi_autoexec_len;
+#define EFI_AUTOEXEC_NAME "autoexec.ipxe"
+
+/** An EFI autoexec script loader */
+struct efi_autoexec_loader {
+ /** Required protocol GUID */
+ EFI_GUID *protocol;
+ /**
+ * Load autoexec script
+ *
+ * @v handle Handle on which protocol was found
+ * @v image Image to fill in
+ * @ret rc Return status code
+ */
+ int ( * load ) ( EFI_HANDLE handle, struct image **image );
+};
/**
- * Load autoexec script from path within filesystem
+ * Load autoexec script from filesystem
*
- * @v device Device handle
- * @v path Relative path to image, or NULL to load from root
+ * @v handle Simple filesystem protocol handle
+ * @v image Image to fill in
* @ret rc Return status code
*/
-static int efi_autoexec_filesystem ( EFI_HANDLE device,
- EFI_DEVICE_PATH_PROTOCOL *path ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- union {
- void *interface;
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *fs;
- } u;
- struct {
- EFI_FILE_INFO info;
- CHAR16 name[ sizeof ( efi_autoexec_wname ) /
- sizeof ( efi_autoexec_wname[0] ) ];
- } info;
- FILEPATH_DEVICE_PATH *filepath;
- EFI_FILE_PROTOCOL *root;
- EFI_FILE_PROTOCOL *file;
- UINTN size;
- VOID *data;
- unsigned int dirlen;
- size_t len;
- CHAR16 *wname;
- EFI_STATUS efirc;
+static int efi_autoexec_filesystem ( EFI_HANDLE handle, struct image **image ) {
+ EFI_HANDLE device = efi_loaded_image->DeviceHandle;
int rc;
- /* Identify directory */
- if ( path ) {
-
- /* Check relative device path is a file path */
- if ( ! ( ( path->Type == MEDIA_DEVICE_PATH ) &&
- ( path->SubType == MEDIA_FILEPATH_DP ) ) ) {
- DBGC ( device, "EFI %s image path ",
- efi_handle_name ( device ) );
- DBGC ( device, " \"%s\" is not a file path\n",
- efi_devpath_text ( path ) );
- rc = -ENOTTY;
- goto err_not_filepath;
- }
- filepath = container_of ( path, FILEPATH_DEVICE_PATH, Header );
-
- /* Find length of containing directory */
- dirlen = ( ( ( ( path->Length[1] << 8 ) | path->Length[0] )
- - offsetof ( typeof ( *filepath ), PathName ) )
- / sizeof ( filepath->PathName[0] ) );
- for ( ; dirlen ; dirlen-- ) {
- if ( filepath->PathName[ dirlen - 1 ] == L'\\' )
- break;
- }
-
- } else {
-
- /* Use root directory */
- filepath = NULL;
- dirlen = 0;
- }
-
- /* Allocate filename */
- len = ( ( dirlen * sizeof ( wname[0] ) ) + sizeof ( efi_autoexec_wname ) );
- wname = malloc ( len );
- if ( ! wname ) {
- rc = -ENOMEM;
- goto err_wname;
- }
- memcpy ( wname, filepath->PathName, ( dirlen * sizeof ( wname[0] ) ) );
- memcpy ( &wname[dirlen], efi_autoexec_wname, sizeof ( efi_autoexec_wname ) );
-
- /* 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, wname,
- EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFI %s has no %ls: %s\n",
- efi_handle_name ( device ), wname, 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 ), wname, 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 ), wname );
- 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 ), wname, 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 ), wname, strerror ( rc ) );
- goto err_read;
+ /* Check that we were loaded from a filesystem */
+ if ( handle != device ) {
+ DBGC ( device, "EFI %s is not the file system handle\n",
+ efi_handle_name ( device ) );
+ return -ENOTTY;
}
- /* Record autoexec script */
- efi_autoexec = data;
- efi_autoexec_len = size;
- data = NULL;
- DBGC ( device, "EFI %s found %ls\n", efi_handle_name ( device ), wname );
+ /* Try loading from loaded image directory, if supported */
+ if ( ( rc = imgacquire ( "file:" EFI_AUTOEXEC_NAME,
+ EFI_AUTOEXEC_TIMEOUT, image ) ) == 0 )
+ return 0;
- /* Success */
- rc = 0;
+ /* Try loading from root directory, if supported */
+ if ( ( rc = imgacquire ( "file:/" EFI_AUTOEXEC_NAME,
+ EFI_AUTOEXEC_TIMEOUT, image ) ) == 0 )
+ return 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:
- free ( wname );
- err_wname:
- err_not_filepath:
return rc;
}
/**
- * Load autoexec script from TFTP server
+ * Load autoexec script via temporary network device
*
- * @v device Device handle
+ * @v handle Managed network protocol service binding handle
+ * @v image Image to fill in
* @ret rc Return status code
*/
-static int efi_autoexec_tftp ( EFI_HANDLE device ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- union {
- void *interface;
- EFI_PXE_BASE_CODE_PROTOCOL *pxe;
- } u;
- EFI_PXE_BASE_CODE_MODE *mode;
- EFI_PXE_BASE_CODE_PACKET *packet;
- union {
- struct in_addr in;
- EFI_IP_ADDRESS ip;
- } server;
- size_t filename_max;
- char *filename;
- char *sep;
- UINT64 size;
- VOID *data;
- EFI_STATUS efirc;
+static int efi_autoexec_network ( EFI_HANDLE handle, struct image **image ) {
+ EFI_HANDLE device = efi_loaded_image->DeviceHandle;
+ struct net_device *netdev;
int rc;
- /* Open PXE base code protocol */
- if ( ( efirc = bs->OpenProtocol ( device,
- &efi_pxe_base_code_protocol_guid,
- &u.interface, efi_image_handle,
- device,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
- rc = -EEFI ( efirc );
- DBGC ( device, "EFI %s has no PXE base code instance: %s\n",
+ /* Create temporary network device */
+ if ( ( rc = mnptemp_create ( handle, &netdev ) ) != 0 ) {
+ DBGC ( device, "EFI %s could not create net device: %s\n",
efi_handle_name ( device ), strerror ( rc ) );
- goto err_pxe;
- }
-
- /* Do not attempt to parse DHCPv6 packets */
- mode = u.pxe->Mode;
- if ( mode->UsingIpv6 ) {
- rc = -ENOTSUP;
- DBGC ( device, "EFI %s has IPv6 PXE base code\n",
- efi_handle_name ( device ) );
- goto err_ipv6;
+ goto err_create;
}
- /* Identify relevant reply packet */
- if ( mode->PxeReplyReceived &&
- mode->PxeReply.Dhcpv4.BootpBootFile[0] ) {
- /* Use boot filename if present in PXE reply */
- DBGC ( device, "EFI %s using PXE reply filename\n",
- efi_handle_name ( device ) );
- packet = &mode->PxeReply;
- } else if ( mode->DhcpAckReceived &&
- mode->DhcpAck.Dhcpv4.BootpBootFile[0] ) {
- /* Otherwise, use boot filename if present in DHCPACK */
- DBGC ( device, "EFI %s using DHCPACK filename\n",
- efi_handle_name ( device ) );
- packet = &mode->DhcpAck;
- } else if ( mode->ProxyOfferReceived &&
- mode->ProxyOffer.Dhcpv4.BootpBootFile[0] ) {
- /* Otherwise, use boot filename if present in ProxyDHCPOFFER */
- DBGC ( device, "EFI %s using ProxyDHCPOFFER filename\n",
- efi_handle_name ( device ) );
- packet = &mode->ProxyOffer;
- } else {
- /* No boot filename available */
- rc = -ENOENT;
- DBGC ( device, "EFI %s has no PXE boot filename\n",
- efi_handle_name ( device ) );
- goto err_packet;
- }
-
- /* Allocate filename */
- filename_max = ( sizeof ( packet->Dhcpv4.BootpBootFile )
- + ( sizeof ( efi_autoexec_name ) - 1 /* NUL */ )
- + 1 /* NUL */ );
- filename = zalloc ( filename_max );
- if ( ! filename ) {
- rc = -ENOMEM;
- goto err_filename;
- }
-
- /* Extract next-server address and boot filename */
- memset ( &server, 0, sizeof ( server ) );
- memcpy ( &server.in, packet->Dhcpv4.BootpSiAddr,
- sizeof ( server.in ) );
- memcpy ( filename, packet->Dhcpv4.BootpBootFile,
- sizeof ( packet->Dhcpv4.BootpBootFile ) );
-
- /* Update filename to autoexec script name */
- sep = strrchr ( filename, '/' );
- if ( ! sep )
- sep = strrchr ( filename, '\\' );
- if ( ! sep )
- sep = ( filename - 1 );
- strcpy ( ( sep + 1 ), efi_autoexec_name );
-
- /* Get file size */
- if ( ( efirc = u.pxe->Mtftp ( u.pxe,
- EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
- NULL, FALSE, &size, NULL, &server.ip,
- ( ( UINT8 * ) filename ), NULL,
- FALSE ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFI %s could not get size of %s:%s: %s\n",
- efi_handle_name ( device ), inet_ntoa ( server.in ),
- filename, strerror ( rc ) );
- goto err_size;
- }
-
- /* Ignore zero-length files */
- if ( ! size ) {
- rc = -EINVAL;
- DBGC ( device, "EFI %s has zero-length %s:%s\n",
- efi_handle_name ( device ), inet_ntoa ( server.in ),
- filename );
- goto err_empty;
- }
-
- /* Allocate temporary copy */
- if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, size,
- &data ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFI %s could not allocate %s:%s: %s\n",
- efi_handle_name ( device ), inet_ntoa ( server.in ),
- filename, strerror ( rc ) );
- goto err_alloc;
+ /* Open network device */
+ if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
+ DBGC ( device, "EFI %s could not open net device: %s\n",
+ efi_handle_name ( device ), strerror ( rc ) );
+ goto err_open;
}
- /* Download file */
- if ( ( efirc = u.pxe->Mtftp ( u.pxe, EFI_PXE_BASE_CODE_TFTP_READ_FILE,
- data, FALSE, &size, NULL, &server.ip,
- ( ( UINT8 * ) filename ), NULL,
- FALSE ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFI %s could not download %s:%s: %s\n",
- efi_handle_name ( device ), inet_ntoa ( server.in ),
- filename, strerror ( rc ) );
- goto err_download;
+ /* Attempt download */
+ rc = imgacquire ( EFI_AUTOEXEC_NAME, EFI_AUTOEXEC_TIMEOUT, image );
+ if ( rc != 0 ) {
+ DBGC ( device, "EFI %s could not download %s: %s\n",
+ efi_handle_name ( device ), EFI_AUTOEXEC_NAME,
+ strerror ( rc ) );
}
- /* Record autoexec script */
- efi_autoexec = data;
- efi_autoexec_len = size;
- data = NULL;
- DBGC ( device, "EFI %s found %s:%s\n", efi_handle_name ( device ),
- inet_ntoa ( server.in ), filename );
+ /* Ensure network exchanges have completed */
+ sync ( EFI_AUTOEXEC_TIMEOUT );
- /* Success */
- rc = 0;
-
- err_download:
- if ( data )
- bs->FreePool ( data );
- err_alloc:
- err_empty:
- err_size:
- free ( filename );
- err_filename:
- err_packet:
- err_ipv6:
- bs->CloseProtocol ( device, &efi_pxe_base_code_protocol_guid,
- efi_image_handle, device );
- err_pxe:
+ err_open:
+ mnptemp_destroy ( netdev );
+ err_create:
return rc;
}
+/** Autoexec script loaders */
+static struct efi_autoexec_loader efi_autoexec_loaders[] = {
+ {
+ .protocol = &efi_simple_file_system_protocol_guid,
+ .load = efi_autoexec_filesystem,
+ },
+ {
+ .protocol = &efi_managed_network_service_binding_protocol_guid,
+ .load = efi_autoexec_network,
+ },
+};
+
/**
* Load autoexec script
*
- * @v device Device handle
- * @v path Image path within device handle
* @ret rc Return status code
*/
-int efi_autoexec_load ( EFI_HANDLE device,
- EFI_DEVICE_PATH_PROTOCOL *path ) {
- int rc;
-
- /* Sanity check */
- assert ( efi_autoexec == NULL );
- assert ( efi_autoexec_len == 0 );
-
- /* Try loading from file system loaded image directory, if supported */
- if ( ( rc = efi_autoexec_filesystem ( device, path ) ) == 0 )
- return 0;
-
- /* Try loading from file system root directory, if supported */
- if ( ( rc = efi_autoexec_filesystem ( device, NULL ) ) == 0 )
- return 0;
-
- /* Try loading via TFTP, if supported */
- if ( ( rc = efi_autoexec_tftp ( device ) ) == 0 )
- return 0;
-
- return -ENOENT;
-}
-
-/**
- * Register autoexec script
- *
- */
-static void efi_autoexec_startup ( void ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+int efi_autoexec_load ( void ) {
EFI_HANDLE device = efi_loaded_image->DeviceHandle;
+ EFI_HANDLE handle;
+ struct efi_autoexec_loader *loader;
struct image *image;
+ unsigned int i;
+ int rc;
- /* Do nothing if we have no autoexec script */
- if ( ! efi_autoexec )
- return;
+ /* Use first applicable loader */
+ for ( i = 0 ; i < ( sizeof ( efi_autoexec_loaders ) /
+ sizeof ( efi_autoexec_loaders[0] ) ) ; i ++ ) {
+
+ /* Locate required protocol for this loader */
+ loader = &efi_autoexec_loaders[i];
+ if ( ( rc = efi_locate_device ( device, loader->protocol,
+ &handle, 0 ) ) != 0 ) {
+ DBGC ( device, "EFI %s found no %s: %s\n",
+ efi_handle_name ( device ),
+ efi_guid_ntoa ( loader->protocol ),
+ strerror ( rc ) );
+ continue;
+ }
+ DBGC ( device, "EFI %s found %s on ",
+ efi_handle_name ( device ),
+ efi_guid_ntoa ( loader->protocol ) );
+ DBGC ( device, "%s\n", efi_handle_name ( handle ) );
+
+ /* Try loading */
+ if ( ( rc = loader->load ( handle, &image ) ) != 0 )
+ return rc;
+
+ /* Discard zero-length images */
+ if ( ! image->len ) {
+ DBGC ( device, "EFI %s discarding zero-length %s\n",
+ efi_handle_name ( device ), image->name );
+ unregister_image ( image );
+ return -ENOENT;
+ }
- /* Create autoexec image */
- 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 ), efi_autoexec_name );
- return;
+ DBGC ( device, "EFI %s loaded %s (%zd bytes)\n",
+ efi_handle_name ( device ), image->name, image->len );
+ return 0;
}
- DBGC ( device, "EFI %s registered %s\n",
- efi_handle_name ( device ), efi_autoexec_name );
- /* Free temporary copy */
- bs->FreePool ( efi_autoexec );
- efi_autoexec = NULL;
+ return -ENOENT;
}
-
-/** Autoexec script startup function */
-struct startup_fn efi_autoexec_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
- .name = "efi_autoexec",
- .startup = efi_autoexec_startup,
-};
diff --git a/src/interface/efi/efiprefix.c b/src/interface/efi/efiprefix.c
index f6395b65..10d8f0bf 100644
--- a/src/interface/efi/efiprefix.c
+++ b/src/interface/efi/efiprefix.c
@@ -81,25 +81,19 @@ EFI_STATUS EFIAPI _efi_start ( EFI_HANDLE image_handle,
static void efi_init_application ( void ) {
EFI_HANDLE device = efi_loaded_image->DeviceHandle;
EFI_DEVICE_PATH_PROTOCOL *devpath = efi_loaded_image_path;
- EFI_DEVICE_PATH_PROTOCOL *filepath = efi_loaded_image->FilePath;
struct uri *uri;
/* Set current working URI from device path, if present */
uri = efi_path_uri ( devpath );
if ( uri )
churi ( uri );
+ uri_put ( uri );
/* Identify autoboot device, if any */
efi_set_autoboot_ll_addr ( device, devpath );
/* Store cached DHCP packet, if any */
efi_cachedhcp_record ( device, devpath );
-
- /* Load autoexec script, if any */
- efi_autoexec_load ( device, filepath );
-
- /* Drop temporary reference to URI */
- uri_put ( uri );
}
/** EFI application initialisation function */
@@ -114,6 +108,9 @@ struct init_fn efi_init_application_fn __init_fn ( INIT_NORMAL ) = {
*/
static int efi_probe ( struct root_device *rootdev __unused ) {
+ /* Try loading autoexec script */
+ efi_autoexec_load();
+
/* Remove any vetoed drivers */
efi_veto();