
On Tue, 28 May 2024 at 17:43, Heinrich Schuchardt heinrich.schuchardt@canonical.com wrote:
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@canonical.com
v2: Rename create_initrd_dp() to create_lo_dp_part(). Use enum as parameter for create_lo_dp_part(). Use function efi_load_option_dp_join() to avoid code duplication.
cmd/efidebug.c | 130 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 37 deletions(-)
diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 762027daf8a..966b4b83361 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -654,38 +654,80 @@ static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag, }
/**
- create_initrd_dp() - create a special device for our Boot### option
- enum efi_lo_dp_part - part of device path in load option
- */
+enum efi_lo_dp_part {
/** @EFI_LO_DP_PART_BINARY: binary */
EFI_LO_DP_PART_BINARY,
/** @EFI_LO_DP_PART_INITRD: initial RAM disk */
EFI_LO_DP_PART_INITRD,
/** EFI_LP_DP_PART_FDT: device-tree */
EFI_LP_DP_PART_FDT,
+};
+/**
- create_lo_dp() - create a special device path for our Boot### option
- @dev: device
- @part: disk partition
- @file: filename
- @shortform: create short form device path
*/
- @type: part of device path to be created
- Return: pointer to the device path or ERR_PTR
static -struct efi_device_path *create_initrd_dp(const char *dev, const char *part,
const char *file, int shortform)
+struct efi_device_path *create_lo_dp_part(const char *dev, const char *part,
const char *file, bool shortform,
enum efi_lo_dp_part type)
{ struct efi_device_path *tmp_dp = NULL, *tmp_fp = NULL, *short_fp = NULL;
struct efi_device_path *initrd_dp = NULL;
struct efi_device_path *dp = NULL;
const struct efi_device_path *dp_prefix; efi_status_t ret;
const struct efi_initrd_dp id_dp = {
const struct efi_initrd_dp fdt_dp = {
.vendor = {
{
DEVICE_PATH_TYPE_MEDIA_DEVICE,
DEVICE_PATH_SUB_TYPE_VENDOR_PATH,
sizeof(fdt_dp.vendor),
},
EFI_FDT_GUID,
},
.end = {
DEVICE_PATH_TYPE_END,
DEVICE_PATH_SUB_TYPE_END,
sizeof(fdt_dp.end),
}
};
const struct efi_initrd_dp initrd_dp = { .vendor = { { DEVICE_PATH_TYPE_MEDIA_DEVICE, DEVICE_PATH_SUB_TYPE_VENDOR_PATH,
sizeof(id_dp.vendor),
sizeof(initrd_dp.vendor), }, EFI_INITRD_MEDIA_GUID, }, .end = { DEVICE_PATH_TYPE_END, DEVICE_PATH_SUB_TYPE_END,
sizeof(id_dp.end),
sizeof(initrd_dp.end), } };
switch (type) {
case EFI_LO_DP_PART_INITRD:
dp_prefix = &initrd_dp.vendor.dp;
break;
case EFI_LP_DP_PART_FDT:
dp_prefix = &fdt_dp.vendor.dp;
break;
default:
dp_prefix = NULL;
break;
}
ret = efi_dp_from_name(dev, part, file, &tmp_dp, &tmp_fp); if (ret != EFI_SUCCESS) { printf("Cannot create device path for \"%s %s\"\n", part, file);
@@ -696,13 +739,12 @@ struct efi_device_path *create_initrd_dp(const char *dev, const char *part, if (!short_fp) short_fp = tmp_fp;
initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp,
short_fp, 0);
dp = efi_dp_concat(dp_prefix, short_fp, 0);
out: efi_free_pool(tmp_dp); efi_free_pool(tmp_fp);
return initrd_dp;
return dp;
}
/** @@ -793,9 +835,8 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag, efi_guid_t guid; u16 *label; struct efi_device_path *file_path = NULL;
struct efi_device_path *fp_free = NULL;
struct efi_device_path *final_fp = NULL; struct efi_device_path *initrd_dp = NULL;
struct efi_device_path *fdt_dp = NULL; struct efi_load_option lo; void *data = NULL; efi_uintn_t size;
@@ -843,22 +884,31 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag, lo.label = label; /* label will be changed below */
/* file path */
ret = efi_dp_from_name(argv[3], argv[4], argv[5],
NULL, &fp_free);
if (ret != EFI_SUCCESS) {
printf("Cannot create device path for \"%s %s\"\n",
argv[3], argv[4]);
file_path = create_lo_dp_part(argv[3], argv[4], argv[5],
shortform,
EFI_LO_DP_PART_BINARY);
argc -= 5;
argv += 5;
break;
case 'd':
shortform = 1;
fallthrough;
case 'D':
if (argc < 3 || fdt_dp) {
r = CMD_RET_USAGE;
goto out;
}
fdt_dp = create_lo_dp_part(argv[1], argv[2], argv[3],
shortform,
EFI_LP_DP_PART_FDT);
if (!fdt_dp) {
printf("Cannot add a device-tree\n"); r = CMD_RET_FAILURE; goto out; }
if (shortform)
file_path = efi_dp_shorten(fp_free);
if (!file_path)
file_path = fp_free;
fp_size += efi_dp_size(file_path) +
sizeof(struct efi_device_path);
argc -= 5;
argv += 5;
argc -= 3;
argv += 3; break; case 'i': shortform = 1;
@@ -869,8 +919,9 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag, goto out; }
initrd_dp = create_initrd_dp(argv[1], argv[2], argv[3],
shortform);
initrd_dp = create_lo_dp_part(argv[1], argv[2], argv[3],
shortform,
EFI_LO_DP_PART_INITRD); if (!initrd_dp) { printf("Cannot add an initrd\n"); r = CMD_RET_FAILURE;
@@ -878,8 +929,6 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag, } argc -= 3; argv += 3;
fp_size += efi_dp_size(initrd_dp) +
sizeof(struct efi_device_path); break; case 's': if (argc < 1 || lo.optional_data) {
@@ -897,7 +946,6 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag, &file_path, &fp_size); if (r != CMD_RET_SUCCESS) goto out;
fp_free = file_path; argc -= 3; argv += 3; } else{
@@ -917,14 +965,14 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag, goto out; }
final_fp = efi_dp_concat(file_path, initrd_dp, 1);
if (!final_fp) {
ret = efi_load_option_dp_join(&file_path, &fp_size, initrd_dp, fdt_dp);
if (ret != EFI_SUCCESS) { printf("Cannot create final device path\n"); r = CMD_RET_FAILURE; goto out; }
lo.file_path = final_fp;
lo.file_path = file_path; lo.file_path_length = fp_size; size = efi_serialize_load_option(&lo, (u8 **)&data);
@@ -945,9 +993,9 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
out: free(data);
efi_free_pool(final_fp); efi_free_pool(initrd_dp);
efi_free_pool(fp_free);
efi_free_pool(fdt_dp);
efi_free_pool(file_path); free(lo.label); return r;
@@ -1009,7 +1057,8 @@ static int do_efi_boot_rm(struct cmd_tbl *cmdtp, int flag, */ static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size) {
struct efi_device_path *initrd_path = NULL;
struct efi_device_path *fdt_path;
struct efi_device_path *initrd_path; struct efi_load_option lo; efi_status_t ret;
@@ -1038,6 +1087,12 @@ static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size) efi_free_pool(initrd_path); }
fdt_path = efi_dp_from_lo(&lo, &efi_guid_fdt);
if (fdt_path) {
printf(" device-tree path: %pD\n", fdt_path);
efi_free_pool(fdt_path);
}
printf(" data:\n"); print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, lo.optional_data, *size, true);
@@ -1565,8 +1620,9 @@ U_BOOT_LONGHELP(efidebug, "\n" "efidebug boot add - set UEFI BootXXXX variable\n" " -b|-B <bootid> <label> <interface> <devnum>[:<part>] <file path>\n"
" -d|-D <interface> <devnum>[:<part>] <device-tree file path>\n" " -i|-I <interface> <devnum>[:<part>] <initrd file path>\n"
" (-b, -i for short form device path)\n"
" (-b, -d, -i for short form device path)\n"
#if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT)) " -u <bootid> <label> <uri>\n"
#endif
2.43.0
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org