[PATCH v2 5/9] efi_loader: use short-form DP for load options
AKASHI Takahiro
takahiro.akashi at linaro.org
Wed Mar 23 09:18:35 CET 2022
On Sat, Mar 19, 2022 at 10:11:44AM +0100, Heinrich Schuchardt wrote:
> From: Heinrich Schuchardt <xypron.glpk at gmx.de>
>
> The GUID of partitions is sufficient for identification and will stay
> constant in the lifetime of a boot option. The preceding path of the
> device-path may change due to changes in the enumeration of devices.
> Therefore it is preferable to use the short-form of device-paths in load
> options. Adjust the 'efidebug boot add' command accordingly.
>
> Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
> ---
> v2:
> support both short and long form device paths
> split off exporting efi_dp_shorten() into a separate patch
> ---
> cmd/efidebug.c | 70 ++++++++++++++++++++++++++++++++++----------------
> 1 file changed, 48 insertions(+), 22 deletions(-)
>
> diff --git a/cmd/efidebug.c b/cmd/efidebug.c
> index 401d13cc4c..51e2850d21 100644
> --- a/cmd/efidebug.c
> +++ b/cmd/efidebug.c
> @@ -734,20 +734,20 @@ static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag,
> }
>
> /**
> - * create_initrd_dp() - Create a special device for our Boot### option
> - *
> - * @dev: Device
> - * @part: Disk partition
> - * @file: Filename
> - * Return: Pointer to the device path or ERR_PTR
> + * create_initrd_dp() - create a special device for our Boot### option
> *
> + * @dev: device
> + * @part: disk partition
> + * @file: filename
> + * @shortform: create short form device path
> + * 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)
> + const char *file, int shortform)
>
> {
> - struct efi_device_path *tmp_dp = NULL, *tmp_fp = NULL;
> + struct efi_device_path *tmp_dp = NULL, *tmp_fp = NULL, *short_fp = NULL;
> struct efi_device_path *initrd_dp = NULL;
> efi_status_t ret;
> const struct efi_initrd_dp id_dp = {
> @@ -771,9 +771,13 @@ struct efi_device_path *create_initrd_dp(const char *dev, const char *part,
> printf("Cannot create device path for \"%s %s\"\n", part, file);
> goto out;
> }
> + if (shortform)
> + short_fp = efi_dp_shorten(tmp_fp);
> + if (!short_fp)
> + short_fp = tmp_fp;
>
> initrd_dp = efi_dp_append((const struct efi_device_path *)&id_dp,
> - tmp_fp);
> + short_fp);
>
> out:
> efi_free_pool(tmp_dp);
> @@ -807,6 +811,7 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
> size_t label_len, label_len16;
> u16 *label;
> struct efi_device_path *device_path = NULL, *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_load_option lo;
> @@ -826,7 +831,18 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
> argc--;
> argv++; /* 'add' */
> for (; argc > 0; argc--, argv++) {
> - if (!strcmp(argv[0], "-b")) {
> + int shortform;
> +
> + if (*argv[0] != '-' || strlen(argv[0]) != 2) {
> + r = CMD_RET_USAGE;
> + goto out;
> + }
> + shortform = 0;
> + switch (argv[0][1]) {
> + case 'b':
> + shortform = 1;
> + /* fallthrough */
> + case 'B':
> if (argc < 5 || lo.label) {
> r = CMD_RET_USAGE;
> goto out;
> @@ -849,24 +865,33 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
>
> /* file path */
> ret = efi_dp_from_name(argv[3], argv[4], argv[5],
> - &device_path, &file_path);
> + &device_path, &fp_free);
The semantics of efi_dp_from_name() seems odd as both "device_path" and
"file_path" (or "fp_free") may partially contain a duplicated device path.
That is why "device_path" is not used after this line.
Although this behavior has not changed since my initial implementation,
"file_path" should not have included preceding device path components
other than the file path media device path.
Anyhow, we can pass NULL instead of "&device_path" for now.
> if (ret != EFI_SUCCESS) {
> printf("Cannot create device path for \"%s %s\"\n",
> argv[3], argv[4]);
> 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;
> - } else if (!strcmp(argv[0], "-i")) {
> + break;
> + case 'i':
> + shortform = 1;
> + /* fallthrough */
> + case 'I':
> if (argc < 3 || initrd_dp) {
> r = CMD_RET_USAGE;
> goto out;
> }
>
> - initrd_dp = create_initrd_dp(argv[1], argv[2], argv[3]);
> + initrd_dp = create_initrd_dp(argv[1], argv[2], argv[3],
> + shortform);
> if (!initrd_dp) {
> printf("Cannot add an initrd\n");
> r = CMD_RET_FAILURE;
> @@ -876,7 +901,8 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
> argv += 3;
> fp_size += efi_dp_size(initrd_dp) +
> sizeof(struct efi_device_path);
> - } else if (!strcmp(argv[0], "-s")) {
> + break;
> + case 's':
> if (argc < 1 || lo.optional_data) {
> r = CMD_RET_USAGE;
> goto out;
> @@ -884,7 +910,8 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
> lo.optional_data = (const u8 *)argv[1];
> argc -= 1;
> argv += 1;
> - } else {
> + break;
> + default:
> r = CMD_RET_USAGE;
> goto out;
> }
> @@ -927,7 +954,7 @@ out:
> efi_free_pool(final_fp);
> efi_free_pool(initrd_dp);
> efi_free_pool(device_path);
> - efi_free_pool(file_path);
> + efi_free_pool(fp_free);
> free(lo.label);
>
> return r;
> @@ -1571,12 +1598,11 @@ static int do_efidebug(struct cmd_tbl *cmdtp, int flag,
> static char efidebug_help_text[] =
> " - UEFI Shell-like interface to configure UEFI environment\n"
> "\n"
> - "efidebug boot add "
> - "-b <bootid> <label> <interface> <devnum>[:<part>] <file path> "
> - "-i <interface> <devnum>[:<part>] <initrd file path> "
> - "-s '<optional data>'\n"
> - " - set UEFI BootXXXX variable\n"
> - " <load options> will be passed to UEFI application\n"
> + "efidebug boot add - set UEFI BootXXXX variable\n"
> + " -b|-B <bootid> <label> <interface> <devnum>[:<part>] <file path>\n"
> + " -i|-I <interface> <devnum>[:<part>] <initrd file path>\n"
> + " (-b, -i for short form device path)\n"
I know you want to use short-forms (-b/-i) as default, but this change of meanings
potentially breaks the backward compatibility of command syntax although it's not a bug fix.
-Takahiro Akashi
> + " -s '<optional data>'\n"
> "efidebug boot rm <bootid#1> [<bootid#2> [<bootid#3> [...]]]\n"
> " - delete UEFI BootXXXX variables\n"
> "efidebug boot dump\n"
> --
> 2.34.1
>
More information about the U-Boot
mailing list