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/image.h>
29 #include <ipxe/init.h>
30 #include <ipxe/efi/efi.h>
31 #include <ipxe/efi/efi_autoexec.h>
33 #include <ipxe/efi/Guid/FileInfo.h>
34 
35 /** @file
36  *
37  * EFI autoexec script
38  *
39  */
40 
41 /** Autoexec script filename */
42 #define AUTOEXEC_FILENAME L"autoexec.ipxe"
43 
44 /** Autoexec script image name */
45 #define AUTOEXEC_NAME "autoexec.ipxe"
46 
47 /** Autoexec script (if any) */
48 static void *efi_autoexec;
49 
50 /** Autoexec script length */
51 static size_t efi_autoexec_len;
52 
53 /**
54  * Load autoexec script
55  *
56  * @v device Device handle
57  * @ret rc Return status code
58  */
61  static wchar_t name[] = AUTOEXEC_FILENAME;
62  union {
63  void *interface;
65  } u;
66  struct {
68  CHAR16 name[ sizeof ( name ) / sizeof ( name[0] ) ];
69  } info;
71  EFI_FILE_PROTOCOL *file;
72  UINTN size;
73  VOID *data;
74  EFI_STATUS efirc;
75  int rc;
76 
77  /* Sanity check */
78  assert ( efi_autoexec == NULL );
79  assert ( efi_autoexec_len == 0 );
80 
81  /* Open simple file system protocol */
82  if ( ( efirc = bs->OpenProtocol ( device,
84  &u.interface, efi_image_handle,
85  device,
87  rc = -EEFI ( efirc );
88  DBGC ( device, "EFI %s has no filesystem instance: %s\n",
89  efi_handle_name ( device ), strerror ( rc ) );
90  goto err_filesystem;
91  }
92 
93  /* Open root directory */
94  if ( ( efirc = u.fs->OpenVolume ( u.fs, &root ) ) != 0 ) {
95  rc = -EEFI ( efirc );
96  DBGC ( device, "EFI %s could not open volume: %s\n",
97  efi_handle_name ( device ), strerror ( rc ) );
98  goto err_volume;
99  }
100 
101  /* Open autoexec script */
102  if ( ( efirc = root->Open ( root, &file, name,
103  EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
104  rc = -EEFI ( efirc );
105  DBGC ( device, "EFI %s has no %ls: %s\n",
106  efi_handle_name ( device ), name, strerror ( rc ) );
107  goto err_open;
108  }
109 
110  /* Get file information */
111  size = sizeof ( info );
112  if ( ( efirc = file->GetInfo ( file, &efi_file_info_id, &size,
113  &info ) ) != 0 ) {
114  rc = -EEFI ( efirc );
115  DBGC ( device, "EFI %s could not get %ls info: %s\n",
116  efi_handle_name ( device ), name, strerror ( rc ) );
117  goto err_getinfo;
118  }
119  size = info.info.FileSize;
120 
121  /* Ignore zero-length files */
122  if ( ! size ) {
123  rc = -EINVAL;
124  DBGC ( device, "EFI %s has zero-length %ls\n",
125  efi_handle_name ( device ), name );
126  goto err_empty;
127  }
128 
129  /* Allocate temporary copy */
130  if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, size,
131  &data ) ) != 0 ) {
132  rc = -EEFI ( efirc );
133  DBGC ( device, "EFI %s could not allocate %ls: %s\n",
134  efi_handle_name ( device ), name, strerror ( rc ) );
135  goto err_alloc;
136  }
137 
138  /* Read file */
139  if ( ( efirc = file->Read ( file, &size, data ) ) != 0 ) {
140  rc = -EEFI ( efirc );
141  DBGC ( device, "EFI %s could not read %ls: %s\n",
142  efi_handle_name ( device ), name, strerror ( rc ) );
143  goto err_read;
144  }
145 
146  /* Record autoexec script */
147  efi_autoexec = data;
149  data = NULL;
150  DBGC ( device, "EFI %s found %ls\n",
151  efi_handle_name ( device ), name );
152 
153  /* Success */
154  rc = 0;
155 
156  err_read:
157  if ( data )
158  bs->FreePool ( data );
159  err_alloc:
160  err_empty:
161  err_getinfo:
162  file->Close ( file );
163  err_open:
164  root->Close ( root );
165  err_volume:
168  err_filesystem:
169  return rc;
170 }
171 
172 /**
173  * Register autoexec script
174  *
175  */
176 static void efi_autoexec_startup ( void ) {
179  const char *name = AUTOEXEC_NAME;
180  struct image *image;
181 
182  /* Do nothing if we have no autoexec script */
183  if ( ! efi_autoexec )
184  return;
185 
186  /* Create autoexec image */
189  if ( ! image ) {
190  DBGC ( device, "EFI %s could not create %s\n",
191  efi_handle_name ( device ), name );
192  return;
193  }
194  DBGC ( device, "EFI %s registered %s\n",
195  efi_handle_name ( device ), name );
196 
197  /* Free temporary copy */
198  bs->FreePool ( efi_autoexec );
199  efi_autoexec = NULL;
200 }
201 
202 /** Autoexec script startup function */
203 struct startup_fn efi_autoexec_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
204  .name = "efi_autoexec",
205  .startup = efi_autoexec_startup,
206 };
static size_t efi_autoexec_len
Autoexec script length.
Definition: efi_autoexec.c:51
EFI_FILE_CLOSE Close
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define STARTUP_NORMAL
Normal startup.
Definition: init.h:63
EFI_LOADED_IMAGE_PROTOCOL * efi_loaded_image
Loaded image protocol for this image.
Definition: efi_init.c:36
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:162
u32 info
Definition: ar9003_mac.h:67
struct stp_switch root
Root switch.
Definition: stp.h:26
Error codes.
#define AUTOEXEC_NAME
Autoexec script image name.
Definition: efi_autoexec.c:45
#define DBGC(...)
Definition: compiler.h:505
EFI_FILE_GET_INFO GetInfo
struct image * image_memory(const char *name, userptr_t data, size_t len)
Create registered image from block of memory.
Definition: image.c:534
unsigned short CHAR16
Definition: ProcessorBind.h:59
struct startup_fn efi_autoexec_startup_fn __startup_fn(STARTUP_NORMAL)
Autoexec script startup function.
An executable image.
Definition: image.h:24
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1906
const char * name
Definition: init.h:42
A startup/shutdown function.
Definition: init.h:41
A hardware device.
Definition: device.h:73
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
An object interface.
Definition: interface.h:124
SimpleFileSystem protocol as defined in the UEFI 2.0 specification.
Executable images.
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition: efi_guid.c:232
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL
Definition: UefiSpec.h:1271
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:722
uint32_t fs
Definition: librm.h:252
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1836
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:33
UINT64 UINTN
Unsigned value of native width.
Definition: ProcessorBind.h:71
#define VOID
Undeclared type.
Definition: Base.h:319
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1855
Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.SetInfo() and EFI_FILE_P...
static void efi_autoexec_startup(void)
Register autoexec script.
Definition: efi_autoexec.c:176
EFI API.
EFI_GUID efi_file_info_id
File information GUID.
Definition: efi_guid.c:303
#define EFI_FILE_MODE_READ
EFI autoexec script.
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
static void * efi_autoexec
Autoexec script (if any)
Definition: efi_autoexec.c:48
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
union @17 u
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
#define AUTOEXEC_FILENAME
Autoexec script filename.
Definition: efi_autoexec.c:42
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1905
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
The data portions of a loaded Boot Serves Driver, and the default data allocation type used by a Boot...
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
String functions.
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
Definition: efi.h:50
EFI_HANDLE DeviceHandle
The device handle that the EFI Image was loaded from.
Definition: LoadedImage.h:61
EFI_ALLOCATE_POOL AllocatePool
Definition: UefiSpec.h:1854
int efi_autoexec_load(EFI_HANDLE device)
Load autoexec script.
Definition: efi_autoexec.c:59