Pull request for UEFI sub-system for efi-2021-04-rc2

Bug fixes:
 
 * do not allow creating of files with filenames on FAT file system
 * install UEFI System Partition GUID on ESP handle
 * in dtbdump.efi test tool use GUID to find ESP handle
 
 Documentation:
 
 * man-page for load command
 * describe end of life of plat_auto
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAmAcTmoACgkQxIHbvCwF
 GsT0ag/6AjtRtGd8ySYix9lytmDphyztvTTHrd/Bz+UWi64iEIOH6t/RIAPG0yb0
 WJBvTe9eGxbNx5VOx426YtPUGFfzAakMyRaAL5Y4wkQsKgseq3q2sE55wzG4nTiR
 nmweR7TPslSkGtqQQehGGtdMJn//M/alABtTQs5eyjOkJPEc4DzATeksfA64t2Dj
 ijaU4dWbKVHy8spz3xH9cIdF1fvCJGxvSvXCVculN5bfgCf/MJYq6gb2VgXyLL1w
 +6GNklzNKRY8Lk9C4hqq2ktK4dQ4R0qKgqxtihwuSdbZmhV6cScKvmNPCqdYx/1l
 p5ywE067KRm16Hl/41QhKPMVleqn33Td3U4I+CWvO9DPnsH7pY9iRymM6zfRm9+j
 nO4f8++OqG/YXL+oABLkSIZaoYWqGmZd5Nc1bq9sTXthUXHZeC6/V19n0TJYVIV5
 HtIPFJbqn4S4uKjTFxyvudE6OfeW4+HpsY7bQHDRXWY1Kma0fgMYbhFZdUeNyr+6
 N8EFXZ5nKVWqLH9zlAIPOn0AEXzOfvsWad+NU0bILY8f60SqW0AydjvzG8z9CU3e
 vqxx+NxcG26SYscIcANvMI7HxtB6mblBYF2vSqBAkSrQ23Om+dnKkLhHO8pkkNtn
 J4rLpAxEAA1yaqKK/1n67D6pSqvjdWQqOfgL/3E1sqgAGYYOBrc=
 =rQaL
 -----END PGP SIGNATURE-----

Merge tag 'efi-2021-04-rc2' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi

Pull request for UEFI sub-system for efi-2021-04-rc2

Bug fixes:

* do not allow creating of files with filenames on FAT file system
* install UEFI System Partition GUID on ESP handle
* in dtbdump.efi test tool use GUID to find ESP handle

Documentation:

* man-page for load command
* describe end of life of plat_auto
This commit is contained in:
Tom Rini 2021-02-04 17:35:50 -05:00
commit 55ffabec7f
10 changed files with 214 additions and 87 deletions

View File

@ -16,6 +16,7 @@
#include <log.h> #include <log.h>
#include <malloc.h> #include <malloc.h>
#include <mapmem.h> #include <mapmem.h>
#include <part.h>
#include <search.h> #include <search.h>
#include <linux/ctype.h> #include <linux/ctype.h>
@ -502,6 +503,10 @@ static const struct {
"Device-Tree Fixup", "Device-Tree Fixup",
EFI_DT_FIXUP_PROTOCOL_GUID, EFI_DT_FIXUP_PROTOCOL_GUID,
}, },
{
"System Partition",
PARTITION_SYSTEM_GUID
},
/* Configuration table GUIDs */ /* Configuration table GUIDs */
{ {
"ACPI table", "ACPI table",

View File

@ -725,7 +725,7 @@ The steps are:
2. If plat_auto is non-zero, then the platform data space 2. If plat_auto is non-zero, then the platform data space
is allocated. This is only useful for device tree operation, since is allocated. This is only useful for device tree operation, since
otherwise you would have to specific the platform data in the otherwise you would have to specify the platform data in the
U_BOOT_DRVINFO() declaration. The space is allocated for the device and U_BOOT_DRVINFO() declaration. The space is allocated for the device and
zeroed. It will be accessible as dev->plat. zeroed. It will be accessible as dev->plat.
@ -861,8 +861,8 @@ remove it. This performs the probe steps in reverse:
be dynamically allocated, and thus needs to be deallocated during the be dynamically allocated, and thus needs to be deallocated during the
remove() method, either: remove() method, either:
- if the plat_auto is non-zero, the deallocation - if the plat_auto is non-zero, the deallocation happens automatically
happens automatically within the driver model core; or within the driver model core in the unbind stage; or
- when plat_auto is 0, both the allocation (in probe() - when plat_auto is 0, both the allocation (in probe()
or preferably of_to_plat()) and the deallocation in remove() or preferably of_to_plat()) and the deallocation in remove()

View File

@ -61,8 +61,3 @@ Examples
pc = 0x56076dd1a0f9, pc_reloc = 0x540f9 pc = 0x56076dd1a0f9, pc_reloc = 0x540f9
resetting ... resetting ...
Return value
------------
The return value $? is always set to 0 (true).

View File

@ -23,6 +23,7 @@ Shell commands
exit exit
false false
for for
load
loady loady
mbr mbr
pstore pstore

74
doc/usage/load.rst Normal file
View File

@ -0,0 +1,74 @@
.. SPDX-License-Identifier: GPL-2.0+:
load command
============
Synopsis
--------
::
load <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]
Description
-----------
The load command is used to read a file from a filesystem into memory.
The number of transferred bytes is saved in the environment variable filesize.
The load address is saved in the environment variable fileaddr.
interface
interface for accessing the block device (mmc, sata, scsi, usb, ....)
dev
device number
part
partition number, defaults to 0 (whole device)
addr
load address, defaults to environment variable loadaddr or if loadaddr is
not set to configuration variable CONFIG_SYS_LOAD_ADDR
filename
path to file, defaults to environment variable bootfile
bytes
maximum number of bytes to load
pos
number of bytes to skip
addr, bytes, pos are hexadecimal numbers.
Example
-------
::
=> load mmc 0:1 ${kernel_addr_r} snp.efi
149280 bytes read in 11 ms (12.9 MiB/s)
=>
=> load mmc 0:1 ${kernel_addr_r} snp.efi 1000000
149280 bytes read in 9 ms (15.8 MiB/s)
=>
=> load mmc 0:1 ${kernel_addr_r} snp.efi 1000000 100
149024 bytes read in 10 ms (14.2 MiB/s)
=>
=> load mmc 0:1 ${kernel_addr_r} snp.efi 10
16 bytes read in 1 ms (15.6 KiB/s)
=>
Configuration
-------------
The load command is only available if CONFIG_CMD_FS_GENERIC=y.
Return value
------------
The return value $? is set to 0 (true) if the file was successfully loaded
even if the number of bytes is less then the specified length.
If an error occurs, the return value $? is set to 1 (false).

View File

@ -1237,12 +1237,38 @@ again:
} }
*last_slash_cont = '\0'; *last_slash_cont = '\0';
*basename = last_slash_cont + 1; filename = last_slash_cont + 1;
} else { } else {
*dirname = "/"; /* root by default */ *dirname = "/"; /* root by default */
*basename = filename;
} }
/*
* The FAT32 File System Specification v1.03 requires leading and
* trailing spaces as well as trailing periods to be ignored.
*/
for (; *filename == ' '; ++filename)
;
/* Keep special entries '.' and '..' */
if (filename[0] == '.' &&
(!filename[1] || (filename[1] == '.' && !filename[2])))
goto done;
/* Remove trailing periods and spaces */
for (p = filename + strlen(filename) - 1; p >= filename; --p) {
switch (*p) {
case ' ':
case '.':
*p = 0;
break;
default:
goto done;
}
}
done:
*basename = filename;
return 0; return 0;
} }
@ -1259,8 +1285,10 @@ again:
static int normalize_longname(char *l_filename, const char *filename) static int normalize_longname(char *l_filename, const char *filename)
{ {
const char *p, illegal[] = "<>:\"/\\|?*"; const char *p, illegal[] = "<>:\"/\\|?*";
size_t len;
if (strlen(filename) >= VFAT_MAXLEN_BYTES) len = strlen(filename);
if (!len || len >= VFAT_MAXLEN_BYTES || filename[len - 1] == '.')
return -1; return -1;
for (p = filename; *p; ++p) { for (p = filename; *p; ++p) {
@ -1299,9 +1327,8 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
goto exit; goto exit;
} }
filename = basename; if (normalize_longname(l_filename, basename)) {
if (normalize_longname(l_filename, filename)) { printf("FAT: illegal filename (%s)\n", basename);
printf("FAT: illegal filename (%s)\n", filename);
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
@ -1349,15 +1376,6 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
char shortname[SHORT_NAME_SIZE]; char shortname[SHORT_NAME_SIZE];
int ndent; int ndent;
if (itr->is_root) {
/* root dir cannot have "." or ".." */
if (!strcmp(l_filename, ".") ||
!strcmp(l_filename, "..")) {
ret = -EINVAL;
goto exit;
}
}
if (pos) { if (pos) {
/* No hole allowed */ /* No hole allowed */
ret = -EINVAL; ret = -EINVAL;
@ -1365,7 +1383,7 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
} }
/* Check if long name is needed */ /* Check if long name is needed */
ndent = set_name(itr, filename, shortname); ndent = set_name(itr, basename, shortname);
if (ndent < 0) { if (ndent < 0) {
ret = ndent; ret = ndent;
goto exit; goto exit;
@ -1375,7 +1393,7 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
goto exit; goto exit;
if (ndent > 1) { if (ndent > 1) {
/* Set long name entries */ /* Set long name entries */
ret = fill_dir_slot(itr, filename, shortname); ret = fill_dir_slot(itr, basename, shortname);
if (ret) if (ret)
goto exit; goto exit;
} }
@ -1611,31 +1629,31 @@ exit:
return ret; return ret;
} }
int fat_mkdir(const char *new_dirname) int fat_mkdir(const char *dirname)
{ {
dir_entry *retdent; dir_entry *retdent;
fsdata datablock = { .fatbuf = NULL, }; fsdata datablock = { .fatbuf = NULL, };
fsdata *mydata = &datablock; fsdata *mydata = &datablock;
fat_itr *itr = NULL; fat_itr *itr = NULL;
char *dirname_copy, *parent, *dirname; char *dirname_copy, *parent, *basename;
char l_dirname[VFAT_MAXLEN_BYTES]; char l_dirname[VFAT_MAXLEN_BYTES];
int ret = -1; int ret = -1;
loff_t actwrite; loff_t actwrite;
unsigned int bytesperclust; unsigned int bytesperclust;
dir_entry *dotdent = NULL; dir_entry *dotdent = NULL;
dirname_copy = strdup(new_dirname); dirname_copy = strdup(dirname);
if (!dirname_copy) if (!dirname_copy)
goto exit; goto exit;
split_filename(dirname_copy, &parent, &dirname); split_filename(dirname_copy, &parent, &basename);
if (!strlen(dirname)) { if (!strlen(basename)) {
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
if (normalize_longname(l_dirname, dirname)) { if (normalize_longname(l_dirname, basename)) {
printf("FAT: illegal filename (%s)\n", dirname); printf("FAT: illegal filename (%s)\n", basename);
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
@ -1678,7 +1696,7 @@ int fat_mkdir(const char *new_dirname)
} }
/* Check if long name is needed */ /* Check if long name is needed */
ndent = set_name(itr, dirname, shortname); ndent = set_name(itr, basename, shortname);
if (ndent < 0) { if (ndent < 0) {
ret = ndent; ret = ndent;
goto exit; goto exit;
@ -1688,7 +1706,7 @@ int fat_mkdir(const char *new_dirname)
goto exit; goto exit;
if (ndent > 1) { if (ndent > 1) {
/* Set long name entries */ /* Set long name entries */
ret = fill_dir_slot(itr, dirname, shortname); ret = fill_dir_slot(itr, basename, shortname);
if (ret) if (ret)
goto exit; goto exit;
} }

View File

@ -244,6 +244,21 @@ static char *dp_media(char *s, struct efi_device_path *dp)
cddp->partition_start, cddp->partition_size); cddp->partition_start, cddp->partition_size);
break; break;
} }
case DEVICE_PATH_SUB_TYPE_VENDOR_PATH: {
int i, n;
struct efi_device_path_vendor *vdp =
(struct efi_device_path_vendor *)dp;
s += sprintf(s, "VenMedia(%pUl", &vdp->guid);
n = (int)vdp->dp.length - sizeof(struct efi_device_path_vendor);
if (n > 0) {
s += sprintf(s, ",");
for (i = 0; i < n; ++i)
s += sprintf(s, "%02x", vdp->vendor_data[i]);
}
s += sprintf(s, ")");
break;
}
case DEVICE_PATH_SUB_TYPE_FILE_PATH: { case DEVICE_PATH_SUB_TYPE_FILE_PATH: {
struct efi_device_path_file_path *fp = struct efi_device_path_file_path *fp =
(struct efi_device_path_file_path *)dp; (struct efi_device_path_file_path *)dp;

View File

@ -19,6 +19,7 @@
struct efi_system_partition efi_system_partition; struct efi_system_partition efi_system_partition;
const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID; const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
/** /**
* struct efi_disk_obj - EFI disk object * struct efi_disk_obj - EFI disk object
@ -362,6 +363,7 @@ static efi_status_t efi_disk_add_dev(
{ {
struct efi_disk_obj *diskobj; struct efi_disk_obj *diskobj;
struct efi_object *handle; struct efi_object *handle;
const efi_guid_t *guid = NULL;
efi_status_t ret; efi_status_t ret;
/* Don't add empty devices */ /* Don't add empty devices */
@ -400,6 +402,8 @@ static efi_status_t efi_disk_add_dev(
efi_free_pool(node); efi_free_pool(node);
diskobj->offset = part_info->start; diskobj->offset = part_info->start;
diskobj->media.last_block = part_info->size - 1; diskobj->media.last_block = part_info->size - 1;
if (part_info->bootable & PART_EFI_SYSTEM_PARTITION)
guid = &efi_system_partition_guid;
} else { } else {
diskobj->dp = efi_dp_from_part(desc, part); diskobj->dp = efi_dp_from_part(desc, part);
diskobj->offset = 0; diskobj->offset = 0;
@ -417,7 +421,8 @@ static efi_status_t efi_disk_add_dev(
handle = &diskobj->header; handle = &diskobj->header;
ret = EFI_CALL(efi_install_multiple_protocol_interfaces( ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
&handle, &efi_guid_device_path, diskobj->dp, &handle, &efi_guid_device_path, diskobj->dp,
&efi_block_io_guid, &diskobj->ops, NULL)); &efi_block_io_guid, &diskobj->ops,
guid, NULL, NULL));
if (ret != EFI_SUCCESS) if (ret != EFI_SUCCESS)
return ret; return ret;
@ -467,13 +472,7 @@ static efi_status_t efi_disk_add_dev(
/* Store first EFI system partition */ /* Store first EFI system partition */
if (part && !efi_system_partition.if_type) { if (part && !efi_system_partition.if_type) {
int r; if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) {
struct disk_partition info;
r = part_get_info(desc, part, &info);
if (r)
return EFI_DEVICE_ERROR;
if (info.bootable & PART_EFI_SYSTEM_PARTITION) {
efi_system_partition.if_type = desc->if_type; efi_system_partition.if_type = desc->if_type;
efi_system_partition.devnum = desc->devnum; efi_system_partition.devnum = desc->devnum;
efi_system_partition.part = part; efi_system_partition.part = part;

View File

@ -110,6 +110,7 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb,
{ {
efi_status_t ret; efi_status_t ret;
size_t required_size; size_t required_size;
size_t total_size;
bootm_headers_t img = { 0 }; bootm_headers_t img = { 0 };
EFI_ENTRY("%p, %p, %p, %d", this, dtb, buffer_size, flags); EFI_ENTRY("%p, %p, %p, %d", this, dtb, buffer_size, flags);
@ -124,20 +125,20 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb,
goto out; goto out;
} }
if (flags & EFI_DT_APPLY_FIXUPS) { if (flags & EFI_DT_APPLY_FIXUPS) {
/* Check size */
required_size = fdt_off_dt_strings(dtb) + required_size = fdt_off_dt_strings(dtb) +
fdt_size_dt_strings(dtb) + fdt_size_dt_strings(dtb) +
0x3000; 0x3000;
} else { total_size = fdt_totalsize(dtb);
required_size = fdt_totalsize(dtb); if (required_size < total_size)
} required_size = total_size;
if (required_size > *buffer_size) { if (required_size > *buffer_size) {
*buffer_size = required_size; *buffer_size = required_size;
ret = EFI_BUFFER_TOO_SMALL; ret = EFI_BUFFER_TOO_SMALL;
goto out; goto out;
} }
fdt_set_totalsize(dtb, *buffer_size);
if (flags & EFI_DT_APPLY_FIXUPS) { fdt_set_totalsize(dtb, *buffer_size);
if (image_setup_libfdt(&img, dtb, 0, NULL)) { if (image_setup_libfdt(&img, dtb, 0, NULL)) {
log_err("failed to process device tree\n"); log_err("failed to process device tree\n");
ret = EFI_INVALID_PARAMETER; ret = EFI_INVALID_PARAMETER;
@ -147,10 +148,10 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb,
if (flags & EFI_DT_RESERVE_MEMORY) if (flags & EFI_DT_RESERVE_MEMORY)
efi_carve_out_dt_rsv(dtb); efi_carve_out_dt_rsv(dtb);
if (EFI_DT_INSTALL_TABLE) { if (flags & EFI_DT_INSTALL_TABLE) {
ret = efi_install_configuration_table(&efi_guid_fdt, dtb); ret = efi_install_configuration_table(&efi_guid_fdt, dtb);
if (ret != EFI_SUCCESS) { if (ret != EFI_SUCCESS) {
log_err("ERROR: failed to install device tree\n"); log_err("failed to install device tree\n");
goto out; goto out;
} }
} }

View File

@ -9,6 +9,7 @@
#include <common.h> #include <common.h>
#include <efi_api.h> #include <efi_api.h>
#include <efi_dt_fixup.h> #include <efi_dt_fixup.h>
#include <part.h>
#define BUFFER_SIZE 64 #define BUFFER_SIZE 64
#define ESC 0x17 #define ESC 0x17
@ -27,6 +28,7 @@ static efi_handle_t handle;
static struct efi_system_table *systable; static struct efi_system_table *systable;
static const efi_guid_t efi_dt_fixup_protocol_guid = EFI_DT_FIXUP_PROTOCOL_GUID; static const efi_guid_t efi_dt_fixup_protocol_guid = EFI_DT_FIXUP_PROTOCOL_GUID;
static const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID; static const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
static const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
/** /**
* print() - print string * print() - print string
@ -230,6 +232,52 @@ void do_help(void)
error(L"exit - exit the shell\r\n"); error(L"exit - exit the shell\r\n");
} }
/**
* open_file_system() - open simple file system protocol
*
* file_system: interface of the simple file system protocol
* Return: status code
*/
static efi_status_t
open_file_system(struct efi_simple_file_system_protocol **file_system)
{
struct efi_loaded_image *loaded_image;
efi_status_t ret;
efi_handle_t *handle_buffer = NULL;
efi_uintn_t count;
ret = bs->open_protocol(handle, &loaded_image_guid,
(void **)&loaded_image, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(L"Loaded image protocol not found\r\n");
return ret;
}
/* Open the simple file system protocol on the same partition */
ret = bs->open_protocol(loaded_image->device_handle,
&guid_simple_file_system_protocol,
(void **)file_system, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret == EFI_SUCCESS)
return ret;
/* Open the simple file system protocol on the UEFI system partition */
ret = bs->locate_handle_buffer(BY_PROTOCOL, &efi_system_partition_guid,
NULL, &count, &handle_buffer);
if (ret == EFI_SUCCESS && handle_buffer)
ret = bs->open_protocol(handle_buffer[0],
&guid_simple_file_system_protocol,
(void **)file_system, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS)
error(L"Failed to open simple file system protocol\r\n");
if (handle)
bs->free_pool(handle_buffer);
return ret;
}
/** /**
* do_load() - load and install device-tree * do_load() - load and install device-tree
* *
@ -239,7 +287,6 @@ void do_help(void)
efi_status_t do_load(u16 *filename) efi_status_t do_load(u16 *filename)
{ {
struct efi_dt_fixup_protocol *dt_fixup_prot; struct efi_dt_fixup_protocol *dt_fixup_prot;
struct efi_loaded_image *loaded_image;
struct efi_simple_file_system_protocol *file_system; struct efi_simple_file_system_protocol *file_system;
struct efi_file_handle *root = NULL, *file = NULL; struct efi_file_handle *root = NULL, *file = NULL;
u64 addr = 0; u64 addr = 0;
@ -258,22 +305,9 @@ efi_status_t do_load(u16 *filename)
filename = skip_whitespace(filename); filename = skip_whitespace(filename);
ret = bs->open_protocol(handle, &loaded_image_guid, ret = open_file_system(&file_system);
(void **)&loaded_image, NULL, NULL, if (ret != EFI_SUCCESS)
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(L"Loaded image protocol not found\r\n");
return ret;
}
/* Open the simple file system protocol */
ret = bs->open_protocol(loaded_image->device_handle,
&guid_simple_file_system_protocol,
(void **)&file_system, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(L"Failed to open simple file system protocol\r\n");
goto out; goto out;
}
/* Open volume */ /* Open volume */
ret = file_system->open_volume(file_system, &root); ret = file_system->open_volume(file_system, &root);
@ -389,7 +423,6 @@ out:
*/ */
efi_status_t do_save(u16 *filename) efi_status_t do_save(u16 *filename)
{ {
struct efi_loaded_image *loaded_image;
struct efi_simple_file_system_protocol *file_system; struct efi_simple_file_system_protocol *file_system;
efi_uintn_t dtb_size; efi_uintn_t dtb_size;
struct efi_file_handle *root, *file; struct efi_file_handle *root, *file;
@ -409,23 +442,9 @@ efi_status_t do_save(u16 *filename)
filename = skip_whitespace(filename); filename = skip_whitespace(filename);
ret = bs->open_protocol(handle, &loaded_image_guid, ret = open_file_system(&file_system);
(void **)&loaded_image, NULL, NULL, if (ret != EFI_SUCCESS)
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(L"Loaded image protocol not found\r\n");
return ret; return ret;
}
/* Open the simple file system protocol */
ret = bs->open_protocol(loaded_image->device_handle,
&guid_simple_file_system_protocol,
(void **)&file_system, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(L"Failed to open simple file system protocol\r\n");
return ret;
}
/* Open volume */ /* Open volume */
ret = file_system->open_volume(file_system, &root); ret = file_system->open_volume(file_system, &root);