iPXE
efi_file.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2013 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 file 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 <wchar.h>
41#include <ipxe/image.h>
42#include <ipxe/cpio.h>
43#include <ipxe/initrd.h>
44#include <ipxe/efi/efi.h>
52#include <ipxe/efi/efi_path.h>
53#include <ipxe/efi/efi_file.h>
54
55/** EFI media ID */
56#define EFI_MEDIA_ID_MAGIC 0x69505845
57
58/** Linux initrd fixed device path vendor GUID */
59#define LINUX_INITRD_VENDOR_GUID \
60 { 0x5568e427, 0x68fc, 0x4f3d, \
61 { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } }
62
63/** An EFI virtual file reader */
65 /** EFI file */
66 struct efi_file *file;
67 /** Position within virtual file */
68 size_t pos;
69 /** Output data buffer */
70 void *data;
71 /** Length of output data buffer */
72 size_t len;
73};
74
75/** An EFI file */
76struct efi_file {
77 /** Reference count */
78 struct refcnt refcnt;
79 /** EFI file protocol */
81 /** EFI load file protocol */
83 /** Image (if any) */
84 struct image *image;
85 /** Filename */
86 const char *name;
87 /** Current file position */
88 size_t pos;
89 /**
90 * Read from file
91 *
92 * @v reader File reader
93 * @ret len Length read
94 */
95 size_t ( * read ) ( struct efi_file_reader *reader );
96};
97
98/** An EFI fixed device path file */
100 /** EFI file */
102 /** Device path */
104 /** EFI handle */
106};
107
110
111/**
112 * Free EFI file
113 *
114 * @v refcnt Reference count
115 */
116static void efi_file_free ( struct refcnt *refcnt ) {
117 struct efi_file *file =
118 container_of ( refcnt, struct efi_file, refcnt );
119
120 image_put ( file->image );
121 free ( file );
122}
123
124/**
125 * Get EFI file name (for debugging)
126 *
127 * @v file EFI file
128 * @ret name Name
129 */
130static const char * efi_file_name ( struct efi_file *file ) {
131
132 return ( file == &efi_file_root ? "<root>" : file->name );
133}
134
135/**
136 * Find EFI file image
137 *
138 * @v name Filename
139 * @ret image Image, or NULL
140 */
141static struct image * efi_file_find ( const char *name ) {
142 struct image *image;
143
144 /* Find image */
146 if ( strcasecmp ( image->name, name ) == 0 )
147 return image;
148 }
149
150 return NULL;
151}
152
153/**
154 * Get length of EFI file
155 *
156 * @v file EFI file
157 * @ret len Length of file
158 */
159static size_t efi_file_len ( struct efi_file *file ) {
160 struct efi_file_reader reader;
161
162 /* If this is the root directory, then treat as length zero */
163 if ( ! file->read )
164 return 0;
165
166 /* Initialise reader */
167 reader.file = file;
168 reader.pos = 0;
169 reader.data = NULL;
170 reader.len = 0;
171
172 /* Perform dummy read to determine file length */
173 file->read ( &reader );
174
175 return reader.pos;
176}
177
178/**
179 * Read chunk of EFI file
180 *
181 * @v reader EFI file reader
182 * @v data Input data, or NULL to zero-fill
183 * @v len Length of input data
184 * @ret len Length of output data
185 */
186static size_t efi_file_read_chunk ( struct efi_file_reader *reader,
187 const void *data, size_t len ) {
188 struct efi_file *file = reader->file;
189 size_t offset;
190
191 /* Calculate offset into input data */
192 offset = ( file->pos - reader->pos );
193
194 /* Consume input data range */
195 reader->pos += len;
196
197 /* Calculate output length */
198 if ( offset < len ) {
199 len -= offset;
200 } else {
201 len = 0;
202 }
203 if ( len > reader->len )
204 len = reader->len;
205
206 /* Copy or zero output data */
207 if ( data ) {
208 memcpy ( reader->data, ( data + offset ), len );
209 } else {
210 memset ( reader->data, 0, len );
211 }
212
213 /* Consume output buffer */
214 file->pos += len;
215 reader->data += len;
216 reader->len -= len;
217
218 return len;
219}
220
221/**
222 * Read from image-backed file
223 *
224 * @v reader EFI file reader
225 * @ret len Length read
226 */
227static size_t efi_file_read_image ( struct efi_file_reader *reader ) {
228 struct efi_file *file = reader->file;
229 struct image *image = file->image;
230
231 /* Read from file */
232 return efi_file_read_chunk ( reader, image->data, image->len );
233}
234
235/**
236 * Read from magic initrd file
237 *
238 * @v reader EFI file reader
239 * @ret len Length read
240 */
241static size_t efi_file_read_initrd ( struct efi_file_reader *reader ) {
242 struct efi_file *file = reader->file;
243 struct cpio_header cpio;
244 struct image *image;
245 const char *name;
246 size_t pad_len;
247 size_t cpio_len;
248 size_t name_len;
249 size_t len;
250 unsigned int i;
251
252 /* Read from file */
253 len = 0;
255
256 /* Skip hidden images */
257 if ( image->flags & IMAGE_HIDDEN )
258 continue;
259
260 /* Pad to alignment boundary */
261 pad_len = ( ( -reader->pos ) & ( INITRD_ALIGN - 1 ) );
262 if ( pad_len ) {
263 DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) pad\n",
264 efi_file_name ( file ), reader->pos,
265 ( reader->pos + pad_len ) );
266 }
267 len += efi_file_read_chunk ( reader, NULL, pad_len );
268
269 /* Read CPIO header(s), if applicable */
270 name = cpio_name ( image );
271 for ( i = 0 ; ( cpio_len = cpio_header ( image, i, &cpio ) );
272 i++ ) {
273 name_len = ( cpio_len - sizeof ( cpio ) );
274 pad_len = cpio_pad_len ( cpio_len );
275 DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) %s header\n",
276 efi_file_name ( file ), reader->pos,
277 ( reader->pos + cpio_len + pad_len ),
278 image->name );
279 len += efi_file_read_chunk ( reader, &cpio,
280 sizeof ( cpio ) );
281 len += efi_file_read_chunk ( reader, name, name_len );
282 len += efi_file_read_chunk ( reader, NULL, pad_len );
283 }
284
285 /* Read file data */
286 DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) %s\n",
287 efi_file_name ( file ), reader->pos,
288 ( reader->pos + image->len ), image->name );
289 len += efi_file_read_chunk ( reader, image->data, image->len );
290 }
291
292 return len;
293}
294
295/**
296 * Open fixed file
297 *
298 * @v file EFI file
299 * @v wname Filename
300 * @v new New EFI file
301 * @ret efirc EFI status code
302 */
304 const wchar_t *wname,
305 EFI_FILE_PROTOCOL **new ) {
306
307 /* Increment reference count */
308 ref_get ( &file->refcnt );
309
310 /* Return opened file */
311 *new = &file->file;
312
313 DBGC ( file, "EFIFILE %s opened via %ls\n",
314 efi_file_name ( file ), wname );
315 return 0;
316}
317
318/**
319 * Associate file with image
320 *
321 * @v file EFI file
322 * @v image Image
323 */
324static void efi_file_image ( struct efi_file *file, struct image *image ) {
325
326 file->image = image;
327 file->name = image->name;
329}
330
331/**
332 * Open image-backed file
333 *
334 * @v image Image
335 * @v wname Filename
336 * @v new New EFI file
337 * @ret efirc EFI status code
338 */
340 const wchar_t *wname,
341 EFI_FILE_PROTOCOL **new ) {
342 struct efi_file *file;
343
344 /* Allocate and initialise file */
345 file = zalloc ( sizeof ( *file ) );
346 if ( ! file )
348 ref_init ( &file->refcnt, efi_file_free );
349 memcpy ( &file->file, &efi_file_root.file, sizeof ( file->file ) );
350 memcpy ( &file->load, &efi_file_root.load, sizeof ( file->load ) );
352
353 /* Return opened file */
354 *new = &file->file;
355
356 DBGC ( file, "EFIFILE %s opened via %ls\n",
357 efi_file_name ( file ), wname );
358 return 0;
359}
360
361/**
362 * Open file
363 *
364 * @v this EFI file
365 * @ret new New EFI file
366 * @v wname Filename
367 * @v mode File mode
368 * @v attributes File attributes (for newly-created files)
369 * @ret efirc EFI status code
370 */
371static EFI_STATUS EFIAPI
373 CHAR16 *wname, UINT64 mode, UINT64 attributes __unused ) {
374 struct efi_file *file = container_of ( this, struct efi_file, file );
375 char buf[ wcslen ( wname ) + 1 /* NUL */ ];
376 struct image *image;
377 char *name;
378 char *sep;
379
380 /* Convert name to ASCII */
381 snprintf ( buf, sizeof ( buf ), "%ls", wname );
382 name = buf;
383
384 /* Initial '\' indicates opening from the root directory */
385 while ( *name == '\\' ) {
386 file = &efi_file_root;
387 name++;
388 }
389
390 /* Strip redundant path separator characters */
391 while ( ( *name == '\\' ) || ( *name == '.' ) )
392 name++;
393
394 /* Allow root directory itself to be opened */
395 if ( ! *name )
396 return efi_file_open_fixed ( &efi_file_root, wname, new );
397
398 /* Fail unless opening from the root */
399 if ( file != &efi_file_root ) {
400 DBGC ( file, "EFIFILE %s is not a directory\n",
401 efi_file_name ( file ) );
402 return EFI_NOT_FOUND;
403 }
404
405 /* Fail unless opening read-only */
406 if ( mode != EFI_FILE_MODE_READ ) {
407 DBGC ( file, "EFIFILE %s cannot be opened in mode %#08llx\n",
408 name, mode );
409 return EFI_WRITE_PROTECTED;
410 }
411
412 /* Allow registered images to be opened */
413 if ( ( image = efi_file_find ( name ) ) != NULL )
414 return efi_file_open_image ( image, wname, new );
415
416 /* Allow magic initrd to be opened */
417 if ( strcasecmp ( name, efi_file_initrd.file.name ) == 0 ) {
418 return efi_file_open_fixed ( &efi_file_initrd.file, wname,
419 new );
420 }
421
422 /* Allow currently selected image to be opened as "grub*.efi",
423 * to work around buggy versions of the UEFI shim.
424 */
425 if ( ( strncasecmp ( name, "grub", 4 ) == 0 ) &&
426 ( ( sep = strrchr ( name, '.' ) ) != NULL ) &&
427 ( strcasecmp ( sep, ".efi" ) == 0 ) &&
428 ( ( image = find_image_tag ( &selected_image ) ) != NULL ) ) {
429 return efi_file_open_image ( image, wname, new );
430 }
431
432 DBGC ( file, "EFIFILE %ls does not exist\n", wname );
433 return EFI_NOT_FOUND;
434}
435
436/**
437 * Close file
438 *
439 * @v this EFI file
440 * @ret efirc EFI status code
441 */
443 struct efi_file *file = container_of ( this, struct efi_file, file );
444
445 /* Close file */
446 DBGC ( file, "EFIFILE %s closed\n", efi_file_name ( file ) );
447 ref_put ( &file->refcnt );
448
449 return 0;
450}
451
452/**
453 * Close and delete file
454 *
455 * @v this EFI file
456 * @ret efirc EFI status code
457 */
459 struct efi_file *file = container_of ( this, struct efi_file, file );
460
461 DBGC ( file, "EFIFILE %s cannot be deleted\n", efi_file_name ( file ) );
462
463 /* Close file */
464 efi_file_close ( this );
465
466 /* Warn of failure to delete */
468}
469
470/**
471 * Return variable-length data structure
472 *
473 * @v base Base data structure (starting with UINT64)
474 * @v base_len Length of base data structure
475 * @v name Name to append to base data structure
476 * @v len Length of data buffer
477 * @v data Data buffer
478 * @ret efirc EFI status code
479 */
480static EFI_STATUS efi_file_varlen ( UINT64 *base, size_t base_len,
481 const char *name, UINTN *len, VOID *data ) {
482 size_t name_len;
483
484 /* Calculate structure length */
485 name_len = strlen ( name );
486 *base = ( base_len + ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
487 if ( *len < *base ) {
488 *len = *base;
490 }
491
492 /* Copy data to buffer */
493 *len = *base;
494 memcpy ( data, base, base_len );
495 efi_snprintf ( ( data + base_len ), ( name_len + 1 /* NUL */ ),
496 "%s", name );
497
498 return 0;
499}
500
501/**
502 * Return file information structure
503 *
504 * @v file EFI file
505 * @v len Length of data buffer
506 * @v data Data buffer
507 * @ret efirc EFI status code
508 */
510 VOID *data ) {
512 size_t file_len;
513
514 /* Get file length */
515 file_len = efi_file_len ( file );
516
517 /* Populate file information */
518 memset ( &info, 0, sizeof ( info ) );
519 info.FileSize = file_len;
520 info.PhysicalSize = file_len;
521 info.Attribute = EFI_FILE_READ_ONLY;
522 if ( file == &efi_file_root )
523 info.Attribute |= EFI_FILE_DIRECTORY;
524
526 file->name, len, data );
527}
528
529/**
530 * Read directory entry
531 *
532 * @v file EFI file
533 * @v len Length to read
534 * @v data Data buffer
535 * @ret efirc EFI status code
536 */
538 VOID *data ) {
539 EFI_STATUS efirc;
540 struct efi_file entry;
541 struct image *image;
542 unsigned int index;
543
544 /* Construct directory entries for image-backed files */
545 index = file->pos;
547
548 /* Skip hidden images */
549 if ( image->flags & IMAGE_HIDDEN )
550 continue;
551
552 /* Skip preceding images */
553 if ( index-- )
554 continue;
555
556 /* Construct directory entry */
557 efi_file_image ( &entry, image );
558 efirc = efi_file_info ( &entry, len, data );
559 if ( efirc == 0 )
560 file->pos++;
561 return efirc;
562 }
563
564 /* No more entries */
565 *len = 0;
566 return 0;
567}
568
569/**
570 * Read from file
571 *
572 * @v this EFI file
573 * @v len Length to read
574 * @v data Data buffer
575 * @ret efirc EFI status code
576 */
578 UINTN *len, VOID *data ) {
579 struct efi_file *file = container_of ( this, struct efi_file, file );
580 struct efi_file_reader reader;
581 size_t pos = file->pos;
582
583 /* If this is the root directory, then construct a directory entry */
584 if ( ! file->read )
585 return efi_file_read_dir ( file, len, data );
586
587 /* Initialise reader */
588 reader.file = file;
589 reader.pos = 0;
590 reader.data = data;
591 reader.len = *len;
592
593 /* Read from the file */
594 DBGC ( file, "EFIFILE %s read [%#08zx,%#08zx)\n",
595 efi_file_name ( file ), pos, ( ( size_t ) ( pos + *len ) ) );
596 *len = file->read ( &reader );
597 assert ( ( pos + *len ) == file->pos );
598
599 return 0;
600}
601
602/**
603 * Write to file
604 *
605 * @v this EFI file
606 * @v len Length to write
607 * @v data Data buffer
608 * @ret efirc EFI status code
609 */
611 UINTN *len, VOID *data __unused ) {
612 struct efi_file *file = container_of ( this, struct efi_file, file );
613
614 DBGC ( file, "EFIFILE %s cannot write [%#08zx, %#08zx)\n",
615 efi_file_name ( file ), file->pos,
616 ( ( size_t ) ( file->pos + *len ) ) );
617 return EFI_WRITE_PROTECTED;
618}
619
620/**
621 * Set file position
622 *
623 * @v this EFI file
624 * @v position New file position
625 * @ret efirc EFI status code
626 */
628 UINT64 position ) {
629 struct efi_file *file = container_of ( this, struct efi_file, file );
630 size_t len;
631
632 /* Get file length */
633 len = efi_file_len ( file );
634
635 /* Check for the magic end-of-file value */
636 if ( position == 0xffffffffffffffffULL )
637 position = len;
638
639 /* Fail if we attempt to seek past the end of the file (since
640 * we do not support writes).
641 */
642 if ( position > len ) {
643 DBGC ( file, "EFIFILE %s cannot seek to %#08llx of %#08zx\n",
644 efi_file_name ( file ), position, len );
645 return EFI_UNSUPPORTED;
646 }
647
648 /* Set position */
649 file->pos = position;
650 DBGC ( file, "EFIFILE %s position set to %#08zx\n",
651 efi_file_name ( file ), file->pos );
652
653 return 0;
654}
655
656/**
657 * Get file position
658 *
659 * @v this EFI file
660 * @ret position New file position
661 * @ret efirc EFI status code
662 */
664 UINT64 *position ) {
665 struct efi_file *file = container_of ( this, struct efi_file, file );
666
667 *position = file->pos;
668 return 0;
669}
670
671/**
672 * Get file information
673 *
674 * @v this EFI file
675 * @v type Type of information
676 * @v len Buffer size
677 * @v data Buffer
678 * @ret efirc EFI status code
679 */
681 EFI_GUID *type,
682 UINTN *len, VOID *data ) {
683 struct efi_file *file = container_of ( this, struct efi_file, file );
685 struct image *image;
686
687 /* Determine information to return */
688 if ( memcmp ( type, &efi_file_info_id, sizeof ( *type ) ) == 0 ) {
689
690 /* Get file information */
691 DBGC ( file, "EFIFILE %s get file information\n",
692 efi_file_name ( file ) );
693 return efi_file_info ( file, len, data );
694
695 } else if ( memcmp ( type, &efi_file_system_info_id,
696 sizeof ( *type ) ) == 0 ) {
697
698 /* Get file system information */
699 DBGC ( file, "EFIFILE %s get file system information\n",
700 efi_file_name ( file ) );
701 memset ( &fsinfo, 0, sizeof ( fsinfo ) );
702 fsinfo.ReadOnly = 1;
704 fsinfo.VolumeSize += image->len;
705 return efi_file_varlen ( &fsinfo.Size,
707 len, data );
708 } else {
709
710 DBGC ( file, "EFIFILE %s cannot get information of type %s\n",
711 efi_file_name ( file ), efi_guid_ntoa ( type ) );
712 return EFI_UNSUPPORTED;
713 }
714}
715
716/**
717 * Set file information
718 *
719 * @v this EFI file
720 * @v type Type of information
721 * @v len Buffer size
722 * @v data Buffer
723 * @ret efirc EFI status code
724 */
725static EFI_STATUS EFIAPI
728 struct efi_file *file = container_of ( this, struct efi_file, file );
729
730 DBGC ( file, "EFIFILE %s cannot set information of type %s\n",
732 return EFI_WRITE_PROTECTED;
733}
734
735/**
736 * Flush file modified data
737 *
738 * @v this EFI file
739 * @v type Type of information
740 * @v len Buffer size
741 * @v data Buffer
742 * @ret efirc EFI status code
743 */
745 struct efi_file *file = container_of ( this, struct efi_file, file );
746
747 DBGC ( file, "EFIFILE %s flushed\n", efi_file_name ( file ) );
748 return 0;
749}
750
751/**
752 * Load file
753 *
754 * @v this EFI file loader
755 * @v path File path
756 * @v boot Boot policy
757 * @v len Buffer size
758 * @v data Buffer, or NULL
759 * @ret efirc EFI status code
760 */
761static EFI_STATUS EFIAPI
764 BOOLEAN boot __unused, UINTN *len, VOID *data ) {
765 struct efi_file *file = container_of ( this, struct efi_file, load );
766 size_t max_len;
767 size_t file_len;
768 EFI_STATUS efirc;
769
770 /* Calculate maximum length */
771 max_len = ( data ? *len : 0 );
772 DBGC ( file, "EFIFILE %s load at %p+%#zx\n",
773 efi_file_name ( file ), data, max_len );
774
775 /* Check buffer size */
776 file_len = efi_file_len ( file );
777 if ( file_len > max_len ) {
778 *len = file_len;
780 }
781
782 /* Read from file */
783 if ( ( efirc = efi_file_read ( &file->file, len, data ) ) != 0 )
784 return efirc;
785
786 return 0;
787}
788
789/** Root directory */
790static struct efi_file efi_file_root = {
791 .refcnt = REF_INIT ( ref_no_free ),
792 .file = {
793 .Revision = EFI_FILE_PROTOCOL_REVISION,
794 .Open = efi_file_open,
795 .Close = efi_file_close,
796 .Delete = efi_file_delete,
797 .Read = efi_file_read,
798 .Write = efi_file_write,
799 .GetPosition = efi_file_get_position,
800 .SetPosition = efi_file_set_position,
801 .GetInfo = efi_file_get_info,
802 .SetInfo = efi_file_set_info,
803 .Flush = efi_file_flush,
804 },
805 .load = {
806 .LoadFile = efi_file_load,
807 },
808 .image = NULL,
809 .name = "",
810};
811
812/** Linux initrd fixed device path */
813static struct {
816} __attribute__ (( packed )) efi_file_initrd_path = {
817 .vendor = {
818 .Header = {
819 .Type = MEDIA_DEVICE_PATH,
820 .SubType = MEDIA_VENDOR_DP,
821 .Length[0] = sizeof ( efi_file_initrd_path.vendor ),
822 },
824 },
825 .end = {
826 .Type = END_DEVICE_PATH_TYPE,
828 .Length[0] = sizeof ( efi_file_initrd_path.end ),
829 },
831
832/** Magic initrd file */
833static struct efi_file_path efi_file_initrd = {
834 .file = {
835 .refcnt = REF_INIT ( ref_no_free ),
836 .file = {
837 .Revision = EFI_FILE_PROTOCOL_REVISION,
838 .Open = efi_file_open,
839 .Close = efi_file_close,
840 .Delete = efi_file_delete,
841 .Read = efi_file_read,
842 .Write = efi_file_write,
843 .GetPosition = efi_file_get_position,
844 .SetPosition = efi_file_set_position,
845 .GetInfo = efi_file_get_info,
846 .SetInfo = efi_file_set_info,
847 .Flush = efi_file_flush,
848 },
849 .load = {
850 .LoadFile = efi_file_load,
851 },
852 .image = NULL,
853 .name = "initrd.magic",
854 .read = efi_file_read_initrd,
855 },
856 .path = &efi_file_initrd_path.vendor.Header,
857};
858
859/**
860 * Open root directory
861 *
862 * @v filesystem EFI simple file system
863 * @ret file EFI file handle
864 * @ret efirc EFI status code
865 */
866static EFI_STATUS EFIAPI
869
870 DBGC ( &efi_file_root, "EFIFILE open volume\n" );
871 return efi_file_open_fixed ( &efi_file_root, L"<volume>", file );
872}
873
874/** EFI simple file system protocol */
879
880/** Dummy block I/O reset */
881static EFI_STATUS EFIAPI
883
884 DBGC ( &efi_file_root, "EFIFILE block %sreset\n",
885 ( extended ? "extended " : "" ) );
886 return 0;
887}
888
889/** Dummy block I/O read */
890static EFI_STATUS EFIAPI
893
894 DBGC ( &efi_file_root, "EFIFILE block read ID %#08x LBA %#08llx -> "
895 "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
896 data, ( ( size_t ) len ) );
897 return EFI_NO_MEDIA;
898}
899
900/** Dummy block I/O write */
901static EFI_STATUS EFIAPI
903 UINT32 MediaId, EFI_LBA lba, UINTN len,
904 VOID *data ) {
905
906 DBGC ( &efi_file_root, "EFIFILE block write ID %#08x LBA %#08llx <- "
907 "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
908 data, ( ( size_t ) len ) );
909 return EFI_NO_MEDIA;
910}
911
912/** Dummy block I/O flush */
913static EFI_STATUS EFIAPI
915
916 DBGC ( &efi_file_root, "EFIFILE block flush\n" );
917 return 0;
918}
919
920/** Dummy block I/O media */
922 .MediaId = EFI_MEDIA_ID_MAGIC,
923 .MediaPresent = TRUE,
924 .ReadOnly = TRUE,
925 .BlockSize = 1,
926};
927
928/** Dummy EFI block I/O protocol */
931 .Media = &efi_block_io_media,
932 .Reset = efi_block_io_reset,
933 .ReadBlocks = efi_block_io_read_blocks,
934 .WriteBlocks = efi_block_io_write_blocks,
935 .FlushBlocks = efi_block_io_flush_blocks,
936};
937
938/** Dummy disk I/O read */
939static EFI_STATUS EFIAPI
942
943 DBGC ( &efi_file_root, "EFIFILE disk read ID %#08x offset %#08llx -> "
944 "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
945 data, ( ( size_t ) len ) );
946 return EFI_NO_MEDIA;
947}
948
949/** Dummy disk I/O write */
950static EFI_STATUS EFIAPI
953
954 DBGC ( &efi_file_root, "EFIFILE disk write ID %#08x offset %#08llx <- "
955 "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
956 data, ( ( size_t ) len ) );
957 return EFI_NO_MEDIA;
958}
959
960/** Dummy EFI disk I/O protocol */
966
967/**
968 * Claim use of fixed device path
969 *
970 * @v file Fixed device path file
971 * @ret rc Return status code
972 *
973 * The design choice in Linux of using a single fixed device path is
974 * unfortunately messy to support, since device paths must be unique
975 * within a system. When multiple bootloaders are used (e.g. GRUB
976 * loading iPXE loading Linux) then only one bootloader can ever
977 * install the device path onto a handle. Bootloaders must therefore
978 * be prepared to locate an existing handle and uninstall its device
979 * path protocol instance before installing a new handle with the
980 * required device path.
981 */
982static int efi_file_path_claim ( struct efi_file_path *file ) {
983 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
987 EFI_STATUS efirc;
988 int rc;
989
990 /* Sanity check */
991 assert ( file->handle == NULL );
992
993 /* Locate handle with this device path, if any */
994 end = file->path;
995 if ( ( ( efirc = bs->LocateDevicePath ( &efi_device_path_protocol_guid,
996 &end, &handle ) ) != 0 ) ||
997 ( end->Type != END_DEVICE_PATH_TYPE ) ) {
998 return 0;
999 }
1000
1001 /* Locate device path protocol on this handle */
1003 &old ) != 0 ) ) {
1004 DBGC ( file, "EFIFILE %s could not locate %s: %s\n",
1005 efi_file_name ( &file->file ),
1006 efi_devpath_text ( file->path ), strerror ( rc ) );
1007 return rc;
1008 }
1009
1010 /* Uninstall device path protocol, leaving other protocols untouched */
1011 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1012 handle,
1014 NULL ) ) != 0 ) {
1015 rc = -EEFI ( efirc );
1016 DBGC ( file, "EFIFILE %s could not claim %s: %s\n",
1017 efi_file_name ( &file->file ),
1018 efi_devpath_text ( file->path ), strerror ( rc ) );
1019 return rc;
1020 }
1021
1022 DBGC ( file, "EFIFILE %s claimed %s",
1023 efi_file_name ( &file->file ), efi_devpath_text ( file->path ) );
1024 DBGC ( file, " from %s\n", efi_handle_name ( handle ) );
1025 return 0;
1026}
1027
1028/**
1029 * Install fixed device path file
1030 *
1031 * @v file Fixed device path file
1032 * @ret rc Return status code
1033 *
1034 * Linux 5.7 added the ability to autodetect an initrd by searching
1035 * for a handle via a fixed vendor-specific "Linux initrd device path"
1036 * and then locating and using the EFI_LOAD_FILE2_PROTOCOL instance on
1037 * that handle.
1038 */
1040 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1041 EFI_STATUS efirc;
1042 int rc;
1043
1044 /* Sanity check */
1045 assert ( file->handle == NULL );
1046
1047 /* Create a new handle with this device path */
1048 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1049 &file->handle,
1052 NULL ) ) != 0 ) {
1053 rc = -EEFI ( efirc );
1054 DBGC ( file, "EFIFILE %s could not install %s: %s\n",
1055 efi_file_name ( &file->file ),
1056 efi_devpath_text ( file->path ), strerror ( rc ) );
1057 return rc;
1058 }
1059
1060 DBGC ( file, "EFIFILE %s installed as %s\n",
1061 efi_file_name ( &file->file ), efi_devpath_text ( file->path ) );
1062 return 0;
1063}
1064
1065/**
1066 * Uninstall fixed device path file
1067 *
1068 * @v file Fixed device path file
1069 * @ret rc Return status code
1070 */
1072 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1073 EFI_STATUS efirc;
1074 int rc;
1075
1076 /* Do nothing if file is already uninstalled */
1077 if ( ! file->handle )
1078 return;
1079
1080 /* Uninstall protocols. Do this via two separate calls, in
1081 * case another executable has already uninstalled the device
1082 * path protocol from our handle.
1083 */
1084 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1085 file->handle,
1087 NULL ) ) != 0 ) {
1088 rc = -EEFI ( efirc );
1089 DBGC ( file, "EFIFILE %s could not uninstall %s: %s\n",
1090 efi_file_name ( &file->file ),
1091 efi_devpath_text ( file->path ), strerror ( rc ) );
1092 /* Continue uninstalling */
1093 }
1094 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1095 file->handle,
1097 NULL ) ) != 0 ) {
1098 rc = -EEFI ( efirc );
1099 DBGC ( file, "EFIFILE %s could not uninstall %s: %s\n",
1100 efi_file_name ( &file->file ),
1102 strerror ( rc ) );
1103 /* Continue uninstalling */
1104 }
1105
1106 /* Mark handle as uninstalled */
1107 file->handle = NULL;
1108}
1109
1110/**
1111 * Install EFI simple file system protocol
1112 *
1113 * @v handle EFI handle
1114 * @ret rc Return status code
1115 */
1117 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1118 EFI_DISK_IO_PROTOCOL *diskio;
1119 struct image *image;
1120 EFI_STATUS efirc;
1121 int rc;
1122
1123 /* Reset root directory state */
1124 efi_file_root.pos = 0;
1125
1126 /* Install the simple file system protocol, block I/O
1127 * protocol, and disk I/O protocol. We don't have a block
1128 * device, but large parts of the EDK2 codebase make the
1129 * assumption that file systems are normally attached to block
1130 * devices, and so we create a dummy block device on the same
1131 * handle just to keep things looking normal.
1132 */
1133 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1134 &handle,
1141 rc = -EEFI ( efirc );
1142 DBGC ( handle, "Could not install simple file system "
1143 "protocols: %s\n", strerror ( rc ) );
1144 goto err_install;
1145 }
1146
1147 /* The FAT filesystem driver has a bug: if a block device
1148 * contains no FAT filesystem but does have an
1149 * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instance, the FAT driver
1150 * will assume that it must have previously installed the
1151 * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. This causes the FAT
1152 * driver to claim control of our device, and to refuse to
1153 * stop driving it, which prevents us from later uninstalling
1154 * correctly.
1155 *
1156 * Work around this bug by opening the disk I/O protocol
1157 * ourselves, thereby preventing the FAT driver from opening
1158 * it.
1159 *
1160 * Note that the alternative approach of opening the block I/O
1161 * protocol (and thereby in theory preventing DiskIo from
1162 * attaching to the block I/O protocol) causes an endless loop
1163 * of calls to our DRIVER_STOP method when starting the EFI
1164 * shell. I have no idea why this is.
1165 */
1167 &diskio ) ) != 0 ) {
1168 DBGC ( handle, "Could not open disk I/O protocol: %s\n",
1169 strerror ( rc ) );
1171 goto err_open;
1172 }
1173 assert ( diskio == &efi_disk_io_protocol );
1174
1175 /* Claim Linux initrd fixed device path */
1176 if ( ( rc = efi_file_path_claim ( &efi_file_initrd ) ) != 0 )
1177 goto err_initrd_claim;
1178
1179 /* Install Linux initrd fixed device path file if non-empty */
1180 for_each_image ( image ) {
1181 if ( image->flags & IMAGE_HIDDEN )
1182 continue;
1183 if ( ( rc = efi_file_path_install ( &efi_file_initrd ) ) != 0 )
1184 goto err_initrd_install;
1185 break;
1186 }
1187
1188 return 0;
1189
1191 err_initrd_install:
1192 err_initrd_claim:
1194 err_open:
1196 handle,
1203 err_install:
1204 return rc;
1205}
1206
1207/**
1208 * Uninstall EFI simple file system protocol
1209 *
1210 * @v handle EFI handle
1211 */
1213 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1214 EFI_STATUS efirc;
1215 int rc;
1216
1217 /* Uninstall Linux initrd fixed device path file */
1219
1220 /* Close our own disk I/O protocol */
1222
1223 /* We must install the file system protocol first, since
1224 * otherwise the EDK2 code will attempt to helpfully uninstall
1225 * it when the block I/O protocol is uninstalled, leading to a
1226 * system lock-up.
1227 */
1228 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1229 handle,
1235 &efi_block_io_protocol, NULL ) ) != 0 ) {
1236 rc = -EEFI ( efirc );
1237 DBGC ( handle, "Could not uninstall simple file system "
1238 "protocols: %s\n", strerror ( rc ) );
1239 /* Oh dear */
1240 }
1241}
unsigned char BOOLEAN
Logical Boolean.
UINT64 UINTN
Unsigned value of native width.
unsigned long long UINT64
8-byte unsigned value.
unsigned short CHAR16
2-byte Character.
#define EFIAPI
unsigned int UINT32
4-byte unsigned value.
#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_REVISION
Definition BlockIo.h:205
struct _EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL
Definition BlockIo.h:23
#define MEDIA_DEVICE_PATH
#define END_ENTIRE_DEVICE_PATH_SUBTYPE
#define END_DEVICE_PATH_TYPE
#define MEDIA_VENDOR_DP
Media vendor device path subtype.
Disk IO protocol as defined in the UEFI 2.0 specification.
#define EFI_DISK_IO_PROTOCOL_REVISION
Definition DiskIo.h:91
struct _EFI_DISK_IO_PROTOCOL EFI_DISK_IO_PROTOCOL
Definition DiskIo.h:29
Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.SetInfo() and EFI_FILE_P...
#define SIZE_OF_EFI_FILE_INFO
The FileName field of the EFI_FILE_INFO data structure is variable length.
Definition FileInfo.h:65
Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.GetInfo() or EFI_FILE_PR...
#define SIZE_OF_EFI_FILE_SYSTEM_INFO
The VolumeLabel field of the EFI_FILE_SYSTEM_INFO data structure is variable length.
Load File protocol as defined in the UEFI 2.0 specification.
struct _EFI_LOAD_FILE2_PROTOCOL EFI_LOAD_FILE2_PROTOCOL
Definition LoadFile2.h:31
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
#define EFI_FILE_PROTOCOL_REVISION
#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
#define EFI_FILE_DIRECTORY
#define EFI_FILE_MODE_READ
#define EFI_FILE_READ_ONLY
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
UINT64 EFI_LBA
Logical block address.
#define EFI_WRITE_PROTECTED
Enumeration of EFI_STATUS.
#define EFI_NO_MEDIA
Enumeration of EFI_STATUS.
#define EFI_NOT_FOUND
Enumeration of EFI_STATUS.
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
GUID EFI_GUID
128-bit buffer containing a unique identifier value.
#define EFI_BUFFER_TOO_SMALL
Enumeration of EFI_STATUS.
#define EFI_OUT_OF_RESOURCES
Enumeration of EFI_STATUS.
#define EFI_WARN_DELETE_FAILURE
Enumeration of EFI_STATUS.
u32 info
Definition ar9003_mac.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
__SIZE_TYPE__ size_t
Definition stdint.h:6
long index
Definition bigint.h:65
long pad_len
Definition bigint.h:31
int old
Definition bitops.h:65
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
const char * name
Definition ath9k_hw.c:1986
uint16_t offset
Offset to command line.
Definition bzimage.h:3
size_t cpio_header(struct image *image, unsigned int index, struct cpio_header *cpio)
Construct CPIO header for image, if applicable.
Definition cpio.c:156
CPIO archives.
static size_t cpio_pad_len(size_t len)
Get CPIO header zero-padding length.
Definition cpio.h:82
static const char * cpio_name(struct image *image)
Get CPIO image name.
Definition cpio.h:71
static unsigned short vendor
Definition davicom.c:128
ring len
Length.
Definition dwmac.h:226
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
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
static EFI_STATUS EFIAPI efi_file_read(EFI_FILE_PROTOCOL *this, UINTN *len, VOID *data)
Read from file.
Definition efi_file.c:577
static EFI_STATUS EFIAPI efi_block_io_write_blocks(EFI_BLOCK_IO_PROTOCOL *this __unused, UINT32 MediaId, EFI_LBA lba, UINTN len, VOID *data)
Dummy block I/O write.
Definition efi_file.c:902
static size_t efi_file_read_image(struct efi_file_reader *reader)
Read from image-backed file.
Definition efi_file.c:227
static EFI_STATUS EFIAPI efi_file_open_volume(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *filesystem __unused, EFI_FILE_PROTOCOL **file)
Open root directory.
Definition efi_file.c:867
static EFI_SIMPLE_FILE_SYSTEM_PROTOCOL efi_simple_file_system_protocol
EFI simple file system protocol.
Definition efi_file.c:875
static void efi_file_image(struct efi_file *file, struct image *image)
Associate file with image.
Definition efi_file.c:324
static EFI_STATUS efi_file_varlen(UINT64 *base, size_t base_len, const char *name, UINTN *len, VOID *data)
Return variable-length data structure.
Definition efi_file.c:480
static EFI_STATUS EFIAPI efi_block_io_reset(EFI_BLOCK_IO_PROTOCOL *this __unused, BOOLEAN extended)
Dummy block I/O reset.
Definition efi_file.c:882
static void efi_file_path_uninstall(struct efi_file_path *file)
Uninstall fixed device path file.
Definition efi_file.c:1071
static EFI_STATUS EFIAPI efi_file_delete(EFI_FILE_PROTOCOL *this)
Close and delete file.
Definition efi_file.c:458
static EFI_STATUS EFIAPI efi_file_get_info(EFI_FILE_PROTOCOL *this, EFI_GUID *type, UINTN *len, VOID *data)
Get file information.
Definition efi_file.c:680
static EFI_STATUS efi_file_info(struct efi_file *file, UINTN *len, VOID *data)
Return file information structure.
Definition efi_file.c:509
static size_t efi_file_len(struct efi_file *file)
Get length of EFI file.
Definition efi_file.c:159
static size_t efi_file_read_chunk(struct efi_file_reader *reader, const void *data, size_t len)
Read chunk of EFI file.
Definition efi_file.c:186
static EFI_STATUS EFIAPI efi_disk_io_write_disk(EFI_DISK_IO_PROTOCOL *this __unused, UINT32 MediaId, UINT64 offset, UINTN len, VOID *data)
Dummy disk I/O write.
Definition efi_file.c:951
static EFI_BLOCK_IO_MEDIA efi_block_io_media
Dummy block I/O media.
Definition efi_file.c:921
static EFI_BLOCK_IO_PROTOCOL efi_block_io_protocol
Dummy EFI block I/O protocol.
Definition efi_file.c:929
static int efi_file_path_install(struct efi_file_path *file)
Install fixed device path file.
Definition efi_file.c:1039
static EFI_STATUS efi_file_open_image(struct image *image, const wchar_t *wname, EFI_FILE_PROTOCOL **new)
Open image-backed file.
Definition efi_file.c:339
static struct efi_file_path efi_file_initrd
Magic initrd file.
Definition efi_file.c:109
#define LINUX_INITRD_VENDOR_GUID
Linux initrd fixed device path vendor GUID.
Definition efi_file.c:59
static void efi_file_free(struct refcnt *refcnt)
Free EFI file.
Definition efi_file.c:116
static EFI_STATUS EFIAPI efi_file_set_info(EFI_FILE_PROTOCOL *this, EFI_GUID *type, UINTN len __unused, VOID *data __unused)
Set file information.
Definition efi_file.c:726
int efi_file_install(EFI_HANDLE handle)
Install EFI simple file system protocol.
Definition efi_file.c:1116
static EFI_STATUS EFIAPI efi_file_open(EFI_FILE_PROTOCOL *this, EFI_FILE_PROTOCOL **new, CHAR16 *wname, UINT64 mode, UINT64 attributes __unused)
Open file.
Definition efi_file.c:372
static EFI_STATUS efi_file_read_dir(struct efi_file *file, UINTN *len, VOID *data)
Read directory entry.
Definition efi_file.c:537
void efi_file_uninstall(EFI_HANDLE handle)
Uninstall EFI simple file system protocol.
Definition efi_file.c:1212
static struct efi_file efi_file_root
Root directory.
Definition efi_file.c:108
static struct image * efi_file_find(const char *name)
Find EFI file image.
Definition efi_file.c:141
static EFI_STATUS EFIAPI efi_block_io_flush_blocks(EFI_BLOCK_IO_PROTOCOL *this __unused)
Dummy block I/O flush.
Definition efi_file.c:914
static int efi_file_path_claim(struct efi_file_path *file)
Claim use of fixed device path.
Definition efi_file.c:982
static EFI_STATUS EFIAPI efi_file_write(EFI_FILE_PROTOCOL *this, UINTN *len, VOID *data __unused)
Write to file.
Definition efi_file.c:610
static EFI_STATUS EFIAPI efi_file_load(EFI_LOAD_FILE2_PROTOCOL *this, EFI_DEVICE_PATH_PROTOCOL *path __unused, BOOLEAN boot __unused, UINTN *len, VOID *data)
Load file.
Definition efi_file.c:762
#define EFI_MEDIA_ID_MAGIC
EFI media ID.
Definition efi_file.c:56
static EFI_STATUS efi_file_open_fixed(struct efi_file *file, const wchar_t *wname, EFI_FILE_PROTOCOL **new)
Open fixed file.
Definition efi_file.c:303
static struct @155172135212117201227002307145202243102020027056 efi_file_initrd_path
Linux initrd fixed device path.
static const char * efi_file_name(struct efi_file *file)
Get EFI file name (for debugging)
Definition efi_file.c:130
static EFI_STATUS EFIAPI efi_file_flush(EFI_FILE_PROTOCOL *this)
Flush file modified data.
Definition efi_file.c:744
static EFI_STATUS EFIAPI efi_block_io_read_blocks(EFI_BLOCK_IO_PROTOCOL *this __unused, UINT32 MediaId, EFI_LBA lba, UINTN len, VOID *data)
Dummy block I/O read.
Definition efi_file.c:891
static EFI_DISK_IO_PROTOCOL efi_disk_io_protocol
Dummy EFI disk I/O protocol.
Definition efi_file.c:961
static EFI_STATUS EFIAPI efi_file_set_position(EFI_FILE_PROTOCOL *this, UINT64 position)
Set file position.
Definition efi_file.c:627
static EFI_STATUS EFIAPI efi_disk_io_read_disk(EFI_DISK_IO_PROTOCOL *this __unused, UINT32 MediaId, UINT64 offset, UINTN len, VOID *data)
Dummy disk I/O read.
Definition efi_file.c:940
static EFI_STATUS EFIAPI efi_file_close(EFI_FILE_PROTOCOL *this)
Close file.
Definition efi_file.c:442
static EFI_STATUS EFIAPI efi_file_get_position(EFI_FILE_PROTOCOL *this, UINT64 *position)
Get file position.
Definition efi_file.c:663
static size_t efi_file_read_initrd(struct efi_file_reader *reader)
Read from magic initrd file.
Definition efi_file.c:241
EFI file protocols.
EFI_GUID efi_load_file2_protocol_guid
Load file 2 protocol GUID.
Definition efi_guid.c:269
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition efi_guid.c:726
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_disk_io_protocol_guid
Disk I/O protocol GUID.
Definition efi_guid.c:189
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition efi_guid.c:337
EFI_GUID efi_file_info_id
File information GUID.
Definition efi_guid.c:463
void efi_close_by_driver(EFI_HANDLE handle, EFI_GUID *protocol)
Close protocol opened for persistent use by a driver.
Definition efi_open.c:279
EFI device paths.
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
EFI strings.
uint8_t filesystem
System type.
Definition eltorito.h:12
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint16_t mode
Acceleration mode.
Definition ena.h:15
Error codes.
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBGC(...)
Definition compiler.h:505
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 FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
struct image * find_image_tag(struct image_tag *tag)
Find image by tag.
Definition image.c:393
Executable images.
static struct image * image_get(struct image *image)
Increment reference count on an image.
Definition image.h:240
static void image_put(struct image *image)
Decrement reference count on an image.
Definition image.h:250
#define for_each_image(image)
Iterate over all registered images.
Definition image.h:191
struct image_tag selected_image
#define IMAGE_HIDDEN
Image will be hidden from enumeration.
Definition image.h:86
#define __attribute__(x)
Definition compiler.h:10
EFI API.
#define efi_open_by_driver(handle, protocol, interface)
Open protocol for persistent use by a driver.
Definition efi.h:474
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition efi.h:444
#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 DBGC_EFI_OPENERS(...)
Definition efi.h:345
EFI_SYSTEM_TABLE * efi_systab
uint16_t handle
Handle.
Definition smbios.h:5
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
String functions.
Initial ramdisk (initrd) reshuffling.
#define INITRD_ALIGN
Initial ramdisk chunk alignment.
Definition initrd.h:17
uint32_t base
Base.
Definition librm.h:3
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
uint32_t end
Ending offset.
Definition netvsc.h:7
void ref_no_free(struct refcnt *refcnt __unused)
Do not free reference-counted object.
Definition refcnt.c:102
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition refcnt.h:78
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
__WCHAR_TYPE__ wchar_t
Definition stddef.h:50
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int strncasecmp(const char *first, const char *second, size_t max)
Compare case-insensitive strings.
Definition string.c:222
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
char * strrchr(const char *src, int character)
Find rightmost character within a string.
Definition string.c:290
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
Block IO read only mode data and updated only via members of BlockIO.
Definition BlockIo.h:131
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
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition UefiSpec.h:1972
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition DevicePath.h:46
BOOLEAN ReadOnly
TRUE if the volume only supports read access.
UINT64 VolumeSize
The number of bytes managed by the file system.
UINT64 Size
The size of the EFI_FILE_SYSTEM_INFO structure, including the Null-terminated VolumeLabel string.
The Vendor Device Path allows the creation of vendor-defined Device Paths.
Definition DevicePath.h:143
A CPIO archive header.
Definition cpio.h:21
An EFI fixed device path file.
Definition efi_file.c:99
EFI_DEVICE_PATH_PROTOCOL * path
Device path.
Definition efi_file.c:103
struct efi_file file
EFI file.
Definition efi_file.c:101
EFI_HANDLE handle
EFI handle.
Definition efi_file.c:105
An EFI virtual file reader.
Definition efi_file.c:64
struct efi_file * file
EFI file.
Definition efi_file.c:66
size_t len
Length of output data buffer.
Definition efi_file.c:72
void * data
Output data buffer.
Definition efi_file.c:70
size_t pos
Position within virtual file.
Definition efi_file.c:68
An EFI file.
Definition efi_file.c:76
size_t(* read)(struct efi_file_reader *reader)
Read from file.
Definition efi_file.c:95
const char * name
Filename.
Definition efi_file.c:86
EFI_FILE_PROTOCOL file
EFI file protocol.
Definition efi_file.c:80
struct refcnt refcnt
Reference count.
Definition efi_file.c:78
EFI_LOAD_FILE2_PROTOCOL load
EFI load file protocol.
Definition efi_file.c:82
struct image * image
Image (if any)
Definition efi_file.c:84
size_t pos
Current file position.
Definition efi_file.c:88
An executable image.
Definition image.h:24
unsigned int flags
Flags.
Definition image.h:40
const void * data
Read-only data.
Definition image.h:51
char * name
Name.
Definition image.h:38
size_t len
Length of raw file image.
Definition image.h:56
A reference counter.
Definition refcnt.h:27
#define TRUE
Definition tlan.h:46
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383
size_t wcslen(const wchar_t *string)
Calculate length of wide-character string.
Definition wchar.c:57