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;