iPXE
efi_block.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 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/**
28 * @file
29 *
30 * EFI block device protocols
31 *
32 */
33
34#include <stddef.h>
35#include <stdlib.h>
36#include <stdio.h>
37#include <string.h>
38#include <strings.h>
39#include <errno.h>
40#include <ipxe/refcnt.h>
41#include <ipxe/list.h>
42#include <ipxe/uri.h>
43#include <ipxe/interface.h>
44#include <ipxe/blockdev.h>
45#include <ipxe/xfer.h>
46#include <ipxe/open.h>
47#include <ipxe/retry.h>
48#include <ipxe/timer.h>
49#include <ipxe/process.h>
50#include <ipxe/sanboot.h>
51#include <ipxe/iso9660.h>
52#include <ipxe/acpi.h>
53#include <ipxe/efi/efi.h>
58#include <ipxe/efi/efi_driver.h>
60#include <ipxe/efi/efi_snp.h>
61#include <ipxe/efi/efi_path.h>
62#include <ipxe/efi/efi_null.h>
63#include <ipxe/efi/efi_wrap.h>
64#include <ipxe/efi/efi_block.h>
65
66/** ACPI table protocol protocol */
69
70/** Boot filename */
72
73/** EFI SAN device private data */
75 /** SAN device */
77 /** EFI handle */
79 /** Media descriptor */
81 /** Block I/O protocol */
83 /** Device path protocol */
85};
86
87/**
88 * Read from or write to EFI block device
89 *
90 * @v sandev SAN device
91 * @v lba Starting LBA
92 * @v data Data buffer
93 * @v len Size of buffer
94 * @v sandev_rw SAN device read/write method
95 * @ret rc Return status code
96 */
97static int efi_block_rw ( struct san_device *sandev, uint64_t lba,
98 void *data, size_t len,
99 int ( * sandev_rw ) ( struct san_device *sandev,
101 unsigned int count,
102 void *buffer ) ) {
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}
124
125/**
126 * Reset EFI block device
127 *
128 * @v block_io Block I/O protocol
129 * @v verify Perform extended verification
130 * @ret efirc EFI status code
131 */
133 BOOLEAN verify __unused ) {
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}
145
146/**
147 * Read from EFI block device
148 *
149 * @v block_io Block I/O protocol
150 * @v media Media identifier
151 * @v lba Starting LBA
152 * @v len Size of buffer
153 * @v data Data buffer
154 * @ret efirc EFI status code
155 */
156static EFI_STATUS EFIAPI
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}
171
172/**
173 * Write to EFI block device
174 *
175 * @v block_io Block I/O protocol
176 * @v media Media identifier
177 * @v lba Starting LBA
178 * @v len Size of buffer
179 * @v data Data buffer
180 * @ret efirc EFI status code
181 */
182static EFI_STATUS EFIAPI
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}
197
198/**
199 * Flush data to EFI block device
200 *
201 * @v block_io Block I/O protocol
202 * @ret efirc EFI status code
203 */
204static EFI_STATUS EFIAPI
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}
215
216/**
217 * Connect all possible drivers to EFI block device
218 *
219 * @v drive Drive number
220 * @v handle Block device handle
221 */
222static void efi_block_connect ( unsigned int drive, EFI_HANDLE handle ) {
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}
234
235/**
236 * Hook EFI block device
237 *
238 * @v drive Drive number
239 * @v uris List of URIs
240 * @v count Number of URIs
241 * @v flags Flags
242 * @ret drive Drive number, or negative error
243 */
244static int efi_block_hook ( unsigned int drive, struct uri **uris,
245 unsigned int count, unsigned int flags ) {
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}
352
353/**
354 * Unhook EFI block device
355 *
356 * @v drive Drive number
357 */
358static void efi_block_unhook ( unsigned int drive ) {
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}
403
404/** An installed ACPI table */
406 /** List of installed tables */
408 /** Table key */
410};
411
412/** List of installed ACPI tables */
413static LIST_HEAD ( efi_acpi_tables );
414
415/**
416 * Install ACPI table
417 *
418 * @v hdr ACPI description header
419 * @ret rc Return status code
420 */
421static int efi_block_install ( struct acpi_header *hdr ) {
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}
466
467/**
468 * Describe EFI block devices
469 *
470 * @ret rc Return status code
471 */
472static int efi_block_describe ( void ) {
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}
508
509/**
510 * Open root directory within a filesystem
511 *
512 * @v drive Drive number
513 * @v handle Filesystem handle
514 * @v root Root directory file to fill in
515 * @ret rc Return status code
516 */
517static int efi_block_root ( unsigned int drive, EFI_HANDLE handle,
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}
541
542/**
543 * Check for existence of a file within a filesystem
544 *
545 * @v drive Drive number
546 * @v handle Filesystem handle
547 * @v root Root directory
548 * @v filename Filename (or NULL to use default)
549 * @ret rc Return status code
550 */
551static int efi_block_filename ( unsigned int drive, EFI_HANDLE handle,
553 const char *filename ) {
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}
585
586/**
587 * Check for EFI block device filesystem label
588 *
589 * @v drive Drive number
590 * @v root Root directory
591 * @v label Volume label
592 * @ret rc Return status code
593 */
594static int efi_block_label ( unsigned int drive, EFI_FILE_PROTOCOL *root,
595 const char *label ) {
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}
647
648/**
649 * Check EFI block device filesystem match
650 *
651 * @v drive Drive number
652 * @v handle Filesystem handle
653 * @v path Block device path
654 * @v config Boot configuration parameters
655 * @v fspath Filesystem device path to fill in
656 * @ret rc Return status code
657 */
658static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
660 struct san_boot_config *config,
661 EFI_DEVICE_PATH_PROTOCOL **fspath ) {
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}
739
740/**
741 * Scan EFI block device for a matching filesystem
742 *
743 * @v drive Drive number
744 * @v handle Block device handle
745 * @v config Boot configuration parameters
746 * @v fspath Filesystem device path to fill in
747 * @ret rc Return status code
748 */
749static int efi_block_scan ( unsigned int drive, EFI_HANDLE handle,
750 struct san_boot_config *config,
751 EFI_DEVICE_PATH_PROTOCOL **fspath ) {
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}
798
799/**
800 * Boot from EFI block device filesystem boot image
801 *
802 * @v drive Drive number
803 * @v fspath Filesystem device path
804 * @v filename Filename (or NULL to use default)
805 * @ret rc Return status code
806 */
807static int efi_block_exec ( unsigned int drive,
809 const char *filename ) {
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}
885
886/**
887 * Check that EFI block device is eligible for a local virtual drive number
888 *
889 * @v handle Block device handle
890 * @ret rc Return status code
891 *
892 * We assign virtual drive numbers for local (non-SAN) EFI block
893 * devices that represent complete disks, to provide roughly
894 * equivalent functionality to BIOS drive numbers.
895 */
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}
926
927/**
928 * Boot from EFI block device
929 *
930 * @v drive Drive number
931 * @v config Boot configuration parameters
932 * @ret rc Return status code
933 */
934static int efi_block_boot ( unsigned int drive,
935 struct san_boot_config *config ) {
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}
1050
unsigned char BOOLEAN
Logical Boolean.
UINT64 UINTN
Unsigned value of native width.
unsigned short CHAR16
2-byte Character.
#define EFIAPI
unsigned int UINT32
4-byte unsigned value.
The file provides the protocol to install or remove an ACPI table from a platform.
struct _EFI_ACPI_TABLE_PROTOCOL EFI_ACPI_TABLE_PROTOCOL
Definition AcpiTable.h:22
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define VOID
Undeclared type.
Definition Base.h:272
Block IO protocol as defined in the UEFI 2.0 specification.
#define EFI_BLOCK_IO_PROTOCOL_REVISION3
Definition BlockIo.h:207
struct _EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL
Definition BlockIo.h:23
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
#define SIZE_OF_FILEPATH_DEVICE_PATH
#define MEDIA_DEVICE_PATH
Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.GetInfo() or EFI_FILE_PR...
#define EFI_REMOVABLE_MEDIA_FILE_NAME
SimpleFileSystem protocol as defined in the UEFI 2.0 specification.
struct _EFI_FILE_PROTOCOL EFI_FILE_PROTOCOL
struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
EFI_FILE_PROTOCOL EFI_FILE
#define EFI_FILE_MODE_READ
UINT64 EFI_LBA
Logical block address.
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
@ ByProtocol
Retrieve the set of handles from the handle database that support a specified protocol.
Definition UefiSpec.h:1531
int acpi_install(int(*install)(struct acpi_header *acpi))
Install ACPI tables.
Definition acpi.c:344
void acpi_fix_checksum(struct acpi_header *acpi)
Fix up ACPI table checksum.
Definition acpi.c:80
u32 info
Definition ar9003_mac.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned long long uint64_t
Definition stdint.h:13
long index
Definition bigint.h:65
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition asprintf.c:42
Block devices.
ring len
Length.
Definition dwmac.h:226
uint64_t guid
GUID.
Definition edd.h:1
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 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 void efi_block_unhook(unsigned int drive)
Unhook EFI block device.
Definition efi_block.c:358
static int efi_block_describe(void)
Describe EFI block devices.
Definition efi_block.c:472
static wchar_t efi_block_boot_filename[]
Boot filename.
Definition efi_block.c:71
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
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_install(struct acpi_header *hdr)
Install ACPI table.
Definition efi_block.c:421
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
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 int efi_block_boot(unsigned int drive, struct san_boot_config *config)
Boot from EFI block device.
Definition efi_block.c:934
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_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 EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition efi_block.c:67
static int efi_block_hook(unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
Hook EFI block device.
Definition efi_block.c:244
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 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
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
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
int efi_connect(EFI_HANDLE device, EFI_HANDLE driver)
Connect UEFI driver(s)
Definition efi_connect.c:58
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
void efi_driver_reconnect_all(void)
Reconnect original EFI drivers to all possible devices.
Definition efi_driver.c:659
EFI driver interface.
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
Definition efi_guid.c:145
EFI_GUID efi_file_system_info_id
File system information GUID.
Definition efi_guid.c:466
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition efi_guid.c:169
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition efi_guid.c:337
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition efi_init.c:36
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition efi_init.c:60
void efi_nullify_block(EFI_BLOCK_IO_PROTOCOL *block)
Nullify block I/O protocol.
Definition efi_null.c:397
EFI null interfaces.
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition efi_path.c:174
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition efi_path.c:920
EFI_DEVICE_PATH_PROTOCOL * efi_path_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition efi_path.c:163
int efi_path_guid(EFI_DEVICE_PATH_PROTOCOL *path, union uuid *guid)
Get partition GUID from device path.
Definition efi_path.c:261
EFI device paths.
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition efi_path.h:31
iPXE EFI SNP interface
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
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
EFI strings.
#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
EFI driver interface.
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint8_t flags
Flags.
Definition ena.h:7
Error codes.
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBGC2(...)
Definition compiler.h:522
#define DBGC2_HDA(...)
Definition compiler.h:523
#define DBGC(...)
Definition compiler.h:505
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
uint8_t drive
Drive number.
Definition int13.h:5
uint16_t size
Buffer size.
Definition dwmac.h:3
static unsigned int count
Number of entries.
Definition dwmac.h:220
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
uint64_t lba
Starting block number.
Definition int13.h:11
#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 EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define ENODEV
No such device.
Definition errno.h:510
#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
#define le32_to_cpu(value)
Definition byteswap.h:114
ACPI data structures.
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition acpi.h:207
EFI API.
#define EFI_REQUEST_PROTOCOL(_protocol, _ptr)
Declare an EFI protocol to be requested by iPXE.
Definition efi.h:122
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition efi.h:444
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition efi.h:167
#define EFI_HANDLE
Definition efi.h:53
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
#define DBGC2_EFI_PROTOCOLS(...)
Definition efi.h:358
EFI_SYSTEM_TABLE * efi_systab
iPXE sanboot API
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
Definition sanboot.h:226
#define SAN_DEFAULT_DRIVE
Default SAN drive number.
Definition sanboot.h:34
void san_unhook(unsigned int drive)
Unhook SAN device.
int san_describe(void)
Describe SAN devices for SAN-booted operating system.
int san_hook(unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
Hook SAN device.
#define for_each_sandev(sandev)
Iterate over all SAN devices.
Definition sanboot.h:197
int san_boot(unsigned int drive, struct san_boot_config *config)
Attempt to boot from a SAN device.
#define PROVIDE_SANBOOT(_subsys, _api_func, _func)
Provide a sanboot API implementation.
Definition sanboot.h:139
uint16_t handle
Handle.
Definition smbios.h:5
iPXE timers
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
String functions.
Object interfaces.
ISO9660 CD-ROM specification.
uint32_t fs
Definition librm.h:3
unsigned long tmp
Definition linux_pci.h:65
Linked lists.
#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
#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
#define LIST_HEAD(list)
Declare a static list head.
Definition list.h:38
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
uint32_t end
Ending offset.
Definition netvsc.h:7
Data transfer interface opening.
Processes.
Reference counting.
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
Retry timers.
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
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
Read from SAN device.
Definition sanboot.c:647
int register_sandev(struct san_device *sandev, unsigned int drive, unsigned int flags)
Register SAN device.
Definition sanboot.c:880
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
Write to SAN device.
Definition sanboot.c:668
struct san_device * sandev_next(unsigned int drive)
Find next SAN device by drive number.
Definition sanboot.c:108
int sandev_reset(struct san_device *sandev)
Reset SAN device.
Definition sanboot.c:576
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
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition sanboot.c:92
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
struct stp_switch root
Root switch.
Definition stp.h:15
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition string.c:209
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
char * strncpy(char *dest, const char *src, size_t max)
Copy string.
Definition string.c:361
Block IO read only mode data and updated only via members of BlockIO.
Definition BlockIo.h:131
BOOLEAN LogicalPartition
TRUE if LBA 0 is the first block of a partition; otherwise FALSE.
Definition BlockIo.h:153
EFI Boot Services Table.
Definition UefiSpec.h:1931
EFI_IMAGE_START StartImage
Definition UefiSpec.h:1979
EFI_FREE_POOL FreePool
Definition UefiSpec.h:1950
EFI_IMAGE_UNLOAD UnloadImage
Definition UefiSpec.h:1981
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition UefiSpec.h:2011
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition UefiSpec.h:2010
EFI_IMAGE_LOAD LoadImage
Definition UefiSpec.h:1978
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
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
EFI_BLOCK_IO_MEDIA * Media
Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
Definition BlockIo.h:227
An ACPI description header.
Definition acpi.h:180
uint64_t blocks
Total number of blocks.
Definition blockdev.h:20
size_t blksize
Block size.
Definition blockdev.h:22
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
EFI SAN device private data.
Definition efi_block.c:74
struct san_device * sandev
SAN device.
Definition efi_block.c:76
EFI_BLOCK_IO_MEDIA media
Media descriptor.
Definition efi_block.c:80
EFI_DEVICE_PATH_PROTOCOL * path
Device path protocol.
Definition efi_block.c:84
EFI_HANDLE handle
EFI handle.
Definition efi_block.c:78
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition efi_block.c:82
An executable image.
Definition image.h:24
A text label widget.
Definition label.h:16
A doubly-linked list entry (or list head)
Definition list.h:19
SAN boot configuration parameters.
Definition sanboot.h:111
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 SAN device.
Definition sanboot.h:59
void * priv
Driver private data.
Definition sanboot.h:90
struct san_path * active
Current active path.
Definition sanboot.h:95
unsigned int drive
Drive number.
Definition sanboot.h:66
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
A Uniform Resource Identifier.
Definition uri.h:65
static char media[]
Definition sundance.c:85
#define FALSE
Definition tlan.h:45
A universally unique ID.
Definition uuid.h:16
Uniform Resource Identifiers.
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
Definition uuid.c:46
Data transfer interfaces.