2 * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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
20 FILE_LICENCE ( GPL2_OR_LATER );
36 #include <ipxe/image.h>
37 #include <ipxe/efi/efi.h>
38 #include <ipxe/efi/Protocol/SimpleFileSystem.h>
39 #include <ipxe/efi/Protocol/BlockIo.h>
40 #include <ipxe/efi/Protocol/DiskIo.h>
41 #include <ipxe/efi/Guid/FileInfo.h>
42 #include <ipxe/efi/Guid/FileSystemInfo.h>
43 #include <ipxe/efi/efi_strings.h>
44 #include <ipxe/efi/efi_file.h>
46 /** EFI file information GUID */
47 static EFI_GUID efi_file_info_id = EFI_FILE_INFO_ID;
49 /** EFI file system information GUID */
50 static EFI_GUID efi_file_system_info_id = EFI_FILE_SYSTEM_INFO_ID;
53 #define EFI_MEDIA_ID_MAGIC 0x69505845
55 /** An image exposed as an EFI file */
57 /** EFI file protocol */
58 EFI_FILE_PROTOCOL file;
61 /** Current file position */
65 static struct efi_file efi_file_root;
68 * Get EFI file name (for debugging)
73 static const char * efi_file_name ( struct efi_file *file ) {
75 return ( file->image ? file->image->name : "<root>" );
82 * @ret image Image, or NULL
84 static struct image * efi_file_find ( const CHAR16 *wname ) {
85 char name[ wcslen ( wname ) + 1 /* NUL */ ];
89 snprintf ( name, sizeof ( name ), "%ls", wname );
90 list_for_each_entry ( image, &images, list ) {
91 if ( strcasecmp ( image->name, name ) == 0 )
103 * @ret new New EFI file
106 * @v attributes File attributes (for newly-created files)
107 * @ret efirc EFI status code
109 static EFI_STATUS EFIAPI
110 efi_file_open ( EFI_FILE_PROTOCOL *this, EFI_FILE_PROTOCOL **new,
111 CHAR16 *wname, UINT64 mode __unused,
112 UINT64 attributes __unused ) {
113 struct efi_file *file = container_of ( this, struct efi_file, file );
114 struct efi_file *new_file;
117 /* Initial '\' indicates opening from the root directory */
118 while ( *wname == L'\\' ) {
119 file = &efi_file_root;
123 /* Allow root directory itself to be opened */
124 if ( ( wname[0] == L'\0' ) || ( wname[0] == L'.' ) ) {
125 *new = &efi_file_root.file;
129 /* Fail unless opening from the root */
131 DBGC ( file, "EFIFILE %s is not a directory\n",
132 efi_file_name ( file ) );
133 return EFI_NOT_FOUND;
137 image = efi_file_find ( wname );
139 DBGC ( file, "EFIFILE \"%ls\" does not exist\n", wname );
140 return EFI_NOT_FOUND;
143 /* Fail unless opening read-only */
144 if ( mode != EFI_FILE_MODE_READ ) {
145 DBGC ( file, "EFIFILE %s cannot be opened in mode %#08llx\n",
147 return EFI_WRITE_PROTECTED;
150 /* Allocate and initialise file */
151 new_file = zalloc ( sizeof ( *new_file ) );
152 memcpy ( &new_file->file, &efi_file_root.file,
153 sizeof ( new_file->file ) );
154 new_file->image = image_get ( image );
155 *new = &new_file->file;
156 DBGC ( new_file, "EFIFILE %s opened\n", efi_file_name ( new_file ) );
165 * @ret efirc EFI status code
167 static EFI_STATUS EFIAPI efi_file_close ( EFI_FILE_PROTOCOL *this ) {
168 struct efi_file *file = container_of ( this, struct efi_file, file );
170 /* Do nothing if this is the root */
175 DBGC ( file, "EFIFILE %s closed\n", efi_file_name ( file ) );
176 image_put ( file->image );
183 * Close and delete file
186 * @ret efirc EFI status code
188 static EFI_STATUS EFIAPI efi_file_delete ( EFI_FILE_PROTOCOL *this ) {
189 struct efi_file *file = container_of ( this, struct efi_file, file );
191 DBGC ( file, "EFIFILE %s cannot be deleted\n", efi_file_name ( file ) );
194 efi_file_close ( this );
196 /* Warn of failure to delete */
197 return EFI_WARN_DELETE_FAILURE;
201 * Return variable-length data structure
203 * @v base Base data structure (starting with UINT64)
204 * @v base_len Length of base data structure
205 * @v name Name to append to base data structure
206 * @v len Length of data buffer
207 * @v data Data buffer
208 * @ret efirc EFI status code
210 static EFI_STATUS efi_file_varlen ( UINT64 *base, size_t base_len,
211 const char *name, UINTN *len, VOID *data ) {
214 /* Calculate structure length */
215 name_len = strlen ( name );
216 *base = ( base_len + ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
217 if ( *len < *base ) {
219 return EFI_BUFFER_TOO_SMALL;
222 /* Copy data to buffer */
224 memcpy ( data, base, base_len );
225 efi_snprintf ( ( data + base_len ), ( name_len + 1 /* NUL */ ),
232 * Return file information structure
234 * @v image Image, or NULL for the root directory
235 * @v len Length of data buffer
236 * @v data Data buffer
237 * @ret efirc EFI status code
239 static EFI_STATUS efi_file_info ( struct image *image, UINTN *len,
244 /* Populate file information */
245 memset ( &info, 0, sizeof ( info ) );
247 info.FileSize = image->len;
248 info.PhysicalSize = image->len;
249 info.Attribute = EFI_FILE_READ_ONLY;
252 info.Attribute = ( EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY );
256 return efi_file_varlen ( &info.Size, SIZE_OF_EFI_FILE_INFO, name,
261 * Read directory entry
264 * @v len Length to read
265 * @v data Data buffer
266 * @ret efirc EFI status code
268 static EFI_STATUS efi_file_read_dir ( struct efi_file *file, UINTN *len,
274 /* Construct directory entry at current position */
276 for_each_image ( image ) {
277 if ( index-- == 0 ) {
278 efirc = efi_file_info ( image, len, data );
285 /* No more entries */
294 * @v len Length to read
295 * @v data Data buffer
296 * @ret efirc EFI status code
298 static EFI_STATUS EFIAPI efi_file_read ( EFI_FILE_PROTOCOL *this,
299 UINTN *len, VOID *data ) {
300 struct efi_file *file = container_of ( this, struct efi_file, file );
303 /* If this is the root directory, then construct a directory entry */
305 return efi_file_read_dir ( file, len, data );
307 /* Read from the file */
308 remaining = ( file->image->len - file->pos );
309 if ( *len > remaining )
311 DBGC ( file, "EFIFILE %s read [%#08zx,%#08zx)\n",
312 efi_file_name ( file ), file->pos,
313 ( ( size_t ) ( file->pos + *len ) ) );
314 copy_from_user ( data, file->image->data, file->pos, *len );
323 * @v len Length to write
324 * @v data Data buffer
325 * @ret efirc EFI status code
327 static EFI_STATUS EFIAPI efi_file_write ( EFI_FILE_PROTOCOL *this,
328 UINTN *len, VOID *data __unused ) {
329 struct efi_file *file = container_of ( this, struct efi_file, file );
331 DBGC ( file, "EFIFILE %s cannot write [%#08zx, %#08zx)\n",
332 efi_file_name ( file ), file->pos,
333 ( ( size_t ) ( file->pos + *len ) ) );
334 return EFI_WRITE_PROTECTED;
341 * @v position New file position
342 * @ret efirc EFI status code
344 static EFI_STATUS EFIAPI efi_file_set_position ( EFI_FILE_PROTOCOL *this,
346 struct efi_file *file = container_of ( this, struct efi_file, file );
348 /* If this is the root directory, reset to the start */
349 if ( ! file->image ) {
350 DBGC ( file, "EFIFILE root directory rewound\n" );
355 /* Check for the magic end-of-file value */
356 if ( position == 0xffffffffffffffffULL )
357 position = file->image->len;
359 /* Fail if we attempt to seek past the end of the file (since
360 * we do not support writes).
362 if ( position > file->image->len ) {
363 DBGC ( file, "EFIFILE %s cannot seek to %#08llx of %#08zx\n",
364 efi_file_name ( file ), position, file->image->len );
365 return EFI_UNSUPPORTED;
369 file->pos = position;
370 DBGC ( file, "EFIFILE %s position set to %#08zx\n",
371 efi_file_name ( file ), file->pos );
380 * @ret position New file position
381 * @ret efirc EFI status code
383 static EFI_STATUS EFIAPI efi_file_get_position ( EFI_FILE_PROTOCOL *this,
385 struct efi_file *file = container_of ( this, struct efi_file, file );
387 *position = file->pos;
392 * Get file information
395 * @v type Type of information
398 * @ret efirc EFI status code
400 static EFI_STATUS EFIAPI efi_file_get_info ( EFI_FILE_PROTOCOL *this,
402 UINTN *len, VOID *data ) {
403 struct efi_file *file = container_of ( this, struct efi_file, file );
404 EFI_FILE_SYSTEM_INFO fsinfo;
407 /* Determine information to return */
408 if ( memcmp ( type, &efi_file_info_id, sizeof ( *type ) ) == 0 ) {
410 /* Get file information */
411 DBGC ( file, "EFIFILE %s get file information\n",
412 efi_file_name ( file ) );
413 return efi_file_info ( file->image, len, data );
415 } else if ( memcmp ( type, &efi_file_system_info_id,
416 sizeof ( *type ) ) == 0 ) {
418 /* Get file system information */
419 DBGC ( file, "EFIFILE %s get file system information\n",
420 efi_file_name ( file ) );
421 memset ( &fsinfo, 0, sizeof ( fsinfo ) );
423 for_each_image ( image )
424 fsinfo.VolumeSize += image->len;
425 return efi_file_varlen ( &fsinfo.Size,
426 SIZE_OF_EFI_FILE_SYSTEM_INFO, "iPXE",
430 DBGC ( file, "EFIFILE %s cannot get information of type %s\n",
431 efi_file_name ( file ), efi_guid_ntoa ( type ) );
432 return EFI_UNSUPPORTED;
437 * Set file information
440 * @v type Type of information
443 * @ret efirc EFI status code
445 static EFI_STATUS EFIAPI
446 efi_file_set_info ( EFI_FILE_PROTOCOL *this, EFI_GUID *type,
447 UINTN len __unused, VOID *data __unused ) {
448 struct efi_file *file = container_of ( this, struct efi_file, file );
450 DBGC ( file, "EFIFILE %s cannot set information of type %s\n",
451 efi_file_name ( file ), efi_guid_ntoa ( type ) );
452 return EFI_WRITE_PROTECTED;
456 * Flush file modified data
459 * @v type Type of information
462 * @ret efirc EFI status code
464 static EFI_STATUS EFIAPI efi_file_flush ( EFI_FILE_PROTOCOL *this ) {
465 struct efi_file *file = container_of ( this, struct efi_file, file );
467 DBGC ( file, "EFIFILE %s flushed\n", efi_file_name ( file ) );
471 /** Root directory */
472 static struct efi_file efi_file_root = {
474 .Revision = EFI_FILE_PROTOCOL_REVISION,
475 .Open = efi_file_open,
476 .Close = efi_file_close,
477 .Delete = efi_file_delete,
478 .Read = efi_file_read,
479 .Write = efi_file_write,
480 .GetPosition = efi_file_get_position,
481 .SetPosition = efi_file_set_position,
482 .GetInfo = efi_file_get_info,
483 .SetInfo = efi_file_set_info,
484 .Flush = efi_file_flush,
490 * Open root directory
492 * @v filesystem EFI simple file system
493 * @ret file EFI file handle
494 * @ret efirc EFI status code
496 static EFI_STATUS EFIAPI
497 efi_file_open_volume ( EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *filesystem __unused,
498 EFI_FILE_PROTOCOL **file ) {
500 DBGC ( &efi_file_root, "EFIFILE open volume\n" );
501 *file = &efi_file_root.file;
505 /** EFI simple file system protocol */
506 static EFI_SIMPLE_FILE_SYSTEM_PROTOCOL efi_simple_file_system_protocol = {
507 .Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
508 .OpenVolume = efi_file_open_volume,
511 /** Dummy block I/O reset */
512 static EFI_STATUS EFIAPI
513 efi_block_io_reset ( EFI_BLOCK_IO_PROTOCOL *this __unused, BOOLEAN extended ) {
515 DBGC ( &efi_file_root, "EFIFILE block %sreset\n",
516 ( extended ? "extended " : "" ) );
520 /** Dummy block I/O read */
521 static EFI_STATUS EFIAPI
522 efi_block_io_read_blocks ( EFI_BLOCK_IO_PROTOCOL *this __unused, UINT32 MediaId,
523 EFI_LBA lba, UINTN len, VOID *data ) {
525 DBGC ( &efi_file_root, "EFIFILE block read ID %#08x LBA %#08llx -> "
526 "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
527 data, ( ( size_t ) len ) );
531 /** Dummy block I/O write */
532 static EFI_STATUS EFIAPI
533 efi_block_io_write_blocks ( EFI_BLOCK_IO_PROTOCOL *this __unused,
534 UINT32 MediaId, EFI_LBA lba, UINTN len,
537 DBGC ( &efi_file_root, "EFIFILE block write ID %#08x LBA %#08llx <- "
538 "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
539 data, ( ( size_t ) len ) );
543 /** Dummy block I/O flush */
544 static EFI_STATUS EFIAPI
545 efi_block_io_flush_blocks ( EFI_BLOCK_IO_PROTOCOL *this __unused ) {
547 DBGC ( &efi_file_root, "EFIFILE block flush\n" );
551 /** Dummy block I/O media */
552 static EFI_BLOCK_IO_MEDIA efi_block_io_media = {
553 .MediaId = EFI_MEDIA_ID_MAGIC,
554 .MediaPresent = TRUE,
559 /** Dummy EFI block I/O protocol */
560 static EFI_BLOCK_IO_PROTOCOL efi_block_io_protocol = {
561 .Revision = EFI_BLOCK_IO_PROTOCOL_REVISION,
562 .Media = &efi_block_io_media,
563 .Reset = efi_block_io_reset,
564 .ReadBlocks = efi_block_io_read_blocks,
565 .WriteBlocks = efi_block_io_write_blocks,
566 .FlushBlocks = efi_block_io_flush_blocks,
569 /** Dummy disk I/O read */
570 static EFI_STATUS EFIAPI
571 efi_disk_io_read_disk ( EFI_DISK_IO_PROTOCOL *this __unused, UINT32 MediaId,
572 UINT64 offset, UINTN len, VOID *data ) {
574 DBGC ( &efi_file_root, "EFIFILE disk read ID %#08x offset %#08llx -> "
575 "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
576 data, ( ( size_t ) len ) );
580 /** Dummy disk I/O write */
581 static EFI_STATUS EFIAPI
582 efi_disk_io_write_disk ( EFI_DISK_IO_PROTOCOL *this __unused, UINT32 MediaId,
583 UINT64 offset, UINTN len, VOID *data ) {
585 DBGC ( &efi_file_root, "EFIFILE disk write ID %#08x offset %#08llx <- "
586 "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
587 data, ( ( size_t ) len ) );
591 /** Dummy EFI disk I/O protocol */
592 static EFI_DISK_IO_PROTOCOL efi_disk_io_protocol = {
593 .Revision = EFI_DISK_IO_PROTOCOL_REVISION,
594 .ReadDisk = efi_disk_io_read_disk,
595 .WriteDisk = efi_disk_io_write_disk,
599 * Install EFI simple file system protocol
601 * @v handle EFI handle
602 * @ret rc Return status code
604 int efi_file_install ( EFI_HANDLE handle ) {
605 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
607 EFI_DISK_IO_PROTOCOL *diskio;
613 /* Install the simple file system protocol, block I/O
614 * protocol, and disk I/O protocol. We don't have a block
615 * device, but large parts of the EDK2 codebase make the
616 * assumption that file systems are normally attached to block
617 * devices, and so we create a dummy block device on the same
618 * handle just to keep things looking normal.
620 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
622 &efi_block_io_protocol_guid,
623 &efi_block_io_protocol,
624 &efi_disk_io_protocol_guid,
625 &efi_disk_io_protocol,
626 &efi_simple_file_system_protocol_guid,
627 &efi_simple_file_system_protocol, NULL ) ) != 0 ) {
628 rc = -EEFI ( efirc );
629 DBGC ( handle, "Could not install simple file system "
630 "protocols: %s\n", strerror ( rc ) );
634 /* The FAT filesystem driver has a bug: if a block device
635 * contains no FAT filesystem but does have an
636 * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instance, the FAT driver
637 * will assume that it must have previously installed the
638 * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. This causes the FAT
639 * driver to claim control of our device, and to refuse to
640 * stop driving it, which prevents us from later uninstalling
643 * Work around this bug by opening the disk I/O protocol
644 * ourselves, thereby preventing the FAT driver from opening
647 * Note that the alternative approach of opening the block I/O
648 * protocol (and thereby in theory preventing DiskIo from
649 * attaching to the block I/O protocol) causes an endless loop
650 * of calls to our DRIVER_STOP method when starting the EFI
651 * shell. I have no idea why this is.
653 if ( ( efirc = bs->OpenProtocol ( handle, &efi_disk_io_protocol_guid,
654 &diskio.interface, efi_image_handle,
656 EFI_OPEN_PROTOCOL_BY_DRIVER ) ) != 0){
657 rc = -EEFI ( efirc );
658 DBGC ( handle, "Could not open disk I/O protocol: %s\n",
660 DBGC_EFI_OPENERS ( handle, handle, &efi_disk_io_protocol_guid );
663 assert ( diskio.diskio == &efi_disk_io_protocol );
667 bs->CloseProtocol ( handle, &efi_disk_io_protocol_guid,
668 efi_image_handle, handle );
670 bs->UninstallMultipleProtocolInterfaces (
672 &efi_simple_file_system_protocol_guid,
673 &efi_simple_file_system_protocol,
674 &efi_disk_io_protocol_guid,
675 &efi_disk_io_protocol,
676 &efi_block_io_protocol_guid,
677 &efi_block_io_protocol, NULL );
683 * Uninstall EFI simple file system protocol
685 * @v handle EFI handle
687 void efi_file_uninstall ( EFI_HANDLE handle ) {
688 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
692 /* Close our own disk I/O protocol */
693 bs->CloseProtocol ( handle, &efi_disk_io_protocol_guid,
694 efi_image_handle, handle );
696 /* We must install the file system protocol first, since
697 * otherwise the EDK2 code will attempt to helpfully uninstall
698 * it when the block I/O protocol is uninstalled, leading to a
701 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
703 &efi_simple_file_system_protocol_guid,
704 &efi_simple_file_system_protocol,
705 &efi_disk_io_protocol_guid,
706 &efi_disk_io_protocol,
707 &efi_block_io_protocol_guid,
708 &efi_block_io_protocol, NULL ) ) != 0 ) {
709 rc = -EEFI ( efirc );
710 DBGC ( handle, "Could not uninstall simple file system "
711 "protocols: %s\n", strerror ( rc ) );