UINT32 timeout_sec_config;
UINT32 timeout_sec_efivar;
CHAR16 *entry_default_pattern;
+ CHAR16 *entry_default_efivar;
CHAR16 *entry_oneshot;
CHAR16 *options_edit;
BOOLEAN editor;
UINT64 key;
UINTN x_max, y_max;
SecureBootMode secure;
- _cleanup_freepool_ CHAR16 *device_part_uuid = NULL, *default_efivar = NULL;
+ _cleanup_freepool_ CHAR16 *device_part_uuid = NULL;
assert(config);
assert(loaded_image_path);
secure = secure_boot_mode();
(void) efivar_get(LOADER_GUID, L"LoaderDevicePartUUID", &device_part_uuid);
- (void) efivar_get(LOADER_GUID, L"LoaderEntryDefault", &default_efivar);
/* We employ some unusual indentation here for readability. */
}
ps_string(L" default: %s\n", config->entry_default_pattern);
+ ps_string(L" default (EFI var): %s\n", config->entry_default_efivar);
ps_string(L" default (one-shot): %s\n", config->entry_oneshot);
- ps_string(L" default (EFI var): %s\n", default_efivar);
ps_bool(L" editor: %s\n", config->editor);
ps_bool(L" auto-entries: %s\n", config->auto_entries);
ps_bool(L" auto-firmware: %s\n", config->auto_firmware);
INT16 idx;
BOOLEAN exit = FALSE, run = TRUE, firmware_setup = FALSE;
INT64 console_mode_initial = ST->ConOut->Mode->Mode, console_mode_efivar_saved = config->console_mode_efivar;
+ INTN default_efivar_saved = config->idx_default_efivar;
graphics_mode(FALSE);
ST->ConIn->Reset(ST->ConIn, FALSE);
case KEYPRESS(0, 0, 'd'):
case KEYPRESS(0, 0, 'D'):
if (config->idx_default_efivar != (INTN)idx_highlight) {
- /* store the selected entry in a persistent EFI variable */
- efivar_set(
- LOADER_GUID,
- L"LoaderEntryDefault",
- config->entries[idx_highlight]->id,
- EFI_VARIABLE_NON_VOLATILE);
+ FreePool(config->entry_default_efivar);
+ config->entry_default_efivar = StrDuplicate(config->entries[idx_highlight]->id);
+ if (!config->entry_default_efivar) {
+ log_oom();
+ return FALSE;
+ }
config->idx_default_efivar = idx_highlight;
status = StrDuplicate(L"Default boot entry selected.");
} else {
- /* clear the default entry EFI variable */
- efivar_set(LOADER_GUID, L"LoaderEntryDefault", NULL, EFI_VARIABLE_NON_VOLATILE);
+ config->entry_default_efivar = mfree(config->entry_default_efivar);
config->idx_default_efivar = -1;
status = StrDuplicate(L"Default boot entry cleared.");
}
/* Update EFI vars after we left the menu to reduce NVRAM writes. */
+ if (default_efivar_saved != config->idx_default_efivar)
+ efivar_set(LOADER_GUID, L"LoaderEntryDefault", config->entry_default_efivar, EFI_VARIABLE_NON_VOLATILE);
+
if (console_mode_efivar_saved != config->console_mode_efivar) {
if (config->console_mode_efivar == CONSOLE_MODE_KEEP)
efivar_set(LOADER_GUID, L"LoaderConfigConsoleMode", NULL, EFI_VARIABLE_NON_VOLATILE);
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigConsoleMode", &value);
if (!EFI_ERROR(err))
config->console_mode_efivar = value;
+
+ err = efivar_get(LOADER_GUID, L"LoaderEntryOneShot", &config->entry_oneshot);
+ if (!EFI_ERROR(err))
+ /* Unset variable now, after all it's "one shot". */
+ (void) efivar_set(LOADER_GUID, L"LoaderEntryOneShot", NULL, EFI_VARIABLE_NON_VOLATILE);
+
+ (void) efivar_get(LOADER_GUID, L"LoaderEntryDefault", &config->entry_default_efivar);
}
static void config_load_entries(
static INTN config_entry_find(Config *config, CHAR16 *id) {
assert(config);
- assert(id);
+
+ if (!id)
+ return -1;
for (UINTN i = 0; i < config->entry_count; i++)
if (StrCmp(config->entries[i]->id, id) == 0)
}
static void config_default_entry_select(Config *config) {
- _cleanup_freepool_ CHAR16 *entry_default = NULL;
- EFI_STATUS err;
INTN i;
assert(config);
- /*
- * The EFI variable to specify a boot entry for the next, and only the
- * next reboot. The variable is always cleared directly after it is read.
- */
- err = efivar_get(LOADER_GUID, L"LoaderEntryOneShot", &config->entry_oneshot);
- if (!EFI_ERROR(err)) {
- efivar_set(LOADER_GUID, L"LoaderEntryOneShot", NULL, EFI_VARIABLE_NON_VOLATILE);
-
- i = config_entry_find(config, config->entry_oneshot);
- if (i >= 0) {
- config->idx_default = i;
- return;
- }
+ i = config_entry_find(config, config->entry_oneshot);
+ if (i >= 0) {
+ config->idx_default = i;
+ return;
}
- /*
- * The EFI variable to select the default boot entry overrides the
- * configured pattern. The variable can be set and cleared by pressing
- * the 'd' key in the loader selection menu.
- */
- err = efivar_get(LOADER_GUID, L"LoaderEntryDefault", &entry_default);
- if (!EFI_ERROR(err)) {
- i = config_entry_find(config, entry_default);
- if (i >= 0) {
- config->idx_default = i;
- config->idx_default_efivar = i;
- return;
- }
+ i = config_entry_find(config, config->entry_default_efivar);
+ if (i >= 0) {
+ config->idx_default = i;
+ config->idx_default_efivar = i;
+ return;
}
if (config->entry_count == 0)