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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <string.h>
27 #include <errno.h>
28 #include <ipxe/timer.h>
29 #include <ipxe/image.h>
30 #include <ipxe/netdevice.h>
31 #include <ipxe/uri.h>
32 #include <ipxe/efi/efi.h>
33 #include <ipxe/efi/efi_utils.h>
34 #include <ipxe/efi/efi_autoexec.h>
35 #include <ipxe/efi/mnpnet.h>
36 #include <usr/imgmgmt.h>
37 #include <usr/sync.h>
38 
39 /** @file
40  *
41  * EFI autoexec script
42  *
43  */
44 
45 /** Timeout for autoexec script downloads */
46 #define EFI_AUTOEXEC_TIMEOUT ( 2 * TICKS_PER_SEC )
47 
48 /** Autoexec script image name */
49 #define EFI_AUTOEXEC_NAME "autoexec.ipxe"
50 
51 /** An EFI autoexec script loader */
53  /** Required protocol GUID */
55  /**
56  * Load autoexec script
57  *
58  * @v handle Handle on which protocol was found
59  * @v image Image to fill in
60  * @ret rc Return status code
61  */
62  int ( * load ) ( EFI_HANDLE handle, struct image **image );
63 };
64 
65 /**
66  * Load autoexec script from filesystem
67  *
68  * @v handle Simple filesystem protocol handle
69  * @v image Image to fill in
70  * @ret rc Return status code
71  */
74  int rc;
75 
76  /* Check that we were loaded from a filesystem */
77  if ( handle != device ) {
78  DBGC ( device, "EFI %s is not the file system handle\n",
79  efi_handle_name ( device ) );
80  return -ENOTTY;
81  }
82 
83  /* Try loading from loaded image directory, if supported */
84  if ( ( rc = imgacquire ( "file:" EFI_AUTOEXEC_NAME,
85  EFI_AUTOEXEC_TIMEOUT, image ) ) == 0 )
86  return 0;
87 
88  /* Try loading from root directory, if supported */
89  if ( ( rc = imgacquire ( "file:/" EFI_AUTOEXEC_NAME,
90  EFI_AUTOEXEC_TIMEOUT, image ) ) == 0 )
91  return 0;
92 
93  return rc;
94 }
95 
96 /**
97  * Load autoexec script via temporary network device
98  *
99  * @v handle Managed network protocol service binding handle
100  * @v image Image to fill in
101  * @ret rc Return status code
102  */
105  struct net_device *netdev;
106  int rc;
107 
108  /* Create temporary network device */
109  if ( ( rc = mnptemp_create ( handle, &netdev ) ) != 0 ) {
110  DBGC ( device, "EFI %s could not create net device: %s\n",
111  efi_handle_name ( device ), strerror ( rc ) );
112  goto err_create;
113  }
114 
115  /* Do nothing unless we have a usable current working URI */
116  if ( ! cwuri ) {
117  DBGC ( device, "EFI %s has no current working URI\n",
118  efi_handle_name ( device ) );
119  rc = -ENOTTY;
120  goto err_cwuri;
121  }
122 
123  /* Open network device */
124  if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
125  DBGC ( device, "EFI %s could not open net device: %s\n",
126  efi_handle_name ( device ), strerror ( rc ) );
127  goto err_open;
128  }
129 
130  /* Attempt download */
132  if ( rc != 0 ) {
133  DBGC ( device, "EFI %s could not download %s: %s\n",
135  strerror ( rc ) );
136  }
137 
138  /* Ensure network exchanges have completed */
140 
141  err_open:
142  err_cwuri:
144  err_create:
145  return rc;
146 }
147 
148 /** Autoexec script loaders */
150  {
152  .load = efi_autoexec_filesystem,
153  },
154  {
156  .load = efi_autoexec_network,
157  },
158 };
159 
160 /**
161  * Load autoexec script
162  *
163  * @ret rc Return status code
164  */
165 int efi_autoexec_load ( void ) {
168  struct efi_autoexec_loader *loader;
169  struct image *image;
170  unsigned int i;
171  int rc;
172 
173  /* Use first applicable loader */
174  for ( i = 0 ; i < ( sizeof ( efi_autoexec_loaders ) /
175  sizeof ( efi_autoexec_loaders[0] ) ) ; i ++ ) {
176 
177  /* Locate required protocol for this loader */
178  loader = &efi_autoexec_loaders[i];
179  if ( ( rc = efi_locate_device ( device, loader->protocol,
180  &handle, 0 ) ) != 0 ) {
181  DBGC ( device, "EFI %s found no %s: %s\n",
183  efi_guid_ntoa ( loader->protocol ),
184  strerror ( rc ) );
185  continue;
186  }
187  DBGC ( device, "EFI %s found %s on ",
189  efi_guid_ntoa ( loader->protocol ) );
190  DBGC ( device, "%s\n", efi_handle_name ( handle ) );
191 
192  /* Try loading */
193  if ( ( rc = loader->load ( handle, &image ) ) != 0 )
194  return rc;
195 
196  /* Discard zero-length images */
197  if ( ! image->len ) {
198  DBGC ( device, "EFI %s discarding zero-length %s\n",
201  return -ENOENT;
202  }
203 
204  DBGC ( device, "EFI %s loaded %s (%zd bytes)\n",
206  return 0;
207  }
208 
209  return -ENOENT;
210 }
EFI_LOADED_IMAGE_PROTOCOL * efi_loaded_image
Loaded image protocol for this image.
Definition: efi_init.c:37
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
128 bit buffer containing a unique identifier value.
Definition: Base.h:215
Error codes.
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
iPXE timers
An executable image.
Definition: image.h:24
EFI_GUID efi_managed_network_service_binding_protocol_guid
Managed network service binding protocol GUID.
Definition: efi_guid.c:255
Uniform Resource Identifiers.
#define EFI_AUTOEXEC_TIMEOUT
Timeout for autoexec script downloads.
Definition: efi_autoexec.c:46
static int efi_autoexec_filesystem(EFI_HANDLE handle, struct image **image)
Load autoexec script from filesystem.
Definition: efi_autoexec.c:72
int efi_autoexec_load(void)
Load autoexec script.
Definition: efi_autoexec.c:165
EFI utilities.
EFI_GUID * protocol
Required protocol GUID.
Definition: efi_autoexec.c:54
A hardware device.
Definition: device.h:73
#define EFI_AUTOEXEC_NAME
Autoexec script image name.
Definition: efi_autoexec.c:49
void mnptemp_destroy(struct net_device *netdev)
Destroy temporary MNP network device.
Definition: mnpnet.c:551
int sync(unsigned long timeout)
Wait for pending operations to complete.
Definition: sync.c:73
Executable images.
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition: efi_guid.c:303
static struct net_device * netdev
Definition: gdbudp.c:52
static int efi_autoexec_network(EFI_HANDLE handle, struct image **image)
Load autoexec script via temporary network device.
Definition: efi_autoexec.c:103
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition: efi_debug.c:254
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
size_t len
Length of raw file image.
Definition: image.h:43
A network device.
Definition: netdevice.h:352
static struct efi_autoexec_loader efi_autoexec_loaders[]
Autoexec script loaders.
Definition: efi_autoexec.c:149
MNP NIC driver.
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:45
EFI API.
int mnptemp_create(EFI_HANDLE handle, struct net_device **netdev)
Create temporary MNP network device.
Definition: mnpnet.c:514
Network device management.
void unregister_image(struct image *image)
Unregister executable image.
Definition: image.c:303
int(* load)(EFI_HANDLE handle, struct image **image)
Load autoexec script.
Definition: efi_autoexec.c:62
Image management.
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
Wait for pending operations to complete.
EFI autoexec script.
struct uri * cwuri
Current working URI.
Definition: cwuri.c:38
uint16_t handle
Handle.
Definition: smbios.h:16
char * name
Name.
Definition: image.h:34
An EFI autoexec script loader.
Definition: efi_autoexec.c:52
String functions.
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:861
int imgacquire(const char *name_uri, unsigned long timeout, struct image **image)
Acquire an image.
Definition: imgmgmt.c:141
Definition: efi.h:59
EFI_HANDLE DeviceHandle
The device handle that the EFI Image was loaded from.
Definition: LoadedImage.h:55