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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_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>
49 #include <ipxe/efi/Guid/FileInfo.h>
51 #include <ipxe/efi/efi_strings.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 */
76 struct 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 */
99 struct efi_file_path {
100  /** EFI file */
101  struct efi_file file;
102  /** Device path */
104  /** EFI handle */
106 };
107 
108 static struct efi_file efi_file_root;
110 
111 /**
112  * Free EFI file
113  *
114  * @v refcnt Reference count
115  */
116 static 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  */
130 static 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  */
141 static struct image * efi_file_find ( const char *name ) {
142  struct image *image;
143 
144  /* Find image */
145  for_each_image ( 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  */
159 static 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  */
186 static 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  */
227 static 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  */
241 static 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;
254  for_each_image ( image ) {
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  */
324 static void efi_file_image ( struct efi_file *file, struct image *image ) {
325 
326  file->image = image;
327  file->name = image->name;
328  file->read = efi_file_read_image;
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 )
347  return EFI_OUT_OF_RESOURCES;
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  */
371 static 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  */
480 static 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;
489  return EFI_BUFFER_TOO_SMALL;
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;
546  for_each_image ( image ) {
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 );
684  EFI_FILE_SYSTEM_INFO fsinfo;
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  */
725 static 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  */
761 static 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;
779  return EFI_BUFFER_TOO_SMALL;
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 */
790 static 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 */
813 static 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  },
823  .Guid = LINUX_INITRD_VENDOR_GUID,
824  },
825  .end = {
826  .Type = END_DEVICE_PATH_TYPE,
828  .Length[0] = sizeof ( efi_file_initrd_path.end ),
829  },
830 };
831 
832 /** Magic initrd file */
833 static 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  */
866 static EFI_STATUS EFIAPI
868  EFI_FILE_PROTOCOL **file ) {
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 */
877  .OpenVolume = efi_file_open_volume,
878 };
879 
880 /** Dummy block I/O reset */
881 static 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 */
890 static EFI_STATUS EFIAPI
892  EFI_LBA lba, UINTN len, VOID *data ) {
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 */
901 static 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 */
913 static EFI_STATUS EFIAPI
915 
916  DBGC ( &efi_file_root, "EFIFILE block flush\n" );
917  return 0;
918 }
919 
920 /** Dummy block I/O media */
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 */
939 static EFI_STATUS EFIAPI
941  UINT64 offset, UINTN len, VOID *data ) {
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 */
950 static EFI_STATUS EFIAPI
952  UINT64 offset, UINTN len, VOID *data ) {
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 */
963  .ReadDisk = efi_disk_io_read_disk,
964  .WriteDisk = efi_disk_io_write_disk,
965 };
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  */
982 static int efi_file_path_claim ( struct efi_file_path *file ) {
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  */
1039 static int efi_file_path_install ( struct efi_file_path *file ) {
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  */
1071 static void efi_file_path_uninstall ( struct efi_file_path *file ) {
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  */
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,
1140  &efi_simple_file_system_protocol, NULL ) ) != 0 ) {
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  */
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 }
VENDOR_DEVICE_PATH vendor
Definition: efi_file.c:814
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
#define __attribute__(x)
Definition: compiler.h:10
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
void * data
Output data buffer.
Definition: efi_file.c:70
struct image_tag selected_image
unsigned int flags
Flags.
Definition: image.h:40
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2099
uint32_t base
Base.
Definition: librm.h:138
static void efi_file_free(struct refcnt *refcnt)
Free EFI file.
Definition: efi_file.c:116
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:118
struct refcnt refcnt
Reference count.
Definition: efi_file.c:78
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1986
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
BOOLEAN ReadOnly
TRUE if the volume only supports read access.
An EFI virtual file reader.
Definition: efi_file.c:64
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
EFI file protocols.
UINT64 Revision
The version of the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:175
u32 info
Definition: ar9003_mac.h:24
static EFI_STATUS EFIAPI efi_file_get_position(EFI_FILE_PROTOCOL *this, UINT64 *position)
Get file position.
Definition: efi_file.c:663
static int efi_file_path_install(struct efi_file_path *file)
Install fixed device path file.
Definition: efi_file.c:1039
A CPIO archive header.
Definition: cpio.h:21
#define END_DEVICE_PATH_TYPE
Definition: DevicePath.h:1394
char * strrchr(const char *src, int character)
Find rightmost character within a string.
Definition: string.c:290
EFI_GUID efi_file_system_info_id
File system information GUID.
Definition: efi_guid.c:466
128 bit buffer containing a unique identifier value.
Definition: Base.h:216
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
Error codes.
__SIZE_TYPE__ size_t
Definition: stdint.h:6
const void * data
Read-only data.
Definition: image.h:51
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 void efi_file_path_uninstall(struct efi_file_path *file)
Uninstall fixed device path file.
Definition: efi_file.c:1071
EFI strings.
uint16_t mode
Acceleration mode.
Definition: ena.h:26
unsigned char BOOLEAN
Disk IO protocol as defined in the UEFI 2.0 specification.
uint32_t type
Operating system type.
Definition: ena.h:12
static EFI_BLOCK_IO_PROTOCOL efi_block_io_protocol
Dummy EFI block I/O protocol.
Definition: efi_file.c:929
static struct image * image_get(struct image *image)
Increment reference count on an image.
Definition: image.h:240
#define DBGC(...)
Definition: compiler.h:505
This protocol provides control over block devices.
Definition: BlockIo.h:217
long index
Definition: bigint.h:65
unsigned int UINT32
Definition: ProcessorBind.h:99
static struct @437 efi_file_initrd_path
Linux initrd fixed device path.
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:2010
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:209
int old
Definition: bitops.h:65
unsigned short CHAR16
void efi_file_uninstall(EFI_HANDLE handle)
Uninstall EFI simple file system protocol.
Definition: efi_file.c:1212
static EFI_STATUS EFIAPI efi_file_read(EFI_FILE_PROTOCOL *this, UINTN *len, VOID *data)
Read from file.
Definition: efi_file.c:577
int strncasecmp(const char *first, const char *second, size_t max)
Compare case-insensitive strings.
Definition: string.c:222
#define DBGC_EFI_OPENERS(...)
Definition: efi.h:345
An executable image.
Definition: image.h:24
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:46
#define EFI_FILE_READ_ONLY
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
#define EFI_BUFFER_TOO_SMALL
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:120
EFI_FILE_PROTOCOL file
EFI file protocol.
Definition: efi_file.c:80
#define EFI_FILE_DIRECTORY
#define SIZE_OF_EFI_FILE_INFO
The FileName field of the EFI_FILE_INFO data structure is variable length.
Definition: FileInfo.h:65
static EFI_DISK_IO_PROTOCOL efi_disk_io_protocol
Dummy EFI disk I/O protocol.
Definition: efi_file.c:961
static size_t cpio_pad_len(size_t len)
Get CPIO header zero-padding length.
Definition: cpio.h:82
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_NO_MEDIA
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:127
#define EFI_OUT_OF_RESOURCES
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:124
size_t wcslen(const wchar_t *string)
Calculate length of wide-character string.
Definition: wchar.c:57
EFI_GUID efi_disk_io_protocol_guid
Disk I/O protocol GUID.
Definition: efi_guid.c:189
CPIO archives.
#define INITRD_ALIGN
Initial ramdisk chunk alignment.
Definition: initrd.h:17
static size_t efi_file_len(struct efi_file *file)
Get length of EFI file.
Definition: efi_file.c:159
int efi_file_install(EFI_HANDLE handle)
Install EFI simple file system protocol.
Definition: efi_file.c:1116
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
A reference counter.
Definition: refcnt.h:27
struct image * find_image_tag(struct image_tag *tag)
Find image by tag.
Definition: image.c:393
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 efi_file_info(struct efi_file *file, UINTN *len, VOID *data)
Return file information structure.
Definition: efi_file.c:509
#define MEDIA_VENDOR_DP
Media vendor device path subtype.
Definition: DevicePath.h:1096
size_t pos
Current file position.
Definition: efi_file.c:88
struct efi_file * file
EFI file.
Definition: efi_file.c:66
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
void * memcpy(void *dest, const void *src, size_t len) __nonnull
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
size_t len
Length of output data buffer.
Definition: efi_file.c:72
static struct efi_file_path efi_file_initrd
Magic initrd file.
Definition: efi_file.c:109
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
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
SimpleFileSystem protocol as defined in the UEFI 2.0 specification.
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
Executable images.
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition: efi_guid.c:337
UINT64 EFI_LBA
Logical block address.
Definition: UefiBaseType.h:48
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
FILE_SECBOOT(PERMITTED)
#define efi_open_by_driver(handle, protocol, interface)
Open protocol for persistent use by a driver.
Definition: efi.h:474
The Vendor Device Path allows the creation of vendor-defined Device Paths.
Definition: DevicePath.h:143
ring len
Length.
Definition: dwmac.h:231
static struct efi_file efi_file_root
Root directory.
Definition: efi_file.c:108
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:107
#define EFI_DISK_IO_PROTOCOL_REVISION
Definition: DiskIo.h:91
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:247
uint8_t filesystem
System type.
Definition: eltorito.h:24
This protocol is used to abstract Block I/O interfaces.
Definition: DiskIo.h:101
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:652
static EFI_STATUS EFIAPI efi_file_set_position(EFI_FILE_PROTOCOL *this, UINT64 position)
Set file position.
Definition: efi_file.c:627
#define EFI_WRITE_PROTECTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:123
#define LINUX_INITRD_VENDOR_GUID
Linux initrd fixed device path vendor GUID.
Definition: efi_file.c:59
#define for_each_image(image)
Iterate over all registered images.
Definition: image.h:191
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
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 void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
EFI_GUID efi_load_file2_protocol_guid
Load file 2 protocol GUID.
Definition: efi_guid.c:269
#define EFIAPI
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
EFI Boot Services Table.
Definition: UefiSpec.h:1931
size_t len
Length of raw file image.
Definition: image.h:56
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:93
#define IMAGE_HIDDEN
Image will be hidden from enumeration.
Definition: image.h:86
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:2011
static EFI_STATUS EFIAPI efi_file_close(EFI_FILE_PROTOCOL *this)
Close file.
Definition: efi_file.c:442
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition: efi.h:444
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
uint64_t lba
Starting block number.
Definition: int13.h:22
static void image_put(struct image *image)
Decrement reference count on an image.
Definition: image.h:250
static EFI_STATUS EFIAPI efi_file_flush(EFI_FILE_PROTOCOL *this)
Flush file modified data.
Definition: efi_file.c:744
EFI device paths.
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:1012
UINT64 UINTN
Unsigned value of native width.
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:169
UINT64 VolumeSize
The number of bytes managed by the file system.
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
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition: efi_guid.c:726
static EFI_STATUS EFIAPI efi_file_write(EFI_FILE_PROTOCOL *this, UINTN *len, VOID *data __unused)
Write to file.
Definition: efi_file.c:610
#define VOID
Undeclared type.
Definition: Base.h:272
unsigned long long UINT64
Definition: ProcessorBind.h:97
Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.SetInfo() and EFI_FILE_P...
#define TRUE
Definition: tlan.h:46
#define EFI_FILE_PROTOCOL_REVISION
#define EFI_WARN_DELETE_FAILURE
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:151
EFI_DEVICE_PATH_PROTOCOL end
Definition: efi_file.c:815
EFI API.
#define EFI_MEDIA_ID_MAGIC
EFI media ID.
Definition: efi_file.c:56
EFI_HANDLE handle
EFI handle.
Definition: efi_file.c:105
static EFI_STATUS efi_file_read_dir(struct efi_file *file, UINTN *len, VOID *data)
Read directory entry.
Definition: efi_file.c:537
size_t pos
Position within virtual file.
Definition: efi_file.c:68
Block IO read only mode data and updated only via members of BlockIO.
Definition: BlockIo.h:131
EFI_LOAD_FILE2_PROTOCOL load
EFI load file protocol.
Definition: efi_file.c:82
long pad_len
Definition: bigint.h:31
static EFI_STATUS EFIAPI efi_file_delete(EFI_FILE_PROTOCOL *this)
Close and delete file.
Definition: efi_file.c:458
#define END_ENTIRE_DEVICE_PATH_SUBTYPE
Definition: DevicePath.h:1395
Initial ramdisk (initrd) reshuffling.
#define EFI_NOT_FOUND
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:129
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
Definition: efi_guid.c:145
#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
EFI_GUID efi_file_info_id
File information GUID.
Definition: efi_guid.c:463
#define EFI_FILE_MODE_READ
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:32
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
Block IO protocol as defined in the UEFI 2.0 specification.
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct image * image
Image (if any)
Definition: efi_file.c:84
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition: refcnt.h:78
EFI_DEVICE_PATH_PROTOCOL * path
Device path.
Definition: efi_file.c:103
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 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
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:47
EFI_SYSTEM_TABLE * efi_systab
UINT32 MediaId
The curent media Id.
Definition: BlockIo.h:135
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_block_io_flush_blocks(EFI_BLOCK_IO_PROTOCOL *this __unused)
Dummy block I/O flush.
Definition: efi_file.c:914
UINT64 Revision
The revision to which the block IO interface adheres.
Definition: BlockIo.h:223
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
size_t(* read)(struct efi_file_reader *reader)
Read from file.
Definition: efi_file.c:95
static EFI_SIMPLE_FILE_SYSTEM_PROTOCOL efi_simple_file_system_protocol
EFI simple file system protocol.
Definition: efi_file.c:875
An EFI fixed device path file.
Definition: efi_file.c:99
static size_t efi_file_read_initrd(struct efi_file_reader *reader)
Read from magic initrd file.
Definition: efi_file.c:241
uint16_t handle
Handle.
Definition: smbios.h:17
Load File protocol as defined in the UEFI 2.0 specification.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
char * name
Name.
Definition: image.h:38
#define EFI_BLOCK_IO_PROTOCOL_REVISION
Definition: BlockIo.h:205
UINT64 Revision
The revision to which the disk I/O interface adheres.
Definition: DiskIo.h:107
void ref_no_free(struct refcnt *refcnt __unused)
Do not free reference-counted object.
Definition: refcnt.c:102
static struct image * efi_file_find(const char *name)
Find EFI file image.
Definition: efi_file.c:141
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
UINT64 Size
The size of the EFI_FILE_SYSTEM_INFO structure, including the Null-terminated VolumeLabel string.
String functions.
Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.GetInfo() or EFI_FILE_PR...
static EFI_BLOCK_IO_MEDIA efi_block_io_media
Dummy block I/O media.
Definition: efi_file.c:921
An EFI file.
Definition: efi_file.c:76
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
Definition: efi.h:62
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition: UefiSpec.h:1972
const char * name
Filename.
Definition: efi_file.c:86
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
The EFI_LOAD_FILE_PROTOCOL is a simple protocol used to obtain files from arbitrary devices.
Definition: LoadFile2.h:75
#define SIZE_OF_EFI_FILE_SYSTEM_INFO
The VolumeLabel field of the EFI_FILE_SYSTEM_INFO data structure is variable length.
struct efi_file file
EFI file.
Definition: efi_file.c:101
String functions.
static const char * efi_file_name(struct efi_file *file)
Get EFI file name (for debugging)
Definition: efi_file.c:130
void * memset(void *dest, int character, size_t len) __nonnull
static const char * cpio_name(struct image *image)
Get CPIO image name.
Definition: cpio.h:71
static void efi_file_image(struct efi_file *file, struct image *image)
Associate file with image.
Definition: efi_file.c:324