diff --git a/grub2-Add-hidden-menu-entries.patch b/grub2-Add-hidden-menu-entries.patch new file mode 100644 index 0000000..8ee7929 --- /dev/null +++ b/grub2-Add-hidden-menu-entries.patch @@ -0,0 +1,232 @@ +From a06004f4c668abd7c760a2818d0a8205da7568e7 Mon Sep 17 00:00:00 2001 +From: Alexander Graf +Date: Tue, 26 Apr 2016 15:29:25 +0200 +Subject: [PATCH v3] Add hidden menu entries + +The menu infrastructure is quite powerful. It allows you to define menu +entries that can contain arbitrary grub commands that can do a lot more +than just boot kernel entries. + +For some of these it makes sense to hide them inside the normal menu +though and instead have them available through hotkeys that get advertised +differently. My main use case is to switch to the serial console when +gfxterm is loaded. + +So this patch adds support for hidden menu entries that are accessible +using hotkeys, but are not accessible in the grub menu. + +Signed-off-by: Alexander Graf + +--- + +v1 -> v2: + + - fix default entry selection + +v2 -> v3: + + - replace "--hidden" parameter with new command "hiddenentry" + +diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c +index dd9d9f1..b282c4f 100644 +--- a/grub-core/commands/legacycfg.c ++++ b/grub-core/commands/legacycfg.c +@@ -133,7 +133,7 @@ legacy_file (const char *filename) + args[0] = oldname; + grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy", + NULL, NULL, +- entrysrc, 0); ++ entrysrc, 0, 0); + grub_free (args); + entrysrc[0] = 0; + grub_free (oldname); +@@ -186,7 +186,7 @@ legacy_file (const char *filename) + } + args[0] = entryname; + grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, +- NULL, NULL, entrysrc, 0); ++ NULL, NULL, entrysrc, 0, 0); + grub_free (args); + } + +diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c +index 58d4dad..b4d6c31 100644 +--- a/grub-core/commands/menuentry.c ++++ b/grub-core/commands/menuentry.c +@@ -78,7 +78,7 @@ grub_normal_add_menu_entry (int argc, const char **args, + char **classes, const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, +- int submenu) ++ int submenu, int hidden) + { + int menu_hotkey = 0; + char **menu_args = NULL; +@@ -188,8 +188,11 @@ grub_normal_add_menu_entry (int argc, const char **args, + (*last)->args = menu_args; + (*last)->sourcecode = menu_sourcecode; + (*last)->submenu = submenu; ++ (*last)->hidden = hidden; ++ ++ if (!hidden) ++ menu->size++; + +- menu->size++; + return GRUB_ERR_NONE; + + fail: +@@ -286,7 +289,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) + users, + ctxt->state[2].arg, 0, + ctxt->state[3].arg, +- ctxt->extcmd->cmd->name[0] == 's'); ++ ctxt->extcmd->cmd->name[0] == 's', ++ ctxt->extcmd->cmd->name[0] == 'h'); + + src = args[argc - 1]; + args[argc - 1] = NULL; +@@ -303,7 +307,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) + ctxt->state[0].args, ctxt->state[4].arg, + users, + ctxt->state[2].arg, prefix, src + 1, +- ctxt->extcmd->cmd->name[0] == 's'); ++ ctxt->extcmd->cmd->name[0] == 's', ++ ctxt->extcmd->cmd->name[0] == 'h'); + + src[len - 1] = ch; + args[argc - 1] = src; +@@ -311,7 +316,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) + return r; + } + +-static grub_extcmd_t cmd, cmd_sub; ++static grub_extcmd_t cmd, cmd_sub, cmd_hidden; + + void + grub_menu_init (void) +@@ -327,6 +332,13 @@ grub_menu_init (void) + | GRUB_COMMAND_FLAG_EXTRACTOR, + N_("BLOCK"), N_("Define a submenu."), + options); ++ cmd_hidden = grub_register_extcmd ("hiddenentry", grub_cmd_menuentry, ++ GRUB_COMMAND_FLAG_BLOCKS ++ | GRUB_COMMAND_ACCEPT_DASH ++ | GRUB_COMMAND_FLAG_EXTRACTOR, ++ N_("BLOCK"), ++ N_("Define a hidden menu entry."), ++ options); + } + + void +diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c +index 719e2fb..2a151fe 100644 +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -40,6 +40,8 @@ + grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu, + int nested) = NULL; + ++#define MENU_INCLUDE_HIDDEN 0x10000 ++ + enum timeout_style { + TIMEOUT_STYLE_MENU, + TIMEOUT_STYLE_COUNTDOWN, +@@ -80,8 +82,20 @@ grub_menu_get_entry (grub_menu_t menu, int no) + { + grub_menu_entry_t e; + +- for (e = menu->entry_list; e && no > 0; e = e->next, no--) +- ; ++ if (no & MENU_INCLUDE_HIDDEN) { ++ no &= ~MENU_INCLUDE_HIDDEN; ++ ++ for (e = menu->entry_list; e && no > 0; e = e->next, no--) ++ ; ++ } else { ++ for (e = menu->entry_list; e && no > 0; e = e->next, no--) { ++ /* Skip hidden entries */ ++ while (e && e->hidden) ++ e = e->next; ++ } ++ while (e && e->hidden) ++ e = e->next; ++ } + + return e; + } +@@ -93,10 +107,10 @@ get_entry_index_by_hotkey (grub_menu_t menu, int hotkey) + grub_menu_entry_t entry; + int i; + +- for (i = 0, entry = menu->entry_list; i < menu->size; ++ for (i = 0, entry = menu->entry_list; entry; + i++, entry = entry->next) + if (entry->hotkey == hotkey) +- return i; ++ return i | MENU_INCLUDE_HIDDEN; + + return -1; + } +@@ -510,6 +524,10 @@ get_entry_number (grub_menu_t menu, const char *name) + grub_menu_entry_t e = menu->entry_list; + int i; + ++ /* Skip hidden entries */ ++ while (e && e->hidden) ++ e = e->next; ++ + grub_errno = GRUB_ERR_NONE; + + for (i = 0; e; i++) +@@ -521,6 +539,10 @@ get_entry_number (grub_menu_t menu, const char *name) + break; + } + e = e->next; ++ ++ /* Skip hidden entries */ ++ while (e && e->hidden) ++ e = e->next; + } + + if (! e) +diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c +index e22bb91..4ac2d6b 100644 +--- a/grub-core/normal/menu_text.c ++++ b/grub-core/normal/menu_text.c +@@ -290,6 +290,10 @@ print_entries (grub_menu_t menu, const struct menu_viewer_data *data) + e, data); + if (e) + e = e->next; ++ ++ /* Skip hidden entries */ ++ while (e && e->hidden) ++ e = e->next; + } + + grub_term_gotoxy (data->term, +diff --git a/include/grub/menu.h b/include/grub/menu.h +index ee2b5e9..eb8a86b 100644 +--- a/include/grub/menu.h ++++ b/include/grub/menu.h +@@ -58,6 +58,8 @@ struct grub_menu_entry + + int submenu; + ++ int hidden; ++ + /* The next element. */ + struct grub_menu_entry *next; + }; +diff --git a/include/grub/normal.h b/include/grub/normal.h +index 218cbab..bcb4124 100644 +--- a/include/grub/normal.h ++++ b/include/grub/normal.h +@@ -145,7 +145,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, + const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, +- int submenu); ++ int submenu, int hidden); + + grub_err_t + grub_normal_set_password (const char *user, const char *password); diff --git a/grub2-SUSE-Add-the-t-hotkey.patch b/grub2-SUSE-Add-the-t-hotkey.patch new file mode 100644 index 0000000..2e84634 --- /dev/null +++ b/grub2-SUSE-Add-the-t-hotkey.patch @@ -0,0 +1,68 @@ +From f6be3d41e24e685846dfc90ac1ca447501813687 Mon Sep 17 00:00:00 2001 +From: Alexander Graf +Date: Tue, 26 Apr 2016 15:59:03 +0200 +Subject: [PATCH] SUSE: Add the "t" hotkey + +While graphical output is fancy and nice, in some environments (EFI) we can +only have fancy graphical on frame buffer _or_ ugly serial on any output. + +To give the user a nicely graphical screen in the default case, but still +allow them to get their boot menu on the serial console, let's add a new +hidden option "t" that switches the output device back to the firmware default. + +Signed-off-by: Alexander Graf + +--- + +v1 -> v2 + + - use hiddenentry instead of --hidden + +diff --git a/Makefile.util.def b/Makefile.util.def +index f9caccb..d94de92 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -504,6 +504,12 @@ script = { + installdir = grubconf; + }; + ++script = { ++ name = '95_textmode'; ++ common = util/grub.d/95_textmode.in; ++ installdir = grubconf; ++}; ++ + program = { + mansection = 1; + name = grub-mkrescue; +diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in +index 93a9023..b6ec7e2 100644 +--- a/util/grub.d/00_header.in ++++ b/util/grub.d/00_header.in +@@ -184,6 +184,9 @@ EOF + fi + fi + ++ if [ -d /sys/firmware/efi ]; then ++ echo 'echo "Please press 't' to show the boot menu on this console"' ++ fi + cat << EOF + set gfxmode=${GRUB_GFXMODE} + load_video +diff --git a/util/grub.d/95_textmode.in b/util/grub.d/95_textmode.in +new file mode 100644 +index 0000000..fa48cf9 +--- /dev/null ++++ b/util/grub.d/95_textmode.in +@@ -0,0 +1,11 @@ ++#!/bin/sh ++ ++if [ -d /sys/firmware/efi ]; then ++ echo " ++ # On EFI systems we can only have graphics *or* serial, so allow the user ++ # to switch between the two ++ hiddenentry 'Text mode' --hotkey 't' { ++ set textmode=true ++ terminal_output console ++ }" ++fi diff --git a/grub2.changes b/grub2.changes index 4fad15d..8537714 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Apr 28 09:06:11 UTC 2016 - agraf@suse.com + +- Add support for "t" hotkey to switch to text mode (bsc#976836) + * added grub2-SUSE-Add-the-t-hotkey.patch +- Add support for hidden menu entries (bsc#976836) + * added grub2-Add-hidden-menu-entries.patch + ------------------------------------------------------------------- Tue Apr 19 08:21:24 UTC 2016 - mchang@suse.com diff --git a/grub2.spec b/grub2.spec index b32a135..64d4523 100644 --- a/grub2.spec +++ b/grub2.spec @@ -203,6 +203,9 @@ Patch122: grub2-efi-xen-cmdline.patch # 32bit ARM EFI FDT table pass-through support Patch130: 0001-arm64-Move-firmware-fdt-search-into-global-function.patch Patch131: 0002-arm-efi-Use-fdt-from-firmware-when-available.patch +# Hidden menu entry and hotkey "t" for text console +Patch140: grub2-Add-hidden-menu-entries.patch +Patch141: grub2-SUSE-Add-the-t-hotkey.patch # PPC64 LE support Patch205: grub2-ppc64le-disable-video.patch Patch207: grub2-ppc64le-memory-map.patch @@ -424,6 +427,8 @@ mv po/grub.pot po/%{name}.pot %patch122 -p1 %patch130 -p1 %patch131 -p1 +%patch140 -p1 +%patch141 -p1 %patch205 -p1 %patch207 -p1 %patch233 -p1 @@ -841,6 +846,7 @@ fi %config %{_sysconfdir}/grub.d/40_custom %config %{_sysconfdir}/grub.d/41_custom %config %{_sysconfdir}/grub.d/90_persistent +%config %{_sysconfdir}/grub.d/95_textmode %{_sbindir}/%{name}-install %{_sbindir}/%{name}-mkconfig %{_sbindir}/%{name}-once