[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