[RFC 04/14] cmd: eficonfig: add support for setting fdt
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Fri Apr 26 16:13:11 CEST 2024
We already support creating a load option where the device-path
field contains the concatenation of the binary device-path and
optionally the device path of the initrd which we expose via the
EFI_LOAD_FILE2_PROTOCOL.
Allow to append another device-path pointing to the device-tree
identified by the device-tree GUID.
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
---
cmd/eficonfig.c | 68 +++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 63 insertions(+), 5 deletions(-)
diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
index 1c57e66040b..d314051ee58 100644
--- a/cmd/eficonfig.c
+++ b/cmd/eficonfig.c
@@ -62,6 +62,7 @@ struct eficonfig_filepath_info {
struct eficonfig_boot_option {
struct eficonfig_select_file_info file_info;
struct eficonfig_select_file_info initrd_info;
+ struct eficonfig_select_file_info fdt_info;
unsigned int boot_index;
u16 *description;
u16 *optional_data;
@@ -1308,6 +1309,10 @@ static efi_status_t eficonfig_show_boot_option(struct eficonfig_boot_option *bo,
if (ret != EFI_SUCCESS)
goto out;
+ ret = prepare_file_selection_entry(efi_menu, "Fdt File: ", &bo->fdt_info);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
ret = create_boot_option_entry(efi_menu, "Optional Data: ", bo->optional_data,
eficonfig_boot_add_optional_data, bo);
if (ret != EFI_SUCCESS)
@@ -1394,21 +1399,39 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
struct efi_device_path *final_dp = NULL;
struct efi_device_path *device_dp = NULL;
struct efi_device_path *initrd_dp = NULL;
+ struct efi_device_path *fdt_dp = NULL;
struct efi_device_path *initrd_device_dp = NULL;
+ struct efi_device_path *fdt_device_dp = NULL;
- const struct efi_initrd_dp id_dp = {
+ const struct efi_initrd_dp initrd_prefix = {
.vendor = {
{
DEVICE_PATH_TYPE_MEDIA_DEVICE,
DEVICE_PATH_SUB_TYPE_VENDOR_PATH,
- sizeof(id_dp.vendor),
+ sizeof(initrd_prefix.vendor),
},
EFI_INITRD_MEDIA_GUID,
},
.end = {
DEVICE_PATH_TYPE_END,
DEVICE_PATH_SUB_TYPE_END,
- sizeof(id_dp.end),
+ sizeof(initrd_prefix.end),
+ }
+ };
+
+ const struct efi_initrd_dp fdt_prefix = {
+ .vendor = {
+ {
+ DEVICE_PATH_TYPE_MEDIA_DEVICE,
+ DEVICE_PATH_SUB_TYPE_VENDOR_PATH,
+ sizeof(fdt_prefix.vendor),
+ },
+ EFI_FDT_GUID,
+ },
+ .end = {
+ DEVICE_PATH_TYPE_END,
+ DEVICE_PATH_SUB_TYPE_END,
+ sizeof(initrd_prefix.end),
}
};
@@ -1424,6 +1447,12 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
goto out;
}
+ bo->fdt_info.current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE);
+ if (!bo->fdt_info.current_path) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
bo->description = calloc(1, EFICONFIG_DESCRIPTION_MAX * sizeof(u16));
if (!bo->description) {
ret = EFI_OUT_OF_RESOURCES;
@@ -1456,13 +1485,20 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
if (lo.file_path)
fill_file_info(lo.file_path, &bo->file_info, device_dp);
- /* Initrd file path(optional) is placed at second instance. */
+ /* Initrd file path (optional) is placed at second instance. */
initrd_dp = efi_dp_from_lo(&lo, &efi_lf2_initrd_guid);
if (initrd_dp) {
fill_file_info(initrd_dp, &bo->initrd_info, initrd_device_dp);
efi_free_pool(initrd_dp);
}
+ /* Fdt file path (optional) is placed as third instance. */
+ fdt_dp = efi_dp_from_lo(&lo, &efi_guid_fdt);
+ if (fdt_dp) {
+ fill_file_info(fdt_dp, &bo->fdt_info, fdt_device_dp);
+ efi_free_pool(fdt_dp);
+ }
+
if (size > 0)
memcpy(bo->optional_data, lo.optional_data, size);
}
@@ -1484,11 +1520,23 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
ret = EFI_OUT_OF_RESOURCES;
goto out;
}
- initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp,
+ initrd_dp = efi_dp_concat((const struct efi_device_path *)&initrd_prefix,
dp);
efi_free_pool(dp);
}
+ if (bo->fdt_info.dp_volume) {
+ dp = eficonfig_create_device_path(bo->fdt_info.dp_volume,
+ bo->fdt_info.current_path);
+ if (!dp) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+ fdt_dp = efi_dp_concat((const struct efi_device_path *)&fdt_prefix,
+ dp);
+ efi_free_pool(dp);
+ }
+
dp = eficonfig_create_device_path(bo->file_info.dp_volume, bo->file_info.current_path);
if (!dp) {
ret = EFI_OUT_OF_RESOURCES;
@@ -1505,6 +1553,13 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
goto out;
}
}
+ if (fdt_dp) {
+ final_dp = efi_dp_merge(final_dp, &final_dp_size, fdt_dp);
+ if (!final_dp) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+ }
if (utf16_utf8_strlen(bo->optional_data)) {
len = utf16_utf8_strlen(bo->optional_data) + 1;
@@ -1522,9 +1577,12 @@ out:
free(bo->description);
free(bo->file_info.current_path);
free(bo->initrd_info.current_path);
+ free(bo->fdt_info.current_path);
efi_free_pool(device_dp);
efi_free_pool(initrd_device_dp);
efi_free_pool(initrd_dp);
+ efi_free_pool(fdt_device_dp);
+ efi_free_pool(fdt_dp);
efi_free_pool(final_dp);
return ret;
--
2.43.0
More information about the U-Boot
mailing list