grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] hold shift or control to disable timeout even timeout=0


From: David Fries
Subject: [PATCH] hold shift or control to disable timeout even timeout=0
Date: Wed, 23 Jul 2008 19:52:59 -0500
User-agent: Mutt/1.5.4i

There are various projects trying to speed up booting a computer.
Here is a patch designed to do just that.  grub by default waits a few
seconds to give the user the chance to interact with the menu or
command line.  Currently for a fast bootup a timeout of zero can be
specified, but then you loose any chance at interacting with grub.  It
would be better to have a zero timeout delay, and yet be able to
interact when needed.

While booting, BIOS reads and tracks the status of key presses.  At
grub boot time it can be queried to find out if control or shift are
held, even if they were pressed before grub started executing.  This
patch will disable the timeout if shift or control are held to allow
interaction if desired, and if not timeout=0 will allow boot to
proceed without a timeout delay.

This calls the getshiftflags BIOS int 16h function 2 in startup.S, to
find out the status of the shift and control keys (among others).  The
required header and source files were modified to expose
grub_getshiftflags.  menu.c checks grub_getshiftflags and will disable
the timeout.


Index: kern/term.c
===================================================================
--- kern/term.c (revision 1702)
+++ kern/term.c (working copy)
@@ -186,6 +186,14 @@
   return (grub_cur_term->checkkey) ();
 }
 
+int
+grub_getshiftflags (void)
+{
+  if (!grub_cur_term->getshiftflags)
+    return 0;
+  return (grub_cur_term->getshiftflags) ();
+}
+
 grub_uint16_t
 grub_getxy (void)
 {
Index: kern/i386/pc/startup.S
===================================================================
--- kern/i386/pc/startup.S      (revision 1702)
+++ kern/i386/pc/startup.S      (working copy)
@@ -1333,7 +1333,36 @@
        popl    %ebp
        ret
 
+
+/*
+ * int grub_console_getshiftflags (void)
+ *     Get the currently held modifier keys and flags, 0 none held.
+ * BIOS call "INT 16H Function 02H" get shift flags
+ *     Call with       %ah = 0x2
+ *     Return:         %ah = "AH destroyed by many BIOSes"
+ *                     %al = shift flags
+ *     See include/grub/term.h GRUB_THERM_* for flag values.
+ */
+FUNCTION(grub_console_getshiftflags)
+       pushl   %ebp
+       xorl    %edx, %edx      /* zero */
        
+       call    prot_to_real    /* enter real mode */
+       .code16
+
+       movb    $0x2, %ah
+       int     $0x16
+
+       movb    %al, %dl        /* Only 8 bits are kept */
+
+       DATA32  call    real_to_prot
+       .code32
+
+       movl    %edx, %eax      /* flags in %eax for return */
+       popl    %ebp
+       ret
+
+
 /*
  * grub_uint16_t grub_console_getxy (void)
  * BIOS call "INT 10H Function 03h" to get cursor position
Index: include/grub/term.h
===================================================================
--- include/grub/term.h (revision 1702)
+++ include/grub/term.h (working copy)
@@ -33,6 +33,16 @@
 #define GRUB_TERM_TAB          '\t'
 #define GRUB_TERM_BACKSPACE    '\b'
 
+/* Bit values for keys helpd by grub_getshiftflags (). */
+#define GRUB_TERM_RSHIFT_DOWN          0x01
+#define GRUB_TERM_LSHIFT_DOWN          0x02
+#define GRUB_TERM_CTRL_DOWN            0x04
+#define GRUB_TERM_ALT_DOWN             0x08
+#define GRUB_TERM_SCROLLLOCK_DOWN      0x10
+#define GRUB_TERM_NUMLOCK_DOWN         0x20
+#define GRUB_TERM_CAPSLOCK_DOWN                0x40
+#define GRUB_TERM_INSERT_ACTIVE                0x80
+
 #ifndef ASM_FILE
 
 #include <grub/err.h>
@@ -155,11 +165,16 @@
      encoded in Unicode.  */
   grub_ssize_t (*getcharwidth) (grub_uint32_t c);
   
-  /* Check if any input character is available.  */
+  /* Check if any input character is available.  -1 if a key is not available,
+   * otherwise the key value (which is not removed).
+   */
   int (*checkkey) (void);
   
-  /* Get a character.  */
+  /* Get a character blocking if necessary.  */
   int (*getkey) (void);
+
+  /* Get the currently held modifier keys and flags, 0 none held. */
+  int (*getshiftflags) (void);
   
   /* Get the screen size. The return value is ((Width << 8) | Height).  */
   grub_uint16_t (*getwh) (void);
@@ -210,6 +225,7 @@
 grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code);
 int EXPORT_FUNC(grub_getkey) (void);
 int EXPORT_FUNC(grub_checkkey) (void);
+int EXPORT_FUNC(grub_getshiftflags) (void);
 grub_uint16_t EXPORT_FUNC(grub_getwh) (void);
 grub_uint16_t EXPORT_FUNC(grub_getxy) (void);
 void EXPORT_FUNC(grub_gotoxy) (grub_uint8_t x, grub_uint8_t y);
Index: include/grub/i386/pc/console.h
===================================================================
--- include/grub/i386/pc/console.h      (revision 1702)
+++ include/grub/i386/pc/console.h      (working copy)
@@ -42,6 +42,7 @@
 void grub_console_real_putchar (int c);
 int EXPORT_FUNC(grub_console_checkkey) (void);
 int EXPORT_FUNC(grub_console_getkey) (void);
+int EXPORT_FUNC(grub_console_getshiftflags) (void);
 grub_uint16_t grub_console_getxy (void);
 void grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y);
 void grub_console_cls (void);
Index: ChangeLog
===================================================================
--- ChangeLog   (revision 1725)
+++ ChangeLog   (working copy)
@@ -1,3 +1,18 @@
+2008-07-23  David Fries <address@hidden>
+
+       Allow holding control or shift to abort timeout, even timeout=0.  This
+       allows no timeout delay and still be interactive.
+
+       * kern/term.c: add function grub_getshiftflags
+       * kern/i386/pc/startup.S: add grub_console_getshiftflags
+       * include/grub/term.h: add flag #defines, add getshiftflags function
+       pointer, export grub_getshiftflags
+       * include/grub/i386/pc/console.h: prototype for
+       grub_console_getshiftflags
+       * normal/menu.c(run_menu): check for shift or control and abort
+       timeout
+       * term/i386/pc/console.c: set .getshiftflags
+
 2008-07-23  Robert Millan  <address@hidden>
 
        * Makefile.in (UNICODE_ARROWS, UNICODE_LINES): New variables (they
Index: normal/menu.c
===================================================================
--- normal/menu.c       (revision 1702)
+++ normal/menu.c       (working copy)
@@ -339,6 +339,15 @@
   if (default_entry < 0 || default_entry >= menu->size)
     default_entry = 0;
 
+  /* If shift or control are held when menu starts, abort the timeout.
+     This was added to allow a timeout of 0 to speed the boot time, and
+     still allow access to the grub menu if desired. */
+  if (grub_getshiftflags () &
+      (GRUB_TERM_RSHIFT_DOWN | GRUB_TERM_LSHIFT_DOWN | GRUB_TERM_CTRL_DOWN))
+    {
+      grub_env_unset ("timeout");
+    }
+
   /* If timeout is 0, drawing is pointless (and ugly).  */
   if (get_timeout () == 0)
     return default_entry;
Index: term/i386/pc/console.c
===================================================================
--- term/i386/pc/console.c      (revision 1702)
+++ term/i386/pc/console.c      (working copy)
@@ -134,6 +134,7 @@
     .getcharwidth = grub_console_getcharwidth,
     .checkkey = grub_console_checkkey,
     .getkey = grub_console_getkey,
+    .getshiftflags = grub_console_getshiftflags,
     .getwh = grub_console_getwh,
     .getxy = grub_console_getxy,
     .gotoxy = grub_console_gotoxy,

-- 
David Fries <address@hidden>
http://fries.net/~david/ (PGP encryption key available)

Attachment: pgpDTEKPDoTQY.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]