[PATCH v2 3/8] cmd: efidebug: add support for setting fdt
Ilias Apalodimas
ilias.apalodimas at linaro.org
Tue May 28 17:36:45 CEST 2024
On Tue, 28 May 2024 at 17:43, Heinrich Schuchardt
<heinrich.schuchardt at 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 at 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 at linaro.org>
More information about the U-Boot
mailing list