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