[RFC PATCH 3/3] efidebug: add multiple device path instances on Boot####
Heinrich Schuchardt
xypron.glpk at gmx.de
Wed Jan 13 14:13:44 CET 2021
On 13.01.21 12:11, Ilias Apalodimas wrote:
> The UEFI spec allow a packed array of UEFI device paths in the
> FilePathList[] of an EFI_LOAD_OPTION. The first file path must
> describe the laoded image but the rest are OS specific.
> Previous patches parse the device path and try to use the second
> member of the array as an initrd. So let's modify efidebug slightly
> and install the second file described in the command line as the
> initrd device path.
Please, describe the syntax of the efidebug command in the commit message.
>
> Signed-off-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
> ---
> cmd/efidebug.c | 89 +++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 81 insertions(+), 8 deletions(-)
>
> diff --git a/cmd/efidebug.c b/cmd/efidebug.c
> index 5fb7b1e3c6a9..8d62981aca92 100644
> --- a/cmd/efidebug.c
> +++ b/cmd/efidebug.c
> @@ -8,6 +8,7 @@
> #include <charset.h>
> #include <common.h>
> #include <command.h>
> +#include <efi_helper.h>
> #include <efi_loader.h>
> #include <efi_rng.h>
> #include <exports.h>
> @@ -17,6 +18,7 @@
> #include <mapmem.h>
> #include <search.h>
> #include <linux/ctype.h>
> +#include <linux/err.h>
>
> #define BS systab.boottime
> #define RT systab.runtime
> @@ -782,6 +784,42 @@ static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag,
> return CMD_RET_SUCCESS;
> }
>
> +/**
> + * add_initrd_instance() - Append a device path to load_options pointing to an
> + * inirtd
> + *
> + * @argc: Number of arguments
> + * @argv: Argument array
> + * @file_path Existing device path, the new instance will be appended
> + * Return: Pointer to the device path or ERR_PTR
> + *
> + */
> +static struct efi_device_path *add_initrd_instance(int argc, char *const argv[],
> + struct efi_device_path *file_path)
> +{
> + struct efi_device_path *tmp_dp = NULL, *tmp_fp = NULL;
> + struct efi_device_path *final_fp = NULL;
> + efi_status_t ret;
> +
> + if (argc < 8)
> + return ERR_PTR(-EINVAL);
> +
> + ret = efi_dp_from_name(argv[6], argv[7], argv[8], &tmp_dp,
> + &tmp_fp);
> + if (ret != EFI_SUCCESS) {
> + printf("Cannot create device path for \"%s %s\"\n",
> + argv[6], argv[7]);
> + goto out;
> + }
> +
> + final_fp = efi_dp_append_instance(file_path, tmp_fp);
> +
> +out:
> + efi_free_pool(tmp_dp);
> + efi_free_pool(tmp_fp);
> + return final_fp ? final_fp : ERR_PTR(-EINVAL);
> +}
> +
> /**
> * do_efi_boot_add() - set UEFI load option
> *
> @@ -794,7 +832,11 @@ static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag,
> *
> * Implement efidebug "boot add" sub-command. Create or change UEFI load option.
> *
> - * efidebug boot add <id> <label> <interface> <devnum>[:<part>] <file> <options>
> + * Without initrd:
> + * efidebug boot add <id> <label> <interface> <devnum>[:<part>] <file> <options>
> + *
> + * With initrd:
> + * efidebug boot add <id> <label> <interface> <devnum>[:<part>] <file> <interface2> <devnum2>[:<part>] <initrd> <options>
> */
> static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
> int argc, char *const argv[])
> @@ -807,13 +849,14 @@ 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 *final_fp = NULL;
> struct efi_load_option lo;
> void *data = NULL;
> efi_uintn_t size;
> efi_status_t ret;
> int r = CMD_RET_SUCCESS;
>
> - if (argc < 6 || argc > 7)
> + if (argc < 6 || argc > 9)
> return CMD_RET_USAGE;
>
> id = (int)simple_strtoul(argv[1], &endp, 16);
> @@ -829,6 +872,12 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
> /* attributes */
> lo.attributes = LOAD_OPTION_ACTIVE; /* always ACTIVE */
>
> + /* optional data */
> + if (argc == 6)
> + lo.optional_data = NULL;
> + else
> + lo.optional_data = (const u8 *)argv[6];
> +
> /* label */
> label_len = strlen(argv[2]);
> label_len16 = utf8_utf16_strnlen(argv[2], label_len);
> @@ -847,15 +896,30 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
> r = CMD_RET_FAILURE;
> goto out;
> }
> +
> + /* add initrd instance in device path */
> + if (argc >= 9) {
> + final_fp = add_initrd_instance(argc, argv, file_path);
> + if (IS_ERR(final_fp)) {
> + r = CMD_RET_FAILURE;
> + goto out;
> + }
> +
> + /* add_initrd_instance allocates a new device path */
> + efi_free_pool(file_path);
> + file_path = final_fp;
> +
> + /* update optional data */
> + if (argc == 9)
> + lo.optional_data = NULL;
> + else
> + lo.optional_data = (const u8 *)argv[9];
> + }
> +
> lo.file_path = file_path;
> lo.file_path_length = efi_dp_size(file_path)
> + sizeof(struct efi_device_path); /* for END */
>
> - /* optional data */
> - if (argc == 6)
> - lo.optional_data = NULL;
> - else
> - lo.optional_data = (const u8 *)argv[6];
>
> size = efi_serialize_load_option(&lo, (u8 **)&data);
> if (!size) {
> @@ -939,11 +1003,13 @@ 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_load_option lo;
> char *label, *p;
> size_t label_len16, label_len;
> u16 *dp_str;
> efi_status_t ret;
> + efi_uintn_t initrd_dp_size;
>
> ret = efi_deserialize_load_option(&lo, data, size);
> if (ret != EFI_SUCCESS) {
> @@ -973,6 +1039,13 @@ static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size)
> dp_str = efi_dp_str(lo.file_path);
> printf(" file_path: %ls\n", dp_str);
> efi_free_pool(dp_str);
> + initrd_path = efi_dp_instance_by_idx(lo.file_path, &initrd_dp_size, INITRD_DP);
> + if (initrd_path) {
> + dp_str = efi_dp_str(initrd_path);
> + printf(" initrd_path: %ls\n", dp_str);
> + efi_free_pool(dp_str);
> + efi_free_pool(initrd_path);
> + }
>
> printf(" data:\n");
> print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1,
> @@ -1583,7 +1656,7 @@ static char efidebug_help_text[] =
Where is the change to efidebug_help_text[]?
Best regards
Heinrich
> #endif
>
> U_BOOT_CMD(
> - efidebug, 10, 0, do_efidebug,
> + efidebug, CONFIG_SYS_MAXARGS, 0, do_efidebug,
> "Configure UEFI environment",
> efidebug_help_text
> );
>
More information about the U-Boot
mailing list