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
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.
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
40 #include <ipxe/image.h>
41 #include <ipxe/efi/efi.h>
42 #include <ipxe/efi/Protocol/SimpleFileSystem.h>
43 #include <ipxe/efi/Protocol/BlockIo.h>
44 #include <ipxe/efi/Protocol/DiskIo.h>
45 #include <ipxe/efi/Guid/FileInfo.h>
46 #include <ipxe/efi/Guid/FileSystemInfo.h>
47 #include <ipxe/efi/efi_strings.h>
48 #include <ipxe/efi/efi_file.h>
50 /** EFI file information GUID */
51 static EFI_GUID efi_file_info_id = EFI_FILE_INFO_ID;
53 /** EFI file system information GUID */
54 static EFI_GUID efi_file_system_info_id = EFI_FILE_SYSTEM_INFO_ID;
57 #define EFI_MEDIA_ID_MAGIC 0x69505845
59 /** An image exposed as an EFI file */
61 /** EFI file protocol */
62 EFI_FILE_PROTOCOL file;
65 /** Current file position */
69 static struct efi_file efi_file_root;
72 * Get EFI file name (for debugging)
77 static const char * efi_file_name ( struct efi_file *file ) {
79 return ( file->image ? file->image->name : "<root>" );
86 * @ret image Image, or NULL
88 static struct image * efi_file_find ( const CHAR16 *wname ) {
89 char name[ wcslen ( wname ) + 1 /* NUL */ ];
93 snprintf ( name, sizeof ( name ), "%ls", wname );
94 list_for_each_entry ( image, &images, list ) {
95 if ( strcasecmp ( image->name, name ) == 0 )
107 * @ret new New EFI file
110 * @v attributes File attributes (for newly-created files)
111 * @ret efirc EFI status code
113 static EFI_STATUS EFIAPI
114 efi_file_open ( EFI_FILE_PROTOCOL *this, EFI_FILE_PROTOCOL **new,
115 CHAR16 *wname, UINT64 mode __unused,
116 UINT64 attributes __unused ) {
117 struct efi_file *file = container_of ( this, struct efi_file, file );
118 struct efi_file *new_file;
121 /* Initial '\' indicates opening from the root directory */
122 while ( *wname == L'\\' ) {
123 file = &efi_file_root;
127 /* Allow root directory itself to be opened */
128 if ( ( wname[0] == L'\0' ) || ( wname[0] == L'.' ) ) {
129 *new = &efi_file_root.file;
133 /* Fail unless opening from the root */
135 DBGC ( file, "EFIFILE %s is not a directory\n",
136 efi_file_name ( file ) );
137 return EFI_NOT_FOUND;
141 image = efi_file_find ( wname );
143 DBGC ( file, "EFIFILE \"%ls\" does not exist\n", wname );
144 return EFI_NOT_FOUND;
147 /* Fail unless opening read-only */
148 if ( mode != EFI_FILE_MODE_READ ) {
149 DBGC ( file, "EFIFILE %s cannot be opened in mode %#08llx\n",
151 return EFI_WRITE_PROTECTED;
154 /* Allocate and initialise file */
155 new_file = zalloc ( sizeof ( *new_file ) );
156 memcpy ( &new_file->file, &efi_file_root.file,
157 sizeof ( new_file->file ) );
158 new_file->image = image_get ( image );
159 *new = &new_file->file;
160 DBGC ( new_file, "EFIFILE %s opened\n", efi_file_name ( new_file ) );
169 * @ret efirc EFI status code
171 static EFI_STATUS EFIAPI efi_file_close ( EFI_FILE_PROTOCOL *this ) {
172 struct efi_file *file = container_of ( this, struct efi_file, file );
174 /* Do nothing if this is the root */
179 DBGC ( file, "EFIFILE %s closed\n", efi_file_name ( file ) );
180 image_put ( file->image );
187 * Close and delete file
190 * @ret efirc EFI status code
192 static EFI_STATUS EFIAPI efi_file_delete ( EFI_FILE_PROTOCOL *this ) {
193 struct efi_file *file = container_of ( this, struct efi_file, file );
195 DBGC ( file, "EFIFILE %s cannot be deleted\n", efi_file_name ( file ) );
198 efi_file_close ( this );
200 /* Warn of failure to delete */
201 return EFI_WARN_DELETE_FAILURE;
205 * Return variable-length data structure
207 * @v base Base data structure (starting with UINT64)
208 * @v base_len Length of base data structure
209 * @v name Name to append to base data structure
210 * @v len Length of data buffer
211 * @v data Data buffer
212 * @ret efirc EFI status code
214 static EFI_STATUS efi_file_varlen ( UINT64 *base, size_t base_len,
215 const char *name, UINTN *len, VOID *data ) {
218 /* Calculate structure length */
219 name_len = strlen ( name );
220 *base = ( base_len + ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
221 if ( *len < *base ) {
223 return EFI_BUFFER_TOO_SMALL;
226 /* Copy data to buffer */
228 memcpy ( data, base, base_len );
229 efi_snprintf ( ( data + base_len ), ( name_len + 1 /* NUL */ ),
236 * Return file information structure
238 * @v image Image, or NULL for the root directory
239 * @v len Length of data buffer
240 * @v data Data buffer
241 * @ret efirc EFI status code
243 static EFI_STATUS efi_file_info ( struct image *image, UINTN *len,
248 /* Populate file information */
249 memset ( &info, 0, sizeof ( info ) );
251 info.FileSize = image->len;
252 info.PhysicalSize = image->len;
253 info.Attribute = EFI_FILE_READ_ONLY;
256 info.Attribute = ( EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY );
260 return efi_file_varlen ( &info.Size, SIZE_OF_EFI_FILE_INFO, name,
265 * Read directory entry
268 * @v len Length to read
269 * @v data Data buffer
270 * @ret efirc EFI status code
272 static EFI_STATUS efi_file_read_dir ( struct efi_file *file, UINTN *len,
278 /* Construct directory entry at current position */
280 for_each_image ( image ) {
281 if ( index-- == 0 ) {
282 efirc = efi_file_info ( image, len, data );
289 /* No more entries */
298 * @v len Length to read
299 * @v data Data buffer
300 * @ret efirc EFI status code
302 static EFI_STATUS EFIAPI efi_file_read ( EFI_FILE_PROTOCOL *this,
303 UINTN *len, VOID *data ) {
304 struct efi_file *file = container_of ( this, struct efi_file, file );
307 /* If this is the root directory, then construct a directory entry */
309 return efi_file_read_dir ( file, len, data );
311 /* Read from the file */
312 remaining = ( file->image->len - file->pos );
313 if ( *len > remaining )
315 DBGC ( file, "EFIFILE %s read [%#08zx,%#08zx)\n",
316 efi_file_name ( file ), file->pos,
317 ( ( size_t ) ( file->pos + *len ) ) );
318 copy_from_user ( data, file->image->data, file->pos, *len );
327 * @v len Length to write
328 * @v data Data buffer
329 * @ret efirc EFI status code
331 static EFI_STATUS EFIAPI efi_file_write ( EFI_FILE_PROTOCOL *this,
332 UINTN *len, VOID *data __unused ) {
333 struct efi_file *file = container_of ( this, struct efi_file, file );
335 DBGC ( file, "EFIFILE %s cannot write [%#08zx, %#08zx)\n",
336 efi_file_name ( file ), file->pos,
337 ( ( size_t ) ( file->pos + *len ) ) );
338 return EFI_WRITE_PROTECTED;
345 * @v position New file position
346 * @ret efirc EFI status code
348 static EFI_STATUS EFIAPI efi_file_set_position ( EFI_FILE_PROTOCOL *this,
350 struct efi_file *file = container_of ( this, struct efi_file, file );
352 /* If this is the root directory, reset to the start */
353 if ( ! file->image ) {
354 DBGC ( file, "EFIFILE root directory rewound\n" );
359 /* Check for the magic end-of-file value */
360 if ( position == 0xffffffffffffffffULL )
361 position = file->image->len;
363 /* Fail if we attempt to seek past the end of the file (since
364 * we do not support writes).
366 if ( position > file->image->len ) {
367 DBGC ( file, "EFIFILE %s cannot seek to %#08llx of %#08zx\n",
368 efi_file_name ( file ), position, file->image->len );
369 return EFI_UNSUPPORTED;
373 file->pos = position;
374 DBGC ( file, "EFIFILE %s position set to %#08zx\n",
375 efi_file_name ( file ), file->pos );
384 * @ret position New file position
385 * @ret efirc EFI status code
387 static EFI_STATUS EFIAPI efi_file_get_position ( EFI_FILE_PROTOCOL *this,
389 struct efi_file *file = container_of ( this, struct efi_file, file );
391 *position = file->pos;
396 * Get file information
399 * @v type Type of information
402 * @ret efirc EFI status code
404 static EFI_STATUS EFIAPI efi_file_get_info ( EFI_FILE_PROTOCOL *this,
406 UINTN *len, VOID *data ) {
407 struct efi_file *file = container_of ( this, struct efi_file, file );
408 EFI_FILE_SYSTEM_INFO fsinfo;
411 /* Determine information to return */
412 if ( memcmp ( type, &efi_file_info_id, sizeof ( *type ) ) == 0 ) {
414 /* Get file information */
415 DBGC ( file, "EFIFILE %s get file information\n",
416 efi_file_name ( file ) );
417 return efi_file_info ( file->image, len, data );
419 } else if ( memcmp ( type, &efi_file_system_info_id,
420 sizeof ( *type ) ) == 0 ) {
422 /* Get file system information */
423 DBGC ( file, "EFIFILE %s get file system information\n",
424 efi_file_name ( file ) );
425 memset ( &fsinfo, 0, sizeof ( fsinfo ) );
427 for_each_image ( image )
428 fsinfo.VolumeSize += image->len;
429 return efi_file_varlen ( &fsinfo.Size,
430 SIZE_OF_EFI_FILE_SYSTEM_INFO, "iPXE",
434 DBGC ( file, "EFIFILE %s cannot get information of type %s\n",
435 efi_file_name ( file ), efi_guid_ntoa ( type ) );
436 return EFI_UNSUPPORTED;
441 * Set file information
444 * @v type Type of information
447 * @ret efirc EFI status code
449 static EFI_STATUS EFIAPI
450 efi_file_set_info ( EFI_FILE_PROTOCOL *this, EFI_GUID *type,
451 UINTN len __unused, VOID *data __unused ) {
452 struct efi_file *file = container_of ( this, struct efi_file, file );
454 DBGC ( file, "EFIFILE %s cannot set information of type %s\n",
455 efi_file_name ( file ), efi_guid_ntoa ( type ) );
456 return EFI_WRITE_PROTECTED;
460 * Flush file modified data
463 * @v type Type of information
466 * @ret efirc EFI status code
468 static EFI_STATUS EFIAPI efi_file_flush ( EFI_FILE_PROTOCOL *this ) {
469 struct efi_file *file = container_of ( this, struct efi_file, file );
471 DBGC ( file, "EFIFILE %s flushed\n", efi_file_name ( file ) );
475 /** Root directory */
476 static struct efi_file efi_file_root = {
478 .Revision = EFI_FILE_PROTOCOL_REVISION,
479 .Open = efi_file_open,
480 .Close = efi_file_close,
481 .Delete = efi_file_delete,
482 .Read = efi_file_read,
483 .Write = efi_file_write,
484 .GetPosition = efi_file_get_position,
485 .SetPosition = efi_file_set_position,
486 .GetInfo = efi_file_get_info,
487 .SetInfo = efi_file_set_info,
488 .Flush = efi_file_flush,
494 * Open root directory
496 * @v filesystem EFI simple file system
497 * @ret file EFI file handle
498 * @ret efirc EFI status code
500 static EFI_STATUS EFIAPI
501 efi_file_open_volume ( EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *filesystem __unused,
502 EFI_FILE_PROTOCOL **file ) {
504 DBGC ( &efi_file_root, "EFIFILE open volume\n" );
505 *file = &efi_file_root.file;
509 /** EFI simple file system protocol */
510 static EFI_SIMPLE_FILE_SYSTEM_PROTOCOL efi_simple_file_system_protocol = {
511 .Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
512 .OpenVolume = efi_file_open_volume,
515 /** Dummy block I/O reset */
516 static EFI_STATUS EFIAPI
517 efi_block_io_reset ( EFI_BLOCK_IO_PROTOCOL *this __unused, BOOLEAN extended ) {
519 DBGC ( &efi_file_root, "EFIFILE block %sreset\n",
520 ( extended ? "extended " : "" ) );
524 /** Dummy block I/O read */
525 static EFI_STATUS EFIAPI
526 efi_block_io_read_blocks ( EFI_BLOCK_IO_PROTOCOL *this __unused, UINT32 MediaId,
527 EFI_LBA lba, UINTN len, VOID *data ) {
529 DBGC ( &efi_file_root, "EFIFILE block read ID %#08x LBA %#08llx -> "
530 "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
531 data, ( ( size_t ) len ) );
535 /** Dummy block I/O write */
536 static EFI_STATUS EFIAPI
537 efi_block_io_write_blocks ( EFI_BLOCK_IO_PROTOCOL *this __unused,
538 UINT32 MediaId, EFI_LBA lba, UINTN len,
541 DBGC ( &efi_file_root, "EFIFILE block write ID %#08x LBA %#08llx <- "
542 "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
543 data, ( ( size_t ) len ) );
547 /** Dummy block I/O flush */
548 static EFI_STATUS EFIAPI
549 efi_block_io_flush_blocks ( EFI_BLOCK_IO_PROTOCOL *this __unused ) {
551 DBGC ( &efi_file_root, "EFIFILE block flush\n" );
555 /** Dummy block I/O media */
556 static EFI_BLOCK_IO_MEDIA efi_block_io_media = {
557 .MediaId = EFI_MEDIA_ID_MAGIC,
558 .MediaPresent = TRUE,
563 /** Dummy EFI block I/O protocol */
564 static EFI_BLOCK_IO_PROTOCOL efi_block_io_protocol = {
565 .Revision = EFI_BLOCK_IO_PROTOCOL_REVISION,
566 .Media = &efi_block_io_media,
567 .Reset = efi_block_io_reset,
568 .ReadBlocks = efi_block_io_read_blocks,
569 .WriteBlocks = efi_block_io_write_blocks,
570 .FlushBlocks = efi_block_io_flush_blocks,
573 /** Dummy disk I/O read */
574 static EFI_STATUS EFIAPI
575 efi_disk_io_read_disk ( EFI_DISK_IO_PROTOCOL *this __unused, UINT32 MediaId,
576 UINT64 offset, UINTN len, VOID *data ) {
578 DBGC ( &efi_file_root, "EFIFILE disk read ID %#08x offset %#08llx -> "
579 "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
580 data, ( ( size_t ) len ) );
584 /** Dummy disk I/O write */
585 static EFI_STATUS EFIAPI
586 efi_disk_io_write_disk ( EFI_DISK_IO_PROTOCOL *this __unused, UINT32 MediaId,
587 UINT64 offset, UINTN len, VOID *data ) {
589 DBGC ( &efi_file_root, "EFIFILE disk write ID %#08x offset %#08llx <- "
590 "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
591 data, ( ( size_t ) len ) );
595 /** Dummy EFI disk I/O protocol */
596 static EFI_DISK_IO_PROTOCOL efi_disk_io_protocol = {
597 .Revision = EFI_DISK_IO_PROTOCOL_REVISION,
598 .ReadDisk = efi_disk_io_read_disk,
599 .WriteDisk = efi_disk_io_write_disk,
603 * Install EFI simple file system protocol
605 * @v handle EFI handle
606 * @ret rc Return status code
608 int efi_file_install ( EFI_HANDLE handle ) {
609 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
611 EFI_DISK_IO_PROTOCOL *diskio;
617 /* Install the simple file system protocol, block I/O
618 * protocol, and disk I/O protocol. We don't have a block
619 * device, but large parts of the EDK2 codebase make the
620 * assumption that file systems are normally attached to block
621 * devices, and so we create a dummy block device on the same
622 * handle just to keep things looking normal.
624 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
626 &efi_block_io_protocol_guid,
627 &efi_block_io_protocol,
628 &efi_disk_io_protocol_guid,
629 &efi_disk_io_protocol,
630 &efi_simple_file_system_protocol_guid,
631 &efi_simple_file_system_protocol, NULL ) ) != 0 ) {
632 rc = -EEFI ( efirc );
633 DBGC ( handle, "Could not install simple file system "
634 "protocols: %s\n", strerror ( rc ) );
638 /* The FAT filesystem driver has a bug: if a block device
639 * contains no FAT filesystem but does have an
640 * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instance, the FAT driver
641 * will assume that it must have previously installed the
642 * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. This causes the FAT
643 * driver to claim control of our device, and to refuse to
644 * stop driving it, which prevents us from later uninstalling
647 * Work around this bug by opening the disk I/O protocol
648 * ourselves, thereby preventing the FAT driver from opening
651 * Note that the alternative approach of opening the block I/O
652 * protocol (and thereby in theory preventing DiskIo from
653 * attaching to the block I/O protocol) causes an endless loop
654 * of calls to our DRIVER_STOP method when starting the EFI
655 * shell. I have no idea why this is.
657 if ( ( efirc = bs->OpenProtocol ( handle, &efi_disk_io_protocol_guid,
658 &diskio.interface, efi_image_handle,
660 EFI_OPEN_PROTOCOL_BY_DRIVER ) ) != 0){
661 rc = -EEFI ( efirc );
662 DBGC ( handle, "Could not open disk I/O protocol: %s\n",
664 DBGC_EFI_OPENERS ( handle, handle, &efi_disk_io_protocol_guid );
667 assert ( diskio.diskio == &efi_disk_io_protocol );
671 bs->CloseProtocol ( handle, &efi_disk_io_protocol_guid,
672 efi_image_handle, handle );
674 bs->UninstallMultipleProtocolInterfaces (
676 &efi_simple_file_system_protocol_guid,
677 &efi_simple_file_system_protocol,
678 &efi_disk_io_protocol_guid,
679 &efi_disk_io_protocol,
680 &efi_block_io_protocol_guid,
681 &efi_block_io_protocol, NULL );
687 * Uninstall EFI simple file system protocol
689 * @v handle EFI handle
691 void efi_file_uninstall ( EFI_HANDLE handle ) {
692 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
696 /* Close our own disk I/O protocol */
697 bs->CloseProtocol ( handle, &efi_disk_io_protocol_guid,
698 efi_image_handle, handle );
700 /* We must install the file system protocol first, since
701 * otherwise the EDK2 code will attempt to helpfully uninstall
702 * it when the block I/O protocol is uninstalled, leading to a
705 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
707 &efi_simple_file_system_protocol_guid,
708 &efi_simple_file_system_protocol,
709 &efi_disk_io_protocol_guid,
710 &efi_disk_io_protocol,
711 &efi_block_io_protocol_guid,
712 &efi_block_io_protocol, NULL ) ) != 0 ) {
713 rc = -EEFI ( efirc );
714 DBGC ( handle, "Could not uninstall simple file system "
715 "protocols: %s\n", strerror ( rc ) );