iPXE
efi_autoexec.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <string.h>
28#include <errno.h>
29#include <ipxe/timer.h>
30#include <ipxe/image.h>
31#include <ipxe/netdevice.h>
32#include <ipxe/uri.h>
33#include <ipxe/efi/efi.h>
34#include <ipxe/efi/efi_utils.h>
36#include <ipxe/efi/mnpnet.h>
37#include <usr/imgmgmt.h>
38#include <usr/sync.h>
39
40/** @file
41 *
42 * EFI autoexec script
43 *
44 */
45
46/** Timeout for autoexec script downloads */
47#define EFI_AUTOEXEC_TIMEOUT ( 30 * TICKS_PER_SEC )
48
49/** Timeout for autoexec pending operation completion */
50#define EFI_AUTOEXEC_SYNC_TIMEOUT ( 1 * TICKS_PER_SEC )
51
52/** Autoexec script image name */
53#define EFI_AUTOEXEC_NAME "autoexec.ipxe"
54
55/** An EFI autoexec script loader */
57 /** Required protocol GUID */
59 /**
60 * Load autoexec script
61 *
62 * @v handle Handle on which protocol was found
63 * @v image Image to fill in
64 * @ret rc Return status code
65 */
66 int ( * load ) ( EFI_HANDLE handle, struct image **image );
67};
68
69/**
70 * Load autoexec script from filesystem
71 *
72 * @v handle Simple filesystem protocol handle
73 * @v image Image to fill in
74 * @ret rc Return status code
75 */
77 EFI_HANDLE device = efi_loaded_image->DeviceHandle;
78 int rc;
79
80 /* Check that we were loaded from a filesystem */
81 if ( handle != device ) {
82 DBGC ( device, "EFI %s is not the file system handle\n",
84 return -ENOTTY;
85 }
86
87 /* Try loading from loaded image directory, if supported */
88 if ( ( rc = imgacquire ( "file:" EFI_AUTOEXEC_NAME,
89 EFI_AUTOEXEC_TIMEOUT, image ) ) == 0 )
90 return 0;
91
92 /* Try loading from root directory, if supported */
93 if ( ( rc = imgacquire ( "file:/" EFI_AUTOEXEC_NAME,
94 EFI_AUTOEXEC_TIMEOUT, image ) ) == 0 )
95 return 0;
96
97 return rc;
98}
99
100/**
101 * Load autoexec script via temporary network device
102 *
103 * @v handle Managed network protocol service binding handle
104 * @v image Image to fill in
105 * @ret rc Return status code
106 */
108 EFI_HANDLE device = efi_loaded_image->DeviceHandle;
109 struct net_device *netdev;
110 int rc;
111
112 /* Create temporary network device */
113 if ( ( rc = mnptemp_create ( handle, &netdev ) ) != 0 ) {
114 DBGC ( device, "EFI %s could not create net device: %s\n",
116 goto err_create;
117 }
118
119 /* Do nothing unless we have a usable current working URI */
120 if ( ! cwuri ) {
121 DBGC ( device, "EFI %s has no current working URI\n",
123 rc = -ENOTTY;
124 goto err_cwuri;
125 }
126
127 /* Open network device */
128 if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
129 DBGC ( device, "EFI %s could not open net device: %s\n",
131 goto err_open;
132 }
133
134 /* Attempt download */
136 if ( rc != 0 ) {
137 DBGC ( device, "EFI %s could not download %s: %s\n",
139 strerror ( rc ) );
140 }
141
142 /* Ensure network exchanges have completed */
144
145 err_open:
146 err_cwuri:
148 err_create:
149 return rc;
150}
151
152/** Autoexec script loaders */
154 {
157 },
158 {
160 .load = efi_autoexec_network,
161 },
162};
163
164/**
165 * Load autoexec script
166 *
167 * @ret rc Return status code
168 */
169int efi_autoexec_load ( void ) {
170 EFI_HANDLE device = efi_loaded_image->DeviceHandle;
172 struct efi_autoexec_loader *loader;
173 struct image *image;
174 unsigned int i;
175 int rc;
176
177 /* Use first applicable loader */
178 for ( i = 0 ; i < ( sizeof ( efi_autoexec_loaders ) /
179 sizeof ( efi_autoexec_loaders[0] ) ) ; i ++ ) {
180
181 /* Locate required protocol for this loader */
182 loader = &efi_autoexec_loaders[i];
183 if ( ( rc = efi_locate_device ( device, loader->protocol,
184 &handle, 0 ) ) != 0 ) {
185 DBGC ( device, "EFI %s found no %s: %s\n",
187 efi_guid_ntoa ( loader->protocol ),
188 strerror ( rc ) );
189 continue;
190 }
191 DBGC ( device, "EFI %s found %s on ",
193 efi_guid_ntoa ( loader->protocol ) );
194 DBGC ( device, "%s\n", efi_handle_name ( handle ) );
195
196 /* Try loading */
197 if ( ( rc = loader->load ( handle, &image ) ) != 0 )
198 return rc;
199
200 /* Discard zero-length images */
201 if ( ! image->len ) {
202 DBGC ( device, "EFI %s discarding zero-length %s\n",
205 return -ENOENT;
206 }
207
208 DBGC ( device, "EFI %s loaded %s (%zd bytes)\n",
210 return 0;
211 }
212
213 return -ENOENT;
214}
GUID EFI_GUID
128-bit buffer containing a unique identifier value.
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
struct uri * cwuri
Current working URI.
Definition cwuri.c:39
#define EFI_AUTOEXEC_SYNC_TIMEOUT
Timeout for autoexec pending operation completion.
static int efi_autoexec_filesystem(EFI_HANDLE handle, struct image **image)
Load autoexec script from filesystem.
static struct efi_autoexec_loader efi_autoexec_loaders[]
Autoexec script loaders.
#define EFI_AUTOEXEC_TIMEOUT
Timeout for autoexec script downloads.
#define EFI_AUTOEXEC_NAME
Autoexec script image name.
int efi_autoexec_load(void)
Load autoexec script.
static int efi_autoexec_network(EFI_HANDLE handle, struct image **image)
Load autoexec script via temporary network device.
EFI autoexec script.
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition efi_guid.c:726
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition efi_guid.c:337
EFI_GUID efi_managed_network_service_binding_protocol_guid
Managed network service binding protocol GUID.
Definition efi_guid.c:285
EFI_LOADED_IMAGE_PROTOCOL * efi_loaded_image
Loaded image protocol for this image.
Definition efi_init.c:39
int efi_locate_device(EFI_HANDLE device, EFI_GUID *protocol, EFI_HANDLE *parent, unsigned int skip)
Locate parent device supporting a given protocol.
Definition efi_utils.c:46
EFI utilities.
Error codes.
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC(...)
Definition compiler.h:505
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOENT
No such file or directory.
Definition errno.h:515
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
void unregister_image(struct image *image)
Unregister executable image.
Definition image.c:358
Executable images.
int imgacquire(const char *name_uri, unsigned long timeout, struct image **image)
Acquire an image.
Definition imgmgmt.c:143
Image management.
EFI API.
#define EFI_HANDLE
Definition efi.h:53
uint16_t handle
Handle.
Definition smbios.h:5
iPXE timers
String functions.
void mnptemp_destroy(struct net_device *netdev)
Destroy temporary MNP network device.
Definition mnpnet.c:541
int mnptemp_create(EFI_HANDLE handle, struct net_device **netdev)
Create temporary MNP network device.
Definition mnpnet.c:504
MNP NIC driver.
int netdev_open(struct net_device *netdev)
Open network device.
Definition netdevice.c:862
Network device management.
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A hardware device.
Definition device.h:77
An EFI autoexec script loader.
EFI_GUID * protocol
Required protocol GUID.
int(* load)(EFI_HANDLE handle, struct image **image)
Load autoexec script.
An executable image.
Definition image.h:24
char * name
Name.
Definition image.h:38
size_t len
Length of raw file image.
Definition image.h:56
A network device.
Definition netdevice.h:353
int sync(unsigned long timeout)
Wait for pending operations to complete.
Definition sync.c:74
Wait for pending operations to complete.
Uniform Resource Identifiers.