[PATCH v8 3/9] eficonfig: add "Edit Boot Option" menu entry
Masahisa Kojima
masahisa.kojima at linaro.org
Sun Jun 19 06:56:01 CEST 2022
This commit adds the menu entry to edit the existing
BOOT#### variable contents.
User selects the item from the boot option list, then
user can edit the description, file path and optional_data.
Note that automatically generated boot option entry by bootmenu
to suppport the removable media device is filtered out and user
can not edit the automatically generated entry.
Signed-off-by: Masahisa Kojima <masahisa.kojima at linaro.org>
---
Changes in v8:
- fix menu header string
- fix function and structure prefix to "eficonfig"
Newly created in v7
cmd/eficonfig.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 172 insertions(+)
diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
index 20747db115..0a58b83ea3 100644
--- a/cmd/eficonfig.c
+++ b/cmd/eficonfig.c
@@ -1197,6 +1197,177 @@ out:
return ret;
}
+static efi_status_t eficonfig_process_boot_selected(void *data)
+{
+ struct eficonfig_boot_selection_data *info = data;
+
+ if (info)
+ *info->selected = info->bootorder_index;
+
+ return EFI_SUCCESS;
+}
+
+static efi_status_t eficonfig_show_boot_selection(u16 *bootorder, efi_uintn_t count,
+ int *selected)
+{
+ u32 i;
+ efi_status_t ret;
+ efi_uintn_t size, actual_count = 0;
+ void *load_option;
+ struct efi_load_option lo;
+ u16 varname[] = u"Boot####";
+ struct eficonfig_item *menu_item, *iter;
+
+ menu_item = calloc(count + 1, sizeof(struct eficonfig_item));
+ if (!menu_item) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
+ iter = menu_item;
+ for (i = 0; i < count; i++) {
+ efi_create_indexed_name(varname, sizeof(varname),
+ "Boot", bootorder[i]);
+ load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
+ if (!load_option)
+ continue;
+
+ ret = efi_deserialize_load_option(&lo, load_option, &size);
+ if (ret != EFI_SUCCESS) {
+ log_warning("Invalid load option for %ls\n", varname);
+ free(load_option);
+ continue;
+ }
+
+ if (size >= sizeof(efi_guid_t) &&
+ !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) {
+ /*
+ * auto generated entry has GUID in optional_data,
+ * skip auto generated entry because it will be generated
+ * again even if it is edited or deleted.
+ */
+ free(load_option);
+ continue;
+ }
+
+ if (lo.attributes & LOAD_OPTION_ACTIVE) {
+ char *buf, *p;
+ struct eficonfig_boot_selection_data *info;
+
+ info = calloc(1, sizeof(struct eficonfig_boot_selection_data));
+ if (!info) {
+ free(load_option);
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
+ buf = calloc(1, utf16_utf8_strlen(lo.label) + 1);
+ if (!buf) {
+ free(load_option);
+ free(info);
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+ p = buf;
+ utf16_utf8_strcpy(&p, lo.label);
+ info->bootorder_index = i;
+ info->selected = selected;
+ iter->title = buf;
+ iter->func = eficonfig_process_boot_selected;
+ iter->data = info;
+ iter++;
+ actual_count++;
+ }
+ free(load_option);
+ }
+
+ /* add "Quit" entry */
+ iter->title = strdup("Quit");
+ iter->func = eficonfig_process_quit;
+ iter->data = NULL;
+ actual_count += 1;
+
+ ret = eficonfig_process_common(menu_item, actual_count, " ** Select Boot Option **");
+
+out:
+ iter = menu_item;
+ for (i = 0; i < actual_count; i++, iter++) {
+ free(iter->title);
+ free(iter->data);
+ }
+
+ free(menu_item);
+
+ return ret;
+}
+
+static efi_status_t eficonfig_process_edit_boot_option(void *data)
+{
+ u16 *bootorder;
+ efi_status_t ret;
+ efi_uintn_t num, size;
+ struct eficonfig_boot_option *bo = NULL;
+
+ bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
+ if (!bootorder) {
+ eficonfig_print_msg("BootOrder is not defined!");
+ ret = EFI_NOT_FOUND;
+ return ret;
+ }
+
+ num = size / sizeof(u16);
+ while (1) {
+ int selected;
+ void *load_option;
+ struct efi_load_option lo;
+ u16 varname[] = u"Boot####";
+
+ ret = eficonfig_show_boot_selection(bootorder, num, &selected);
+ if (ret != EFI_SUCCESS)
+ break;
+
+ bo = calloc(1, sizeof(struct eficonfig_boot_option));
+ if (!bo) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
+ bo->boot_index = selected;
+ efi_create_indexed_name(varname, sizeof(varname),
+ "Boot", bootorder[selected]);
+ load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
+ if (!load_option) {
+ free(bo);
+ ret = EFI_NOT_FOUND;
+ goto out;
+ }
+
+ ret = efi_deserialize_load_option(&lo, load_option, &size);
+ if (ret != EFI_SUCCESS) {
+ free(bo);
+ free(load_option);
+ goto out;
+ }
+
+ ret = eficonfig_edit_boot_option(varname, bo, lo.label, lo.optional_data,
+ size, lo.file_path,
+ " ** Edit Boot Option ** ");
+
+ free(load_option);
+ free(bo);
+ if (ret != EFI_SUCCESS && ret != EFI_ABORTED)
+ break;
+ }
+
+out:
+ free(bootorder);
+
+ /* to stay the parent menu */
+ ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret;
+
+ return ret;
+}
+
static efi_status_t eficonfig_init(void)
{
efi_status_t ret;
@@ -1230,6 +1401,7 @@ static efi_status_t eficonfig_init(void)
static const struct eficonfig_item maintenance_menu_items[] = {
{"Add Boot Option", eficonfig_process_add_boot_option},
+ {"Edit Boot Option", eficonfig_process_edit_boot_option},
{"Quit", eficonfig_process_quit},
};
--
2.17.1
More information about the U-Boot
mailing list