diff options
author | Kay Sievers <kay@vrfy.org> | 2012-07-15 00:15:40 +0200 |
---|---|---|
committer | Kay Sievers <kay@vrfy.org> | 2012-07-15 02:21:35 +0200 |
commit | fc85a34194b2d623614b1490b456c4e7a70f553e (patch) | |
tree | 75f4f9e91e30f351f48d4e2ce80527ef956d556a | |
parent | 6d23e5fd047a712102eb946423ec4246d66b2c25 (diff) |
add "title-version", "title-machine" to non-unique menu "title"s
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | gummiboot.c | 160 | ||||
-rwxr-xr-x | loader-postinst.sh | 43 |
3 files changed, 159 insertions, 48 deletions
@@ -11,9 +11,5 @@ and which supports: create/update/delete conf fragment, update/cleanup all fragments belonging to this machine. -* add "title-details" (carrying the machine-id / the root device name) support - to the fragment file. Display the details along with the "title" if we have - non-unique titles -> pretty looking menu without silly numbers if not needed - * properly document the config file format, directory layout and EFI variable in the wiki; make it more look like a spec -> easier to adapt other loaders diff --git a/gummiboot.c b/gummiboot.c index a34981c..8e5e35b 100644 --- a/gummiboot.c +++ b/gummiboot.c @@ -41,11 +41,15 @@ enum loader_type { typedef struct { CHAR16 *file; + CHAR16 *title_show; CHAR16 *title; + CHAR16 *title_version; + CHAR16 *title_machine; enum loader_type type; CHAR16 *loader; CHAR16 *options; BOOLEAN no_autoselect; + BOOLEAN non_unique; } ConfigEntry; typedef struct { @@ -361,7 +365,13 @@ static VOID dump_status(Config *config) { entry = config->entries[i]; Print(L"config entry: %d/%d\n", i+1, config->entry_count); Print(L"file '%s'\n", entry->file); - Print(L"title '%s'\n", entry->title); + Print(L"title show '%s'\n", entry->title_show); + if (entry->title) + Print(L"title '%s'\n", entry->title); + if (entry->title_version) + Print(L"title version '%s'\n", entry->title_version); + if (entry->title_machine) + Print(L"title machine '%s'\n", entry->title_machine); Print(L"loader '%s'\n", entry->loader); if (entry->options) Print(L"options '%s'\n", entry->options); @@ -433,7 +443,7 @@ static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry) { for (i = 0; i < config->entry_count; i++) { UINTN entry_len; - entry_len = StrLen(config->entries[i]->title); + entry_len = StrLen(config->entries[i]->title_show); if (line_width < entry_len) line_width = entry_len; } @@ -443,7 +453,7 @@ static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry) { /* menu entries title lines */ lines = AllocatePool(sizeof(CHAR16 *) * config->entry_count); for (i = 0; i < config->entry_count; i++) - lines[i] = PoolPrint(L" %-.*s ", line_width, config->entries[i]->title); + lines[i] = PoolPrint(L" %-.*s ", line_width, config->entries[i]->title_show); status = NULL; clearline = AllocatePool((x_max+1) * sizeof(CHAR16)); @@ -689,7 +699,9 @@ static VOID config_add_entry(Config *config, ConfigEntry *entry) { } static VOID config_entry_free(ConfigEntry *entry) { + FreePool(entry->title_show); FreePool(entry->title); + FreePool(entry->title_machine); FreePool(entry->loader); FreePool(entry->options); } @@ -971,6 +983,18 @@ static VOID config_entry_add_from_file(Config *config, CHAR16 *file, CHAR8 *cont continue; } + if (strcmpa((CHAR8 *)"title-version", key) == 0) { + FreePool(entry->title_version); + entry->title_version = stra_to_str(value); + continue; + } + + if (strcmpa((CHAR8 *)"title-machine", key) == 0) { + FreePool(entry->title_machine); + entry->title_machine = stra_to_str(value); + continue; + } + if (strcmpa((CHAR8 *)"linux", key) == 0) { FreePool(entry->loader); entry->type = LOADER_LINUX; @@ -1055,9 +1079,6 @@ static VOID config_entry_add_from_file(Config *config, CHAR16 *file, CHAR8 *cont entry->file[len - 5] = '\0'; StrLwr(entry->file); - if (!entry->title) - entry->title = StrDuplicate(entry->loader); - config_add_entry(config, entry); } @@ -1145,17 +1166,17 @@ static VOID config_load(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_image /* sort entries after version number */ for (i = 1; i < config->entry_count; i++) { BOOLEAN more; - UINTN j; + UINTN k; more = FALSE; - for (j = 0; j < config->entry_count - i; j++) { + for (k = 0; k < config->entry_count - i; k++) { ConfigEntry *entry; - if (str_verscmp(config->entries[j]->file, config->entries[j+1]->file) <= 0) + if (str_verscmp(config->entries[k]->file, config->entries[k+1]->file) <= 0) continue; - entry = config->entries[j]; - config->entries[j] = config->entries[j+1]; - config->entries[j+1] = entry; + entry = config->entries[k]; + config->entries[k] = config->entries[k+1]; + config->entries[k+1] = entry; more = TRUE; } if (!more) @@ -1242,6 +1263,113 @@ static VOID config_default_entry_select(Config *config) { config->idx_default = config->entry_count-1; } +/* generate a unique title, avoiding non-distinguishable menu entries */ +static VOID config_title_generate(Config *config) { + UINTN i, k; + BOOLEAN unique; + + /* set title */ + for (i = 0; i < config->entry_count; i++) { + CHAR16 *title; + + FreePool(config->entries[i]->title_show); + title = config->entries[i]->title; + if (!title) + title = config->entries[i]->file; + config->entries[i]->title_show = StrDuplicate(title); + } + + unique = TRUE; + for (i = 0; i < config->entry_count; i++) { + for (k = 0; k < config->entry_count; k++) { + if (i == k) + continue; + if (StrCmp(config->entries[i]->title_show, config->entries[k]->title_show) != 0) + continue; + + unique = FALSE; + config->entries[i]->non_unique = TRUE; + config->entries[k]->non_unique = TRUE; + } + } + if (unique) + return; + + /* add version to non-unique titles */ + for (i = 0; i < config->entry_count; i++) { + CHAR16 *s; + + if (!config->entries[i]->non_unique) + continue; + if (!config->entries[i]->title_version) + continue; + + s = PoolPrint(L"%s (%s)", config->entries[i]->title_show, config->entries[i]->title_version); + FreePool(config->entries[i]->title_show); + config->entries[i]->title_show = s; + config->entries[i]->non_unique = FALSE; + } + + unique = TRUE; + for (i = 0; i < config->entry_count; i++) { + for (k = 0; k < config->entry_count; k++) { + if (i == k) + continue; + if (StrCmp(config->entries[i]->title_show, config->entries[k]->title_show) != 0) + continue; + + unique = FALSE; + config->entries[i]->non_unique = TRUE; + config->entries[k]->non_unique = TRUE; + } + } + if (unique) + return; + + /* add machine-id to non-unique titles */ + for (i = 0; i < config->entry_count; i++) { + CHAR16 *s; + + if (!config->entries[i]->non_unique) + continue; + if (!config->entries[i]->title_machine) + continue; + + s = PoolPrint(L"%s (%s)", config->entries[i]->title_show, config->entries[i]->title_machine); + FreePool(config->entries[i]->title_show); + config->entries[i]->title_show = s; + config->entries[i]->non_unique = FALSE; + } + + unique = TRUE; + for (i = 0; i < config->entry_count; i++) { + for (k = 0; k < config->entry_count; k++) { + if (i == k) + continue; + if (StrCmp(config->entries[i]->title_show, config->entries[k]->title_show) != 0) + continue; + + unique = FALSE; + config->entries[i]->non_unique = TRUE; + config->entries[k]->non_unique = TRUE; + } + } + if (unique) + return; + + /* add file name to non-unique titles */ + for (i = 0; i < config->entry_count; i++) { + CHAR16 *s; + + if (!config->entries[i]->non_unique) + continue; + s = PoolPrint(L"%s (%s)", config->entries[i]->title_show, config->entries[i]->file); + FreePool(config->entries[i]->title_show); + config->entries[i]->title_show = s; + config->entries[i]->non_unique = FALSE; + } +} + static VOID config_entry_add_loader(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_image_path, CHAR16 *file, CHAR16 *title, CHAR16 *loader) { EFI_FILE_HANDLE handle; @@ -1370,13 +1498,15 @@ EFI_STATUS EFIAPI efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { /* if we find some well-known loaders, add them to the end of the list */ config_entry_add_loader(&config, root_dir, loaded_image_path, - L"loader-bootmgfw", L"Windows Boot Manager", L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"); + L"builtin-bootmgfw", L"Windows Boot Manager", L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"); config_entry_add_loader(&config, root_dir, loaded_image_path, - L"loader-shellx64", L"EFI Shell", L"\\shellx64.efi"); + L"builtin-shellx64", L"EFI Shell", L"\\shellx64.efi"); config_entry_add_loader(&config, root_dir, loaded_image_path, - L"loader-bootx64", L"EFI Default Loader", L"\\EFI\\BOOT\\BOOTX64.EFI"); + L"builtin-bootx64", L"EFI Default Loader", L"\\EFI\\BOOT\\BOOTX64.EFI"); FreePool(loaded_image_path); + config_title_generate(&config); + /* select entry by configured pattern or EFI LoaderDefaultEntry= variable*/ config_default_entry_select(&config); diff --git a/loader-postinst.sh b/loader-postinst.sh index a705b2e..091baaf 100755 --- a/loader-postinst.sh +++ b/loader-postinst.sh @@ -31,14 +31,14 @@ fi if [[ -d /boot/loader/entries ]]; then EFI_DIR="/boot" -elif [[ -f /boot/efi/loader/entries ]]; then +elif [[ -d /boot/efi/loader/entries ]]; then EFI_DIR="/boot/efi" fi if ! [[ $EFI_DIR ]] ; then - echo "Can't install new kernel for loader: no directory 'loader/entries found!" >&2 - echo "Please create the directory 'loader/entries' in your EFI partition." >&2 - exit 1 + echo "Did not install new kernel and loader entry." >&2 + echo "Please create the directory 'loader/entries/' in your EFI system partition." >&2 + exit 0 fi if [[ -f ${KERNEL_IMAGE/vmlinuz/initrd} ]]; then @@ -55,57 +55,42 @@ if [[ -f /etc/kernel/cmdline ]]; then done < /etc/kernel/cmdline fi if ! [[ $BOOT_OPTIONS ]]; then - echo "Can't load default kernel command line parameters from /etc/kernel/cmdline!" >&2 + echo "Can't determine the kernel command line parameters." >&2 echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2 exit 1 fi [[ -f /etc/os-release ]] && . /etc/os-release if ! [[ $ID ]]; then - echo "Can't determine the ID of your distribution. Please populate /etc/os-release!" >&2 + echo "Can't determine the name of your distribution. Please create /etc/os-release." >&2 echo "See http://www.freedesktop.org/software/systemd/man/os-release.html" >&2 exit 1 fi [[ -f /etc/machine-id ]] && read MACHINE_ID < /etc/machine-id if ! [[ $MACHINE_ID ]]; then - echo "Can't determine your machine id. Please populate /etc/machine-id!" >&2 + echo "Can't determine your machine id. Please create /etc/machine-id!" >&2 echo "See http://www.freedesktop.org/software/systemd/man/machine-id.html" >&2 exit 1 fi -ROOT_DEV=$(while read a a a a mp a a a dev a; do - if [[ $mp = "/" ]]; then - echo $dev - break - fi -done < /proc/self/mountinfo) - -if [[ $ROOT_DEV ]]; then - ROOT_LABEL=$(blkid -p -o udev -u filesystem $ROOT_DEV | - while read line; do - if [[ $line == ID_FS_LABEL* ]]; then - echo ${line##ID_FS_LABEL=} - break - fi - done) -fi - mkdir -p "${EFI_DIR}/${ID}/${MACHINE_ID}" cp --preserve "$KERNEL_IMAGE" "${EFI_DIR}/${ID}/${MACHINE_ID}/" [[ $INITRD_IMAGE ]] && cp --preserve "$INITRD_IMAGE" "${EFI_DIR}/${ID}/${MACHINE_ID}/" { - echo "title $NAME $VERSION_ID ($KERNEL_VERSION) $ROOT_LABEL ${ROOT_DEV##/dev/} ${MACHINE_ID:0:8}" - echo "options $BOOT_OPTIONS" - echo "linux /$ID/$MACHINE_ID/${KERNEL_IMAGE##*/}" - [[ $INITRD_IMAGE ]] && echo "initrd /${ID}/${MACHINE_ID}/${INITRD_IMAGE##*/}" + echo "title $PRETTY_NAME" + echo "title-version $KERNEL_VERSION" + echo "title-machine ${MACHINE_ID:0:8}" + echo "options $BOOT_OPTIONS" + echo "linux /$ID/$MACHINE_ID/${KERNEL_IMAGE##*/}" + [[ $INITRD_IMAGE ]] && echo "initrd /${ID}/${MACHINE_ID}/${INITRD_IMAGE##*/}" } > "${EFI_DIR}/loader/entries/${ID}-${KERNEL_VERSION}-${MACHINE_ID}.conf" if ! [[ -f ${EFI_DIR}/loader/loader.conf ]]; then { - echo "default $ID-" + echo "default $ID-*" } > "${EFI_DIR}/loader/loader.conf" fi |