@@ -29,6 +29,7 @@ obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o
obj-$(CONFIG_CMD_BMP) += bmp.o
obj-$(CONFIG_CMD_BOOTCOUNT) += bootcount.o
obj-$(CONFIG_CMD_BOOTEFI) += bootefi.o
+obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += bootmgr.o
obj-$(CONFIG_CMD_BOOTMENU) += bootmenu.o
obj-$(CONFIG_CMD_BOOTSTAGE) += bootstage.o
obj-$(CONFIG_CMD_BOOTZ) += bootz.o
new file mode 100644
@@ -0,0 +1,640 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * UEFI Bootmanager configuration
+ *
+ * Copyright (c) 2018 AKASHI Takahiro, Linaro Limited
+ */
+#include <charset.h>
+#include <common.h>
+#include <command.h>
+#include <efi_loader.h>
+#include <efi_rng.h>
+#include <hexdump.h>
+#include <malloc.h>
+
+static char bootmgr_help_text[] =
+ " - UEFI Shell-like interface to configure UEFI Boot Manager\n"
+ "bootmgr boot add <bootid> <label> <interface> <devnum>[:<part>] <file path> [<load options>]\n"
+ " - set UEFI BootXXXX variable\n"
+ " <load options> will be passed to UEFI application\n"
+ "bootmgr boot rm <bootid#1> [<bootid#2> [<bootid#3> [...]]]\n"
+ " - delete UEFI BootXXXX variables\n"
+ "bootmgr boot dump\n"
+ " - dump all UEFI BootXXXX variables\n"
+ "bootmgr boot next <bootid>\n"
+ " - set UEFI BootNext variable\n"
+ "bootmgr boot order [<bootid#1> [<bootid#2> [<bootid#3> [...]]]]\n"
+ " - set/show UEFI boot order\n"
+ "\n";
+
+static int u16_tohex(u16 c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+
+ /* not hexadecimal */
+ return -1;
+}
+
+/**
+ * show_efi_boot_opt_data() - dump UEFI load option
+ *
+ * @varname16: variable name
+ * @data: value of UEFI load option variable
+ * @size: size of the boot option
+ *
+ * Decode the value of UEFI load option variable and print information.
+ */
+static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size)
+{
+ struct efi_load_option lo;
+ char *label, *p;
+ size_t label_len16, label_len;
+ u16 *dp_str;
+ efi_status_t ret;
+
+ ret = efi_deserialize_load_option(&lo, data, size);
+ if (ret != EFI_SUCCESS) {
+ printf("%ls: invalid load option\n", varname16);
+ return;
+ }
+
+ label_len16 = u16_strlen(lo.label);
+ label_len = utf16_utf8_strnlen(lo.label, label_len16);
+ label = malloc(label_len + 1);
+ if (!label)
+ return;
+ p = label;
+ utf16_utf8_strncpy(&p, lo.label, label_len16);
+
+ printf("%ls:\nattributes: %c%c%c (0x%08x)\n",
+ varname16,
+ /* ACTIVE */
+ lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-',
+ /* FORCE RECONNECT */
+ lo.attributes & LOAD_OPTION_FORCE_RECONNECT ? 'R' : '-',
+ /* HIDDEN */
+ lo.attributes & LOAD_OPTION_HIDDEN ? 'H' : '-',
+ lo.attributes);
+ printf(" label: %s\n", label);
+
+ dp_str = efi_dp_str(lo.file_path);
+ printf(" file_path: %ls\n", dp_str);
+ efi_free_pool(dp_str);
+
+ printf(" data:\n");
+ print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1,
+ lo.optional_data, *size, true);
+ free(label);
+}
+
+/**
+ * show_efi_boot_opt() - dump UEFI load option
+ *
+ * @varname16: variable name
+ *
+ * Dump information defined by UEFI load option.
+ */
+static void show_efi_boot_opt(u16 *varname16)
+{
+ void *data;
+ efi_uintn_t size;
+ efi_status_t ret;
+
+ size = 0;
+ ret = EFI_CALL(efi_get_variable(varname16, &efi_global_variable_guid,
+ NULL, &size, NULL));
+ if (ret == EFI_BUFFER_TOO_SMALL) {
+ data = malloc(size);
+ if (!data) {
+ printf("ERROR: Out of memory\n");
+ return;
+ }
+ ret = EFI_CALL(efi_get_variable(varname16,
+ &efi_global_variable_guid,
+ NULL, &size, data));
+ if (ret == EFI_SUCCESS)
+ show_efi_boot_opt_data(varname16, data, &size);
+ free(data);
+ }
+}
+
+/**
+ * do_efi_boot_add() - set UEFI load option
+ *
+ * @cmdtp: Command table
+ * @flag: Command flag
+ * @argc: Number of arguments
+ * @argv: Argument array
+ * Return: CMD_RET_SUCCESS on success,
+ * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
+ *
+ * Implement bootmgr "boot add" sub-command. Create or change UEFI load option.
+ *
+ * bootmgr boot add <id> <label> <interface> <devnum>[:<part>] <file> <options>
+ */
+static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ int id;
+ char *endp;
+ char var_name[9];
+ u16 var_name16[9], *p;
+ efi_guid_t guid;
+ size_t label_len, label_len16;
+ u16 *label;
+ struct efi_device_path *device_path = NULL, *file_path = 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)
+ return CMD_RET_USAGE;
+
+ id = (int)simple_strtoul(argv[1], &endp, 16);
+ if (*endp != '\0' || id > 0xffff)
+ return CMD_RET_USAGE;
+
+ sprintf(var_name, "Boot%04X", id);
+ p = var_name16;
+ utf8_utf16_strncpy(&p, var_name, 9);
+
+ guid = efi_global_variable_guid;
+
+ /* attributes */
+ lo.attributes = LOAD_OPTION_ACTIVE; /* always ACTIVE */
+
+ /* label */
+ label_len = strlen(argv[2]);
+ label_len16 = utf8_utf16_strnlen(argv[2], label_len);
+ label = malloc((label_len16 + 1) * sizeof(u16));
+ if (!label)
+ return CMD_RET_FAILURE;
+ lo.label = label; /* label will be changed below */
+ utf8_utf16_strncpy(&label, argv[2], label_len);
+
+ /* file path */
+ ret = efi_dp_from_name(argv[3], argv[4], argv[5], &device_path,
+ &file_path);
+ if (ret != EFI_SUCCESS) {
+ printf("Cannot create device path for \"%s %s\"\n",
+ argv[3], argv[4]);
+ r = CMD_RET_FAILURE;
+ goto out;
+ }
+ 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) {
+ r = CMD_RET_FAILURE;
+ goto out;
+ }
+
+ ret = EFI_CALL(efi_set_variable(var_name16, &guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ size, data));
+ if (ret != EFI_SUCCESS) {
+ printf("Cannot set %ls\n", var_name16);
+ r = CMD_RET_FAILURE;
+ }
+out:
+ free(data);
+ efi_free_pool(device_path);
+ efi_free_pool(file_path);
+ free(lo.label);
+
+ return r;
+}
+
+/**
+ * do_efi_boot_rm() - delete UEFI load options
+ *
+ * @cmdtp: Command table
+ * @flag: Command flag
+ * @argc: Number of arguments
+ * @argv: Argument array
+ * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
+ *
+ * Implement bootmgr "boot rm" sub-command.
+ * Delete UEFI load options.
+ *
+ * bootmgr boot rm <id> ...
+ */
+static int do_efi_boot_rm(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ efi_guid_t guid;
+ int id, i;
+ char *endp;
+ char var_name[9];
+ u16 var_name16[9], *p;
+ efi_status_t ret;
+
+ if (argc == 1)
+ return CMD_RET_USAGE;
+
+ guid = efi_global_variable_guid;
+ for (i = 1; i < argc; i++, argv++) {
+ id = (int)simple_strtoul(argv[1], &endp, 16);
+ if (*endp != '\0' || id > 0xffff)
+ return CMD_RET_FAILURE;
+
+ sprintf(var_name, "Boot%04X", id);
+ p = var_name16;
+ utf8_utf16_strncpy(&p, var_name, 9);
+
+ ret = EFI_CALL(efi_set_variable(var_name16, &guid, 0, 0, NULL));
+ if (ret) {
+ printf("Cannot remove %ls\n", var_name16);
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+/**
+ * show_efi_boot_dump() - dump all UEFI load options
+ *
+ * @cmdtp: Command table
+ * @flag: Command flag
+ * @argc: Number of arguments
+ * @argv: Argument array
+ * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
+ *
+ * Implement bootmgr "boot dump" sub-command.
+ * Dump information of all UEFI load options defined.
+ *
+ * bootmgr boot dump
+ */
+static int do_efi_boot_dump(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ u16 *var_name16, *p;
+ efi_uintn_t buf_size, size;
+ efi_guid_t guid;
+ int id, i, digit;
+ efi_status_t ret;
+
+ if (argc > 1)
+ return CMD_RET_USAGE;
+
+ buf_size = 128;
+ var_name16 = malloc(buf_size);
+ if (!var_name16)
+ return CMD_RET_FAILURE;
+
+ var_name16[0] = 0;
+ for (;;) {
+ size = buf_size;
+ ret = EFI_CALL(efi_get_next_variable_name(&size, var_name16,
+ &guid));
+ if (ret == EFI_NOT_FOUND)
+ break;
+ if (ret == EFI_BUFFER_TOO_SMALL) {
+ buf_size = size;
+ p = realloc(var_name16, buf_size);
+ if (!p) {
+ free(var_name16);
+ return CMD_RET_FAILURE;
+ }
+ var_name16 = p;
+ ret = EFI_CALL(efi_get_next_variable_name(&size,
+ var_name16,
+ &guid));
+ }
+ if (ret != EFI_SUCCESS) {
+ free(var_name16);
+ return CMD_RET_FAILURE;
+ }
+
+ if (memcmp(var_name16, L"Boot", 8))
+ continue;
+
+ for (id = 0, i = 0; i < 4; i++) {
+ digit = u16_tohex(var_name16[4 + i]);
+ if (digit < 0)
+ break;
+ id = (id << 4) + digit;
+ }
+ if (i == 4 && !var_name16[8])
+ show_efi_boot_opt(var_name16);
+ }
+
+ free(var_name16);
+
+ return CMD_RET_SUCCESS;
+}
+
+/**
+ * do_efi_boot_next() - manage UEFI BootNext variable
+ *
+ * @cmdtp: Command table
+ * @flag: Command flag
+ * @argc: Number of arguments
+ * @argv: Argument array
+ * Return: CMD_RET_SUCCESS on success,
+ * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
+ *
+ * Implement bootmgr "boot next" sub-command.
+ * Set BootNext variable.
+ *
+ * bootmgr boot next <id>
+ */
+static int do_efi_boot_next(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ u16 bootnext;
+ efi_uintn_t size;
+ char *endp;
+ efi_guid_t guid;
+ efi_status_t ret;
+ int r = CMD_RET_SUCCESS;
+
+ if (argc != 2)
+ return CMD_RET_USAGE;
+
+ bootnext = (u16)simple_strtoul(argv[1], &endp, 16);
+ if (*endp) {
+ printf("invalid value: %s\n", argv[1]);
+ r = CMD_RET_FAILURE;
+ goto out;
+ }
+
+ guid = efi_global_variable_guid;
+ size = sizeof(u16);
+ ret = EFI_CALL(efi_set_variable(L"BootNext", &guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ size, &bootnext));
+ if (ret != EFI_SUCCESS) {
+ printf("Cannot set BootNext\n");
+ r = CMD_RET_FAILURE;
+ }
+out:
+ return r;
+}
+
+/**
+ * show_efi_boot_order() - show order of UEFI load options
+ *
+ * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
+ *
+ * Show order of UEFI load options defined by BootOrder variable.
+ */
+static int show_efi_boot_order(void)
+{
+ u16 *bootorder;
+ efi_uintn_t size;
+ int num, i;
+ char var_name[9];
+ u16 var_name16[9], *p16;
+ void *data;
+ struct efi_load_option lo;
+ char *label, *p;
+ size_t label_len16, label_len;
+ efi_status_t ret;
+
+ size = 0;
+ ret = EFI_CALL(efi_get_variable(L"BootOrder", &efi_global_variable_guid,
+ NULL, &size, NULL));
+ if (ret != EFI_BUFFER_TOO_SMALL) {
+ if (ret == EFI_NOT_FOUND) {
+ printf("BootOrder not defined\n");
+ return CMD_RET_SUCCESS;
+ } else {
+ return CMD_RET_FAILURE;
+ }
+ }
+ bootorder = malloc(size);
+ if (!bootorder) {
+ printf("ERROR: Out of memory\n");
+ return CMD_RET_FAILURE;
+ }
+ ret = EFI_CALL(efi_get_variable(L"BootOrder", &efi_global_variable_guid,
+ NULL, &size, bootorder));
+ if (ret != EFI_SUCCESS) {
+ ret = CMD_RET_FAILURE;
+ goto out;
+ }
+
+ num = size / sizeof(u16);
+ for (i = 0; i < num; i++) {
+ sprintf(var_name, "Boot%04X", bootorder[i]);
+ p16 = var_name16;
+ utf8_utf16_strncpy(&p16, var_name, 9);
+
+ size = 0;
+ ret = EFI_CALL(efi_get_variable(var_name16,
+ &efi_global_variable_guid, NULL,
+ &size, NULL));
+ if (ret != EFI_BUFFER_TOO_SMALL) {
+ printf("%2d: %s: (not defined)\n", i + 1, var_name);
+ continue;
+ }
+
+ data = malloc(size);
+ if (!data) {
+ ret = CMD_RET_FAILURE;
+ goto out;
+ }
+ ret = EFI_CALL(efi_get_variable(var_name16,
+ &efi_global_variable_guid, NULL,
+ &size, data));
+ if (ret != EFI_SUCCESS) {
+ free(data);
+ ret = CMD_RET_FAILURE;
+ goto out;
+ }
+
+ ret = efi_deserialize_load_option(&lo, data, &size);
+ if (ret != EFI_SUCCESS) {
+ printf("%ls: invalid load option\n", var_name16);
+ ret = CMD_RET_FAILURE;
+ goto out;
+ }
+
+ label_len16 = u16_strlen(lo.label);
+ label_len = utf16_utf8_strnlen(lo.label, label_len16);
+ label = malloc(label_len + 1);
+ if (!label) {
+ free(data);
+ ret = CMD_RET_FAILURE;
+ goto out;
+ }
+ p = label;
+ utf16_utf8_strncpy(&p, lo.label, label_len16);
+ printf("%2d: %s: %s\n", i + 1, var_name, label);
+ free(label);
+
+ free(data);
+ }
+out:
+ free(bootorder);
+
+ return ret;
+}
+
+/**
+ * do_efi_boot_order() - manage UEFI BootOrder variable
+ *
+ * @cmdtp: Command table
+ * @flag: Command flag
+ * @argc: Number of arguments
+ * @argv: Argument array
+ * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
+ *
+ * Implement bootmgr "boot order" sub-command.
+ * Show order of UEFI load options, or change it in BootOrder variable.
+ *
+ * bootmgr boot order [<id> ...]
+ */
+static int do_efi_boot_order(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ u16 *bootorder = NULL;
+ efi_uintn_t size;
+ int id, i;
+ char *endp;
+ efi_guid_t guid;
+ efi_status_t ret;
+ int r = CMD_RET_SUCCESS;
+
+ if (argc == 1)
+ return show_efi_boot_order();
+
+ argc--;
+ argv++;
+
+ size = argc * sizeof(u16);
+ bootorder = malloc(size);
+ if (!bootorder)
+ return CMD_RET_FAILURE;
+
+ for (i = 0; i < argc; i++) {
+ id = (int)simple_strtoul(argv[i], &endp, 16);
+ if (*endp != '\0' || id > 0xffff) {
+ printf("invalid value: %s\n", argv[i]);
+ r = CMD_RET_FAILURE;
+ goto out;
+ }
+
+ bootorder[i] = (u16)id;
+ }
+
+ guid = efi_global_variable_guid;
+ ret = EFI_CALL(efi_set_variable(L"BootOrder", &guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ size, bootorder));
+ if (ret != EFI_SUCCESS) {
+ printf("Cannot set BootOrder\n");
+ r = CMD_RET_FAILURE;
+ }
+out:
+ free(bootorder);
+
+ return r;
+}
+
+static struct cmd_tbl cmd_bootmgr_boot_sub[] = {
+ U_BOOT_CMD_MKENT(add, CONFIG_SYS_MAXARGS, 1, do_efi_boot_add, "", ""),
+ U_BOOT_CMD_MKENT(rm, CONFIG_SYS_MAXARGS, 1, do_efi_boot_rm, "", ""),
+ U_BOOT_CMD_MKENT(dump, CONFIG_SYS_MAXARGS, 1, do_efi_boot_dump, "", ""),
+ U_BOOT_CMD_MKENT(next, CONFIG_SYS_MAXARGS, 1, do_efi_boot_next, "", ""),
+ U_BOOT_CMD_MKENT(order, CONFIG_SYS_MAXARGS, 1, do_efi_boot_order,
+ "", ""),
+};
+
+/**
+ * do_efi_boot_opt() - manage UEFI load options
+ *
+ * @cmdtp: Command table
+ * @flag: Command flag
+ * @argc: Number of arguments
+ * @argv: Argument array
+ * Return: CMD_RET_SUCCESS on success,
+ * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
+ *
+ * Implement bootmgr "boot" sub-command.
+ */
+static int do_efi_boot_opt(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ struct cmd_tbl *cp;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ argc--; argv++;
+
+ cp = find_cmd_tbl(argv[0], cmd_bootmgr_boot_sub,
+ ARRAY_SIZE(cmd_bootmgr_boot_sub));
+ if (!cp)
+ return CMD_RET_USAGE;
+
+ return cp->cmd(cmdtp, flag, argc, argv);
+}
+
+static struct cmd_tbl cmd_bootmgr_sub[] = {
+ U_BOOT_CMD_MKENT(boot, CONFIG_SYS_MAXARGS, 1, do_efi_boot_opt, "", ""),
+};
+
+/**
+ * do_bootmgr() - display and configure UEFI boot manager
+ *
+ * @cmdtp: Command table
+ * @flag: Command flag
+ * @argc: Number of arguments
+ * @argv: Argument array
+ * Return: CMD_RET_SUCCESS on success,
+ * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
+ *
+ * Implement bootmgr command which allows us to display and
+ * configure UEFI environment.
+ */
+static int do_bootmgr(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ struct cmd_tbl *cp;
+ efi_status_t r;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ argc--; argv++;
+
+ /* Initialize UEFI drivers */
+ r = efi_init_obj_list();
+ if (r != EFI_SUCCESS) {
+ printf("Error: Cannot initialize UEFI sub-system, r = %lu\n",
+ r & ~EFI_ERROR_MASK);
+ return CMD_RET_FAILURE;
+ }
+
+ cp = find_cmd_tbl(argv[0], cmd_bootmgr_sub,
+ ARRAY_SIZE(cmd_bootmgr_sub));
+ if (!cp)
+ return CMD_RET_USAGE;
+
+ return cp->cmd(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(bootmgr, CONFIG_SYS_MAXARGS, 0, do_bootmgr,
+ "Configure UEFI boot manager", bootmgr_help_text);
@@ -794,571 +794,6 @@ static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag,
return CMD_RET_SUCCESS;
}
-/**
- * do_efi_boot_add() - set UEFI load option
- *
- * @cmdtp: Command table
- * @flag: Command flag
- * @argc: Number of arguments
- * @argv: Argument array
- * Return: CMD_RET_SUCCESS on success,
- * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
- *
- * Implement efidebug "boot add" sub-command. Create or change UEFI load option.
- *
- * efidebug boot add <id> <label> <interface> <devnum>[:<part>] <file> <options>
- */
-static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
- int argc, char *const argv[])
-{
- int id;
- char *endp;
- char var_name[9];
- u16 var_name16[9], *p;
- efi_guid_t guid;
- size_t label_len, label_len16;
- u16 *label;
- struct efi_device_path *device_path = NULL, *file_path = 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)
- return CMD_RET_USAGE;
-
- id = (int)simple_strtoul(argv[1], &endp, 16);
- if (*endp != '\0' || id > 0xffff)
- return CMD_RET_USAGE;
-
- sprintf(var_name, "Boot%04X", id);
- p = var_name16;
- utf8_utf16_strncpy(&p, var_name, 9);
-
- guid = efi_global_variable_guid;
-
- /* attributes */
- lo.attributes = LOAD_OPTION_ACTIVE; /* always ACTIVE */
-
- /* label */
- label_len = strlen(argv[2]);
- label_len16 = utf8_utf16_strnlen(argv[2], label_len);
- label = malloc((label_len16 + 1) * sizeof(u16));
- if (!label)
- return CMD_RET_FAILURE;
- lo.label = label; /* label will be changed below */
- utf8_utf16_strncpy(&label, argv[2], label_len);
-
- /* file path */
- ret = efi_dp_from_name(argv[3], argv[4], argv[5], &device_path,
- &file_path);
- if (ret != EFI_SUCCESS) {
- printf("Cannot create device path for \"%s %s\"\n",
- argv[3], argv[4]);
- r = CMD_RET_FAILURE;
- goto out;
- }
- 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) {
- r = CMD_RET_FAILURE;
- goto out;
- }
-
- ret = EFI_CALL(efi_set_variable(var_name16, &guid,
- EFI_VARIABLE_NON_VOLATILE |
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
- EFI_VARIABLE_RUNTIME_ACCESS,
- size, data));
- if (ret != EFI_SUCCESS) {
- printf("Cannot set %ls\n", var_name16);
- r = CMD_RET_FAILURE;
- }
-out:
- free(data);
- efi_free_pool(device_path);
- efi_free_pool(file_path);
- free(lo.label);
-
- return r;
-}
-
-/**
- * do_efi_boot_rm() - delete UEFI load options
- *
- * @cmdtp: Command table
- * @flag: Command flag
- * @argc: Number of arguments
- * @argv: Argument array
- * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
- *
- * Implement efidebug "boot rm" sub-command.
- * Delete UEFI load options.
- *
- * efidebug boot rm <id> ...
- */
-static int do_efi_boot_rm(struct cmd_tbl *cmdtp, int flag,
- int argc, char *const argv[])
-{
- efi_guid_t guid;
- int id, i;
- char *endp;
- char var_name[9];
- u16 var_name16[9], *p;
- efi_status_t ret;
-
- if (argc == 1)
- return CMD_RET_USAGE;
-
- guid = efi_global_variable_guid;
- for (i = 1; i < argc; i++, argv++) {
- id = (int)simple_strtoul(argv[1], &endp, 16);
- if (*endp != '\0' || id > 0xffff)
- return CMD_RET_FAILURE;
-
- sprintf(var_name, "Boot%04X", id);
- p = var_name16;
- utf8_utf16_strncpy(&p, var_name, 9);
-
- ret = EFI_CALL(efi_set_variable(var_name16, &guid, 0, 0, NULL));
- if (ret) {
- printf("Cannot remove %ls\n", var_name16);
- return CMD_RET_FAILURE;
- }
- }
-
- return CMD_RET_SUCCESS;
-}
-
-/**
- * show_efi_boot_opt_data() - dump UEFI load option
- *
- * @varname16: variable name
- * @data: value of UEFI load option variable
- * @size: size of the boot option
- *
- * Decode the value of UEFI load option variable and print information.
- */
-static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size)
-{
- struct efi_load_option lo;
- char *label, *p;
- size_t label_len16, label_len;
- u16 *dp_str;
- efi_status_t ret;
-
- ret = efi_deserialize_load_option(&lo, data, size);
- if (ret != EFI_SUCCESS) {
- printf("%ls: invalid load option\n", varname16);
- return;
- }
-
- label_len16 = u16_strlen(lo.label);
- label_len = utf16_utf8_strnlen(lo.label, label_len16);
- label = malloc(label_len + 1);
- if (!label)
- return;
- p = label;
- utf16_utf8_strncpy(&p, lo.label, label_len16);
-
- printf("%ls:\nattributes: %c%c%c (0x%08x)\n",
- varname16,
- /* ACTIVE */
- lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-',
- /* FORCE RECONNECT */
- lo.attributes & LOAD_OPTION_FORCE_RECONNECT ? 'R' : '-',
- /* HIDDEN */
- lo.attributes & LOAD_OPTION_HIDDEN ? 'H' : '-',
- lo.attributes);
- printf(" label: %s\n", label);
-
- dp_str = efi_dp_str(lo.file_path);
- printf(" file_path: %ls\n", dp_str);
- efi_free_pool(dp_str);
-
- printf(" data:\n");
- print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1,
- lo.optional_data, *size, true);
- free(label);
-}
-
-/**
- * show_efi_boot_opt() - dump UEFI load option
- *
- * @varname16: variable name
- *
- * Dump information defined by UEFI load option.
- */
-static void show_efi_boot_opt(u16 *varname16)
-{
- void *data;
- efi_uintn_t size;
- efi_status_t ret;
-
- size = 0;
- ret = EFI_CALL(efi_get_variable(varname16, &efi_global_variable_guid,
- NULL, &size, NULL));
- if (ret == EFI_BUFFER_TOO_SMALL) {
- data = malloc(size);
- if (!data) {
- printf("ERROR: Out of memory\n");
- return;
- }
- ret = EFI_CALL(efi_get_variable(varname16,
- &efi_global_variable_guid,
- NULL, &size, data));
- if (ret == EFI_SUCCESS)
- show_efi_boot_opt_data(varname16, data, &size);
- free(data);
- }
-}
-
-static int u16_tohex(u16 c)
-{
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
-
- /* not hexadecimal */
- return -1;
-}
-
-/**
- * show_efi_boot_dump() - dump all UEFI load options
- *
- * @cmdtp: Command table
- * @flag: Command flag
- * @argc: Number of arguments
- * @argv: Argument array
- * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
- *
- * Implement efidebug "boot dump" sub-command.
- * Dump information of all UEFI load options defined.
- *
- * efidebug boot dump
- */
-static int do_efi_boot_dump(struct cmd_tbl *cmdtp, int flag,
- int argc, char *const argv[])
-{
- u16 *var_name16, *p;
- efi_uintn_t buf_size, size;
- efi_guid_t guid;
- int id, i, digit;
- efi_status_t ret;
-
- if (argc > 1)
- return CMD_RET_USAGE;
-
- buf_size = 128;
- var_name16 = malloc(buf_size);
- if (!var_name16)
- return CMD_RET_FAILURE;
-
- var_name16[0] = 0;
- for (;;) {
- size = buf_size;
- ret = EFI_CALL(efi_get_next_variable_name(&size, var_name16,
- &guid));
- if (ret == EFI_NOT_FOUND)
- break;
- if (ret == EFI_BUFFER_TOO_SMALL) {
- buf_size = size;
- p = realloc(var_name16, buf_size);
- if (!p) {
- free(var_name16);
- return CMD_RET_FAILURE;
- }
- var_name16 = p;
- ret = EFI_CALL(efi_get_next_variable_name(&size,
- var_name16,
- &guid));
- }
- if (ret != EFI_SUCCESS) {
- free(var_name16);
- return CMD_RET_FAILURE;
- }
-
- if (memcmp(var_name16, L"Boot", 8))
- continue;
-
- for (id = 0, i = 0; i < 4; i++) {
- digit = u16_tohex(var_name16[4 + i]);
- if (digit < 0)
- break;
- id = (id << 4) + digit;
- }
- if (i == 4 && !var_name16[8])
- show_efi_boot_opt(var_name16);
- }
-
- free(var_name16);
-
- return CMD_RET_SUCCESS;
-}
-
-/**
- * show_efi_boot_order() - show order of UEFI load options
- *
- * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
- *
- * Show order of UEFI load options defined by BootOrder variable.
- */
-static int show_efi_boot_order(void)
-{
- u16 *bootorder;
- efi_uintn_t size;
- int num, i;
- char var_name[9];
- u16 var_name16[9], *p16;
- void *data;
- struct efi_load_option lo;
- char *label, *p;
- size_t label_len16, label_len;
- efi_status_t ret;
-
- size = 0;
- ret = EFI_CALL(efi_get_variable(L"BootOrder", &efi_global_variable_guid,
- NULL, &size, NULL));
- if (ret != EFI_BUFFER_TOO_SMALL) {
- if (ret == EFI_NOT_FOUND) {
- printf("BootOrder not defined\n");
- return CMD_RET_SUCCESS;
- } else {
- return CMD_RET_FAILURE;
- }
- }
- bootorder = malloc(size);
- if (!bootorder) {
- printf("ERROR: Out of memory\n");
- return CMD_RET_FAILURE;
- }
- ret = EFI_CALL(efi_get_variable(L"BootOrder", &efi_global_variable_guid,
- NULL, &size, bootorder));
- if (ret != EFI_SUCCESS) {
- ret = CMD_RET_FAILURE;
- goto out;
- }
-
- num = size / sizeof(u16);
- for (i = 0; i < num; i++) {
- sprintf(var_name, "Boot%04X", bootorder[i]);
- p16 = var_name16;
- utf8_utf16_strncpy(&p16, var_name, 9);
-
- size = 0;
- ret = EFI_CALL(efi_get_variable(var_name16,
- &efi_global_variable_guid, NULL,
- &size, NULL));
- if (ret != EFI_BUFFER_TOO_SMALL) {
- printf("%2d: %s: (not defined)\n", i + 1, var_name);
- continue;
- }
-
- data = malloc(size);
- if (!data) {
- ret = CMD_RET_FAILURE;
- goto out;
- }
- ret = EFI_CALL(efi_get_variable(var_name16,
- &efi_global_variable_guid, NULL,
- &size, data));
- if (ret != EFI_SUCCESS) {
- free(data);
- ret = CMD_RET_FAILURE;
- goto out;
- }
-
- ret = efi_deserialize_load_option(&lo, data, &size);
- if (ret != EFI_SUCCESS) {
- printf("%ls: invalid load option\n", var_name16);
- ret = CMD_RET_FAILURE;
- goto out;
- }
-
- label_len16 = u16_strlen(lo.label);
- label_len = utf16_utf8_strnlen(lo.label, label_len16);
- label = malloc(label_len + 1);
- if (!label) {
- free(data);
- ret = CMD_RET_FAILURE;
- goto out;
- }
- p = label;
- utf16_utf8_strncpy(&p, lo.label, label_len16);
- printf("%2d: %s: %s\n", i + 1, var_name, label);
- free(label);
-
- free(data);
- }
-out:
- free(bootorder);
-
- return ret;
-}
-
-/**
- * do_efi_boot_next() - manage UEFI BootNext variable
- *
- * @cmdtp: Command table
- * @flag: Command flag
- * @argc: Number of arguments
- * @argv: Argument array
- * Return: CMD_RET_SUCCESS on success,
- * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
- *
- * Implement efidebug "boot next" sub-command.
- * Set BootNext variable.
- *
- * efidebug boot next <id>
- */
-static int do_efi_boot_next(struct cmd_tbl *cmdtp, int flag,
- int argc, char *const argv[])
-{
- u16 bootnext;
- efi_uintn_t size;
- char *endp;
- efi_guid_t guid;
- efi_status_t ret;
- int r = CMD_RET_SUCCESS;
-
- if (argc != 2)
- return CMD_RET_USAGE;
-
- bootnext = (u16)simple_strtoul(argv[1], &endp, 16);
- if (*endp) {
- printf("invalid value: %s\n", argv[1]);
- r = CMD_RET_FAILURE;
- goto out;
- }
-
- guid = efi_global_variable_guid;
- size = sizeof(u16);
- ret = EFI_CALL(efi_set_variable(L"BootNext", &guid,
- EFI_VARIABLE_NON_VOLATILE |
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
- EFI_VARIABLE_RUNTIME_ACCESS,
- size, &bootnext));
- if (ret != EFI_SUCCESS) {
- printf("Cannot set BootNext\n");
- r = CMD_RET_FAILURE;
- }
-out:
- return r;
-}
-
-/**
- * do_efi_boot_order() - manage UEFI BootOrder variable
- *
- * @cmdtp: Command table
- * @flag: Command flag
- * @argc: Number of arguments
- * @argv: Argument array
- * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
- *
- * Implement efidebug "boot order" sub-command.
- * Show order of UEFI load options, or change it in BootOrder variable.
- *
- * efidebug boot order [<id> ...]
- */
-static int do_efi_boot_order(struct cmd_tbl *cmdtp, int flag,
- int argc, char *const argv[])
-{
- u16 *bootorder = NULL;
- efi_uintn_t size;
- int id, i;
- char *endp;
- efi_guid_t guid;
- efi_status_t ret;
- int r = CMD_RET_SUCCESS;
-
- if (argc == 1)
- return show_efi_boot_order();
-
- argc--;
- argv++;
-
- size = argc * sizeof(u16);
- bootorder = malloc(size);
- if (!bootorder)
- return CMD_RET_FAILURE;
-
- for (i = 0; i < argc; i++) {
- id = (int)simple_strtoul(argv[i], &endp, 16);
- if (*endp != '\0' || id > 0xffff) {
- printf("invalid value: %s\n", argv[i]);
- r = CMD_RET_FAILURE;
- goto out;
- }
-
- bootorder[i] = (u16)id;
- }
-
- guid = efi_global_variable_guid;
- ret = EFI_CALL(efi_set_variable(L"BootOrder", &guid,
- EFI_VARIABLE_NON_VOLATILE |
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
- EFI_VARIABLE_RUNTIME_ACCESS,
- size, bootorder));
- if (ret != EFI_SUCCESS) {
- printf("Cannot set BootOrder\n");
- r = CMD_RET_FAILURE;
- }
-out:
- free(bootorder);
-
- return r;
-}
-
-static struct cmd_tbl cmd_efidebug_boot_sub[] = {
- U_BOOT_CMD_MKENT(add, CONFIG_SYS_MAXARGS, 1, do_efi_boot_add, "", ""),
- U_BOOT_CMD_MKENT(rm, CONFIG_SYS_MAXARGS, 1, do_efi_boot_rm, "", ""),
- U_BOOT_CMD_MKENT(dump, CONFIG_SYS_MAXARGS, 1, do_efi_boot_dump, "", ""),
- U_BOOT_CMD_MKENT(next, CONFIG_SYS_MAXARGS, 1, do_efi_boot_next, "", ""),
- U_BOOT_CMD_MKENT(order, CONFIG_SYS_MAXARGS, 1, do_efi_boot_order,
- "", ""),
-};
-
-/**
- * do_efi_boot_opt() - manage UEFI load options
- *
- * @cmdtp: Command table
- * @flag: Command flag
- * @argc: Number of arguments
- * @argv: Argument array
- * Return: CMD_RET_SUCCESS on success,
- * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
- *
- * Implement efidebug "boot" sub-command.
- */
-static int do_efi_boot_opt(struct cmd_tbl *cmdtp, int flag,
- int argc, char *const argv[])
-{
- struct cmd_tbl *cp;
-
- if (argc < 2)
- return CMD_RET_USAGE;
-
- argc--; argv++;
-
- cp = find_cmd_tbl(argv[0], cmd_efidebug_boot_sub,
- ARRAY_SIZE(cmd_efidebug_boot_sub));
- if (!cp)
- return CMD_RET_USAGE;
-
- return cp->cmd(cmdtp, flag, argc, argv);
-}
-
/**
* do_efi_test_bootmgr() - run simple bootmgr for test
*
@@ -1488,7 +923,6 @@ static int do_efi_query_info(struct cmd_tbl *cmdtp, int flag,
}
static struct cmd_tbl cmd_efidebug_sub[] = {
- U_BOOT_CMD_MKENT(boot, CONFIG_SYS_MAXARGS, 1, do_efi_boot_opt, "", ""),
#ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT
U_BOOT_CMD_MKENT(capsule, CONFIG_SYS_MAXARGS, 1, do_efi_capsule,
"", ""),
@@ -1555,19 +989,7 @@ 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 <bootid> <label> <interface> <devnum>[:<part>] <file path> [<load options>]\n"
- " - set UEFI BootXXXX variable\n"
- " <load options> will be passed to UEFI application\n"
- "efidebug boot rm <bootid#1> [<bootid#2> [<bootid#3> [...]]]\n"
- " - delete UEFI BootXXXX variables\n"
- "efidebug boot dump\n"
- " - dump all UEFI BootXXXX variables\n"
- "efidebug boot next <bootid>\n"
- " - set UEFI BootNext variable\n"
- "efidebug boot order [<bootid#1> [<bootid#2> [<bootid#3> [...]]]]\n"
- " - set/show UEFI boot order\n"
- "\n"
-#ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT
+ #ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT
"efidebug capsule update [-v] <capsule address>\n"
" - process a capsule\n"
"efidebug capsule disk-update\n"
@@ -60,8 +60,8 @@ to be pointing to the EFI System Partition which contains the capsule
file. The BootNext, BootXXXX and OsIndications variables can be set
using the following commands::
- => efidebug boot add 0 Boot0000 virtio 0:1 <capsule_file_name>
- => efidebug boot next 0
+ => bootmgr boot add 0 Boot0000 virtio 0:1 <capsule_file_name>
+ => bootmgr boot next 0
=> setenv -e -nv -bs -rt -v OsIndications =0x04
=> saveenv
@@ -198,8 +198,8 @@ command line::
3. Set the following environment and UEFI boot variables
=> setenv -e -nv -bs -rt -v OsIndications =0x04
- => efidebug boot add 0 Boot0000 virtio 0:1 <capsule_file_name>
- => efidebug boot next 0
+ => bootmgr boot add 0 Boot0000 virtio 0:1 <capsule_file_name>
+ => bootmgr boot next 0
=> saveenv
4. Finally, the capsule update can be initiated with the following
@@ -178,7 +178,7 @@ Now in U-Boot install the keys on your board::
Set up boot parameters on your board::
- efidebug boot add 1 HELLO mmc 0:1 /helloworld.efi.signed ""
+ bootmgr boot add 1 HELLO mmc 0:1 /helloworld.efi.signed ""
Now your board can run the signed image via the boot manager (see below).
You can also try this sequence by running Pytest, test_efi_secboot,
@@ -39,8 +39,8 @@ class TestEfiCapsuleFirmwareFit(object):
with u_boot_console.log.section('Test Case 1-a, before reboot'):
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
- 'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""',
- 'efidebug boot order 1',
+ 'bootmgr boot add 1 TEST host 0:1 /helloworld.efi ""',
+ 'bootmgr boot order 1',
'env set -e OsIndications',
'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
'env save'])
@@ -114,8 +114,8 @@ class TestEfiCapsuleFirmwareFit(object):
with u_boot_console.log.section('Test Case 2-a, before reboot'):
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
- 'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""',
- 'efidebug boot order 1',
+ 'bootmgr boot add 1 TEST host 0:1 /helloworld.efi ""',
+ 'bootmgr boot order 1',
'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
'env save'])
@@ -188,8 +188,8 @@ class TestEfiCapsuleFirmwareFit(object):
with u_boot_console.log.section('Test Case 3-a, before reboot'):
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
- 'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""',
- 'efidebug boot order 1',
+ 'bootmgr boot add 1 TEST host 0:1 /helloworld.efi ""',
+ 'bootmgr boot order 1',
'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
'env save'])
@@ -28,16 +28,16 @@ class TestEfiSignedImage(object):
# Test Case 1a, run signed image if no PK
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
- 'efidebug boot add 1 HELLO1 host 0:1 /helloworld.efi.signed ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO1 host 0:1 /helloworld.efi.signed ""',
+ 'bootmgr boot next 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
with u_boot_console.log.section('Test Case 1b'):
# Test Case 1b, run unsigned image if no PK
output = u_boot_console.run_command_list([
- 'efidebug boot add 2 HELLO2 host 0:1 /helloworld.efi ""',
- 'efidebug boot next 2',
+ 'bootmgr boot add 2 HELLO2 host 0:1 /helloworld.efi ""',
+ 'bootmgr boot next 2',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -58,14 +58,14 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO1 host 0:1 /helloworld.efi.signed ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO1 host 0:1 /helloworld.efi.signed ""',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert('\'HELLO1\' failed' in ''.join(output))
assert('efi_start_image() returned: 26' in ''.join(output))
output = u_boot_console.run_command_list([
- 'efidebug boot add 2 HELLO2 host 0:1 /helloworld.efi ""',
- 'efidebug boot next 2',
+ 'bootmgr boot add 2 HELLO2 host 0:1 /helloworld.efi ""',
+ 'bootmgr boot next 2',
'efidebug test bootmgr'])
assert '\'HELLO2\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -77,12 +77,12 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize db'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 2',
+ 'bootmgr boot next 2',
'efidebug test bootmgr'])
assert '\'HELLO2\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -104,8 +104,8 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO host 0:1 /helloworld.efi.signed ""',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -117,7 +117,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize db'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -142,8 +142,8 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO host 0:1 /helloworld.efi.signed ""',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -169,8 +169,8 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed_2sigs ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO host 0:1 /helloworld.efi.signed_2sigs ""',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -181,7 +181,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -a -i 4000000:$filesize db'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -193,7 +193,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -204,7 +204,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -a -i 4000000:$filesize dbx'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -227,8 +227,8 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO host 0:1 /helloworld.efi.signed ""',
+ 'bootmgr boot next 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -239,7 +239,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -253,7 +253,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -39,8 +39,8 @@ class TestEfiSignedImageIntca(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO_a host 0:1 /helloworld.efi.signed_a ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO_a host 0:1 /helloworld.efi.signed_a ""',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO_a\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -48,8 +48,8 @@ class TestEfiSignedImageIntca(object):
with u_boot_console.log.section('Test Case 1b'):
# Test Case 1b, signed and authenticated by root CA
output = u_boot_console.run_command_list([
- 'efidebug boot add 2 HELLO_ab host 0:1 /helloworld.efi.signed_ab ""',
- 'efidebug boot next 2',
+ 'bootmgr boot add 2 HELLO_ab host 0:1 /helloworld.efi.signed_ab ""',
+ 'bootmgr boot next 2',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -70,8 +70,8 @@ class TestEfiSignedImageIntca(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc ""',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -81,7 +81,7 @@ class TestEfiSignedImageIntca(object):
output = u_boot_console.run_command_list([
'fatload host 0:1 4000000 db_b.auth',
'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -91,7 +91,7 @@ class TestEfiSignedImageIntca(object):
output = u_boot_console.run_command_list([
'fatload host 0:1 4000000 db_c.auth',
'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -116,8 +116,8 @@ class TestEfiSignedImageIntca(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc ""',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
# Or,
@@ -129,7 +129,7 @@ class TestEfiSignedImageIntca(object):
output = u_boot_console.run_command_list([
'fatload host 0:1 4000000 dbx_c.auth',
'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx',
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -35,12 +35,12 @@ class TestEfiUnsignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'bootmgr boot next 1',
'bootefi bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert 'efi_start_image() returned: 26' in ''.join(output)
assert 'Hello, world!' not in ''.join(output)
@@ -64,8 +64,8 @@ class TestEfiUnsignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'bootmgr boot next 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -88,12 +88,12 @@ class TestEfiUnsignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'bootmgr boot next 1',
'bootefi bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert 'efi_start_image() returned: 26' in ''.join(output)
assert 'Hello, world!' not in ''.join(output)
@@ -106,12 +106,12 @@ class TestEfiUnsignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
- 'efidebug boot next 1',
+ 'bootmgr boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'bootmgr boot next 1',
'bootefi bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'bootmgr boot next 1',
'efidebug test bootmgr'])
assert 'efi_start_image() returned: 26' in ''.join(output)
assert 'Hello, world!' not in ''.join(output)
Up to now we've been adding all the efi related configuration to 'efidebug' command. The command name feels a bit weird to configure boot manager related commands. Since the bootmanager is growing and we intend to extend it with features like defining the initrd we want to expose to the kernel, it would make sense to split it on a command of it's own. So let's introduce a new command called bootmgr and move all of the existing Boot manager functionality there. Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> --- cmd/Makefile | 1 + cmd/bootmgr.c | 640 ++++++++++++++++++ cmd/efidebug.c | 580 +--------------- doc/board/emulation/qemu_capsule_update.rst | 8 +- doc/uefi/uefi.rst | 2 +- .../test_efi_capsule/test_capsule_firmware.py | 12 +- test/py/tests/test_efi_secboot/test_signed.py | 48 +- .../test_efi_secboot/test_signed_intca.py | 22 +- .../tests/test_efi_secboot/test_unsigned.py | 22 +- 9 files changed, 699 insertions(+), 636 deletions(-) create mode 100644 cmd/bootmgr.c -- 2.30.0