All of lore.kernel.org
 help / color / mirror / Atom feed
* PATCH: Add QEMU BIOS menu for choosing boot device
@ 2007-12-21 22:31 Daniel P. Berrange
  0 siblings, 0 replies; 2+ messages in thread
From: Daniel P. Berrange @ 2007-12-21 22:31 UTC (permalink / raw)
  To: xen-devel; +Cc: Jeremy Katz

[-- Attachment #1: Type: text/plain, Size: 1115 bytes --]

The attached patch implements a mini BIOS menu for choosing a non-default
boot device. When a guest starts it'll display 

   'Press F10 to select boot device'

And wait 3 seconds, before continuing with the normal boot device. If they
press the F10 key, a menu is shown allowing a choice between floppy,
harddisk, cdrom and network (PXE).

I can't take credit for this originally - Jeremy Katz wrote it for KVM,
I merely re-diffed the patch to work against Xen's QEMU/BIOS code tree.
It has been tested in Fedora successfully against 3.1.x and 3.2.x

   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
   CC: Jeremy Katz <katzj@redhat.com>


 rombios.c |  226 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 225 insertions(+), 1 deletion(-)


Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 

[-- Attachment #2: xen-qemu-bootmenu.patch --]
[-- Type: text/plain, Size: 5829 bytes --]

diff -rup xen-3.1.0-src.orig/tools/firmware/rombios/rombios.c xen-3.1.0-src.new/tools/firmware/rombios/rombios.c
--- xen-3.1.0-src.orig/tools/firmware/rombios/rombios.c	2007-05-18 10:45:21.000000000 -0400
+++ xen-3.1.0-src.new/tools/firmware/rombios/rombios.c	2007-10-10 19:34:24.000000000 -0400
@@ -2026,6 +2026,228 @@ print_cdromboot_failure( code )
   return;
 }
 
+#define WAIT_HZ 18
+/**
+ * Check for keystroke.
+ * @returns    True if keystroke available, False if not.
+ */
+Bit8u check_for_keystroke()
+{
+ASM_START
+    mov  ax, #0x100
+    int  #0x16
+    jz   no_key
+    mov  al, #1
+    jmp  done
+no_key:
+    xor  al, al
+done:
+ASM_END
+}
+
+/**
+ * Get keystroke.
+ * @returns    BIOS scan code.
+ */
+Bit8u get_keystroke()
+{
+ASM_START
+    mov  ax, #0x0
+    int  #0x16
+    xchg ah, al
+ASM_END
+}
+
+/**
+ * Waits (sleeps) for the given number of ticks.
+ * Checks for keystroke.
+ *
+ * @returns BIOS scan code if available, 0 if not.
+ * @param   ticks       Number of ticks to sleep.
+ * @param   stop_on_key Whether to stop immediately upon keypress.
+ */
+Bit8u wait(ticks, stop_on_key)
+  Bit16u ticks;
+  Bit8u stop_on_key;
+{
+    long ticks_to_wait, delta;
+    Bit32u prev_ticks, t;
+    Bit8u scan_code = 0;
+
+    /*
+     * The 0:046c wraps around at 'midnight' according to a 18.2Hz clock.
+     * We also have to be careful about interrupt storms.
+     */
+    ticks_to_wait = ticks;
+    prev_ticks = read_dword(0x0, 0x46c);
+    do
+    {
+        t = read_dword(0x0, 0x46c);
+        if (t > prev_ticks)
+        {
+            delta = t - prev_ticks;     /* The temp var is required or bcc screws up. */
+            ticks_to_wait -= delta;
+        }
+        else if (t < prev_ticks)
+            ticks_to_wait -= t;         /* wrapped */
+        prev_ticks = t;
+
+        if (check_for_keystroke())
+        {
+            scan_code = get_keystroke();
+            bios_printf(BIOS_PRINTF_DEBUG, "Key pressed: %x\n", scan_code);
+            if (stop_on_key)
+                return scan_code;
+        }
+    } while (ticks_to_wait > 0);
+    return scan_code;
+}
+
+static void clearscreen() {
+    /* Hide cursor, clear screen and move cursor to starting position */
+ASM_START
+        push bx
+        push cx
+        push dx
+
+        mov  ax, #0x100
+        mov  cx, #0x1000
+        int  #0x10
+
+        mov  ax, #0x700
+        mov  bh, #7
+        xor  cx, cx
+        mov  dx, #0x184f
+        int  #0x10
+
+        mov  ax, #0x200
+        xor  bx, bx
+        xor  dx, dx
+        int  #0x10
+
+        pop  dx
+        pop  cx
+        pop  bx
+ASM_END
+}
+
+int bootmenu(selected)
+  int selected;
+{
+    Bit8u scode;
+    int max;
+
+    /* get the number of boot devices */
+    max = read_word(IPL_SEG, IPL_COUNT_OFFSET);
+
+    for(;;) {
+        clearscreen();
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\n\n\n\n\n\n");
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "          Select boot device\n\n");
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "            1. Floppy\n");
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "            2. Hard drive\n");
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "            3. CD-ROM\n");
+        if (max == 4)
+            bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "            4. Network\n");
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\n          Currently selected: %d\n", selected);
+
+        do {
+            scode = wait(WAIT_HZ, 1);
+        } while (scode == 0);
+        switch(scode) {
+        case 0x02:
+        case 0x03:
+        case 0x04:
+            selected = scode - 1;
+            break;
+        case 0x05:
+            if (max == 4)
+                selected = scode -1 ;
+            else
+                scode = 0;
+            break;
+        case 0x48:
+            selected -= 1;
+            if (selected < 1)
+                selected = 1;
+            scode = 0;
+            break;
+        case 0x50:
+            selected += 1;
+            if (selected > max)
+                selected = max;
+            scode = 0;
+            break;
+        case 0x1c:
+            break;
+        default:
+            scode = 0;
+            break;
+        }
+        if (scode != 0)
+            break;
+    }
+
+    switch (selected) {
+    case 1:
+        return 0x3D;
+    case 2:
+        return 0x3E;
+    case 3:
+        return 0x3F;
+    case 4:
+        return 0x58;
+    default:
+        return 0;
+    }
+}
+
+void interactive_bootkey()
+{
+    Bit16u i;
+    Bit8u scan = 0;
+
+    bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\nPress F10 to select boot device.\n");
+    for (i = 3; i > 0; i--)
+    {
+        scan = wait(WAIT_HZ, 0);
+        switch (scan) {
+        case 0x3D:
+        case 0x3E:
+        case 0x3F:
+        case 0x58:
+            break;
+        case 0x44:
+            scan = bootmenu(inb_cmos(0x3d));
+            break;
+        default:
+            scan = 0;
+            break;
+        }
+        if (scan != 0)
+            break;
+    }
+
+    /* set the default based on the keypress or menu */
+    switch(scan) {
+    case 0x3D:
+        outb_cmos(0x3d, 0x01);
+        break;
+    case 0x3E:
+        outb_cmos(0x3d, 0x02);
+        break;
+    case 0x3F:
+        outb_cmos(0x3d, 0x03);
+        break;
+    case 0x58:
+        outb_cmos(0x3d, 0x04);
+        break;
+    default:
+        break;
+    }
+}
+
+
 void
 nmi_handler_msg()
 {
@@ -9782,7 +10004,9 @@ post_default_ints:
   call _cdemu_init
   ;;
 #endif // BX_ELTORITO_BOOT
- 
+
+  call _interactive_bootkey
+
 #if BX_TCGBIOS
   call _tcpa_calling_int19h          /* specs: 8.2.3 step 1 */
   call _tcpa_add_event_separators    /* specs: 8.2.3 step 2 */

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: PATCH: Add QEMU BIOS menu for choosing boot device
       [not found] <DD74FBB8EE28D441903D56487861CD9D25CA8EF5@lonpexch01.citrite.net>
@ 2008-01-02 15:22 ` Stefano Stabellini
  0 siblings, 0 replies; 2+ messages in thread
From: Stefano Stabellini @ 2008-01-02 15:22 UTC (permalink / raw)
  To: Xen-devel; +Cc: katzj, keir.fraser, berrange

[-- Attachment #1: Type: text/plain, Size: 1008 bytes --]

If more than one boot device has been selected, the currently selected
number displayed in the menu is wrong.
The tiny patch I am attaching makes sure that only the first boot device
is considered.
The patch has to be applied on top of the original patch.

Signed-off-by: Stefano Stabellini <stefano.stabellini@citrix.com>

> The attached patch implements a mini BIOS menu for choosing a
> non-default boot device. When a guest starts it'll display 
> 
>    'Press F10 to select boot device'
> 
> And wait 3 seconds, before continuing with the normal boot device. If
> they press the F10 key, a menu is shown allowing a choice between
> floppy, harddisk, cdrom and network (PXE).
> 
> I can't take credit for this originally - Jeremy Katz wrote it for KVM,
> I merely re-diffed the patch to work against Xen's QEMU/BIOS code tree.
> It has been tested in Fedora successfully against 3.1.x and 3.2.x
> 
>    Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
>    CC: Jeremy Katz <katzj@redhat.com>
> 



[-- Attachment #2: xen-qemu-bootmenu-fix.patch --]
[-- Type: text/x-patch, Size: 833 bytes --]

diff -r 4b278d3fc565 tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c	Wed Jan 02 15:06:13 2008 +0000
+++ b/tools/firmware/rombios/rombios.c	Wed Jan 02 15:07:22 2008 +0000
@@ -2146,6 +2146,7 @@ int bootmenu(selected)
     max = read_word(IPL_SEG, IPL_COUNT_OFFSET);
 
     for(;;) {
+        if (selected > max || selected < 1) selected = 1;
         clearscreen();
         bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\n\n\n\n\n\n");
         bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "          Select boot device\n\n");
@@ -2223,7 +2224,7 @@ void interactive_bootkey()
         case 0x58:
             break;
         case 0x44:
-            scan = bootmenu(inb_cmos(0x3d));
+            scan = bootmenu(inb_cmos(0x3d) & 0x0f);
             break;
         default:
             scan = 0;

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-01-02 15:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-21 22:31 PATCH: Add QEMU BIOS menu for choosing boot device Daniel P. Berrange
     [not found] <DD74FBB8EE28D441903D56487861CD9D25CA8EF5@lonpexch01.citrite.net>
2008-01-02 15:22 ` Stefano Stabellini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.