iPXE
efi_block.c File Reference

EFI block device protocols. More...

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <ipxe/refcnt.h>
#include <ipxe/list.h>
#include <ipxe/uri.h>
#include <ipxe/interface.h>
#include <ipxe/blockdev.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/retry.h>
#include <ipxe/timer.h>
#include <ipxe/process.h>
#include <ipxe/sanboot.h>
#include <ipxe/iso9660.h>
#include <ipxe/acpi.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/BlockIo.h>
#include <ipxe/efi/Protocol/SimpleFileSystem.h>
#include <ipxe/efi/Protocol/AcpiTable.h>
#include <ipxe/efi/Guid/FileSystemInfo.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_strings.h>
#include <ipxe/efi/efi_snp.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/efi/efi_null.h>
#include <ipxe/efi/efi_wrap.h>
#include <ipxe/efi/efi_block.h>

Go to the source code of this file.

Data Structures

struct  efi_block_data
 EFI SAN device private data. More...
struct  efi_acpi_table
 An installed ACPI table. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
 EFI_REQUEST_PROTOCOL (EFI_ACPI_TABLE_PROTOCOL, &acpi)
static int efi_block_rw (struct san_device *sandev, uint64_t lba, void *data, size_t len, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer))
 Read from or write to EFI block device.
static EFI_STATUS EFIAPI efi_block_io_reset (EFI_BLOCK_IO_PROTOCOL *block_io, BOOLEAN verify __unused)
 Reset EFI block device.
static EFI_STATUS EFIAPI efi_block_io_read (EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused, EFI_LBA lba, UINTN len, VOID *data)
 Read from EFI block device.
static EFI_STATUS EFIAPI efi_block_io_write (EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused, EFI_LBA lba, UINTN len, VOID *data)
 Write to EFI block device.
static EFI_STATUS EFIAPI efi_block_io_flush (EFI_BLOCK_IO_PROTOCOL *block_io)
 Flush data to EFI block device.
static void efi_block_connect (unsigned int drive, EFI_HANDLE handle)
 Connect all possible drivers to EFI block device.
static int efi_block_hook (unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
 Hook EFI block device.
static void efi_block_unhook (unsigned int drive)
 Unhook EFI block device.
static LIST_HEAD (efi_acpi_tables)
 List of installed ACPI tables.
static int efi_block_install (struct acpi_header *hdr)
 Install ACPI table.
static int efi_block_describe (void)
 Describe EFI block devices.
static int efi_block_root (unsigned int drive, EFI_HANDLE handle, EFI_FILE_PROTOCOL **root)
 Open root directory within a filesystem.
static int efi_block_filename (unsigned int drive, EFI_HANDLE handle, EFI_FILE_PROTOCOL *root, const char *filename)
 Check for existence of a file within a filesystem.
static int efi_block_label (unsigned int drive, EFI_FILE_PROTOCOL *root, const char *label)
 Check for EFI block device filesystem label.
static int efi_block_match (unsigned int drive, EFI_HANDLE handle, EFI_DEVICE_PATH_PROTOCOL *path, struct san_boot_config *config, EFI_DEVICE_PATH_PROTOCOL **fspath)
 Check EFI block device filesystem match.
static int efi_block_scan (unsigned int drive, EFI_HANDLE handle, struct san_boot_config *config, EFI_DEVICE_PATH_PROTOCOL **fspath)
 Scan EFI block device for a matching filesystem.
static int efi_block_exec (unsigned int drive, EFI_DEVICE_PATH_PROTOCOL *fspath, const char *filename)
 Boot from EFI block device filesystem boot image.
static int efi_block_local (EFI_HANDLE handle)
 Check that EFI block device is eligible for a local virtual drive number.
static int efi_block_boot (unsigned int drive, struct san_boot_config *config)
 Boot from EFI block device.
 PROVIDE_SANBOOT (efi, san_hook, efi_block_hook)
 PROVIDE_SANBOOT (efi, san_unhook, efi_block_unhook)
 PROVIDE_SANBOOT (efi, san_describe, efi_block_describe)
 PROVIDE_SANBOOT (efi, san_boot, efi_block_boot)

Variables

static EFI_ACPI_TABLE_PROTOCOLacpi
 ACPI table protocol protocol.
static wchar_t efi_block_boot_filename [] = EFI_REMOVABLE_MEDIA_FILE_NAME
 Boot filename.

Detailed Description

EFI block device protocols.

Definition in file efi_block.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ EFI_REQUEST_PROTOCOL()

EFI_REQUEST_PROTOCOL ( EFI_ACPI_TABLE_PROTOCOL ,
& acpi )

References acpi.

◆ efi_block_rw()

int efi_block_rw ( struct san_device * sandev,
uint64_t lba,
void * data,
size_t len,
int(* sandev_rw )(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer) )
static

Read from or write to EFI block device.

Parameters
sandevSAN device
lbaStarting LBA
dataData buffer
lenSize of buffer
sandev_rwSAN device read/write method
Return values
rcReturn status code

Definition at line 97 of file efi_block.c.

102 {
103 struct efi_block_data *block = sandev->priv;
104 unsigned int count;
105 int rc;
106
107 /* Sanity check */
108 count = ( len / block->media.BlockSize );
109 if ( ( count * block->media.BlockSize ) != len ) {
110 DBGC ( sandev->drive, "EFIBLK %#02x impossible length %#zx\n",
111 sandev->drive, len );
112 return -EINVAL;
113 }
114
115 /* Read from / write to block device */
116 if ( ( rc = sandev_rw ( sandev, lba, count, data ) ) != 0 ) {
117 DBGC ( sandev->drive, "EFIBLK %#02x I/O failed: %s\n",
118 sandev->drive, strerror ( rc ) );
119 return rc;
120 }
121
122 return 0;
123}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC(...)
Definition compiler.h:505
static unsigned int count
Number of entries.
Definition dwmac.h:220
uint64_t lba
Starting block number.
Definition int13.h:11
#define EINVAL
Invalid argument.
Definition errno.h:429
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
static int sandev_rw(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len))
Read from or write to SAN device.
Definition sanboot.c:598
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
EFI SAN device private data.
Definition efi_block.c:74
struct san_device * sandev
SAN device.
Definition efi_block.c:76
void * priv
Driver private data.
Definition sanboot.h:90
unsigned int drive
Drive number.
Definition sanboot.h:66

References block, buffer, count, data, DBGC, san_device::drive, EINVAL, lba, len, san_device::priv, rc, efi_block_data::sandev, sandev_rw(), and strerror().

Referenced by efi_block_io_read(), and efi_block_io_write().

◆ efi_block_io_reset()

EFI_STATUS EFIAPI efi_block_io_reset ( EFI_BLOCK_IO_PROTOCOL * block_io,
BOOLEAN verify __unused )
static

Reset EFI block device.

Parameters
block_ioBlock I/O protocol
verifyPerform extended verification
Return values
efircEFI status code

Definition at line 132 of file efi_block.c.

133 {
134 struct efi_block_data *block =
136 struct san_device *sandev = block->sandev;
137 int rc;
138
139 DBGC2 ( sandev->drive, "EFIBLK %#02x reset\n", sandev->drive );
141 rc = sandev_reset ( sandev );
143 return EFIRC ( rc );
144}
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition efi_snp.h:92
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition efi_snp.h:100
#define DBGC2(...)
Definition compiler.h:522
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition efi.h:167
int sandev_reset(struct san_device *sandev)
Reset SAN device.
Definition sanboot.c:576
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition efi_block.c:82
A SAN device.
Definition sanboot.h:59

References __unused, block, efi_block_data::block_io, container_of, DBGC2, san_device::drive, efi_snp_claim(), efi_snp_release(), EFIAPI, EFIRC, rc, and sandev_reset().

Referenced by efi_block_hook().

◆ efi_block_io_read()

EFI_STATUS EFIAPI efi_block_io_read ( EFI_BLOCK_IO_PROTOCOL * block_io,
UINT32 media __unused,
EFI_LBA lba,
UINTN len,
VOID * data )
static

Read from EFI block device.

Parameters
block_ioBlock I/O protocol
mediaMedia identifier
lbaStarting LBA
lenSize of buffer
dataData buffer
Return values
efircEFI status code

Definition at line 157 of file efi_block.c.

158 {
159 struct efi_block_data *block =
161 struct san_device *sandev = block->sandev;
162 int rc;
163
164 DBGC2 ( sandev->drive, "EFIBLK %#02x read LBA %#08llx to %p+%#08zx\n",
165 sandev->drive, lba, data, ( ( size_t ) len ) );
167 rc = efi_block_rw ( sandev, lba, data, len, sandev_read );
169 return EFIRC ( rc );
170}
static int efi_block_rw(struct san_device *sandev, uint64_t lba, void *data, size_t len, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer))
Read from or write to EFI block device.
Definition efi_block.c:97
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
Read from SAN device.
Definition sanboot.c:647

References __unused, block, efi_block_data::block_io, container_of, data, DBGC2, san_device::drive, efi_block_rw(), efi_snp_claim(), efi_snp_release(), EFIRC, lba, len, media, rc, sandev_read(), and VOID.

Referenced by efi_block_hook().

◆ efi_block_io_write()

EFI_STATUS EFIAPI efi_block_io_write ( EFI_BLOCK_IO_PROTOCOL * block_io,
UINT32 media __unused,
EFI_LBA lba,
UINTN len,
VOID * data )
static

Write to EFI block device.

Parameters
block_ioBlock I/O protocol
mediaMedia identifier
lbaStarting LBA
lenSize of buffer
dataData buffer
Return values
efircEFI status code

Definition at line 183 of file efi_block.c.

184 {
185 struct efi_block_data *block =
187 struct san_device *sandev = block->sandev;
188 int rc;
189
190 DBGC2 ( sandev->drive, "EFIBLK %#02x write LBA %#08llx from "
191 "%p+%#08zx\n", sandev->drive, lba, data, ( ( size_t ) len ) );
193 rc = efi_block_rw ( sandev, lba, data, len, sandev_write );
195 return EFIRC ( rc );
196}
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
Write to SAN device.
Definition sanboot.c:668

References __unused, block, efi_block_data::block_io, container_of, data, DBGC2, san_device::drive, efi_block_rw(), efi_snp_claim(), efi_snp_release(), EFIRC, lba, len, media, rc, sandev_write(), and VOID.

Referenced by efi_block_hook().

◆ efi_block_io_flush()

EFI_STATUS EFIAPI efi_block_io_flush ( EFI_BLOCK_IO_PROTOCOL * block_io)
static

Flush data to EFI block device.

Parameters
block_ioBlock I/O protocol
Return values
efircEFI status code

Definition at line 205 of file efi_block.c.

205 {
206 struct efi_block_data *block =
208 struct san_device *sandev = block->sandev;
209
210 DBGC2 ( sandev->drive, "EFIBLK %#02x flush\n", sandev->drive );
211
212 /* Nothing to do */
213 return 0;
214}

References block, efi_block_data::block_io, container_of, DBGC2, and san_device::drive.

Referenced by efi_block_hook().

◆ efi_block_connect()

void efi_block_connect ( unsigned int drive,
EFI_HANDLE handle )
static

Connect all possible drivers to EFI block device.

Parameters
driveDrive number
handleBlock device handle

Definition at line 222 of file efi_block.c.

222 {
223 int rc;
224
225 /* Try to connect all possible drivers to this block device */
226 if ( ( rc = efi_connect ( handle, NULL ) ) != 0 ) {
227 DBGC ( drive, "EFIBLK %#02x could not connect drivers: %s\n",
228 drive, strerror ( rc ) );
229 /* May not be an error; may already be connected */
230 }
231 DBGC2 ( drive, "EFIBLK %#02x supports protocols:\n", drive );
233}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
int efi_connect(EFI_HANDLE device, EFI_HANDLE driver)
Connect UEFI driver(s)
Definition efi_connect.c:58
uint8_t drive
Drive number.
Definition int13.h:5
#define DBGC2_EFI_PROTOCOLS(...)
Definition efi.h:358
uint16_t handle
Handle.
Definition smbios.h:5

References DBGC, DBGC2, DBGC2_EFI_PROTOCOLS, drive, efi_connect(), EFI_HANDLE, handle, NULL, rc, and strerror().

Referenced by efi_block_hook(), and efi_block_scan().

◆ efi_block_hook()

int efi_block_hook ( unsigned int drive,
struct uri ** uris,
unsigned int count,
unsigned int flags )
static

Hook EFI block device.

Parameters
driveDrive number
urisList of URIs
countNumber of URIs
flagsFlags
Return values
driveDrive number, or negative error

Definition at line 244 of file efi_block.c.

245 {
246 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
247 struct san_device *sandev;
248 struct efi_block_data *block;
249 int leak = 0;
250 EFI_STATUS efirc;
251 int rc;
252
253 /* Sanity check */
254 if ( ! count ) {
255 DBGC ( drive, "EFIBLK %#02x has no URIs\n", drive );
256 rc = -ENOTTY;
257 goto err_no_uris;
258 }
259
260 /* Allocate and initialise structure */
261 sandev = alloc_sandev ( uris, count, sizeof ( *block ) );
262 if ( ! sandev ) {
263 rc = -ENOMEM;
264 goto err_alloc;
265 }
266 block = sandev->priv;
267 block->sandev = sandev;
268 block->media.MediaPresent = 1;
269 block->media.LogicalBlocksPerPhysicalBlock = 1;
270 block->block_io.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
271 block->block_io.Media = &block->media;
272 block->block_io.Reset = efi_block_io_reset;
273 block->block_io.ReadBlocks = efi_block_io_read;
274 block->block_io.WriteBlocks = efi_block_io_write;
275 block->block_io.FlushBlocks = efi_block_io_flush;
276
277 /* Register SAN device */
278 if ( ( rc = register_sandev ( sandev, drive, flags ) ) != 0 ) {
279 DBGC ( drive, "EFIBLK %#02x could not register: %s\n",
280 drive, strerror ( rc ) );
281 goto err_register;
282 }
283
284 /* Update media descriptor */
285 block->media.BlockSize =
287 block->media.LastBlock =
288 ( ( sandev->capacity.blocks >> sandev->blksize_shift ) - 1 );
289
290 /* Construct device path */
291 if ( ! sandev->active ) {
292 rc = -ENODEV;
293 DBGC ( drive, "EFIBLK %#02x not active after registration\n",
294 drive );
295 goto err_active;
296 }
297 block->path = efi_describe ( &sandev->active->block );
298 if ( ! block->path ) {
299 rc = -ENODEV;
300 DBGC ( drive, "EFIBLK %#02x has no device path\n", drive );
301 goto err_describe;
302 }
303 DBGC2 ( drive, "EFIBLK %#02x has device path %s\n",
304 drive, efi_devpath_text ( block->path ) );
305
306 /* Install protocols */
307 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
308 &block->handle,
311 NULL ) ) != 0 ) {
312 rc = -EEFI ( efirc );
313 DBGC ( drive, "EFIBLK %#02x could not install protocols: %s\n",
314 drive, strerror ( rc ) );
315 goto err_install;
316 }
317 DBGC ( drive, "EFIBLK %#02x installed as SAN drive %s\n",
318 drive, efi_handle_name ( block->handle ) );
319
320 /* Connect all possible protocols */
321 efi_block_connect ( drive, block->handle );
322
323 return drive;
324
325 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
326 block->handle,
329 NULL ) ) != 0 ) {
330 DBGC ( drive, "EFIBLK %#02x could not uninstall protocols: "
331 "%s\n", drive, strerror ( -EEFI ( efirc ) ) );
332 leak = 1;
333 }
334 efi_nullify_block ( &block->block_io );
335 err_install:
336 if ( ! leak ) {
337 free ( block->path );
338 block->path = NULL;
339 }
340 err_describe:
341 err_active:
343 err_register:
344 if ( ! leak )
345 sandev_put ( sandev );
346 err_alloc:
347 err_no_uris:
348 if ( leak )
349 DBGC ( drive, "EFIBLK %#02x nullified and leaked\n", drive );
350 return rc;
351}
#define EFI_BLOCK_IO_PROTOCOL_REVISION3
Definition BlockIo.h:207
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
static EFI_STATUS EFIAPI efi_block_io_reset(EFI_BLOCK_IO_PROTOCOL *block_io, BOOLEAN verify __unused)
Reset EFI block device.
Definition efi_block.c:132
static void efi_block_connect(unsigned int drive, EFI_HANDLE handle)
Connect all possible drivers to EFI block device.
Definition efi_block.c:222
static EFI_STATUS EFIAPI efi_block_io_write(EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused, EFI_LBA lba, UINTN len, VOID *data)
Write to EFI block device.
Definition efi_block.c:183
static EFI_STATUS EFIAPI efi_block_io_flush(EFI_BLOCK_IO_PROTOCOL *block_io)
Flush data to EFI block device.
Definition efi_block.c:205
static EFI_STATUS EFIAPI efi_block_io_read(EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused, EFI_LBA lba, UINTN len, VOID *data)
Read from EFI block device.
Definition efi_block.c:157
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition efi_debug.c:247
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
Definition efi_guid.c:145
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition efi_guid.c:169
void efi_nullify_block(EFI_BLOCK_IO_PROTOCOL *block)
Nullify block I/O protocol.
Definition efi_null.c:397
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition efi_path.c:920
uint8_t flags
Flags.
Definition ena.h:7
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENODEV
No such device.
Definition errno.h:510
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
EFI_SYSTEM_TABLE * efi_systab
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
Definition sanboot.h:226
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
int register_sandev(struct san_device *sandev, unsigned int drive, unsigned int flags)
Register SAN device.
Definition sanboot.c:880
void unregister_sandev(struct san_device *sandev)
Unregister SAN device.
Definition sanboot.c:942
struct san_device * alloc_sandev(struct uri **uris, unsigned int count, size_t priv_size)
Allocate SAN device.
Definition sanboot.c:837
EFI Boot Services Table.
Definition UefiSpec.h:1931
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition UefiSpec.h:2011
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition UefiSpec.h:2010
uint64_t blocks
Total number of blocks.
Definition blockdev.h:20
size_t blksize
Block size.
Definition blockdev.h:22
struct san_path * active
Current active path.
Definition sanboot.h:95
unsigned int blksize_shift
Block size shift.
Definition sanboot.h:85
struct block_device_capacity capacity
Raw block device capacity.
Definition sanboot.h:78
struct interface block
Underlying block device interface.
Definition sanboot.h:48

References san_device::active, alloc_sandev(), block_device_capacity::blksize, san_device::blksize_shift, block, san_path::block, block_device_capacity::blocks, san_device::capacity, count, DBGC, DBGC2, drive, EEFI, efi_block_connect(), efi_block_io_flush(), efi_block_io_protocol_guid, EFI_BLOCK_IO_PROTOCOL_REVISION3, efi_block_io_read(), efi_block_io_reset(), efi_block_io_write(), efi_describe(), efi_device_path_protocol_guid, efi_devpath_text(), efi_handle_name(), efi_nullify_block(), efi_systab, ENODEV, ENOMEM, ENOTTY, flags, free, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, NULL, san_device::priv, rc, register_sandev(), efi_block_data::sandev, sandev_put(), strerror(), EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, and unregister_sandev().

Referenced by PROVIDE_SANBOOT().

◆ efi_block_unhook()

void efi_block_unhook ( unsigned int drive)
static

Unhook EFI block device.

Parameters
driveDrive number

Definition at line 358 of file efi_block.c.

358 {
359 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
360 struct san_device *sandev;
361 struct efi_block_data *block;
362 int leak = efi_shutdown_in_progress;
363 EFI_STATUS efirc;
364
365 /* Find SAN device */
367 if ( ! sandev ) {
368 DBGC ( drive, "EFIBLK %#02x is not a SAN drive\n", drive );
369 return;
370 }
371 block = sandev->priv;
372
373 /* Uninstall protocols */
374 if ( ( ! efi_shutdown_in_progress ) &&
376 block->handle,
379 NULL ) ) != 0 ) ) {
380 DBGC ( drive, "EFIBLK %#02x could not uninstall protocols: "
381 "%s\n", drive, strerror ( -EEFI ( efirc ) ) );
382 leak = 1;
383 }
384 efi_nullify_block ( &block->block_io );
385
386 /* Free device path */
387 if ( ! leak ) {
388 free ( block->path );
389 block->path = NULL;
390 }
391
392 /* Unregister SAN device */
394
395 /* Drop reference to drive */
396 if ( ! leak )
397 sandev_put ( sandev );
398
399 /* Report leakage, if applicable */
400 if ( leak && ( ! efi_shutdown_in_progress ) )
401 DBGC ( drive, "EFIBLK %#02x nullified and leaked\n", drive );
402}
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition efi_init.c:60
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition sanboot.c:92

References block, DBGC, drive, EEFI, efi_block_io_protocol_guid, efi_device_path_protocol_guid, efi_nullify_block(), efi_shutdown_in_progress, efi_systab, free, NULL, san_device::priv, efi_block_data::sandev, sandev_find(), sandev_put(), strerror(), EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, and unregister_sandev().

Referenced by PROVIDE_SANBOOT().

◆ LIST_HEAD()

LIST_HEAD ( efi_acpi_tables )
static

List of installed ACPI tables.

◆ efi_block_install()

int efi_block_install ( struct acpi_header * hdr)
static

Install ACPI table.

Parameters
hdrACPI description header
Return values
rcReturn status code

Definition at line 421 of file efi_block.c.

421 {
422 size_t len = le32_to_cpu ( hdr->length );
423 struct efi_acpi_table *installed;
424 EFI_STATUS efirc;
425 int rc;
426
427 /* Allocate installed table record */
428 installed = zalloc ( sizeof ( *installed ) );
429 if ( ! installed ) {
430 rc = -ENOMEM;
431 goto err_alloc;
432 }
433
434 /* Fill in common parameters */
435 strncpy ( hdr->oem_id, "FENSYS", sizeof ( hdr->oem_id ) );
436 strncpy ( hdr->oem_table_id, "iPXE", sizeof ( hdr->oem_table_id ) );
437
438 /* Fix up ACPI checksum */
440
441 /* Install table */
442 if ( ( efirc = acpi->InstallAcpiTable ( acpi, hdr, len,
443 &installed->key ) ) != 0 ){
444 rc = -EEFI ( efirc );
445 DBGC ( acpi, "EFIBLK could not install %s: %s\n",
446 acpi_name ( hdr->signature ), strerror ( rc ) );
447 DBGC2_HDA ( acpi, 0, hdr, len );
448 goto err_install;
449 }
450
451 /* Add to list of installed tables */
452 list_add_tail ( &installed->list, &efi_acpi_tables );
453
454 DBGC ( acpi, "EFIBLK installed %s as ACPI table %#lx\n",
455 acpi_name ( hdr->signature ),
456 ( ( unsigned long ) installed->key ) );
457 DBGC2_HDA ( acpi, 0, hdr, len );
458 return 0;
459
460 list_del ( &installed->list );
461 err_install:
462 free ( installed );
463 err_alloc:
464 return rc;
465}
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
void acpi_fix_checksum(struct acpi_header *acpi)
Fix up ACPI table checksum.
Definition acpi.c:80
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition efi_block.c:67
#define DBGC2_HDA(...)
Definition compiler.h:523
#define le32_to_cpu(value)
Definition byteswap.h:114
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition acpi.h:207
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
char * strncpy(char *dest, const char *src, size_t max)
Copy string.
Definition string.c:361
An installed ACPI table.
Definition efi_block.c:405
struct list_head list
List of installed tables.
Definition efi_block.c:407
UINTN key
Table key.
Definition efi_block.c:409

References acpi, acpi_fix_checksum(), acpi_name(), DBGC, DBGC2_HDA, EEFI, ENOMEM, free, hdr, efi_acpi_table::key, le32_to_cpu, len, efi_acpi_table::list, list_add_tail, list_del, rc, strerror(), strncpy(), and zalloc().

Referenced by efi_block_describe().

◆ efi_block_describe()

int efi_block_describe ( void )
static

Describe EFI block devices.

Return values
rcReturn status code

Definition at line 472 of file efi_block.c.

472 {
473 struct efi_acpi_table *installed;
474 struct efi_acpi_table *tmp;
475 UINTN key;
476 EFI_STATUS efirc;
477 int rc;
478
479 /* Sanity check */
480 if ( ! acpi ) {
481 DBG ( "EFIBLK has no ACPI table protocol\n" );
482 return -ENOTSUP;
483 }
484
485 /* Uninstall any existing ACPI tables */
486 list_for_each_entry_safe ( installed, tmp, &efi_acpi_tables, list ) {
487 key = installed->key;
488 if ( ( efirc = acpi->UninstallAcpiTable ( acpi, key ) ) != 0 ) {
489 rc = -EEFI ( efirc );
490 DBGC ( acpi, "EFIBLK could not uninstall ACPI table "
491 "%#lx: %s\n", ( ( unsigned long ) key ),
492 strerror ( rc ) );
493 /* Continue anyway */
494 }
495 list_del ( &installed->list );
496 free ( installed );
497 }
498
499 /* Install ACPI tables */
500 if ( ( rc = acpi_install ( efi_block_install ) ) != 0 ) {
501 DBGC ( acpi, "EFIBLK could not install ACPI tables: %s\n",
502 strerror ( rc ) );
503 return rc;
504 }
505
506 return 0;
507}
UINT64 UINTN
Unsigned value of native width.
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
int acpi_install(int(*install)(struct acpi_header *acpi))
Install ACPI tables.
Definition acpi.c:344
static int efi_block_install(struct acpi_header *hdr)
Install ACPI table.
Definition efi_block.c:421
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define ENOTSUP
Operation not supported.
Definition errno.h:590
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459

References acpi, acpi_install(), DBG, DBGC, EEFI, efi_block_install(), ENOTSUP, free, efi_acpi_table::key, key, efi_acpi_table::list, list_del, list_for_each_entry_safe, rc, strerror(), and tmp.

Referenced by PROVIDE_SANBOOT().

◆ efi_block_root()

int efi_block_root ( unsigned int drive,
EFI_HANDLE handle,
EFI_FILE_PROTOCOL ** root )
static

Open root directory within a filesystem.

Parameters
driveDrive number
handleFilesystem handle
rootRoot directory file to fill in
Return values
rcReturn status code

Definition at line 517 of file efi_block.c.

518 {
520 EFI_STATUS efirc;
521 int rc;
522
523 /* Open filesystem protocol */
525 &fs ) ) != 0 ) {
526 DBGC ( drive, "EFIBLK %#02x could not open %s filesystem: %s\n",
528 return rc;
529 }
530
531 /* Open root volume */
532 if ( ( efirc = fs->OpenVolume ( fs, root ) ) != 0 ) {
533 rc = -EEFI ( efirc );
534 DBGC ( drive, "EFIBLK %#02x could not open %s root: %s\n",
536 return rc;
537 }
538
539 return 0;
540}
struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition efi_guid.c:337
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition efi.h:444
uint32_t fs
Definition librm.h:3
struct stp_switch root
Root switch.
Definition stp.h:15

References DBGC, drive, EEFI, EFI_HANDLE, efi_handle_name(), efi_open, efi_simple_file_system_protocol_guid, fs, handle, rc, root, and strerror().

Referenced by efi_block_match().

◆ efi_block_filename()

int efi_block_filename ( unsigned int drive,
EFI_HANDLE handle,
EFI_FILE_PROTOCOL * root,
const char * filename )
static

Check for existence of a file within a filesystem.

Parameters
driveDrive number
handleFilesystem handle
rootRoot directory
filenameFilename (or NULL to use default)
Return values
rcReturn status code

Definition at line 551 of file efi_block.c.

553 {
554 CHAR16 tmp[ filename ? ( strlen ( filename ) + 1 /* wNUL */ ) : 0 ];
555 CHAR16 *wname;
556 EFI_FILE_PROTOCOL *file;
557 EFI_STATUS efirc;
558 int rc;
559
560 /* Construct filename */
561 if ( filename ) {
562 efi_snprintf ( tmp, sizeof ( tmp ), "%s", filename );
563 wname = tmp;
564 } else {
566 }
567
568 /* Try opening file */
569 if ( ( efirc = root->Open ( root, &file, wname,
570 EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
571 rc = -EEFI ( efirc );
572 DBGC ( drive, "EFIBLK %#02x could not open %s/%ls: %s\n",
573 drive, efi_handle_name ( handle ), wname,
574 strerror ( rc ) );
575 goto err_file;
576 }
577
578 /* Success */
579 rc = 0;
580
581 file->Close ( file );
582 err_file:
583 return rc;
584}
unsigned short CHAR16
2-byte Character.
struct _EFI_FILE_PROTOCOL EFI_FILE_PROTOCOL
#define EFI_FILE_MODE_READ
static wchar_t efi_block_boot_filename[]
Boot filename.
Definition efi_block.c:71
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
size_t strlen(const char *src)
Get length of string.
Definition string.c:244

References _EFI_FILE_PROTOCOL::Close, DBGC, drive, EEFI, efi_block_boot_filename, EFI_FILE_MODE_READ, EFI_HANDLE, efi_handle_name(), efi_snprintf(), handle, rc, root, strerror(), strlen(), and tmp.

Referenced by efi_block_match().

◆ efi_block_label()

int efi_block_label ( unsigned int drive,
EFI_FILE_PROTOCOL * root,
const char * label )
static

Check for EFI block device filesystem label.

Parameters
driveDrive number
rootRoot directory
labelVolume label
Return values
rcReturn status code

Definition at line 594 of file efi_block.c.

595 {
597 UINTN size;
598 char *actual;
599 EFI_STATUS efirc;
600 int rc;
601
602 /* Get length of file system information */
603 size = 0;
604 root->GetInfo ( root, &efi_file_system_info_id, &size, NULL );
605
606 /* Allocate file system information */
607 info = malloc ( size );
608 if ( ! info ) {
609 rc = -ENOMEM;
610 goto err_alloc_info;
611 }
612
613 /* Get file system information */
614 if ( ( efirc = root->GetInfo ( root, &efi_file_system_info_id, &size,
615 info ) ) != 0 ) {
616 rc = -EEFI ( efirc );
617 DBGC ( drive, "EFIBLK %#02x could not get filesystem info: "
618 "%s\n", drive, strerror ( rc ) );
619 goto err_get_info;
620 }
621
622 /* Construct volume label for comparison */
623 if ( asprintf ( &actual, "%ls", info->VolumeLabel ) < 0 ) {
624 rc = -ENOMEM;
625 goto err_alloc_label;
626 }
627
628 /* Compare volume label */
629 if ( strcasecmp ( label, actual ) != 0 ) {
630 DBGC ( drive, "EFIBLK %#02x has wrong label \"%s\"\n",
631 drive, actual );
632 rc = -ENOENT;
633 goto err_compare;
634 }
635
636 /* Success */
637 rc = 0;
638
639 err_compare:
640 free ( actual );
641 err_alloc_label:
642 err_get_info:
643 free ( info );
644 err_alloc_info:
645 return rc;
646}
u32 info
Definition ar9003_mac.h:0
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition asprintf.c:42
EFI_GUID efi_file_system_info_id
File system information GUID.
Definition efi_guid.c:466
uint16_t size
Buffer size.
Definition dwmac.h:3
#define ENOENT
No such file or directory.
Definition errno.h:515
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition string.c:209
A text label widget.
Definition label.h:16

References asprintf(), DBGC, drive, EEFI, efi_file_system_info_id, ENOENT, ENOMEM, free, info, malloc(), NULL, rc, root, size, strcasecmp(), and strerror().

Referenced by efi_block_match().

◆ efi_block_match()

int efi_block_match ( unsigned int drive,
EFI_HANDLE handle,
EFI_DEVICE_PATH_PROTOCOL * path,
struct san_boot_config * config,
EFI_DEVICE_PATH_PROTOCOL ** fspath )
static

Check EFI block device filesystem match.

Parameters
driveDrive number
handleFilesystem handle
pathBlock device path
configBoot configuration parameters
fspathFilesystem device path to fill in
Return values
rcReturn status code

Definition at line 658 of file efi_block.c.

661 {
662 EFI_FILE *root;
663 union uuid guid;
664 int rc;
665
666 /* Identify device path */
668 fspath ) ) != 0 ) {
669 DBGC ( drive, "EFIBLK %#02x could not open %s device path: "
670 "%s\n", drive, efi_handle_name ( handle ),
671 strerror ( rc ) );
672 goto err_open;
673 }
674
675 /* Check if filesystem is a child of this block device */
676 if ( memcmp ( *fspath, path, efi_path_len ( path ) ) != 0 ) {
677 /* Not a child device */
678 rc = -ENOTTY;
679 DBGC2 ( drive, "EFIBLK %#02x is not parent of %s\n",
681 goto err_not_child;
682 }
683 DBGC ( drive, "EFIBLK %#02x contains filesystem %s\n",
684 drive, efi_devpath_text ( *fspath ) );
685
686 /* Check if filesystem matches GUID, if applicable */
687 if ( config->uuid ) {
688 if ( ( rc = efi_path_guid ( *fspath, &guid ) ) != 0 ) {
689 DBGC ( drive, "EFIBLK %#02x could not determine GUID: "
690 "%s\n", drive, strerror ( rc ) );
691 goto err_no_guid;
692 }
693 if ( memcmp ( config->uuid, &guid, sizeof ( guid ) ) != 0 ) {
694 DBGC ( drive, "EFIBLK %#02x has wrong GUID %s\n",
695 drive, uuid_ntoa ( &guid ) );
696 rc = -ENOENT;
697 goto err_wrong_guid;
698 }
699 }
700
701 /* Open root directory */
702 if ( ( rc = efi_block_root ( drive, handle, &root ) ) != 0 )
703 goto err_root;
704
705 /* Check if filesystem contains boot filename */
707 config->filename ) ) != 0 ) {
708 goto err_filename;
709 }
710
711 /* Check if filesystem contains additional filename, if applicable */
712 if ( config->extra &&
714 config->extra ) ) != 0 ) ) {
715 goto err_extra;
716 }
717
718 /* Check volume label, if applicable */
719 if ( config->label &&
720 ( ( rc = efi_block_label ( drive, root,
721 config->label ) ) != 0 ) ) {
722 goto err_label;
723 }
724
725 /* Success */
726 rc = 0;
727
728 err_label:
729 err_extra:
730 err_filename:
731 root->Close ( root );
732 err_root:
733 err_wrong_guid:
734 err_no_guid:
735 err_not_child:
736 err_open:
737 return rc;
738}
EFI_FILE_PROTOCOL EFI_FILE
uint64_t guid
GUID.
Definition edd.h:1
static int efi_block_label(unsigned int drive, EFI_FILE_PROTOCOL *root, const char *label)
Check for EFI block device filesystem label.
Definition efi_block.c:594
static int efi_block_root(unsigned int drive, EFI_HANDLE handle, EFI_FILE_PROTOCOL **root)
Open root directory within a filesystem.
Definition efi_block.c:517
static int efi_block_filename(unsigned int drive, EFI_HANDLE handle, EFI_FILE_PROTOCOL *root, const char *filename)
Check for existence of a file within a filesystem.
Definition efi_block.c:551
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition efi_path.c:174
int efi_path_guid(EFI_DEVICE_PATH_PROTOCOL *path, union uuid *guid)
Get partition GUID from device path.
Definition efi_path.c:261
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
const char * filename
Boot filename (or NULL to use default)
Definition sanboot.h:113
const char * label
Filesystem label (or NULL to ignore volume label)
Definition sanboot.h:117
union uuid * uuid
UUID (or NULL to ignore UUID)
Definition sanboot.h:119
const char * extra
Required extra filename (or NULL to ignore)
Definition sanboot.h:115
A universally unique ID.
Definition uuid.h:16
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
Definition uuid.c:46

References DBGC, DBGC2, drive, efi_block_filename(), efi_block_label(), efi_block_root(), efi_device_path_protocol_guid, efi_devpath_text(), EFI_HANDLE, efi_handle_name(), efi_open, efi_path_guid(), efi_path_len(), ENOENT, ENOTTY, san_boot_config::extra, san_boot_config::filename, guid, handle, san_boot_config::label, memcmp(), rc, root, strerror(), san_boot_config::uuid, and uuid_ntoa().

Referenced by efi_block_scan().

◆ efi_block_scan()

int efi_block_scan ( unsigned int drive,
EFI_HANDLE handle,
struct san_boot_config * config,
EFI_DEVICE_PATH_PROTOCOL ** fspath )
static

Scan EFI block device for a matching filesystem.

Parameters
driveDrive number
handleBlock device handle
configBoot configuration parameters
fspathFilesystem device path to fill in
Return values
rcReturn status code

Definition at line 749 of file efi_block.c.

751 {
752 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
754 EFI_HANDLE *handles;
755 UINTN count;
756 unsigned int i;
757 EFI_STATUS efirc;
758 int rc;
759
760 /* Connect up possible file system drivers */
762
763 /* Identify device path */
765 &path ) ) != 0 ) {
766 DBGC ( drive, "EFIBLK %#02x could not open device path: %s\n",
767 drive, strerror ( rc ) );
768 goto err_open;
769 }
770
771 /* Locate all Simple File System protocol handles */
772 if ( ( efirc = bs->LocateHandleBuffer (
774 NULL, &count, &handles ) ) != 0 ) {
775 rc = -EEFI ( efirc );
776 DBGC ( drive, "EFIBLK %#02x cannot locate file systems: %s\n",
777 drive, strerror ( rc ) );
778 goto err_locate;
779 }
780
781 /* Scan for a matching filesystem */
782 rc = -ENOENT;
783 for ( i = 0 ; i < count ; i++ ) {
784
785 /* Check for a matching filesystem */
786 if ( ( rc = efi_block_match ( drive, handles[i], path,
787 config, fspath ) ) != 0 )
788 continue;
789
790 break;
791 }
792
793 bs->FreePool ( handles );
794 err_locate:
795 err_open:
796 return rc;
797}
@ ByProtocol
Retrieve the set of handles from the handle database that support a specified protocol.
Definition UefiSpec.h:1531
static int efi_block_match(unsigned int drive, EFI_HANDLE handle, EFI_DEVICE_PATH_PROTOCOL *path, struct san_boot_config *config, EFI_DEVICE_PATH_PROTOCOL **fspath)
Check EFI block device filesystem match.
Definition efi_block.c:658
#define EFI_HANDLE
Definition efi.h:53
EFI_FREE_POOL FreePool
Definition UefiSpec.h:1950
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
Definition UefiSpec.h:2008
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition DevicePath.h:46

References ByProtocol, count, DBGC, drive, EEFI, efi_block_connect(), efi_block_match(), efi_device_path_protocol_guid, EFI_HANDLE, efi_open, efi_simple_file_system_protocol_guid, efi_systab, ENOENT, EFI_BOOT_SERVICES::FreePool, handle, EFI_BOOT_SERVICES::LocateHandleBuffer, NULL, rc, and strerror().

Referenced by efi_block_boot().

◆ efi_block_exec()

int efi_block_exec ( unsigned int drive,
EFI_DEVICE_PATH_PROTOCOL * fspath,
const char * filename )
static

Boot from EFI block device filesystem boot image.

Parameters
driveDrive number
fspathFilesystem device path
filenameFilename (or NULL to use default)
Return values
rcReturn status code

Definition at line 807 of file efi_block.c.

809 {
810 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
812 FILEPATH_DEVICE_PATH *filepath;
815 size_t fspath_len;
816 size_t filepath_len;
817 size_t path_len;
818 EFI_STATUS efirc;
819 int rc;
820
821 /* Construct device path for boot image */
822 end = efi_path_end ( fspath );
823 fspath_len = ( ( ( void * ) end ) - ( ( void * ) fspath ) );
824 filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
825 ( filename ?
826 ( ( strlen ( filename ) + 1 /* NUL */ ) *
827 sizeof ( filepath->PathName[0] ) ) :
828 sizeof ( efi_block_boot_filename ) ) );
829 path_len = ( fspath_len + filepath_len + sizeof ( *end ) );
830 path = zalloc ( path_len );
831 if ( ! path ) {
832 rc = -ENOMEM;
833 goto err_alloc;
834 }
835 memcpy ( path, fspath, fspath_len );
836 filepath = ( ( ( void * ) path ) + fspath_len );
837 filepath->Header.Type = MEDIA_DEVICE_PATH;
838 filepath->Header.SubType = MEDIA_FILEPATH_DP;
839 filepath->Header.Length[0] = ( filepath_len & 0xff );
840 filepath->Header.Length[1] = ( filepath_len >> 8 );
841 if ( filename ) {
842 efi_sprintf ( filepath->PathName, "%s", filename );
843 } else {
845 sizeof ( efi_block_boot_filename ) );
846 }
847 end = ( ( ( void * ) filepath ) + filepath_len );
849 DBGC ( drive, "EFIBLK %#02x trying to load %s\n",
850 drive, efi_devpath_text ( path ) );
851
852 /* Load image */
853 image = NULL;
854 if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, path, NULL, 0,
855 &image ) ) != 0 ) {
856 rc = -EEFI ( efirc );
857 DBGC ( drive, "EFIBLK %#02x could not load: %s\n",
858 drive, strerror ( rc ) );
859 if ( efirc == EFI_SECURITY_VIOLATION ) {
860 goto err_load_security_violation;
861 } else {
862 goto err_load;
863 }
864 }
865
866 /* Wrap calls made by the loaded image (for debugging) */
868
869 /* Start image */
870 efirc = bs->StartImage ( image, NULL, NULL );
871 rc = ( efirc ? -EEFI ( efirc ) : 0 );
872 DBGC ( drive, "EFIBLK %#02x boot image returned: %s\n",
873 drive, strerror ( rc ) );
874
875 /* Remove wrapper */
876 efi_unwrap();
877
878 err_load_security_violation:
879 bs->UnloadImage ( image );
880 err_load:
881 free ( path );
882 err_alloc:
883 return rc;
884}
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
#define SIZE_OF_FILEPATH_DEVICE_PATH
#define MEDIA_DEVICE_PATH
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition efi_init.c:36
EFI_DEVICE_PATH_PROTOCOL * efi_path_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition efi_path.c:163
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition efi_path.h:31
#define efi_sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition efi_strings.h:46
void efi_unwrap(void)
Remove boot services table wrapper.
Definition efi_wrap.c:1543
void efi_wrap_image(EFI_HANDLE handle)
Wrap calls made by a newly loaded image.
Definition efi_wrap.c:1567
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t end
Ending offset.
Definition netvsc.h:7
EFI_IMAGE_START StartImage
Definition UefiSpec.h:1979
EFI_IMAGE_UNLOAD UnloadImage
Definition UefiSpec.h:1981
EFI_IMAGE_LOAD LoadImage
Definition UefiSpec.h:1978
UINT8 Type
0x01 Hardware Device Path.
Definition DevicePath.h:47
UINT8 Length[2]
Specific Device Path data.
Definition DevicePath.h:59
UINT8 SubType
Varies by Type 0xFF End Entire Device Path, or 0x01 End This Instance of a Device Path and start a ne...
Definition DevicePath.h:54
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
EFI_DEVICE_PATH_PROTOCOL Header
An executable image.
Definition image.h:24
#define FALSE
Definition tlan.h:45

References DBGC, drive, EEFI, efi_block_boot_filename, efi_devpath_text(), EFI_HANDLE, efi_image_handle, efi_path_end(), efi_path_terminate(), EFI_SECURITY_VIOLATION, efi_sprintf, efi_systab, efi_unwrap(), efi_wrap_image(), end, ENOMEM, FALSE, free, FILEPATH_DEVICE_PATH::Header, EFI_DEVICE_PATH_PROTOCOL::Length, EFI_BOOT_SERVICES::LoadImage, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, memcpy(), NULL, FILEPATH_DEVICE_PATH::PathName, rc, SIZE_OF_FILEPATH_DEVICE_PATH, EFI_BOOT_SERVICES::StartImage, strerror(), strlen(), EFI_DEVICE_PATH_PROTOCOL::SubType, EFI_DEVICE_PATH_PROTOCOL::Type, EFI_BOOT_SERVICES::UnloadImage, and zalloc().

Referenced by efi_block_boot().

◆ efi_block_local()

int efi_block_local ( EFI_HANDLE handle)
static

Check that EFI block device is eligible for a local virtual drive number.

Parameters
handleBlock device handle
Return values
rcReturn status code

We assign virtual drive numbers for local (non-SAN) EFI block devices that represent complete disks, to provide roughly equivalent functionality to BIOS drive numbers.

Definition at line 896 of file efi_block.c.

896 {
897 struct san_device *sandev;
898 struct efi_block_data *block;
899 EFI_BLOCK_IO_PROTOCOL *blockio;
900 int rc;
901
902 /* Check if handle belongs to a SAN device */
904 block = sandev->priv;
905 if ( handle == block->handle )
906 return -ENOTTY;
907 }
908
909 /* Open block I/O protocol */
911 &blockio ) ) != 0 ) {
912 DBGC ( handle, "EFIBLK %s could not open block I/O: %s\n",
914 return rc;
915 }
916
917 /* Do not assign drive numbers for partitions */
918 if ( blockio->Media->LogicalPartition ) {
919 DBGC2 ( handle, "EFLBLK %s is a partition\n",
921 return -ENOTTY;
922 }
923
924 return 0;
925}
struct _EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL
Definition BlockIo.h:23
#define for_each_sandev(sandev)
Iterate over all SAN devices.
Definition sanboot.h:197
BOOLEAN LogicalPartition
TRUE if LBA 0 is the first block of a partition; otherwise FALSE.
Definition BlockIo.h:153
EFI_BLOCK_IO_MEDIA * Media
Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
Definition BlockIo.h:227

References block, DBGC, DBGC2, efi_block_io_protocol_guid, EFI_HANDLE, efi_handle_name(), efi_open, ENOTTY, for_each_sandev, handle, EFI_BLOCK_IO_MEDIA::LogicalPartition, _EFI_BLOCK_IO_PROTOCOL::Media, san_device::priv, rc, efi_block_data::sandev, and strerror().

Referenced by efi_block_boot().

◆ efi_block_boot()

int efi_block_boot ( unsigned int drive,
struct san_boot_config * config )
static

Boot from EFI block device.

Parameters
driveDrive number
configBoot configuration parameters
Return values
rcReturn status code

Definition at line 934 of file efi_block.c.

935 {
936 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
938 EFI_HANDLE *handles;
940 UINTN count;
941 struct san_device *sandev;
942 struct efi_block_data *block;
943 unsigned int vdrive;
944 unsigned int index;
945 EFI_STATUS efirc;
946 int rc;
947
948 /* Ensure that any local drives are connected */
950
951 /* Release SNP devices */
953
954 /* Locate all block I/O protocol handles */
955 if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol,
957 NULL, &count,
958 &handles ) ) != 0 ) {
959 rc = -EEFI ( efirc );
960 DBGC ( drive, "EFIBLK %#02x cannot locate block I/O: %s\n",
961 drive, strerror ( rc ) );
962 goto err_locate_block_io;
963 }
964
965 /* Try booting from the first matching block device, if any */
966 rc = -ENOENT;
967 for ( vdrive = 0, index = 0 ; ; vdrive++ ) {
968
969 /* Identify next drive number and block I/O handle */
970 if ( ( sandev = sandev_next ( vdrive ) ) &&
971 ( ( sandev->drive == vdrive ) ||
973 ( index >= count ) ) ) {
974
975 /* There is a SAN drive that either:
976 *
977 * a) has the current virtual drive number, or
978 * b) has a drive number below SAN_DEFAULT_DRIVE, or
979 * c) has a drive number higher than any local drive
980 *
981 * Use this SAN drive, since the explicit SAN
982 * drive numbering takes precedence over the
983 * implicit local drive numbering.
984 */
985 block = sandev->priv;
986 handle = block->handle;
987
988 /* Use SAN drive's explicit drive number */
989 vdrive = sandev->drive;
990 DBGC ( vdrive, "EFIBLK %#02x is SAN drive %s\n",
991 vdrive, efi_handle_name ( handle ) );
992
993 } else if ( index < count ) {
994
995 /* There is no SAN drive meeting any of the
996 * above criteria. Try the next block I/O
997 * handle.
998 */
999 handle = handles[index++];
1000
1001 /* Check if this handle is eligible to be
1002 * given a local virtual drive number.
1003 *
1004 * Do not record this as the overall error
1005 * status, since it is not an interesting
1006 * error.
1007 */
1008 if ( efi_block_local ( handle ) != 0 ) {
1009 /* Do not consume virtual drive number */
1010 vdrive--;
1011 continue;
1012 }
1013
1014 /* Use the current virtual drive number, with
1015 * a minimum of SAN_DEFAULT_DRIVE to match
1016 * typical BIOS drive numbering.
1017 */
1018 if ( vdrive < SAN_DEFAULT_DRIVE )
1019 vdrive = SAN_DEFAULT_DRIVE;
1020 DBGC ( vdrive, "EFIBLK %#02x is local drive %s\n",
1021 vdrive, efi_handle_name ( handle ) );
1022
1023 } else {
1024
1025 /* No more SAN or local drives */
1026 break;
1027 }
1028
1029 /* Skip non-matching drives */
1030 if ( drive && ( drive != vdrive ) )
1031 continue;
1032 DBGC ( vdrive, "EFIBLK %#02x attempting to boot\n", vdrive );
1033
1034 /* Scan for a matching filesystem within this drive */
1035 if ( ( rc = efi_block_scan ( vdrive, handle, config,
1036 &fspath ) ) != 0 ) {
1037 continue;
1038 }
1039
1040 /* Attempt to boot from the matched filesystem */
1041 rc = efi_block_exec ( vdrive, fspath, config->filename );
1042 break;
1043 }
1044
1045 bs->FreePool ( handles );
1046 err_locate_block_io:
1047 efi_snp_claim();
1048 return rc;
1049}
long index
Definition bigint.h:65
static int efi_block_scan(unsigned int drive, EFI_HANDLE handle, struct san_boot_config *config, EFI_DEVICE_PATH_PROTOCOL **fspath)
Scan EFI block device for a matching filesystem.
Definition efi_block.c:749
static int efi_block_exec(unsigned int drive, EFI_DEVICE_PATH_PROTOCOL *fspath, const char *filename)
Boot from EFI block device filesystem boot image.
Definition efi_block.c:807
static int efi_block_local(EFI_HANDLE handle)
Check that EFI block device is eligible for a local virtual drive number.
Definition efi_block.c:896
void efi_driver_reconnect_all(void)
Reconnect original EFI drivers to all possible devices.
Definition efi_driver.c:659
#define SAN_DEFAULT_DRIVE
Default SAN drive number.
Definition sanboot.h:34
struct san_device * sandev_next(unsigned int drive)
Find next SAN device by drive number.
Definition sanboot.c:108

References block, ByProtocol, count, DBGC, drive, san_device::drive, EEFI, efi_block_exec(), efi_block_io_protocol_guid, efi_block_local(), efi_block_scan(), efi_driver_reconnect_all(), EFI_HANDLE, efi_handle_name(), efi_snp_claim(), efi_snp_release(), efi_systab, ENOENT, san_boot_config::filename, EFI_BOOT_SERVICES::FreePool, handle, index, EFI_BOOT_SERVICES::LocateHandleBuffer, NULL, san_device::priv, rc, SAN_DEFAULT_DRIVE, efi_block_data::sandev, sandev_next(), and strerror().

Referenced by PROVIDE_SANBOOT().

◆ PROVIDE_SANBOOT() [1/4]

PROVIDE_SANBOOT ( efi ,
san_hook ,
efi_block_hook  )

References efi_block_hook(), and san_hook().

◆ PROVIDE_SANBOOT() [2/4]

PROVIDE_SANBOOT ( efi ,
san_unhook ,
efi_block_unhook  )

References efi_block_unhook(), and san_unhook().

◆ PROVIDE_SANBOOT() [3/4]

PROVIDE_SANBOOT ( efi ,
san_describe ,
efi_block_describe  )

◆ PROVIDE_SANBOOT() [4/4]

PROVIDE_SANBOOT ( efi ,
san_boot ,
efi_block_boot  )

References efi_block_boot(), and san_boot().

Variable Documentation

◆ acpi

◆ efi_block_boot_filename

wchar_t efi_block_boot_filename[] = EFI_REMOVABLE_MEDIA_FILE_NAME
static

Boot filename.

Definition at line 71 of file efi_block.c.

Referenced by efi_block_exec(), and efi_block_filename().