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>
46 #include <ipxe/efi/Guid/FileInfo.h>
48 #include <ipxe/efi/efi_strings.h>
49 #include <ipxe/efi/efi_file.h>
50 
51 /** EFI media ID */
52 #define EFI_MEDIA_ID_MAGIC 0x69505845
53 
54 /** An EFI virtual file reader */
56  /** EFI file */
57  struct efi_file *file;
58  /** Position within virtual file */
59  size_t pos;
60  /** Output data buffer */
61  void *data;
62  /** Length of output data buffer */
63  size_t len;
64 };
65 
66 /** An EFI file */
67 struct efi_file {
68  /** Reference count */
69  struct refcnt refcnt;
70  /** EFI file protocol */
72  /** Image (if any) */
73  struct image *image;
74  /** Filename */
75  const char *name;
76  /** Current file position */
77  size_t pos;
78  /**
79  * Read from file
80  *
81  * @v reader File reader
82  * @ret len Length read
83  */
84  size_t ( * read ) ( struct efi_file_reader *reader );
85 };
86 
87 static struct efi_file efi_file_root;
88 static struct efi_file efi_file_initrd;
89 
90 /**
91  * Free EFI file
92  *
93  * @v refcnt Reference count
94  */
95 static void efi_file_free ( struct refcnt *refcnt ) {
96  struct efi_file *file =
97  container_of ( refcnt, struct efi_file, refcnt );
98 
99  image_put ( file->image );
100  free ( file );
101 }
102 
103 /**
104  * Get EFI file name (for debugging)
105  *
106  * @v file EFI file
107  * @ret name Name
108  */
109 static const char * efi_file_name ( struct efi_file *file ) {
110 
111  return ( file == &efi_file_root ? "<root>" : file->name );
112 }
113 
114 /**
115  * Find EFI file image
116  *
117  * @v name Filename
118  * @ret image Image, or NULL
119  */
120 static struct image * efi_file_find ( const char *name ) {
121  struct image *image;
122 
123  /* Find image */
125  if ( strcasecmp ( image->name, name ) == 0 )
126  return image;
127  }
128 
129  return NULL;
130 }
131 
132 /**
133  * Get length of EFI file
134  *
135  * @v file EFI file
136  * @ret len Length of file
137  */
138 static size_t efi_file_len ( struct efi_file *file ) {
139  struct efi_file_reader reader;
140 
141  /* If this is the root directory, then treat as length zero */
142  if ( ! file->read )
143  return 0;
144 
145  /* Initialise reader */
146  reader.file = file;
147  reader.pos = 0;
148  reader.data = NULL;
149  reader.len = 0;
150 
151  /* Perform dummy read to determine file length */
152  file->read ( &reader );
153 
154  return reader.pos;
155 }
156 
157 /**
158  * Read chunk of EFI file
159  *
160  * @v reader EFI file reader
161  * @v data Input data, or UNULL to zero-fill
162  * @v len Length of input data
163  * @ret len Length of output data
164  */
165 static size_t efi_file_read_chunk ( struct efi_file_reader *reader,
166  userptr_t data, size_t len ) {
167  struct efi_file *file = reader->file;
168  size_t offset;
169 
170  /* Calculate offset into input data */
171  offset = ( file->pos - reader->pos );
172 
173  /* Consume input data range */
174  reader->pos += len;
175 
176  /* Calculate output length */
177  if ( offset < len ) {
178  len -= offset;
179  } else {
180  len = 0;
181  }
182  if ( len > reader->len )
183  len = reader->len;
184 
185  /* Copy or zero output data */
186  if ( data ) {
187  copy_from_user ( reader->data, data, offset, len );
188  } else {
189  memset ( reader->data, 0, len );
190  }
191 
192  /* Consume output buffer */
193  file->pos += len;
194  reader->data += len;
195  reader->len -= len;
196 
197  return len;
198 }
199 
200 /**
201  * Read from image-backed file
202  *
203  * @v reader EFI file reader
204  * @ret len Length read
205  */
206 static size_t efi_file_read_image ( struct efi_file_reader *reader ) {
207  struct efi_file *file = reader->file;
208  struct image *image = file->image;
209 
210  /* Read from file */
211  return efi_file_read_chunk ( reader, image->data, image->len );
212 }
213 
214 /**
215  * Read from magic initrd file
216  *
217  * @v reader EFI file reader
218  * @ret len Length read
219  */
220 static size_t efi_file_read_initrd ( struct efi_file_reader *reader ) {
221  struct efi_file *file = reader->file;
222  struct cpio_header cpio;
223  struct image *image;
224  const char *name;
225  size_t pad_len;
226  size_t cpio_len;
227  size_t name_len;
228  size_t len;
229 
230  /* Read from file */
231  len = 0;
232  for_each_image ( image ) {
233 
234  /* Ignore currently executing image */
235  if ( image == current_image )
236  continue;
237 
238  /* Pad to alignment boundary */
239  pad_len = ( ( -reader->pos ) & ( INITRD_ALIGN - 1 ) );
240  if ( pad_len ) {
241  DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) pad\n",
242  efi_file_name ( file ), reader->pos,
243  ( reader->pos + pad_len ) );
244  }
245  len += efi_file_read_chunk ( reader, UNULL, pad_len );
246 
247  /* Read CPIO header, if applicable */
248  cpio_len = cpio_header ( image, &cpio );
249  if ( cpio_len ) {
250  name = cpio_name ( image );
251  name_len = cpio_name_len ( image );
252  pad_len = ( cpio_len - sizeof ( cpio ) - name_len );
253  DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) %s header\n",
254  efi_file_name ( file ), reader->pos,
255  ( reader->pos + cpio_len ), image->name );
256  len += efi_file_read_chunk ( reader,
257  virt_to_user ( &cpio ),
258  sizeof ( cpio ) );
259  len += efi_file_read_chunk ( reader,
260  virt_to_user ( name ),
261  name_len );
262  len += efi_file_read_chunk ( reader, UNULL, pad_len );
263  }
264 
265  /* Read file data */
266  DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) %s\n",
267  efi_file_name ( file ), reader->pos,
268  ( reader->pos + image->len ), image->name );
269  len += efi_file_read_chunk ( reader, image->data, image->len );
270  }
271 
272  return len;
273 }
274 
275 /**
276  * Open fixed file
277  *
278  * @v file EFI file
279  * @v new New EFI file
280  * @ret efirc EFI status code
281  */
283  EFI_FILE_PROTOCOL **new ) {
284 
285  /* Increment reference count */
286  ref_get ( &file->refcnt );
287 
288  /* Return opened file */
289  *new = &file->file;
290 
291  DBGC ( file, "EFIFILE %s opened\n", efi_file_name ( file ) );
292  return 0;
293 }
294 
295 /**
296  * Associate file with image
297  *
298  * @v file EFI file
299  * @v image Image
300  */
301 static void efi_file_image ( struct efi_file *file, struct image *image ) {
302 
303  file->image = image;
304  file->name = image->name;
305  file->read = efi_file_read_image;
306 }
307 
308 /**
309  * Open file
310  *
311  * @v this EFI file
312  * @ret new New EFI file
313  * @v wname Filename
314  * @v mode File mode
315  * @v attributes File attributes (for newly-created files)
316  * @ret efirc EFI status code
317  */
318 static EFI_STATUS EFIAPI
320  CHAR16 *wname, UINT64 mode, UINT64 attributes __unused ) {
321  struct efi_file *file = container_of ( this, struct efi_file, file );
322  char buf[ wcslen ( wname ) + 1 /* NUL */ ];
323  struct efi_file *new_file;
324  struct image *image;
325  char *name;
326 
327  /* Convert name to ASCII */
328  snprintf ( buf, sizeof ( buf ), "%ls", wname );
329  name = buf;
330 
331  /* Initial '\' indicates opening from the root directory */
332  while ( *name == '\\' ) {
333  file = &efi_file_root;
334  name++;
335  }
336 
337  /* Allow root directory itself to be opened */
338  if ( ( name[0] == '\0' ) || ( name[0] == '.' ) )
339  return efi_file_open_fixed ( &efi_file_root, new );
340 
341  /* Fail unless opening from the root */
342  if ( file != &efi_file_root ) {
343  DBGC ( file, "EFIFILE %s is not a directory\n",
344  efi_file_name ( file ) );
345  return EFI_NOT_FOUND;
346  }
347 
348  /* Fail unless opening read-only */
349  if ( mode != EFI_FILE_MODE_READ ) {
350  DBGC ( file, "EFIFILE %s cannot be opened in mode %#08llx\n",
351  name, mode );
352  return EFI_WRITE_PROTECTED;
353  }
354 
355  /* Allow magic initrd to be opened */
356  if ( strcasecmp ( name, efi_file_initrd.name ) == 0 )
357  return efi_file_open_fixed ( &efi_file_initrd, new );
358 
359  /* Identify image */
360  image = efi_file_find ( name );
361  if ( ! image ) {
362  DBGC ( file, "EFIFILE %s does not exist\n", name );
363  return EFI_NOT_FOUND;
364  }
365 
366  /* Allocate and initialise file */
367  new_file = zalloc ( sizeof ( *new_file ) );
368  if ( ! new_file )
369  return EFI_OUT_OF_RESOURCES;
370  ref_init ( &file->refcnt, efi_file_free );
371  memcpy ( &new_file->file, &efi_file_root.file,
372  sizeof ( new_file->file ) );
373  efi_file_image ( new_file, image_get ( image ) );
374  *new = &new_file->file;
375  DBGC ( new_file, "EFIFILE %s opened\n", efi_file_name ( new_file ) );
376 
377  return 0;
378 }
379 
380 /**
381  * Close file
382  *
383  * @v this EFI file
384  * @ret efirc EFI status code
385  */
387  struct efi_file *file = container_of ( this, struct efi_file, file );
388 
389  /* Close file */
390  DBGC ( file, "EFIFILE %s closed\n", efi_file_name ( file ) );
391  ref_put ( &file->refcnt );
392 
393  return 0;
394 }
395 
396 /**
397  * Close and delete file
398  *
399  * @v this EFI file
400  * @ret efirc EFI status code
401  */
403  struct efi_file *file = container_of ( this, struct efi_file, file );
404 
405  DBGC ( file, "EFIFILE %s cannot be deleted\n", efi_file_name ( file ) );
406 
407  /* Close file */
408  efi_file_close ( this );
409 
410  /* Warn of failure to delete */
412 }
413 
414 /**
415  * Return variable-length data structure
416  *
417  * @v base Base data structure (starting with UINT64)
418  * @v base_len Length of base data structure
419  * @v name Name to append to base data structure
420  * @v len Length of data buffer
421  * @v data Data buffer
422  * @ret efirc EFI status code
423  */
424 static EFI_STATUS efi_file_varlen ( UINT64 *base, size_t base_len,
425  const char *name, UINTN *len, VOID *data ) {
426  size_t name_len;
427 
428  /* Calculate structure length */
429  name_len = strlen ( name );
430  *base = ( base_len + ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
431  if ( *len < *base ) {
432  *len = *base;
433  return EFI_BUFFER_TOO_SMALL;
434  }
435 
436  /* Copy data to buffer */
437  *len = *base;
438  memcpy ( data, base, base_len );
439  efi_snprintf ( ( data + base_len ), ( name_len + 1 /* NUL */ ),
440  "%s", name );
441 
442  return 0;
443 }
444 
445 /**
446  * Return file information structure
447  *
448  * @v file EFI file
449  * @v len Length of data buffer
450  * @v data Data buffer
451  * @ret efirc EFI status code
452  */
454  VOID *data ) {
456  size_t file_len;
457 
458  /* Get file length */
459  file_len = efi_file_len ( file );
460 
461  /* Populate file information */
462  memset ( &info, 0, sizeof ( info ) );
463  info.FileSize = file_len;
464  info.PhysicalSize = file_len;
465  info.Attribute = EFI_FILE_READ_ONLY;
466  if ( file == &efi_file_root )
467  info.Attribute |= EFI_FILE_DIRECTORY;
468 
470  file->name, len, data );
471 }
472 
473 /**
474  * Read directory entry
475  *
476  * @v file EFI file
477  * @v len Length to read
478  * @v data Data buffer
479  * @ret efirc EFI status code
480  */
482  VOID *data ) {
483  EFI_STATUS efirc;
484  struct efi_file entry;
485  struct image *image;
486  unsigned int index;
487 
488  /* Construct directory entries for image-backed files */
489  index = file->pos;
490  for_each_image ( image ) {
491  if ( index-- == 0 ) {
492  efi_file_image ( &entry, image );
493  efirc = efi_file_info ( &entry, len, data );
494  if ( efirc == 0 )
495  file->pos++;
496  return efirc;
497  }
498  }
499 
500  /* No more entries */
501  *len = 0;
502  return 0;
503 }
504 
505 /**
506  * Read from file
507  *
508  * @v this EFI file
509  * @v len Length to read
510  * @v data Data buffer
511  * @ret efirc EFI status code
512  */
514  UINTN *len, VOID *data ) {
515  struct efi_file *file = container_of ( this, struct efi_file, file );
516  struct efi_file_reader reader;
517  size_t pos = file->pos;
518 
519  /* If this is the root directory, then construct a directory entry */
520  if ( ! file->read )
521  return efi_file_read_dir ( file, len, data );
522 
523  /* Initialise reader */
524  reader.file = file;
525  reader.pos = 0;
526  reader.data = data;
527  reader.len = *len;
528 
529  /* Read from the file */
530  DBGC ( file, "EFIFILE %s read [%#08zx,%#08zx)\n",
531  efi_file_name ( file ), pos, file->pos );
532  *len = file->read ( &reader );
533  assert ( ( pos + *len ) == file->pos );
534 
535  return 0;
536 }
537 
538 /**
539  * Write to file
540  *
541  * @v this EFI file
542  * @v len Length to write
543  * @v data Data buffer
544  * @ret efirc EFI status code
545  */
547  UINTN *len, VOID *data __unused ) {
548  struct efi_file *file = container_of ( this, struct efi_file, file );
549 
550  DBGC ( file, "EFIFILE %s cannot write [%#08zx, %#08zx)\n",
551  efi_file_name ( file ), file->pos,
552  ( ( size_t ) ( file->pos + *len ) ) );
553  return EFI_WRITE_PROTECTED;
554 }
555 
556 /**
557  * Set file position
558  *
559  * @v this EFI file
560  * @v position New file position
561  * @ret efirc EFI status code
562  */
564  UINT64 position ) {
565  struct efi_file *file = container_of ( this, struct efi_file, file );
566  size_t len;
567 
568  /* Get file length */
569  len = efi_file_len ( file );
570 
571  /* Check for the magic end-of-file value */
572  if ( position == 0xffffffffffffffffULL )
573  position = len;
574 
575  /* Fail if we attempt to seek past the end of the file (since
576  * we do not support writes).
577  */
578  if ( position > len ) {
579  DBGC ( file, "EFIFILE %s cannot seek to %#08llx of %#08zx\n",
580  efi_file_name ( file ), position, len );
581  return EFI_UNSUPPORTED;
582  }
583 
584  /* Set position */
585  file->pos = position;
586  DBGC ( file, "EFIFILE %s position set to %#08zx\n",
587  efi_file_name ( file ), file->pos );
588 
589  return 0;
590 }
591 
592 /**
593  * Get file position
594  *
595  * @v this EFI file
596  * @ret position New file position
597  * @ret efirc EFI status code
598  */
600  UINT64 *position ) {
601  struct efi_file *file = container_of ( this, struct efi_file, file );
602 
603  *position = file->pos;
604  return 0;
605 }
606 
607 /**
608  * Get file information
609  *
610  * @v this EFI file
611  * @v type Type of information
612  * @v len Buffer size
613  * @v data Buffer
614  * @ret efirc EFI status code
615  */
617  EFI_GUID *type,
618  UINTN *len, VOID *data ) {
619  struct efi_file *file = container_of ( this, struct efi_file, file );
620  EFI_FILE_SYSTEM_INFO fsinfo;
621  struct image *image;
622 
623  /* Determine information to return */
624  if ( memcmp ( type, &efi_file_info_id, sizeof ( *type ) ) == 0 ) {
625 
626  /* Get file information */
627  DBGC ( file, "EFIFILE %s get file information\n",
628  efi_file_name ( file ) );
629  return efi_file_info ( file, len, data );
630 
631  } else if ( memcmp ( type, &efi_file_system_info_id,
632  sizeof ( *type ) ) == 0 ) {
633 
634  /* Get file system information */
635  DBGC ( file, "EFIFILE %s get file system information\n",
636  efi_file_name ( file ) );
637  memset ( &fsinfo, 0, sizeof ( fsinfo ) );
638  fsinfo.ReadOnly = 1;
640  fsinfo.VolumeSize += image->len;
641  return efi_file_varlen ( &fsinfo.Size,
643  len, data );
644  } else {
645 
646  DBGC ( file, "EFIFILE %s cannot get information of type %s\n",
647  efi_file_name ( file ), efi_guid_ntoa ( type ) );
648  return EFI_UNSUPPORTED;
649  }
650 }
651 
652 /**
653  * Set file information
654  *
655  * @v this EFI file
656  * @v type Type of information
657  * @v len Buffer size
658  * @v data Buffer
659  * @ret efirc EFI status code
660  */
661 static EFI_STATUS EFIAPI
664  struct efi_file *file = container_of ( this, struct efi_file, file );
665 
666  DBGC ( file, "EFIFILE %s cannot set information of type %s\n",
668  return EFI_WRITE_PROTECTED;
669 }
670 
671 /**
672  * Flush file modified data
673  *
674  * @v this EFI file
675  * @v type Type of information
676  * @v len Buffer size
677  * @v data Buffer
678  * @ret efirc EFI status code
679  */
681  struct efi_file *file = container_of ( this, struct efi_file, file );
682 
683  DBGC ( file, "EFIFILE %s flushed\n", efi_file_name ( file ) );
684  return 0;
685 }
686 
687 /** Root directory */
688 static struct efi_file efi_file_root = {
689  .refcnt = REF_INIT ( ref_no_free ),
690  .file = {
691  .Revision = EFI_FILE_PROTOCOL_REVISION,
692  .Open = efi_file_open,
693  .Close = efi_file_close,
694  .Delete = efi_file_delete,
695  .Read = efi_file_read,
696  .Write = efi_file_write,
697  .GetPosition = efi_file_get_position,
698  .SetPosition = efi_file_set_position,
699  .GetInfo = efi_file_get_info,
700  .SetInfo = efi_file_set_info,
701  .Flush = efi_file_flush,
702  },
703  .image = NULL,
704  .name = "",
705 };
706 
707 /** Magic initrd file */
708 static struct efi_file efi_file_initrd = {
709  .refcnt = REF_INIT ( ref_no_free ),
710  .file = {
711  .Revision = EFI_FILE_PROTOCOL_REVISION,
712  .Open = efi_file_open,
713  .Close = efi_file_close,
714  .Delete = efi_file_delete,
715  .Read = efi_file_read,
716  .Write = efi_file_write,
717  .GetPosition = efi_file_get_position,
718  .SetPosition = efi_file_set_position,
719  .GetInfo = efi_file_get_info,
720  .SetInfo = efi_file_set_info,
721  .Flush = efi_file_flush,
722  },
723  .image = NULL,
724  .name = "initrd.magic",
725  .read = efi_file_read_initrd,
726 };
727 
728 /**
729  * Open root directory
730  *
731  * @v filesystem EFI simple file system
732  * @ret file EFI file handle
733  * @ret efirc EFI status code
734  */
735 static EFI_STATUS EFIAPI
737  EFI_FILE_PROTOCOL **file ) {
738 
739  DBGC ( &efi_file_root, "EFIFILE open volume\n" );
741 }
742 
743 /** EFI simple file system protocol */
746  .OpenVolume = efi_file_open_volume,
747 };
748 
749 /** Dummy block I/O reset */
750 static EFI_STATUS EFIAPI
752 
753  DBGC ( &efi_file_root, "EFIFILE block %sreset\n",
754  ( extended ? "extended " : "" ) );
755  return 0;
756 }
757 
758 /** Dummy block I/O read */
759 static EFI_STATUS EFIAPI
761  EFI_LBA lba, UINTN len, VOID *data ) {
762 
763  DBGC ( &efi_file_root, "EFIFILE block read ID %#08x LBA %#08llx -> "
764  "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
765  data, ( ( size_t ) len ) );
766  return EFI_NO_MEDIA;
767 }
768 
769 /** Dummy block I/O write */
770 static EFI_STATUS EFIAPI
772  UINT32 MediaId, EFI_LBA lba, UINTN len,
773  VOID *data ) {
774 
775  DBGC ( &efi_file_root, "EFIFILE block write ID %#08x LBA %#08llx <- "
776  "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
777  data, ( ( size_t ) len ) );
778  return EFI_NO_MEDIA;
779 }
780 
781 /** Dummy block I/O flush */
782 static EFI_STATUS EFIAPI
784 
785  DBGC ( &efi_file_root, "EFIFILE block flush\n" );
786  return 0;
787 }
788 
789 /** Dummy block I/O media */
792  .MediaPresent = TRUE,
793  .ReadOnly = TRUE,
794  .BlockSize = 1,
795 };
796 
797 /** Dummy EFI block I/O protocol */
800  .Media = &efi_block_io_media,
801  .Reset = efi_block_io_reset,
802  .ReadBlocks = efi_block_io_read_blocks,
803  .WriteBlocks = efi_block_io_write_blocks,
804  .FlushBlocks = efi_block_io_flush_blocks,
805 };
806 
807 /** Dummy disk I/O read */
808 static EFI_STATUS EFIAPI
810  UINT64 offset, UINTN len, VOID *data ) {
811 
812  DBGC ( &efi_file_root, "EFIFILE disk read ID %#08x offset %#08llx -> "
813  "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
814  data, ( ( size_t ) len ) );
815  return EFI_NO_MEDIA;
816 }
817 
818 /** Dummy disk I/O write */
819 static EFI_STATUS EFIAPI
821  UINT64 offset, UINTN len, VOID *data ) {
822 
823  DBGC ( &efi_file_root, "EFIFILE disk write ID %#08x offset %#08llx <- "
824  "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
825  data, ( ( size_t ) len ) );
826  return EFI_NO_MEDIA;
827 }
828 
829 /** Dummy EFI disk I/O protocol */
832  .ReadDisk = efi_disk_io_read_disk,
833  .WriteDisk = efi_disk_io_write_disk,
834 };
835 
836 /**
837  * Install EFI simple file system protocol
838  *
839  * @v handle EFI handle
840  * @ret rc Return status code
841  */
844  union {
845  EFI_DISK_IO_PROTOCOL *diskio;
846  void *interface;
847  } diskio;
848  EFI_STATUS efirc;
849  int rc;
850 
851  /* Reset root directory state */
852  efi_file_root.pos = 0;
853 
854  /* Install the simple file system protocol, block I/O
855  * protocol, and disk I/O protocol. We don't have a block
856  * device, but large parts of the EDK2 codebase make the
857  * assumption that file systems are normally attached to block
858  * devices, and so we create a dummy block device on the same
859  * handle just to keep things looking normal.
860  */
861  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
862  &handle,
869  rc = -EEFI ( efirc );
870  DBGC ( handle, "Could not install simple file system "
871  "protocols: %s\n", strerror ( rc ) );
872  goto err_install;
873  }
874 
875  /* The FAT filesystem driver has a bug: if a block device
876  * contains no FAT filesystem but does have an
877  * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instance, the FAT driver
878  * will assume that it must have previously installed the
879  * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. This causes the FAT
880  * driver to claim control of our device, and to refuse to
881  * stop driving it, which prevents us from later uninstalling
882  * correctly.
883  *
884  * Work around this bug by opening the disk I/O protocol
885  * ourselves, thereby preventing the FAT driver from opening
886  * it.
887  *
888  * Note that the alternative approach of opening the block I/O
889  * protocol (and thereby in theory preventing DiskIo from
890  * attaching to the block I/O protocol) causes an endless loop
891  * of calls to our DRIVER_STOP method when starting the EFI
892  * shell. I have no idea why this is.
893  */
894  if ( ( efirc = bs->OpenProtocol ( handle, &efi_disk_io_protocol_guid,
895  &diskio.interface, efi_image_handle,
896  handle,
897  EFI_OPEN_PROTOCOL_BY_DRIVER ) ) != 0){
898  rc = -EEFI ( efirc );
899  DBGC ( handle, "Could not open disk I/O protocol: %s\n",
900  strerror ( rc ) );
902  goto err_open;
903  }
904  assert ( diskio.diskio == &efi_disk_io_protocol );
905 
906  return 0;
907 
910  err_open:
912  handle,
919  err_install:
920  return rc;
921 }
922 
923 /**
924  * Uninstall EFI simple file system protocol
925  *
926  * @v handle EFI handle
927  */
930  EFI_STATUS efirc;
931  int rc;
932 
933  /* Close our own disk I/O protocol */
936 
937  /* We must install the file system protocol first, since
938  * otherwise the EDK2 code will attempt to helpfully uninstall
939  * it when the block I/O protocol is uninstalled, leading to a
940  * system lock-up.
941  */
942  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
943  handle,
949  &efi_block_io_protocol, NULL ) ) != 0 ) {
950  rc = -EEFI ( efirc );
951  DBGC ( handle, "Could not uninstall simple file system "
952  "protocols: %s\n", strerror ( rc ) );
953  /* Oh dear */
954  }
955 }
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:662
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:809
void * data
Output data buffer.
Definition: efi_file.c:61
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
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:95
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:123
struct refcnt refcnt
Reference count.
Definition: efi_file.c:69
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:319
struct image * current_image
Currently-executing image.
Definition: image.c:59
BOOLEAN ReadOnly
TRUE if the volume only supports read access.
An EFI virtual file reader.
Definition: efi_file.c:55
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:616
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:162
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:599
A CPIO archive header.
Definition: cpio.h:19
uint32_t lba
Start address.
Definition: scsi.h:23
EFI_GUID efi_file_system_info_id
File system information GUID.
Definition: efi_guid.c:306
128 bit buffer containing a unique identifier value.
Definition: Base.h:263
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
Error codes.
__SIZE_TYPE__ size_t
Definition: stdint.h:6
EFI strings.
unsigned char BOOLEAN
Definition: ProcessorBind.h:61
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:798
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:211
#define DBGC(...)
Definition: compiler.h:505
This protocol provides control over block devices.
Definition: BlockIo.h:222
unsigned int UINT32
Definition: ProcessorBind.h:56
#define EFI_OPEN_PROTOCOL_BY_DRIVER
Definition: UefiSpec.h:1274
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1915
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:208
static EFI_STATUS efi_file_open_fixed(struct efi_file *file, EFI_FILE_PROTOCOL **new)
Open fixed file.
Definition: efi_file.c:282
unsigned short CHAR16
Definition: ProcessorBind.h:59
void efi_file_uninstall(EFI_HANDLE handle)
Uninstall EFI simple file system protocol.
Definition: efi_file.c:928
static EFI_STATUS EFIAPI efi_file_read(EFI_FILE_PROTOCOL *this, UINTN *len, VOID *data)
Read from file.
Definition: efi_file.c:513
#define DBGC_EFI_OPENERS(...)
Definition: efi.h:286
An executable image.
Definition: image.h:24
#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:760
#define EFI_BUFFER_TOO_SMALL
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:125
EFI_FILE_PROTOCOL file
EFI file protocol.
Definition: efi_file.c:71
#define EFI_FILE_DIRECTORY
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1906
#define SIZE_OF_EFI_FILE_INFO
The FileName field of the EFI_FILE_INFO data structure is variable length.
Definition: FileInfo.h:69
static EFI_DISK_IO_PROTOCOL efi_disk_io_protocol
Dummy EFI disk I/O protocol.
Definition: efi_file.c:830
#define EFI_NO_MEDIA
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:132
#define EFI_OUT_OF_RESOURCES
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:129
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:144
CPIO archives.
static size_t efi_file_len(struct efi_file *file)
Get length of EFI file.
Definition: efi_file.c:138
int efi_file_install(EFI_HANDLE handle)
Install EFI simple file system protocol.
Definition: efi_file.c:842
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:820
A reference counter.
Definition: refcnt.h:26
static size_t efi_file_read_image(struct efi_file_reader *reader)
Read from image-backed file.
Definition: efi_file.c:206
static EFI_STATUS efi_file_info(struct efi_file *file, UINTN *len, VOID *data)
Return file information structure.
Definition: efi_file.c:453
size_t pos
Current file position.
Definition: efi_file.c:77
struct efi_file * file
EFI file.
Definition: efi_file.c:57
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:736
void * memcpy(void *dest, const void *src, size_t len) __nonnull
size_t len
Length of output data buffer.
Definition: efi_file.c:63
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.
Executable images.
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition: efi_guid.c:232
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
UINT64 EFI_LBA
Logical block address.
Definition: UefiBaseType.h:51
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:87
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:104
#define EFI_DISK_IO_PROTOCOL_REVISION
Definition: DiskIo.h:96
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:165
uint8_t filesystem
System type.
Definition: eltorito.h:24
This protocol is used to abstract Block I/O interfaces.
Definition: DiskIo.h:106
static EFI_STATUS EFIAPI efi_file_set_position(EFI_FILE_PROTOCOL *this, UINT64 position)
Set file position.
Definition: efi_file.c:563
#define EFI_WRITE_PROTECTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:128
#define for_each_image(image)
Iterate over all registered images.
Definition: image.h:157
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition: efi_debug.c:192
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:424
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#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:1836
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:33
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
struct list_head images
List of registered images.
Definition: image.c:56
static struct efi_file efi_file_initrd
Magic initrd file.
Definition: efi_file.c:88
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1916
static EFI_STATUS EFIAPI efi_file_close(EFI_FILE_PROTOCOL *this)
Close file.
Definition: efi_file.c:386
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:221
static EFI_STATUS EFIAPI efi_file_flush(EFI_FILE_PROTOCOL *this)
Flush file modified data.
Definition: efi_file.c:680
UINT64 UINTN
Unsigned value of native width.
Definition: ProcessorBind.h:71
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:771
static EFI_STATUS EFIAPI efi_file_write(EFI_FILE_PROTOCOL *this, UINTN *len, VOID *data __unused)
Write to file.
Definition: efi_file.c:546
#define VOID
Undeclared type.
Definition: Base.h:319
unsigned long long UINT64
Definition: ProcessorBind.h:54
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
uint16_t base
Base address.
Definition: edd.h:14
#define EFI_WARN_DELETE_FAILURE
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:155
EFI API.
#define EFI_MEDIA_ID_MAGIC
EFI media ID.
Definition: efi_file.c:52
static EFI_STATUS efi_file_read_dir(struct efi_file *file, UINTN *len, VOID *data)
Read directory entry.
Definition: efi_file.c:481
size_t pos
Position within virtual file.
Definition: efi_file.c:59
Block IO read only mode data and updated only via members of BlockIO.
Definition: BlockIo.h:136
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
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:402
#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:134
#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:108
#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
EFI_GUID efi_file_info_id
File information GUID.
Definition: efi_guid.c:303
#define EFI_FILE_MODE_READ
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
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.
struct image * image
Image (if any)
Definition: efi_file.c:73
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition: refcnt.h:77
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:751
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1905
UINT32 MediaId
The curent media Id.
Definition: BlockIo.h:140
static EFI_STATUS EFIAPI efi_block_io_flush_blocks(EFI_BLOCK_IO_PROTOCOL *this __unused)
Dummy block I/O flush.
Definition: efi_file.c:783
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
UINT64 Revision
The revision to which the block IO interface adheres.
Definition: BlockIo.h:228
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:84
static EFI_SIMPLE_FILE_SYSTEM_PROTOCOL efi_simple_file_system_protocol
EFI simple file system protocol.
Definition: efi_file.c:744
struct list_head list
List of registered images.
Definition: image.h:29
static size_t efi_file_read_initrd(struct efi_file_reader *reader)
Read from magic initrd file.
Definition: efi_file.c:220
uint16_t handle
Handle.
Definition: smbios.h:16
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
#define EFI_BLOCK_IO_PROTOCOL_REVISION
Definition: BlockIo.h:210
UINT64 Revision
The revision to which the disk I/O interface adheres.
Definition: DiskIo.h:112
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:120
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
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:790
An EFI file.
Definition: efi_file.c:67
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
Definition: efi.h:50
const char * name
Filename.
Definition: efi_file.c:75
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
#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
String functions.
static const char * efi_file_name(struct efi_file *file)
Get EFI file name (for debugging)
Definition: efi_file.c:109
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:107
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:301