* 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.