[SeaBIOS] [PATCH v2] boot: add serial-friendly alternatives for invoking the boot menu
Paolo Bonzini
pbonzini at redhat.com
Wed Mar 11 14:57:20 CET 2015
On 05/03/2015 10:27, Paolo Bonzini wrote:
> F11 and F12 are trapped by some terminal emulators, and sgabios does
> not always recognize function keys very well.
>
> Real-world machines often provide replacements for function keys for
> use on the serial console: ESC+1...ESC+0 for F1...F10, ESC+SHIFT+1 and
> ESC+SHIFT+2 for F11...F12. Accept all of them, which can be useful in
> case the user has set boot-menu-key.
>
> The behavior is disabled if ESC is configured to trigger the menu.
> Chromebooks use this configuration.
>
> Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
>
> ---
> v1->v2: disable new behavior if ESC triggers the boot menu [Kevin]
> ---
> src/boot.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 47 insertions(+), 5 deletions(-)
>
> diff --git a/src/boot.c b/src/boot.c
> index f23e9e1..0572ff1 100644
> --- a/src/boot.c
> +++ b/src/boot.c
> @@ -422,7 +422,21 @@ get_raw_keystroke(void)
> memset(&br, 0, sizeof(br));
> br.flags = F_IF;
> call16_int(0x16, &br);
> - return br.ah;
> + return br.ax;
> +}
> +
> +// Read a keystroke - waiting up to 'msec' milliseconds.
> +static int
> +get_keystroke_ascii(int msec)
> +{
> + u32 end = irqtimer_calc(msec);
> + for (;;) {
> + if (check_for_keystroke())
> + return get_raw_keystroke() & 255;
> + if (irqtimer_check(end))
> + return -1;
> + yield_toirq();
> + }
> }
>
> // Read a keystroke - waiting up to 'msec' milliseconds.
> @@ -432,7 +446,7 @@ get_keystroke(int msec)
> u32 end = irqtimer_calc(msec);
> for (;;) {
> if (check_for_keystroke())
> - return get_raw_keystroke();
> + return get_raw_keystroke() >> 8;
> if (irqtimer_check(end))
> return -1;
> yield_toirq();
> @@ -446,6 +460,35 @@ get_keystroke(int msec)
>
> #define DEFAULT_BOOTMENU_WAIT 2500
>
> +static int
> +get_bootmenu_keystroke(bool esc_sequence)
> +{
> + u32 menutime = romfile_loadint("etc/boot-menu-wait", DEFAULT_BOOTMENU_WAIT);
> + int scan_code = get_keystroke(menutime);
> + if (esc_sequence && scan_code == 0x01) {
> + while (get_keystroke(0) >= 0)
> + ;
> + int ascii = get_keystroke_ascii(menutime * 2);
> + switch (ascii) {
> + case '1' ... '9':
> + scan_code = 0x3a + ascii - '0';
> + break;
> + case '0':
> + scan_code = 0x3a + 10;
> + break;
> + case '!':
> + scan_code = 0x85;
> + break;
> + case '@':
> + scan_code = 0x86;
> + break;
> + default:
> + break;
> + }
> + }
> + return scan_code;
> +}
> +
> // Show IPL option menu.
> void
> interactive_bootmenu(void)
> @@ -460,12 +503,11 @@ interactive_bootmenu(void)
>
> char *bootmsg = romfile_loadfile("etc/boot-menu-message", NULL);
> int menukey = romfile_loadint("etc/boot-menu-key", 0x86);
> - printf("%s", bootmsg ?: "\nPress F12 for boot menu.\n\n");
> + printf("%s", bootmsg ?: "\nPress ESC+@ or F12 for boot menu.\n\n");
> free(bootmsg);
>
> - u32 menutime = romfile_loadint("etc/boot-menu-wait", DEFAULT_BOOTMENU_WAIT);
> enable_bootsplash();
> - int scan_code = get_keystroke(menutime);
> + int scan_code = get_bootmenu_keystroke(menukey != 1);
> disable_bootsplash();
> if (scan_code != menukey)
> return;
>
Ping?
paolo
More information about the SeaBIOS
mailing list