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/efi/efi.h>
47 #include <ipxe/efi/Guid/FileInfo.h>
49 #include <ipxe/efi/efi_strings.h>
50 #include <ipxe/efi/efi_path.h>
51 #include <ipxe/efi/efi_file.h>
52 
53 /** EFI media ID */
54 #define EFI_MEDIA_ID_MAGIC 0x69505845
55 
56 /** Linux initrd fixed device path vendor GUID */
57 #define LINUX_INITRD_VENDOR_GUID \
58  { 0x5568e427, 0x68fc, 0x4f3d, \
59  { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } }
60 
61 /** An EFI virtual file reader */
63  /** EFI file */
64  struct efi_file *file;
65  /** Position within virtual file */
66  size_t pos;
67  /** Output data buffer */
68  void *data;
69  /** Length of output data buffer */
70  size_t len;
71 };
72 
73 /** An EFI file */
74 struct efi_file {
75  /** Reference count */
76  struct refcnt refcnt;
77  /** EFI file protocol */
79  /** EFI load file protocol */
81  /** Image (if any) */
82  struct image *image;
83  /** Filename */
84  const char *name;
85  /** Current file position */
86  size_t pos;
87  /**
88  * Read from file
89  *
90  * @v reader File reader
91  * @ret len Length read
92  */
93  size_t ( * read ) ( struct efi_file_reader *reader );
94 };
95 
96 /** An EFI fixed device path file */
97 struct efi_file_path {
98  /** EFI file */
99  struct efi_file file;
100  /** Device path */
102  /** EFI handle */
104 };
105 
106 static struct efi_file efi_file_root;
108 
109 /**
110  * Free EFI file
111  *
112  * @v refcnt Reference count
113  */
114 static void efi_file_free ( struct refcnt *refcnt ) {
115  struct efi_file *file =
116  container_of ( refcnt, struct efi_file, refcnt );
117 
118  image_put ( file->image );
119  free ( file );
120 }
121 
122 /**
123  * Get EFI file name (for debugging)
124  *
125  * @v file EFI file
126  * @ret name Name
127  */
128 static const char * efi_file_name ( struct efi_file *file ) {
129 
130  return ( file == &efi_file_root ? "<root>" : file->name );
131 }
132 
133 /**
134  * Find EFI file image
135  *
136  * @v name Filename
137  * @ret image Image, or NULL
138  */
139 static struct image * efi_file_find ( const char *name ) {
140  struct image *image;
141 
142  /* Find image */
143  for_each_image ( image ) {
144  if ( strcasecmp ( image->name, name ) == 0 )
145  return image;
146  }
147 
148  return NULL;
149 }
150 
151 /**
152  * Get length of EFI file
153  *
154  * @v file EFI file
155  * @ret len Length of file
156  */
157 static size_t efi_file_len ( struct efi_file *file ) {
158  struct efi_file_reader reader;
159 
160  /* If this is the root directory, then treat as length zero */
161  if ( ! file->read )
162  return 0;
163 
164  /* Initialise reader */
165  reader.file = file;
166  reader.pos = 0;
167  reader.data = NULL;
168  reader.len = 0;
169 
170  /* Perform dummy read to determine file length */
171  file->read ( &reader );
172 
173  return reader.pos;
174 }
175 
176 /**
177  * Read chunk of EFI file
178  *
179  * @v reader EFI file reader
180  * @v data Input data, or UNULL to zero-fill
181  * @v len Length of input data
182  * @ret len Length of output data
183  */
184 static size_t efi_file_read_chunk ( struct efi_file_reader *reader,
185  userptr_t data, size_t len ) {
186  struct efi_file *file = reader->file;
187  size_t offset;
188 
189  /* Calculate offset into input data */
190  offset = ( file->pos - reader->pos );
191 
192  /* Consume input data range */
193  reader->pos += len;
194 
195  /* Calculate output length */
196  if ( offset < len ) {
197  len -= offset;
198  } else {
199  len = 0;
200  }
201  if ( len > reader->len )
202  len = reader->len;
203 
204  /* Copy or zero output data */
205  if ( data ) {
206  copy_from_user ( reader->data, data, offset, len );
207  } else {
208  memset ( reader->data, 0, len );
209  }
210 
211  /* Consume output buffer */
212  file->pos += len;
213  reader->data += len;
214  reader->len -= len;
215 
216  return len;
217 }
218 
219 /**
220  * Read from image-backed file
221  *
222  * @v reader EFI file reader
223  * @ret len Length read
224  */
225 static size_t efi_file_read_image ( struct efi_file_reader *reader ) {
226  struct efi_file *file = reader->file;
227  struct image *image = file->image;
228 
229  /* Read from file */
230  return efi_file_read_chunk ( reader, image->data, image->len );
231 }
232 
233 /**
234  * Read from magic initrd file
235  *
236  * @v reader EFI file reader
237  * @ret len Length read
238  */
239 static size_t efi_file_read_initrd ( struct efi_file_reader *reader ) {
240  struct efi_file *file = reader->file;
241  struct cpio_header cpio;
242  struct image *image;
243  const char *name;
244  size_t pad_len;
245  size_t cpio_len;
246  size_t name_len;
247  size_t len;
248 
249  /* Read from file */
250  len = 0;
251  for_each_image ( image ) {
252 
253  /* Skip hidden images */
254  if ( image->flags & IMAGE_HIDDEN )
255  continue;
256 
257  /* Pad to alignment boundary */
258  pad_len = ( ( -reader->pos ) & ( INITRD_ALIGN - 1 ) );
259  if ( pad_len ) {
260  DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) pad\n",
261  efi_file_name ( file ), reader->pos,
262  ( reader->pos + pad_len ) );
263  }
264  len += efi_file_read_chunk ( reader, UNULL, pad_len );
265 
266  /* Read CPIO header, if applicable */
267  cpio_len = cpio_header ( image, &cpio );
268  if ( cpio_len ) {
269  name = cpio_name ( image );
270  name_len = cpio_name_len ( image );
271  pad_len = ( cpio_len - sizeof ( cpio ) - name_len );
272  DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) %s header\n",
273  efi_file_name ( file ), reader->pos,
274  ( reader->pos + cpio_len ), image->name );
275  len += efi_file_read_chunk ( reader,
276  virt_to_user ( &cpio ),
277  sizeof ( cpio ) );
278  len += efi_file_read_chunk ( reader,
279  virt_to_user ( name ),
280  name_len );
281  len += efi_file_read_chunk ( reader, UNULL, 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  /* Allow root directory itself to be opened */
390  if ( ( name[0] == '\0' ) || ( name[0] == '.' ) )
391  return efi_file_open_fixed ( &efi_file_root, wname, new );
392 
393  /* Fail unless opening from the root */
394  if ( file != &efi_file_root ) {
395  DBGC ( file, "EFIFILE %s is not a directory\n",
396  efi_file_name ( file ) );
397  return EFI_NOT_FOUND;
398  }
399 
400  /* Fail unless opening read-only */
401  if ( mode != EFI_FILE_MODE_READ ) {
402  DBGC ( file, "EFIFILE %s cannot be opened in mode %#08llx\n",
403  name, mode );
404  return EFI_WRITE_PROTECTED;
405  }
406 
407  /* Allow registered images to be opened */
408  if ( ( image = efi_file_find ( name ) ) != NULL )
409  return efi_file_open_image ( image, wname, new );
410 
411  /* Allow magic initrd to be opened */
412  if ( strcasecmp ( name, efi_file_initrd.file.name ) == 0 ) {
413  return efi_file_open_fixed ( &efi_file_initrd.file, wname,
414  new );
415  }
416 
417  /* Allow currently selected image to be opened as "grub*.efi",
418  * to work around buggy versions of the UEFI shim.
419  */
420  if ( ( strncasecmp ( name, "grub", 4 ) == 0 ) &&
421  ( ( sep = strrchr ( name, '.' ) ) != NULL ) &&
422  ( strcasecmp ( sep, ".efi" ) == 0 ) &&
423  ( ( image = find_image_tag ( &selected_image ) ) != NULL ) ) {
424  return efi_file_open_image ( image, wname, new );
425  }
426 
427  DBGC ( file, "EFIFILE %ls does not exist\n", wname );
428  return EFI_NOT_FOUND;
429 }
430 
431 /**
432  * Close file
433  *
434  * @v this EFI file
435  * @ret efirc EFI status code
436  */
438  struct efi_file *file = container_of ( this, struct efi_file, file );
439 
440  /* Close file */
441  DBGC ( file, "EFIFILE %s closed\n", efi_file_name ( file ) );
442  ref_put ( &file->refcnt );
443 
444  return 0;
445 }
446 
447 /**
448  * Close and delete file
449  *
450  * @v this EFI file
451  * @ret efirc EFI status code
452  */
454  struct efi_file *file = container_of ( this, struct efi_file, file );
455 
456  DBGC ( file, "EFIFILE %s cannot be deleted\n", efi_file_name ( file ) );
457 
458  /* Close file */
459  efi_file_close ( this );
460 
461  /* Warn of failure to delete */
463 }
464 
465 /**
466  * Return variable-length data structure
467  *
468  * @v base Base data structure (starting with UINT64)
469  * @v base_len Length of base data structure
470  * @v name Name to append to base data structure
471  * @v len Length of data buffer
472  * @v data Data buffer
473  * @ret efirc EFI status code
474  */
475 static EFI_STATUS efi_file_varlen ( UINT64 *base, size_t base_len,
476  const char *name, UINTN *len, VOID *data ) {
477  size_t name_len;
478 
479  /* Calculate structure length */
480  name_len = strlen ( name );
481  *base = ( base_len + ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
482  if ( *len < *base ) {
483  *len = *base;
484  return EFI_BUFFER_TOO_SMALL;
485  }
486 
487  /* Copy data to buffer */
488  *len = *base;
489  memcpy ( data, base, base_len );
490  efi_snprintf ( ( data + base_len ), ( name_len + 1 /* NUL */ ),
491  "%s", name );
492 
493  return 0;
494 }
495 
496 /**
497  * Return file information structure
498  *
499  * @v file EFI file
500  * @v len Length of data buffer
501  * @v data Data buffer
502  * @ret efirc EFI status code
503  */
505  VOID *data ) {
507  size_t file_len;
508 
509  /* Get file length */
510  file_len = efi_file_len ( file );
511 
512  /* Populate file information */
513  memset ( &info, 0, sizeof ( info ) );
514  info.FileSize = file_len;
515  info.PhysicalSize = file_len;
516  info.Attribute = EFI_FILE_READ_ONLY;
517  if ( file == &efi_file_root )
518  info.Attribute |= EFI_FILE_DIRECTORY;
519 
521  file->name, len, data );
522 }
523 
524 /**
525  * Read directory entry
526  *
527  * @v file EFI file
528  * @v len Length to read
529  * @v data Data buffer
530  * @ret efirc EFI status code
531  */
533  VOID *data ) {
534  EFI_STATUS efirc;
535  struct efi_file entry;
536  struct image *image;
537  unsigned int index;
538 
539  /* Construct directory entries for image-backed files */
540  index = file->pos;
541  for_each_image ( image ) {
542 
543  /* Skip hidden images */
544  if ( image->flags & IMAGE_HIDDEN )
545  continue;
546 
547  /* Skip preceding images */
548  if ( index-- )
549  continue;
550 
551  /* Construct directory entry */
552  efi_file_image ( &entry, image );
553  efirc = efi_file_info ( &entry, len, data );
554  if ( efirc == 0 )
555  file->pos++;
556  return efirc;
557  }
558 
559  /* No more entries */
560  *len = 0;
561  return 0;
562 }
563 
564 /**
565  * Read from file
566  *
567  * @v this EFI file
568  * @v len Length to read
569  * @v data Data buffer
570  * @ret efirc EFI status code
571  */
573  UINTN *len, VOID *data ) {
574  struct efi_file *file = container_of ( this, struct efi_file, file );
575  struct efi_file_reader reader;
576  size_t pos = file->pos;
577 
578  /* If this is the root directory, then construct a directory entry */
579  if ( ! file->read )
580  return efi_file_read_dir ( file, len, data );
581 
582  /* Initialise reader */
583  reader.file = file;
584  reader.pos = 0;
585  reader.data = data;
586  reader.len = *len;
587 
588  /* Read from the file */
589  DBGC ( file, "EFIFILE %s read [%#08zx,%#08zx)\n",
590  efi_file_name ( file ), pos, ( ( size_t ) ( pos + *len ) ) );
591  *len = file->read ( &reader );
592  assert ( ( pos + *len ) == file->pos );
593 
594  return 0;
595 }
596 
597 /**
598  * Write to file
599  *
600  * @v this EFI file
601  * @v len Length to write
602  * @v data Data buffer
603  * @ret efirc EFI status code
604  */
606  UINTN *len, VOID *data __unused ) {
607  struct efi_file *file = container_of ( this, struct efi_file, file );
608 
609  DBGC ( file, "EFIFILE %s cannot write [%#08zx, %#08zx)\n",
610  efi_file_name ( file ), file->pos,
611  ( ( size_t ) ( file->pos + *len ) ) );
612  return EFI_WRITE_PROTECTED;
613 }
614 
615 /**
616  * Set file position
617  *
618  * @v this EFI file
619  * @v position New file position
620  * @ret efirc EFI status code
621  */
623  UINT64 position ) {
624  struct efi_file *file = container_of ( this, struct efi_file, file );
625  size_t len;
626 
627  /* Get file length */
628  len = efi_file_len ( file );
629 
630  /* Check for the magic end-of-file value */
631  if ( position == 0xffffffffffffffffULL )
632  position = len;
633 
634  /* Fail if we attempt to seek past the end of the file (since
635  * we do not support writes).
636  */
637  if ( position > len ) {
638  DBGC ( file, "EFIFILE %s cannot seek to %#08llx of %#08zx\n",
639  efi_file_name ( file ), position, len );
640  return EFI_UNSUPPORTED;
641  }
642 
643  /* Set position */
644  file->pos = position;
645  DBGC ( file, "EFIFILE %s position set to %#08zx\n",
646  efi_file_name ( file ), file->pos );
647 
648  return 0;
649 }
650 
651 /**
652  * Get file position
653  *
654  * @v this EFI file
655  * @ret position New file position
656  * @ret efirc EFI status code
657  */
659  UINT64 *position ) {
660  struct efi_file *file = container_of ( this, struct efi_file, file );
661 
662  *position = file->pos;
663  return 0;
664 }
665 
666 /**
667  * Get file information
668  *
669  * @v this EFI file
670  * @v type Type of information
671  * @v len Buffer size
672  * @v data Buffer
673  * @ret efirc EFI status code
674  */
676  EFI_GUID *type,
677  UINTN *len, VOID *data ) {
678  struct efi_file *file = container_of ( this, struct efi_file, file );
679  EFI_FILE_SYSTEM_INFO fsinfo;
680  struct image *image;
681 
682  /* Determine information to return */
683  if ( memcmp ( type, &efi_file_info_id, sizeof ( *type ) ) == 0 ) {
684 
685  /* Get file information */
686  DBGC ( file, "EFIFILE %s get file information\n",
687  efi_file_name ( file ) );
688  return efi_file_info ( file, len, data );
689 
690  } else if ( memcmp ( type, &efi_file_system_info_id,
691  sizeof ( *type ) ) == 0 ) {
692 
693  /* Get file system information */
694  DBGC ( file, "EFIFILE %s get file system information\n",
695  efi_file_name ( file ) );
696  memset ( &fsinfo, 0, sizeof ( fsinfo ) );
697  fsinfo.ReadOnly = 1;
699  fsinfo.VolumeSize += image->len;
700  return efi_file_varlen ( &fsinfo.Size,
702  len, data );
703  } else {
704 
705  DBGC ( file, "EFIFILE %s cannot get information of type %s\n",
706  efi_file_name ( file ), efi_guid_ntoa ( type ) );
707  return EFI_UNSUPPORTED;
708  }
709 }
710 
711 /**
712  * Set file information
713  *
714  * @v this EFI file
715  * @v type Type of information
716  * @v len Buffer size
717  * @v data Buffer
718  * @ret efirc EFI status code
719  */
720 static EFI_STATUS EFIAPI
723  struct efi_file *file = container_of ( this, struct efi_file, file );
724 
725  DBGC ( file, "EFIFILE %s cannot set information of type %s\n",
727  return EFI_WRITE_PROTECTED;
728 }
729 
730 /**
731  * Flush file modified data
732  *
733  * @v this EFI file
734  * @v type Type of information
735  * @v len Buffer size
736  * @v data Buffer
737  * @ret efirc EFI status code
738  */
740  struct efi_file *file = container_of ( this, struct efi_file, file );
741 
742  DBGC ( file, "EFIFILE %s flushed\n", efi_file_name ( file ) );
743  return 0;
744 }
745 
746 /**
747  * Load file
748  *
749  * @v this EFI file loader
750  * @v path File path
751  * @v boot Boot policy
752  * @v len Buffer size
753  * @v data Buffer, or NULL
754  * @ret efirc EFI status code
755  */
756 static EFI_STATUS EFIAPI
759  BOOLEAN boot __unused, UINTN *len, VOID *data ) {
760  struct efi_file *file = container_of ( this, struct efi_file, load );
761  size_t max_len;
762  size_t file_len;
763  EFI_STATUS efirc;
764 
765  /* Calculate maximum length */
766  max_len = ( data ? *len : 0 );
767  DBGC ( file, "EFIFILE %s load at %p+%#zx\n",
768  efi_file_name ( file ), data, max_len );
769 
770  /* Check buffer size */
771  file_len = efi_file_len ( file );
772  if ( file_len > max_len ) {
773  *len = file_len;
774  return EFI_BUFFER_TOO_SMALL;
775  }
776 
777  /* Read from file */
778  if ( ( efirc = efi_file_read ( &file->file, len, data ) ) != 0 )
779  return efirc;
780 
781  return 0;
782 }
783 
784 /** Root directory */
785 static struct efi_file efi_file_root = {
786  .refcnt = REF_INIT ( ref_no_free ),
787  .file = {
788  .Revision = EFI_FILE_PROTOCOL_REVISION,
789  .Open = efi_file_open,
790  .Close = efi_file_close,
791  .Delete = efi_file_delete,
792  .Read = efi_file_read,
793  .Write = efi_file_write,
794  .GetPosition = efi_file_get_position,
795  .SetPosition = efi_file_set_position,
796  .GetInfo = efi_file_get_info,
797  .SetInfo = efi_file_set_info,
798  .Flush = efi_file_flush,
799  },
800  .load = {
801  .LoadFile = efi_file_load,
802  },
803  .image = NULL,
804  .name = "",
805 };
806 
807 /** Linux initrd fixed device path */
808 static struct {
811 } __attribute__ (( packed )) efi_file_initrd_path = {
812  .vendor = {
813  .Header = {
814  .Type = MEDIA_DEVICE_PATH,
815  .SubType = MEDIA_VENDOR_DP,
816  .Length[0] = sizeof ( efi_file_initrd_path.vendor ),
817  },
818  .Guid = LINUX_INITRD_VENDOR_GUID,
819  },
820  .end = {
821  .Type = END_DEVICE_PATH_TYPE,
823  .Length[0] = sizeof ( efi_file_initrd_path.end ),
824  },
825 };
826 
827 /** Magic initrd file */
828 static struct efi_file_path efi_file_initrd = {
829  .file = {
830  .refcnt = REF_INIT ( ref_no_free ),
831  .file = {
832  .Revision = EFI_FILE_PROTOCOL_REVISION,
833  .Open = efi_file_open,
834  .Close = efi_file_close,
835  .Delete = efi_file_delete,
836  .Read = efi_file_read,
837  .Write = efi_file_write,
838  .GetPosition = efi_file_get_position,
839  .SetPosition = efi_file_set_position,
840  .GetInfo = efi_file_get_info,
841  .SetInfo = efi_file_set_info,
842  .Flush = efi_file_flush,
843  },
844  .load = {
845  .LoadFile = efi_file_load,
846  },
847  .image = NULL,
848  .name = "initrd.magic",
849  .read = efi_file_read_initrd,
850  },
851  .path = &efi_file_initrd_path.vendor.Header,
852 };
853 
854 /**
855  * Open root directory
856  *
857  * @v filesystem EFI simple file system
858  * @ret file EFI file handle
859  * @ret efirc EFI status code
860  */
861 static EFI_STATUS EFIAPI
863  EFI_FILE_PROTOCOL **file ) {
864 
865  DBGC ( &efi_file_root, "EFIFILE open volume\n" );
866  return efi_file_open_fixed ( &efi_file_root, L"<volume>", file );
867 }
868 
869 /** EFI simple file system protocol */
872  .OpenVolume = efi_file_open_volume,
873 };
874 
875 /** Dummy block I/O reset */
876 static EFI_STATUS EFIAPI
878 
879  DBGC ( &efi_file_root, "EFIFILE block %sreset\n",
880  ( extended ? "extended " : "" ) );
881  return 0;
882 }
883 
884 /** Dummy block I/O read */
885 static EFI_STATUS EFIAPI
887  EFI_LBA lba, UINTN len, VOID *data ) {
888 
889  DBGC ( &efi_file_root, "EFIFILE block read ID %#08x LBA %#08llx -> "
890  "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
891  data, ( ( size_t ) len ) );
892  return EFI_NO_MEDIA;
893 }
894 
895 /** Dummy block I/O write */
896 static EFI_STATUS EFIAPI
898  UINT32 MediaId, EFI_LBA lba, UINTN len,
899  VOID *data ) {
900 
901  DBGC ( &efi_file_root, "EFIFILE block write ID %#08x LBA %#08llx <- "
902  "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
903  data, ( ( size_t ) len ) );
904  return EFI_NO_MEDIA;
905 }
906 
907 /** Dummy block I/O flush */
908 static EFI_STATUS EFIAPI
910 
911  DBGC ( &efi_file_root, "EFIFILE block flush\n" );
912  return 0;
913 }
914 
915 /** Dummy block I/O media */
918  .MediaPresent = TRUE,
919  .ReadOnly = TRUE,
920  .BlockSize = 1,
921 };
922 
923 /** Dummy EFI block I/O protocol */
926  .Media = &efi_block_io_media,
927  .Reset = efi_block_io_reset,
928  .ReadBlocks = efi_block_io_read_blocks,
929  .WriteBlocks = efi_block_io_write_blocks,
930  .FlushBlocks = efi_block_io_flush_blocks,
931 };
932 
933 /** Dummy disk I/O read */
934 static EFI_STATUS EFIAPI
936  UINT64 offset, UINTN len, VOID *data ) {
937 
938  DBGC ( &efi_file_root, "EFIFILE disk read ID %#08x offset %#08llx -> "
939  "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
940  data, ( ( size_t ) len ) );
941  return EFI_NO_MEDIA;
942 }
943 
944 /** Dummy disk I/O write */
945 static EFI_STATUS EFIAPI
947  UINT64 offset, UINTN len, VOID *data ) {
948 
949  DBGC ( &efi_file_root, "EFIFILE disk write ID %#08x offset %#08llx <- "
950  "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
951  data, ( ( size_t ) len ) );
952  return EFI_NO_MEDIA;
953 }
954 
955 /** Dummy EFI disk I/O protocol */
958  .ReadDisk = efi_disk_io_read_disk,
959  .WriteDisk = efi_disk_io_write_disk,
960 };
961 
962 /**
963  * Claim use of fixed device path
964  *
965  * @v file Fixed device path file
966  * @ret rc Return status code
967  *
968  * The design choice in Linux of using a single fixed device path is
969  * unfortunately messy to support, since device paths must be unique
970  * within a system. When multiple bootloaders are used (e.g. GRUB
971  * loading iPXE loading Linux) then only one bootloader can ever
972  * install the device path onto a handle. Bootloaders must therefore
973  * be prepared to locate an existing handle and uninstall its device
974  * path protocol instance before installing a new handle with the
975  * required device path.
976  */
977 static int efi_file_path_claim ( struct efi_file_path *file ) {
981  VOID *old;
982  EFI_STATUS efirc;
983  int rc;
984 
985  /* Sanity check */
986  assert ( file->handle == NULL );
987 
988  /* Locate handle with this device path, if any */
989  end = file->path;
990  if ( ( ( efirc = bs->LocateDevicePath ( &efi_device_path_protocol_guid,
991  &end, &handle ) ) != 0 ) ||
992  ( end->Type != END_DEVICE_PATH_TYPE ) ) {
993  return 0;
994  }
995 
996  /* Locate device path protocol on this handle */
997  if ( ( ( efirc = bs->HandleProtocol ( handle,
999  &old ) ) != 0 ) ) {
1000  rc = -EEFI ( efirc );
1001  DBGC ( file, "EFIFILE %s could not locate %s: %s\n",
1002  efi_file_name ( &file->file ),
1003  efi_devpath_text ( file->path ), strerror ( rc ) );
1004  return rc;
1005  }
1006 
1007  /* Uninstall device path protocol, leaving other protocols untouched */
1008  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1009  handle,
1011  NULL ) ) != 0 ) {
1012  rc = -EEFI ( efirc );
1013  DBGC ( file, "EFIFILE %s could not claim %s: %s\n",
1014  efi_file_name ( &file->file ),
1015  efi_devpath_text ( file->path ), strerror ( rc ) );
1016  return rc;
1017  }
1018 
1019  DBGC ( file, "EFIFILE %s claimed %s",
1020  efi_file_name ( &file->file ), efi_devpath_text ( file->path ) );
1021  DBGC ( file, " from %s\n", efi_handle_name ( handle ) );
1022  return 0;
1023 }
1024 
1025 /**
1026  * Install fixed device path file
1027  *
1028  * @v file Fixed device path file
1029  * @ret rc Return status code
1030  *
1031  * Linux 5.7 added the ability to autodetect an initrd by searching
1032  * for a handle via a fixed vendor-specific "Linux initrd device path"
1033  * and then locating and using the EFI_LOAD_FILE2_PROTOCOL instance on
1034  * that handle.
1035  */
1036 static int efi_file_path_install ( struct efi_file_path *file ) {
1038  EFI_STATUS efirc;
1039  int rc;
1040 
1041  /* Sanity check */
1042  assert ( file->handle == NULL );
1043 
1044  /* Create a new handle with this device path */
1045  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1046  &file->handle,
1049  NULL ) ) != 0 ) {
1050  rc = -EEFI ( efirc );
1051  DBGC ( file, "EFIFILE %s could not install %s: %s\n",
1052  efi_file_name ( &file->file ),
1053  efi_devpath_text ( file->path ), strerror ( rc ) );
1054  return rc;
1055  }
1056 
1057  DBGC ( file, "EFIFILE %s installed as %s\n",
1058  efi_file_name ( &file->file ), efi_devpath_text ( file->path ) );
1059  return 0;
1060 }
1061 
1062 /**
1063  * Uninstall fixed device path file
1064  *
1065  * @v file Fixed device path file
1066  * @ret rc Return status code
1067  */
1068 static void efi_file_path_uninstall ( struct efi_file_path *file ) {
1070  EFI_STATUS efirc;
1071  int rc;
1072 
1073  /* Do nothing if file is already uninstalled */
1074  if ( ! file->handle )
1075  return;
1076 
1077  /* Uninstall protocols. Do this via two separate calls, in
1078  * case another executable has already uninstalled the device
1079  * path protocol from our handle.
1080  */
1081  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1082  file->handle,
1084  NULL ) ) != 0 ) {
1085  rc = -EEFI ( efirc );
1086  DBGC ( file, "EFIFILE %s could not uninstall %s: %s\n",
1087  efi_file_name ( &file->file ),
1088  efi_devpath_text ( file->path ), strerror ( rc ) );
1089  /* Continue uninstalling */
1090  }
1091  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1092  file->handle,
1094  NULL ) ) != 0 ) {
1095  rc = -EEFI ( efirc );
1096  DBGC ( file, "EFIFILE %s could not uninstall %s: %s\n",
1097  efi_file_name ( &file->file ),
1099  strerror ( rc ) );
1100  /* Continue uninstalling */
1101  }
1102 
1103  /* Mark handle as uninstalled */
1104  file->handle = NULL;
1105 }
1106 
1107 /**
1108  * Install EFI simple file system protocol
1109  *
1110  * @v handle EFI handle
1111  * @ret rc Return status code
1112  */
1115  union {
1116  EFI_DISK_IO_PROTOCOL *diskio;
1117  void *interface;
1118  } 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  */
1166  if ( ( efirc = bs->OpenProtocol ( handle, &efi_disk_io_protocol_guid,
1167  &diskio.interface, efi_image_handle,
1168  handle,
1169  EFI_OPEN_PROTOCOL_BY_DRIVER ) ) != 0){
1170  rc = -EEFI ( efirc );
1171  DBGC ( handle, "Could not open disk I/O protocol: %s\n",
1172  strerror ( rc ) );
1174  goto err_open;
1175  }
1176  assert ( diskio.diskio == &efi_disk_io_protocol );
1177 
1178  /* Claim Linux initrd fixed device path */
1179  if ( ( rc = efi_file_path_claim ( &efi_file_initrd ) ) != 0 )
1180  goto err_initrd_claim;
1181 
1182  /* Install Linux initrd fixed device path file if non-empty */
1183  for_each_image ( image ) {
1184  if ( image->flags & IMAGE_HIDDEN )
1185  continue;
1186  if ( ( rc = efi_file_path_install ( &efi_file_initrd ) ) != 0 )
1187  goto err_initrd_install;
1188  break;
1189  }
1190 
1191  return 0;
1192 
1194  err_initrd_install:
1195  err_initrd_claim:
1198  err_open:
1200  handle,
1207  err_install:
1208  return rc;
1209 }
1210 
1211 /**
1212  * Uninstall EFI simple file system protocol
1213  *
1214  * @v handle EFI handle
1215  */
1218  EFI_STATUS efirc;
1219  int rc;
1220 
1221  /* Uninstall Linux initrd fixed device path file */
1223 
1224  /* Close our own disk I/O protocol */
1227 
1228  /* We must install the file system protocol first, since
1229  * otherwise the EDK2 code will attempt to helpfully uninstall
1230  * it when the block I/O protocol is uninstalled, leading to a
1231  * system lock-up.
1232  */
1233  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1234  handle,
1240  &efi_block_io_protocol, NULL ) ) != 0 ) {
1241  rc = -EEFI ( efirc );
1242  DBGC ( handle, "Could not uninstall simple file system "
1243  "protocols: %s\n", strerror ( rc ) );
1244  /* Oh dear */
1245  }
1246 }
VENDOR_DEVICE_PATH vendor
Definition: efi_file.c:809
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:721
#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:935
void * data
Output data buffer.
Definition: efi_file.c:68
struct image_tag selected_image
unsigned int flags
Flags.
Definition: image.h:36
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2030
size_t cpio_name_len(struct image *image)
Get CPIO image filename.
Definition: cpio.c:56
static void efi_file_free(struct refcnt *refcnt)
Free EFI file.
Definition: efi_file.c:114
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:117
struct refcnt refcnt
Reference count.
Definition: efi_file.c:76
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:62
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:675
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:171
userptr_t data
Raw file image.
Definition: image.h:41
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:658
static int efi_file_path_install(struct efi_file_path *file)
Install fixed device path file.
Definition: efi_file.c:1036
A CPIO archive header.
Definition: cpio.h:19
uint32_t lba
Start address.
Definition: scsi.h:23
#define END_DEVICE_PATH_TYPE
Definition: DevicePath.h:1371
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:393
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
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
uint16_t max_len
Maximum length (in bytes)
Definition: ntlm.h:18
static void efi_file_path_uninstall(struct efi_file_path *file)
Uninstall fixed device path file.
Definition: efi_file.c:1068
EFI strings.
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:924
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
static struct image * image_get(struct image *image)
Increment reference count on an image.
Definition: image.h:218
#define DBGC(...)
Definition: compiler.h:505
This protocol provides control over block devices.
Definition: BlockIo.h:216
unsigned int UINT32
Definition: ProcessorBind.h:98
#define EFI_OPEN_PROTOCOL_BY_DRIVER
Definition: UefiSpec.h:1302
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1945
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:1216
static EFI_STATUS EFIAPI efi_file_read(EFI_FILE_PROTOCOL *this, UINTN *len, VOID *data)
Read from file.
Definition: efi_file.c:572
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:321
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: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:886
#define EFI_BUFFER_TOO_SMALL
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:119
EFI_FILE_PROTOCOL file
EFI file protocol.
Definition: efi_file.c:78
#define EFI_FILE_DIRECTORY
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1936
#define SIZE_OF_EFI_FILE_INFO
The FileName field of the EFI_FILE_INFO data structure is variable length.
Definition: FileInfo.h:63
static const void * base
Base address.
Definition: crypto.h:335
static EFI_DISK_IO_PROTOCOL efi_disk_io_protocol
Dummy EFI disk I/O protocol.
Definition: efi_file.c:956
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:757
#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:41
EFI_GUID efi_disk_io_protocol_guid
Disk I/O protocol GUID.
Definition: efi_guid.c:163
CPIO archives.
static size_t efi_file_len(struct efi_file *file)
Get length of EFI file.
Definition: efi_file.c:157
int efi_file_install(EFI_HANDLE handle)
Install EFI simple file system protocol.
Definition: efi_file.c:1113
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:946
A reference counter.
Definition: refcnt.h:26
struct image * find_image_tag(struct image_tag *tag)
Find image by tag.
Definition: image.c:335
static size_t efi_file_read_image(struct efi_file_reader *reader)
Read from image-backed file.
Definition: efi_file.c:225
static EFI_STATUS efi_file_info(struct efi_file *file, UINTN *len, VOID *data)
Return file information structure.
Definition: efi_file.c:504
#define MEDIA_VENDOR_DP
Media vendor device path subtype.
Definition: DevicePath.h:1075
size_t pos
Current file position.
Definition: efi_file.c:86
struct efi_file * file
EFI file.
Definition: efi_file.c:64
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:862
void * memcpy(void *dest, const void *src, size_t len) __nonnull
size_t len
Length of output data buffer.
Definition: efi_file.c:70
static struct efi_file_path efi_file_initrd
Magic initrd file.
Definition: efi_file.c:107
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An object interface.
Definition: interface.h:124
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:303
UINT64 EFI_LBA
Logical block address.
Definition: UefiBaseType.h:47
The Vendor Device Path allows the creation of vendor-defined Device Paths.
Definition: DevicePath.h:142
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static struct efi_file efi_file_root
Root directory.
Definition: efi_file.c:106
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:106
EFI_HANDLE_PROTOCOL HandleProtocol
Definition: UefiSpec.h:1903
#define EFI_DISK_IO_PROTOCOL_REVISION
Definition: DiskIo.h:90
static size_t efi_file_read_chunk(struct efi_file_reader *reader, userptr_t data, size_t len)
Read chunk of EFI file.
Definition: efi_file.c:184
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:461
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:808
static EFI_STATUS EFIAPI efi_file_set_position(EFI_FILE_PROTOCOL *this, UINT64 position)
Set file position.
Definition: efi_file.c:622
#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:57
#define for_each_image(image)
Iterate over all registered images.
Definition: image.h:172
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition: efi_debug.c:254
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:475
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:239
#define EFIAPI
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1866
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
size_t len
Length of raw file image.
Definition: image.h:43
#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:73
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1946
static EFI_STATUS EFIAPI efi_file_close(EFI_FILE_PROTOCOL *this)
Close file.
Definition: efi_file.c:437
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
static void image_put(struct image *image)
Decrement reference count on an image.
Definition: image.h:228
static EFI_STATUS EFIAPI efi_file_flush(EFI_FILE_PROTOCOL *this)
Flush file modified data.
Definition: efi_file.c:739
EFI device paths.
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:991
UINT64 UINTN
Unsigned value of native width.
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
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:897
static EFI_STATUS EFIAPI efi_file_write(EFI_FILE_PROTOCOL *this, UINTN *len, VOID *data __unused)
Write to file.
Definition: efi_file.c:605
#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:810
EFI API.
#define EFI_MEDIA_ID_MAGIC
EFI media ID.
Definition: efi_file.c:54
EFI_HANDLE handle
EFI handle.
Definition: efi_file.c:103
static EFI_STATUS efi_file_read_dir(struct efi_file *file, UINTN *len, VOID *data)
Read directory entry.
Definition: efi_file.c:532
size_t pos
Position within virtual file.
Definition: efi_file.c:66
Block IO read only mode data and updated only via members of BlockIO.
Definition: BlockIo.h:130
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
EFI_LOAD_FILE2_PROTOCOL load
EFI load file protocol.
Definition: efi_file.c:80
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:453
#define END_ENTIRE_DEVICE_PATH_SUBTYPE
Definition: DevicePath.h:1372
#define INITRD_ALIGN
Alignment for CPIO archives within an initrd.
Definition: cpio.h:57
#define EFI_NOT_FOUND
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:128
#define UNULL
Equivalent of NULL for user pointers.
Definition: uaccess.h:36
uint32_t len
Length.
Definition: ena.h:14
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
Definition: efi_guid.c:119
#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
EFI_GUID efi_file_info_id
File information GUID.
Definition: efi_guid.c:390
#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)
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
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:82
#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:101
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:877
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
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1935
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:977
static EFI_STATUS EFIAPI efi_block_io_flush_blocks(EFI_BLOCK_IO_PROTOCOL *this __unused)
Dummy block I/O flush.
Definition: efi_file.c:909
UINT64 Revision
The revision to which the block IO interface adheres.
Definition: BlockIo.h:222
uint64_t index
Index of the first segment within the content.
Definition: pccrc.h:21
size_t(* read)(struct efi_file_reader *reader)
Read from file.
Definition: efi_file.c:93
static EFI_SIMPLE_FILE_SYSTEM_PROTOCOL efi_simple_file_system_protocol
EFI simple file system protocol.
Definition: efi_file.c:870
An EFI fixed device path file.
Definition: efi_file.c:97
static size_t efi_file_read_initrd(struct efi_file_reader *reader)
Read from magic initrd file.
Definition: efi_file.c:239
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:34
static struct @428 efi_file_initrd_path
Linux initrd fixed device path.
#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:139
#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:916
An EFI file.
Definition: efi_file.c:74
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
Definition: efi.h:59
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition: UefiSpec.h:1907
const char * name
Filename.
Definition: efi_file.c:84
#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.
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
struct efi_file file
EFI file.
Definition: efi_file.c:99
String functions.
static const char * efi_file_name(struct efi_file *file)
Get EFI file name (for debugging)
Definition: efi_file.c:128
void * memset(void *dest, int character, size_t len) __nonnull
size_t cpio_header(struct image *image, struct cpio_header *cpio)
Construct CPIO header for image, if applicable.
Definition: cpio.c:102
static const char * cpio_name(struct image *image)
Get CPIO image name.
Definition: cpio.h:66
static void efi_file_image(struct efi_file *file, struct image *image)
Associate file with image.
Definition: efi_file.c:323