X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fboot%2Fefi%2Fboot.c;h=eb1a4e3b669618378dc182fa165423518fdf759e;hb=17366dcbe347c0a96df513268cb7acfed9b8f1f9;hp=7605c6532d58bb23a19acf9f9856872357505c76;hpb=e7dd673d1e0acfe5420599588c559fd85a3a9e8f;p=elogind.git diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 7605c6532..eb1a4e3b6 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -49,7 +49,6 @@ typedef struct { enum loader_type type; CHAR16 *loader; CHAR16 *options; - CHAR16 *splash; CHAR16 key; EFI_STATUS (*call)(VOID); BOOLEAN no_autoselect; @@ -65,11 +64,9 @@ typedef struct { UINTN timeout_sec_config; INTN timeout_sec_efivar; CHAR16 *entry_default_pattern; - CHAR16 *splash; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL *background; CHAR16 *entry_oneshot; CHAR16 *options_edit; - CHAR16 *entries_auto; + BOOLEAN no_editor; } Config; static VOID cursor_left(UINTN *cursor, UINTN *first) @@ -356,7 +353,7 @@ static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) { return -1; } -static VOID print_status(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_image_path) { +static VOID print_status(Config *config, CHAR16 *loaded_image_path) { UINT64 key; UINTN i; CHAR16 *s; @@ -364,48 +361,11 @@ static VOID print_status(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_imag UINTN x; UINTN y; UINTN size; - EFI_STATUS err; - UINTN color = 0; - const EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel = config->background; uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK); uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); - /* show splash and wait for key */ - for (;;) { - static const EFI_GRAPHICS_OUTPUT_BLT_PIXEL colors[] = { - { .Red = 0xff, .Green = 0xff, .Blue = 0xff }, - { .Red = 0xc0, .Green = 0xc0, .Blue = 0xc0 }, - { .Red = 0xff, .Green = 0, .Blue = 0 }, - { .Red = 0, .Green = 0xff, .Blue = 0 }, - { .Red = 0, .Green = 0, .Blue = 0xff }, - { .Red = 0, .Green = 0, .Blue = 0 }, - }; - - err = EFI_NOT_FOUND; - if (config->splash) - err = graphics_splash(root_dir, config->splash, pixel); - if (EFI_ERROR(err)) - err = graphics_splash(root_dir, L"\\EFI\\systemd\\splash.bmp", pixel); - if (EFI_ERROR(err)) - break; - - /* 'b' rotates through background colors */ - console_key_read(&key, TRUE); - if (key == KEYPRESS(0, 0, 'b')) { - pixel = &colors[color++]; - if (color == ELEMENTSOF(colors)) - color = 0; - - continue; - } - - graphics_mode(FALSE); - uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); - break; - } - - Print(L"systemd-boot version: " VERSION "\n"); + Print(L"systemd-boot version: " 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); @@ -416,7 +376,7 @@ static VOID print_status(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_imag Print(L"console size: %d x %d\n", x, y); if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) { - Print(L"SecureBoot: %s\n", *b > 0 ? L"enabled" : L"disabled"); + Print(L"SecureBoot: %s\n", yes_no(*b > 0)); FreePool(b); } @@ -437,13 +397,7 @@ static VOID print_status(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_imag Print(L"timeout (config): %d\n", config->timeout_sec_config); if (config->entry_default_pattern) Print(L"default pattern: '%s'\n", config->entry_default_pattern); - if (config->splash) - Print(L"splash '%s'\n", config->splash); - if (config->background) - Print(L"background '#%02x%02x%02x'\n", - config->background->Red, - config->background->Green, - config->background->Blue); + Print(L"editor: %s\n", yes_no(!config->no_editor)); Print(L"\n"); Print(L"config entry count: %d\n", config->entry_count); @@ -456,10 +410,6 @@ static VOID print_status(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_imag Print(L"LoaderConfigTimeout: %d\n", i); if (config->entry_oneshot) Print(L"LoaderEntryOneShot: %s\n", config->entry_oneshot); - if (efivar_get(L"LoaderDeviceIdentifier", &s) == EFI_SUCCESS) { - Print(L"LoaderDeviceIdentifier: %s\n", s); - FreePool(s); - } if (efivar_get(L"LoaderDevicePartUUID", &s) == EFI_SUCCESS) { Print(L"LoaderDevicePartUUID: %s\n", s); FreePool(s); @@ -479,15 +429,6 @@ static VOID print_status(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_imag break; entry = config->entries[i]; - - if (entry->splash) { - err = graphics_splash(root_dir, entry->splash, config->background); - if (!EFI_ERROR(err)) { - console_key_read(&key, TRUE); - graphics_mode(FALSE); - } - } - Print(L"config entry: %d/%d\n", i+1, config->entry_count); if (entry->file) Print(L"file '%s'\n", entry->file); @@ -513,9 +454,7 @@ static VOID print_status(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_imag Print(L"loader '%s'\n", entry->loader); if (entry->options) Print(L"options '%s'\n", entry->options); - if (entry->splash) - Print(L"splash '%s'\n", entry->splash); - Print(L"auto-select %s\n", entry->no_autoselect ? L"no" : L"yes"); + Print(L"auto-select %s\n", yes_no(!entry->no_autoselect)); if (entry->call) Print(L"internal call yes\n"); @@ -526,7 +465,7 @@ static VOID print_status(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_imag uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); } -static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry, EFI_FILE *root_dir, CHAR16 *loaded_image_path) { +static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry, CHAR16 *loaded_image_path) { EFI_STATUS err; UINTN visible_max; UINTN idx_highlight; @@ -832,7 +771,7 @@ static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry, EFI_FILE *ro case KEYPRESS(0, 0, 'e'): /* only the options of configured entries can be edited */ - if (config->entries[idx_highlight]->type == LOADER_UNDEFINED) + if (config->no_editor || config->entries[idx_highlight]->type == LOADER_UNDEFINED) break; uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK); uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, y_max-1); @@ -850,7 +789,7 @@ static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry, EFI_FILE *ro break; case KEYPRESS(0, 0, 'P'): - print_status(config, root_dir, loaded_image_path); + print_status(config, loaded_image_path); refresh = TRUE; break; @@ -872,15 +811,12 @@ static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry, EFI_FILE *ro idx_last = idx_highlight; idx_first = 1 + idx_highlight - visible_max; refresh = TRUE; - } - if (idx_highlight < idx_first) { + } else if (idx_highlight < idx_first) { idx_first = idx_highlight; idx_last = idx_highlight + visible_max-1; refresh = TRUE; } - idx_last = idx_first + visible_max-1; - if (!refresh && idx_highlight != idx_highlight_prev) highlight = TRUE; } @@ -1065,39 +1001,12 @@ static VOID config_defaults_load_from_file(Config *config, CHAR8 *content) { continue; } - if (strcmpa((CHAR8 *)"splash", key) == 0) { - FreePool(config->splash); - config->splash = stra_to_path(value); - continue; - } - - if (strcmpa((CHAR8 *)"background", key) == 0) { - CHAR16 c[3]; + if (strcmpa((CHAR8 *)"editor", key) == 0) { + BOOLEAN on; - /* accept #RRGGBB hex notation */ - if (value[0] != '#') + if (EFI_ERROR(parse_boolean(value, &on))) continue; - if (value[7] != '\0') - continue; - - FreePool(config->background); - config->background = AllocateZeroPool(sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); - if (!config->background) - continue; - - c[0] = value[1]; - c[1] = value[2]; - c[2] = '\0'; - config->background->Red = xtoi(c); - - c[0] = value[3]; - c[1] = value[4]; - config->background->Green = xtoi(c); - - c[0] = value[5]; - c[1] = value[6]; - config->background->Blue = xtoi(c); - continue; + config->no_editor = !on; } } } @@ -1195,12 +1104,6 @@ static VOID config_entry_add_from_file(Config *config, EFI_HANDLE *device, CHAR1 FreePool(new); continue; } - - if (strcmpa((CHAR8 *)"splash", key) == 0) { - FreePool(entry->splash); - entry->splash = stra_to_path(value); - continue; - } } if (entry->type == LOADER_UNDEFINED) { @@ -1225,46 +1128,6 @@ static VOID config_entry_add_from_file(Config *config, EFI_HANDLE *device, CHAR1 } FreePool(initrd); - if (entry->machine_id) { - CHAR16 *var; - - /* append additional options from EFI variables for this machine-id */ - var = PoolPrint(L"LoaderEntryOptions-%s", entry->machine_id); - if (var) { - CHAR16 *s; - - if (efivar_get(var, &s) == EFI_SUCCESS) { - if (entry->options) { - CHAR16 *s2; - - s2 = PoolPrint(L"%s %s", entry->options, s); - FreePool(entry->options); - entry->options = s2; - } else - entry->options = s; - } - FreePool(var); - } - - var = PoolPrint(L"LoaderEntryOptionsOneShot-%s", entry->machine_id); - if (var) { - CHAR16 *s; - - if (efivar_get(var, &s) == EFI_SUCCESS) { - if (entry->options) { - CHAR16 *s2; - - s2 = PoolPrint(L"%s %s", entry->options, s); - FreePool(entry->options); - entry->options = s2; - } else - entry->options = s; - efivar_set(var, NULL, TRUE); - } - FreePool(var); - } - } - entry->device = device; entry->file = StrDuplicate(file); len = StrLen(entry->file); @@ -1315,11 +1178,14 @@ static VOID config_load(Config *config, EFI_HANDLE *device, EFI_FILE *root_dir, continue; if (f->Attribute & EFI_FILE_DIRECTORY) continue; + len = StrLen(f->FileName); if (len < 6) continue; if (StriCmp(f->FileName + len - 5, L".conf") != 0) continue; + if (StrnCmp(f->FileName, L"auto-", 5) == 0) + continue; len = file_read(entries_dir, f->FileName, 0, 0, &content); if (len > 0) @@ -1596,19 +1462,6 @@ static BOOLEAN config_entry_add_loader_auto(Config *config, EFI_HANDLE *device, /* do not boot right away into auto-detected entries */ entry->no_autoselect = TRUE; - /* do not show a splash; they do not need one, or they draw their own */ - entry->splash = StrDuplicate(L""); - - /* export identifiers of automatically added entries */ - if (config->entries_auto) { - CHAR16 *s; - - s = PoolPrint(L"%s %s", config->entries_auto, file); - FreePool(config->entries_auto); - config->entries_auto = s; - } else - config->entries_auto = StrDuplicate(file); - return TRUE; } @@ -1810,9 +1663,6 @@ static VOID config_free(Config *config) { FreePool(config->entry_default_pattern); FreePool(config->options_edit); FreePool(config->entry_oneshot); - FreePool(config->entries_auto); - FreePool(config->splash); - FreePool(config->background); } EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { @@ -1850,13 +1700,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { /* export the device path this image is started from */ device_path = DevicePathFromHandle(loaded_image->DeviceHandle); if (device_path) { - CHAR16 *str; EFI_DEVICE_PATH *path, *paths; - str = DevicePathToStr(device_path); - efivar_set(L"LoaderDeviceIdentifier", str, FALSE); - FreePool(str); - paths = UnpackDevicePath(device_path); for (path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) { HARDDRIVE_DEVICE_PATH *drive; @@ -1893,15 +1738,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { ZeroMem(&config, sizeof(Config)); config_load(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path); - if (!config.background) { - config.background = AllocateZeroPool(sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); - if (StriCmp(L"Apple", ST->FirmwareVendor) == 0) { - config.background->Red = 0xc0; - config.background->Green = 0xc0; - config.background->Blue = 0xc0; - } - } - /* if we find some well-known loaders, add them to the end of the list */ config_entry_add_linux(&config, loaded_image, root_dir); config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path, @@ -1911,7 +1747,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path, L"auto-efi-default", '\0', L"EFI Default Loader", L"\\EFI\\Boot\\boot" EFI_MACHINE_TYPE_NAME ".efi"); config_entry_add_osx(&config); - efivar_set(L"LoaderEntriesAuto", config.entries_auto, FALSE); if (efivar_get_raw(&global_guid, L"OsIndicationsSupported", &b, &size) == EFI_SUCCESS) { UINT64 osind = (UINT64)*b; @@ -1964,7 +1799,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { if (menu) { efivar_set_time_usec(L"LoaderTimeMenuUSec", 0); uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x10000, 0, NULL); - if (!menu_run(&config, &entry, root_dir, loaded_image_path)) + if (!menu_run(&config, &entry, loaded_image_path)) break; /* run special entry like "reboot" */ @@ -1972,25 +1807,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { entry->call(); continue; } - } else { - err = EFI_NOT_FOUND; - - /* splash from entry file */ - if (entry->splash) { - /* some entries disable the splash because they draw their own */ - if (entry->splash[0] == '\0') - err = EFI_SUCCESS; - else - err = graphics_splash(root_dir, entry->splash, config.background); - } - - /* splash from config file */ - if (EFI_ERROR(err) && config.splash) - err = graphics_splash(root_dir, config.splash, config.background); - - /* default splash */ - if (EFI_ERROR(err)) - graphics_splash(root_dir, L"\\EFI\\systemd\\splash.bmp", config.background); } /* export the selected boot entry to the system */ @@ -1998,14 +1814,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { uefi_call_wrapper(BS->SetWatchdogTimer, 4, 5 * 60, 0x10000, 0, NULL); err = image_start(image, &config, entry); - - if (err == EFI_ACCESS_DENIED || err == EFI_SECURITY_VIOLATION) { - /* Platform is secure boot and requested image isn't - * trusted. Need to go back to prior boot system and - * install more keys or hashes. Signal failure by - * returning the error */ - Print(L"\nImage %s gives a security error\n", entry->title); - Print(L"Please enrol the hash or signature of %s\n", entry->loader); + if (EFI_ERROR(err)) { + graphics_mode(FALSE); + Print(L"\nFailed to execute %s (%s): %r\n", entry->title, entry->loader, err); uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); goto out; }