#endif
/* magic string to find in the binary image */
-static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot " PACKAGE_VERSION " ####";
+static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot " GIT_VERSION " ####";
static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
BOOLEAN editor;
BOOLEAN auto_entries;
BOOLEAN auto_firmware;
+ BOOLEAN force_menu;
UINTN console_mode;
enum console_mode_change_type console_mode_change;
} Config;
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK);
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- Print(L"systemd-boot version: " PACKAGE_VERSION "\n");
+ Print(L"systemd-boot version: " GIT_VERSION "\n");
Print(L"architecture: " EFI_MACHINE_TYPE_NAME "\n");
Print(L"loaded image: %s\n", loaded_image_path);
Print(L"UEFI specification: %d.%02d\n", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
Print(L"\n--- press key ---\n\n");
console_key_read(&key, TRUE);
- Print(L"timeout: %d\n", config->timeout_sec);
+ Print(L"timeout: %u\n", config->timeout_sec);
if (config->timeout_sec_efivar >= 0)
Print(L"timeout (EFI var): %d\n", config->timeout_sec_efivar);
- Print(L"timeout (config): %d\n", config->timeout_sec_config);
+ Print(L"timeout (config): %u\n", config->timeout_sec_config);
if (config->entry_default_pattern)
Print(L"default pattern: '%s'\n", config->entry_default_pattern);
Print(L"editor: %s\n", yes_no(config->editor));
Print(L"\n");
if (efivar_get_int(L"LoaderConfigTimeout", &i) == EFI_SUCCESS)
- Print(L"LoaderConfigTimeout: %d\n", i);
+ Print(L"LoaderConfigTimeout: %u\n", i);
+
if (config->entry_oneshot)
Print(L"LoaderEntryOneShot: %s\n", config->entry_oneshot);
if (efivar_get(L"LoaderDevicePartUUID", &partstr) == EFI_SUCCESS)
break;
case KEYPRESS(0, 0, 'v'):
- status = PoolPrint(L"systemd-boot " PACKAGE_VERSION " (" EFI_MACHINE_TYPE_NAME "), UEFI Specification %d.%02d, Vendor %s %d.%02d",
+ status = PoolPrint(L"systemd-boot " GIT_VERSION " (" EFI_MACHINE_TYPE_NAME "), UEFI Specification %d.%02d, Vendor %s %d.%02d",
ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff,
ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
break;
}
/* remove trailing whitespace */
- while (linelen > 0 && strchra(sep, line[linelen-1]))
+ while (linelen > 0 && strchra((CHAR8 *)" \t", line[linelen-1]))
linelen--;
line[linelen] = '\0';
value++;
/* unquote */
- if (value[0] == '\"' && line[linelen-1] == '\"') {
+ if (value[0] == '"' && line[linelen-1] == '"') {
value++;
line[linelen-1] = '\0';
}
UINTN sec;
EFI_STATUS err;
- config->editor = TRUE;
- config->auto_entries = TRUE;
- config->auto_firmware = TRUE;
+ *config = (Config) {
+ .editor = TRUE,
+ .auto_entries = TRUE,
+ .auto_firmware = TRUE,
+ };
err = file_read(root_dir, L"\\loader\\loader.conf", 0, 0, &content, NULL);
if (!EFI_ERROR(err))
err = efivar_get_int(L"LoaderConfigTimeout", &sec);
if (!EFI_ERROR(err)) {
- config->timeout_sec_efivar = sec;
+ config->timeout_sec_efivar = sec > INTN_MAX ? INTN_MAX : sec;
config->timeout_sec = sec;
} else
config->timeout_sec_efivar = -1;
+
+ err = efivar_get_int(L"LoaderConfigTimeoutOneShot", &sec);
+ if (!EFI_ERROR(err)) {
+ /* Unset variable now, after all it's "one shot". */
+ (void) efivar_set(L"LoaderConfigTimeoutOneShot", NULL, TRUE);
+
+ config->timeout_sec = sec;
+ config->force_menu = TRUE; /* force the menu when this is set */
+ }
}
static VOID config_load_entries(
}
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
+ static const UINT64 loader_features =
+ (1ULL << 0) | /* I honour the LoaderConfigTimeout variable */
+ (1ULL << 1) | /* I honour the LoaderConfigTimeoutOneShot variable */
+ (1ULL << 2) | /* I honour the LoaderEntryDefault variable */
+ (1ULL << 3) | /* I honour the LoaderEntryOneShot variable */
+ (1ULL << 4) | /* I support boot counting */
+ 0;
+
_cleanup_freepool_ CHAR16 *infostr = NULL, *typestr = NULL;
CHAR8 *b;
UINTN size;
InitializeLib(image, sys_table);
init_usec = time_usec();
efivar_set_time_usec(L"LoaderTimeInitUSec", init_usec);
- efivar_set(L"LoaderInfo", L"systemd-boot " PACKAGE_VERSION, FALSE);
+ efivar_set(L"LoaderInfo", L"systemd-boot " GIT_VERSION, FALSE);
infostr = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
efivar_set(L"LoaderFirmwareInfo", infostr, FALSE);
typestr = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
efivar_set(L"LoaderFirmwareType", typestr, FALSE);
+ (void) efivar_set_raw(&loader_guid, L"LoaderFeatures", &loader_features, sizeof(loader_features), FALSE);
+
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (EFI_ERROR(err)) {
loaded_image_path = DevicePathToStr(loaded_image->FilePath);
efivar_set(L"LoaderImageIdentifier", loaded_image_path, FALSE);
- ZeroMem(&config, sizeof(Config));
config_load_defaults(&config, root_dir);
/* scan /EFI/Linux/ directory */
UINT64 osind = (UINT64)*b;
if (osind & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)
- config_entry_add_call(&config, L"auto-reboot-into-firmware-ui", L"Reboot Into Firmware Interface", reboot_into_firmware);
+ config_entry_add_call(&config, L"auto-reboot-to-firmware-setup", L"Reboot Into Firmware Interface", reboot_into_firmware);
FreePool(b);
}
}
/* select entry or show menu when key is pressed or timeout is set */
- if (config.timeout_sec == 0) {
+ if (config.force_menu || config.timeout_sec > 0)
+ menu = TRUE;
+ else {
UINT64 key;
err = console_key_read(&key, FALSE);
else
menu = TRUE;
}
- } else
- menu = TRUE;
+ }
for (;;) {
ConfigEntry *entry;
uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x10000, 0, NULL);
if (!menu_run(&config, &entry, loaded_image_path))
break;
+ }
- /* run special entry like "reboot" */
- if (entry->call) {
- entry->call();
- continue;
- }
+ /* run special entry like "reboot" */
+ if (entry->call) {
+ entry->call();
+ continue;
}
config_entry_bump_counters(entry, root_dir);