[SeaBIOS] [PATCH] boot: boot menu up to 35 devices with letters and possible pages

Ivan Ivanov qmastery16 at gmail.com
Sat Jun 10 23:44:43 CEST 2017


Extend boot menu: make it possible to select the boot menu entries
with ID larger than 10 by pressing a corresponding letter key. If
there are more than 18 devices, then a boot menu splits into two
pages; you can switch between the pages by pressing the ENTER key.
NOTE: now to access the TPM you need to press the M key. It makes more
sense, because Trusted is adjective while Module is noun - and adds
more convenience, because M letter is at the end of keyboard's 3rd row
of letters, not in the middle of them

Signed-off-by: Ivan Ivanov <qmastery16 at gmail.com>
---
diff --git a/src/boot.c b/src/boot.c
index 59623fb..fa2a0fe 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -447,6 +447,7 @@ get_keystroke(int msec)
  ****************************************************************/

 #define DEFAULT_BOOTMENU_WAIT 2500
+#define DEFAULT_BOOTMENU_PAGE_SIZE 18

 // Show IPL option menu.
 void
@@ -475,20 +476,37 @@ interactive_bootmenu(void)
     while (get_keystroke(0) >= 0)
         ;

-    printf("Select boot device:\n\n");
+    printf("Select boot device");
     wait_threads();

-    // Show menu items
+    // Show menu items after counting them and determining a number of pages
+
     int maxmenu = 0;
     struct bootentry_s *pos;
+    hlist_for_each_entry(pos, &BootList, node)
+        maxmenu++;
+
+    if (maxmenu > DEFAULT_BOOTMENU_PAGE_SIZE)
+        printf(" - page 1 :     // press ENTER "
+               "to switch between the pages...\n\n");
+    else
+        printf(":\n\n");
+
+    char keyboard_keys[35] = {'1','2','3','4','5','6','7','8','9','0',
+                               'q','w','e','r','t','y','u','i','o','p',
+                                'a','s','d','f','g','h','j','k','l',
+                                 'z','x','c','v','b','n'}; /* m = TPM */
+    int entry_id = 0;
     hlist_for_each_entry(pos, &BootList, node) {
         char desc[77];
-        maxmenu++;
-        printf("%d. %s\n", maxmenu
+        if (entry_id == DEFAULT_BOOTMENU_PAGE_SIZE) // show only the first page
+            break;
+        printf("%c. %s\n", keyboard_keys[entry_id]
                , strtcpy(desc, pos->description, ARRAY_SIZE(desc)));
+        entry_id++;
     }
     if (tpm_can_show_menu()) {
-        printf("\nt. TPM Configuration\n");
+        printf("\nm. TPM Configuration\n");
     }

     // Get key press.  If the menu key is ESC, do not restart boot unless
@@ -496,16 +514,65 @@ interactive_bootmenu(void)
     // repeatedly hitting keys to enter the BIOS) will end up hitting ESC
     // multiple times and immediately booting the primary boot device.
     int esc_accepted_time = irqtimer_calc(menukey == 1 ? 1500 : 0);
+    int choice;
+    int page_number = 1;
     for (;;) {
         scan_code = get_keystroke(1000);
         if (scan_code == 1 && !irqtimer_check(esc_accepted_time))
             continue;
-        if (tpm_can_show_menu() && scan_code == 20 /* t */) {
+        if (scan_code == 1)
+            break;
+        if (scan_code == 50 && tpm_can_show_menu()) { // 50 scan code = m = TPM
             printf("\n");
             tpm_menu();
         }
-        if (scan_code >= 1 && scan_code <= maxmenu+1)
+        /* 4 rows of keyboard_keys: 1 row with numbers, 3 rows with letters.
+           Use any of them to select boot device (except the M letter = TPM) */
+        choice = 0;
+        // 1st range: 1-9 and 0 (10) keys <==> 2-11 scan codes <==>
1-10 choice
+        if (scan_code >=  2 && scan_code <= 11) choice = scan_code -  1;
+        // 2nd range: Q-P row of letters <==> 16-25 scan codes <==>
11-20 choice
+        if (scan_code >= 16 && scan_code <= 25) choice = scan_code -  5;
+        // 3rd range: A-L row of letters <==> 30-38 scan codes <==>
21-29 choice
+        if (scan_code >= 30 && scan_code <= 38) choice = scan_code -  9;
+        // 4th range: Z-N row of letters <==> 44-49 scan codes <==>
30-35 choice
+        if (scan_code >= 44 && scan_code <= 49) choice = scan_code - 14;
+
+        // After you choose any of detected boot devices, lets start booting
+        if (choice > 0 && choice <= maxmenu)
             break;
+
+        // If the ENTER key has been pressed and there are 2 pages, switch them
+        if (scan_code == 28 && maxmenu > DEFAULT_BOOTMENU_PAGE_SIZE) {
+            entry_id = 0;
+            page_number = 3 - page_number; // 3 - 1 = 2 ; 3 - 2 = 1
+            printf("\n\nSelect boot device - page %d :     // press ENTER "
+                   "to switch between the pages...\n\n", page_number);
+            if (page_number == 1) {  // print the 1st page
+                hlist_for_each_entry(pos, &BootList, node) {
+                    char desc[77];
+                    if (entry_id == DEFAULT_BOOTMENU_PAGE_SIZE)
+                        break;
+                    printf("%c. %s\n", keyboard_keys[entry_id]
+                           , strtcpy(desc, pos->description,
ARRAY_SIZE(desc)));
+                    entry_id++;
+                }
+            }
+            else {  // print the 2nd page
+                hlist_for_each_entry(pos, &BootList, node) {
+                    char desc[77];
+                    if (entry_id == 35)
+                        break;
+                    if (entry_id >= DEFAULT_BOOTMENU_PAGE_SIZE)
+                        printf("%c. %s\n", keyboard_keys[entry_id]
+                           , strtcpy(desc, pos->description,
ARRAY_SIZE(desc)));
+                    entry_id++;
+                }
+            }
+            if (tpm_can_show_menu()) {
+                printf("\nm. TPM Configuration\n");
+            }
+        }
     }
     printf("\n");
     if (scan_code == 0x01)
@@ -513,7 +580,6 @@ interactive_bootmenu(void)
         return;

     // Find entry and make top priority.
-    int choice = scan_code - 1;
     hlist_for_each_entry(pos, &BootList, node) {
         if (! --choice)
             break;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: long_boot_menu_with_letters_and_pages.patch
Type: text/x-patch
Size: 5324 bytes
Desc: not available
URL: <http://mail.coreboot.org/pipermail/seabios/attachments/20170611/00d25300/attachment.patch>


More information about the SeaBIOS mailing list