This patch adds Qemu firmware configuration device interface to display a splash image at BIOS startup.
Idea and some parts of code are stollen from VirtualBox. Signed-off-by: Laurent Vivier <[email protected]> --- bios/Makefile | 4 +- bios/logo.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bios/logo.h | 56 +++++++++++++++ bios/rombios.c | 125 +++++++++++++++++++++------------- 4 files changed, 340 insertions(+), 51 deletions(-) create mode 100644 bios/logo.c create mode 100644 bios/logo.h diff --git a/bios/Makefile b/bios/Makefile index a2759a9..d30be7d 100644 --- a/bios/Makefile +++ b/bios/Makefile @@ -79,7 +79,7 @@ dist-clean: clean bios-clean: rm -f BIOS-bochs-* -BIOS-bochs-legacy: rombios.c apmbios.S biossums rombios.h +BIOS-bochs-legacy: rombios.c apmbios.S biossums rombios.h logo.c logo.h $(GCC) $(BIOS_BUILD_DATE) -DLEGACY -E -P $< > _rombiosl_.c $(BCC) -o rombiosl.s -C-c -D__i86__ -0 -S _rombiosl_.c sed -e 's/^\.text//' -e 's/^\.data//' rombiosl.s > _rombiosl_.s @@ -90,7 +90,7 @@ BIOS-bochs-legacy: rombios.c apmbios.S biossums rombios.h rm -f _rombiosl_.s -rombios16.bin: rombios.c apmbios.S biossums rombios.h +rombios16.bin: rombios.c apmbios.S biossums rombios.h logo.c logo.h $(GCC) $(BIOS_BUILD_DATE) -E -P $< > _rombios_.c $(BCC) -o rombios.s -C-c -D__i86__ -0 -S _rombios_.c sed -e 's/^\.text//' -e 's/^\.data//' rombios.s > _rombios_.s diff --git a/bios/logo.c b/bios/logo.c new file mode 100644 index 0000000..d41eb10 --- /dev/null +++ b/bios/logo.c @@ -0,0 +1,206 @@ +/** + * Stuff for drawing the BIOS logo. + */ + +/* + * Copyright (C) 2004-2008 Sun Microsystems, Inc. + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa + * Clara, CA 95054 USA or visit http://www.sun.com if you need + * additional information or have any questions. + * + * QEMU/KVM port by Laurent Vivier <[email protected]> + * + */ + +#include "logo.h" + +#define BIOS_CFG_IOPORT 0x510 +#define BIOS_CFG_SIGNATURE 0x0000 +#define BIOS_CFG_SPLASH 0x4007 + +#define WAIT_MS 16 + +/** + * Set video mode (VGA). + * @params New video mode. + */ +void set_mode(mode) + Bit8u mode; + { + ASM_START + push bp + mov bp, sp + + push ax + + mov ah, #0 + mov al, 4[bp] ; mode + int #0x10 + + pop ax + + pop bp + ASM_END + } + +Bit8u read_logo_byte(offset) + Bit8u offset; +{ + outw(BIOS_CFG_IOPORT, BIOS_CFG_SPLASH); + outb(BIOS_CFG_IOPORT + 1, LOGO_CMD_SET_OFFSET); + outb(BIOS_CFG_IOPORT + 1, offset); + return inb(BIOS_CFG_IOPORT + 1); +} + +Bit16u read_logo_word(offset) + Bit8u offset; +{ + Bit16u word; + outw(BIOS_CFG_IOPORT, BIOS_CFG_SPLASH); + outb(BIOS_CFG_IOPORT + 1, LOGO_CMD_SET_OFFSET); + outb(BIOS_CFG_IOPORT + 1, offset); + word = inb(BIOS_CFG_IOPORT + 1); + word = (inb(BIOS_CFG_IOPORT + 1) << 8) | word; + return word; +} + +void clear_screen() +{ +// 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 +} + +Bit8u +logo_enabled() +{ + LOGOHDR *logo_hdr = 0; + Bit8u is_fade_in, is_fade_out, uBootMenu; + Bit16u logo_time; + + /* check QEMU signature */ + + outw(BIOS_CFG_IOPORT, BIOS_CFG_SIGNATURE); + if (inb(BIOS_CFG_IOPORT + 1) != 'Q') + return 0; + if (inb(BIOS_CFG_IOPORT + 1) != 'E') + return 0; + if (inb(BIOS_CFG_IOPORT + 1) != 'M') + return 0; + if (inb(BIOS_CFG_IOPORT + 1) != 'U') + return 0; + + /* check splash signature */ + + if (read_logo_word(&logo_hdr->u16Signature) != LOGO_HDR_MAGIC) + return 0; + + /* Get options */ + + is_fade_in = read_logo_byte(&logo_hdr->fu8FadeIn); + is_fade_out = read_logo_byte(&logo_hdr->fu8FadeOut); + logo_time = read_logo_word(&logo_hdr->u16LogoMillies); + + return (is_fade_in || is_fade_out || logo_time); +} + +void logo_show() +{ + LOGOHDR *logo_hdr = 0; + Bit8u is_fade_in; + Bit16u i; + + set_mode(0x12); /* 640x480 */ + + is_fade_in = read_logo_byte(&logo_hdr->fu8FadeIn); + + outw(BIOS_CFG_IOPORT, BIOS_CFG_SPLASH); + if (is_fade_in) + { + for (i = 0; i < LOGO_SHOW_STEPS; i++) + { + if (i != 0) { /* 0 means "unload image from memory" */ + outb(BIOS_CFG_IOPORT + 1, LOGO_CMD_SHOW_BMP); + outb(BIOS_CFG_IOPORT + 1, i); + } + delay_ticks_and_check_for_keystroke(16 / WAIT_MS, 1); + if (check_for_keystroke()) + break; + } + } + outb(BIOS_CFG_IOPORT + 1, LOGO_CMD_SHOW_BMP); + outb(BIOS_CFG_IOPORT + 1, LOGO_SHOW_STEPS); + + return; +} + +void logo_hide() +{ + LOGOHDR *logo_hdr = 0; + Bit8u is_fade_out; + Bit16u i; + + if (check_for_keystroke()) + goto hide; + + is_fade_out = read_logo_byte(&logo_hdr->fu8FadeOut); + + outw(BIOS_CFG_IOPORT, BIOS_CFG_SPLASH); + if (is_fade_out) + { + for (i = LOGO_SHOW_STEPS; i > 0 ; i--) + { + outb(BIOS_CFG_IOPORT + 1, LOGO_CMD_SHOW_BMP); + outb(BIOS_CFG_IOPORT + 1, i); + delay_ticks_and_check_for_keystroke(16 / WAIT_MS, 1); + if (check_for_keystroke()) + break; + } + } +hide: + outb(BIOS_CFG_IOPORT + 1, LOGO_CMD_SHOW_BMP); + outb(BIOS_CFG_IOPORT + 1, 0); + set_mode(0x03); + clear_screen(); + + return; +} + +Bit8u +logo_display_boot_list() +{ + LOGOHDR *logo_hdr = 0; + + return read_logo_byte(&logo_hdr->fu8ShowBootMenu); +} diff --git a/bios/logo.h b/bios/logo.h new file mode 100644 index 0000000..d7a7b80 --- /dev/null +++ b/bios/logo.h @@ -0,0 +1,56 @@ +/** + * BiosLogo - The Private BIOS Logo Interface. + */ + +/* + * Copyright (C) 2006-2007 Sun Microsystems, Inc. + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa + * Clara, CA 95054 USA or visit http://www.sun.com if you need + * additional information or have any questions. + * + * QEMU/KVM port by Laurent Vivier <[email protected]> + * + */ + +#define LOGO_SHOW_STEPS 16 + +#define LOGO_CMD_NOP 0 +#define LOGO_CMD_SET_OFFSET 0x01 +#define LOGO_CMD_SHOW_BMP 0x02 + +typedef struct LOGOHDR +{ + /** Signature (LOGO_HDR_MAGIC/0x66BB). */ + Bit16u u16Signature; + /** Logo time (msec). */ + Bit16u u16LogoMillies; + /** Fade in - boolean. */ + Bit8u fu8FadeIn; + /** Fade out - boolean. */ + Bit8u fu8FadeOut; + /** Show setup - boolean. */ + Bit8u fu8ShowBootMenu; + /** Reserved / padding. */ + Bit8u u8Reserved; + /** Logo file size. */ + Bit32u cbLogo; +} LOGOHDR; +#define LOGO_HDR_MAGIC 0x66BB diff --git a/bios/rombios.c b/bios/rombios.c index 9a1cdd6..52a1391 100644 --- a/bios/rombios.c +++ b/bios/rombios.c @@ -1917,6 +1917,10 @@ shutdown_status_panic(status) BX_PANIC("Unimplemented shutdown status: %02x\n",(Bit8u)status); } +#ifdef BX_QEMU +#include "logo.c" +#endif + //-------------------------------------------------------------------------- // print_bios_banner // displays a the bios version @@ -1924,6 +1928,10 @@ shutdown_status_panic(status) void print_bios_banner() { +#ifdef BX_QEMU + if (logo_enabled()) + return; +#endif printf(BX_APPNAME" BIOS - build: %s\n%s\nOptions: ", BIOS_BUILD_DATE, bios_cvs_version_string); printf( @@ -2021,65 +2029,78 @@ interactive_bootkey() Bit16u ss = get_SS(); Bit16u valid_choice = 0; +#ifdef BX_QEMU + if (logo_enabled()) { + LOGOHDR *logo_hdr = 0; + Bit16u logo_time; + + logo_show(); + logo_time = read_logo_word(&logo_hdr->u16LogoMillies); + if (!check_for_keystroke()) + delay_ticks_and_check_for_keystroke(WAIT_MS, logo_time / 1000); + logo_hide(); + if (!logo_display_boot_list()) + return; + } else +#endif // BX_QEMU + { + while (check_for_keystroke()) + get_keystroke(); + printf("Press F12 for boot menu.\n\n"); + delay_ticks_and_check_for_keystroke(11, 5); /* ~3 seconds */ + } + if (!check_for_keystroke()) + return; + scan_code = get_keystroke(); + if (scan_code != 0x58) /* F12 */ + return; + while (check_for_keystroke()) get_keystroke(); - printf("Press F12 for boot menu.\n\n"); + printf("Select boot device:\n\n"); - delay_ticks_and_check_for_keystroke(11, 5); /* ~3 seconds */ - if (check_for_keystroke()) + count = read_word(IPL_SEG, IPL_COUNT_OFFSET); + for (i = 0; i < count; i++) { - scan_code = get_keystroke(); - if (scan_code == 0x58) /* F12 */ + memcpyb(ss, &e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (e), sizeof (e)); + printf("%d. ", i+1); + switch(e.type) { - while (check_for_keystroke()) - get_keystroke(); - - printf("Select boot device:\n\n"); - - count = read_word(IPL_SEG, IPL_COUNT_OFFSET); - for (i = 0; i < count; i++) - { - memcpyb(ss, &e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (e), sizeof (e)); - printf("%d. ", i+1); - switch(e.type) + case IPL_TYPE_FLOPPY: + case IPL_TYPE_HARDDISK: + case IPL_TYPE_CDROM: + printf("%s\n", drivetypes[e.type]); + break; + case IPL_TYPE_BEV: + printf("%s", drivetypes[4]); + if (e.description != 0) { - case IPL_TYPE_FLOPPY: - case IPL_TYPE_HARDDISK: - case IPL_TYPE_CDROM: - printf("%s\n", drivetypes[e.type]); - break; - case IPL_TYPE_BEV: - printf("%s", drivetypes[4]); - if (e.description != 0) - { - memcpyb(ss, &description, (Bit16u)(e.description >> 16), (Bit16u)(e.description & 0xffff), 32); - description[32] = 0; - printf(" [%S]", ss, description); - } - printf("\n"); - break; - } - } + memcpyb(ss, &description, (Bit16u)(e.description >> 16), (Bit16u)(e.description & 0xffff), 32); + description[32] = 0; + printf(" [%S]", ss, description); + } + printf("\n"); + break; + } + } - count++; - while (!valid_choice) { - scan_code = get_keystroke(); - if (scan_code == 0x01 || scan_code == 0x58) /* ESC or F12 */ - { - valid_choice = 1; - } - else if (scan_code <= count) - { - valid_choice = 1; - scan_code -= 1; - /* Set user selected device */ - write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, scan_code); - } - } - printf("\n"); + count++; + while (!valid_choice) { + scan_code = get_keystroke(); + if (scan_code == 0x01 || scan_code == 0x58) /* ESC or F12 */ + { + valid_choice = 1; + } + else if (scan_code <= count) + { + valid_choice = 1; + scan_code -= 1; + /* Set user selected device */ + write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, scan_code); } } + printf("\n"); } #endif // BX_ELTORITO_BOOT @@ -2706,6 +2727,9 @@ void ata_detect( ) break; } +#ifdef BX_QEMU + if (!logo_enabled()) { +#endif switch (type) { case ATA_TYPE_ATA: printf("ata%d %s: ",channel,slave?" slave":"master"); @@ -2727,6 +2751,9 @@ void ata_detect( ) printf("ata%d %s: Unknown device\n",channel,slave?" slave":"master"); break; } +#ifdef BX_QEMU + } +#endif } } -- 1.5.6.5 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
