This patch adds Qemu firmware configuration device interface to display a splash image at BIOS startup.
Idea stollen from VirtualBox. Signed-off-by: Laurent Vivier <laurent.viv...@bull.net> --- bios/Makefile | 4 +- bios/rombios.c | 142 ++++++++++++++++++++++++++++++++++++------------------- bios/splash.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bios/splash.h | 32 ++++++++++++ 4 files changed, 271 insertions(+), 51 deletions(-) create mode 100644 bios/splash.c create mode 100644 bios/splash.h Changelog: v2: totally remove code from VirtualBox to not bring GPLv2 to bios. diff --git a/bios/Makefile b/bios/Makefile index a2759a9..605d31f 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 splash.c splash.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 splash.c splash.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/rombios.c b/bios/rombios.c index 9a1cdd6..a02b50f 100644 --- a/bios/rombios.c +++ b/bios/rombios.c @@ -1433,6 +1433,22 @@ void uart_tx_byte(base_port, data) #endif void +set_video(mode) + Bit8u mode; +{ + ASM_START + push bp + mov bp, sp + + mov ah, #0x00 + mov al, 4[bp] + int #0x10 + + pop bp + ASM_END +} + + void wrch(c) Bit8u c; { @@ -1533,6 +1549,8 @@ void put_str(action, segment, offset) } } +#define TICKS_PER_SECONDS 18 + void delay_ticks(ticks) Bit16u ticks; @@ -1917,6 +1935,10 @@ shutdown_status_panic(status) BX_PANIC("Unimplemented shutdown status: %02x\n",(Bit8u)status); } +#ifdef BX_QEMU +#include "splash.c" +#endif + //-------------------------------------------------------------------------- // print_bios_banner // displays a the bios version @@ -1924,6 +1946,10 @@ shutdown_status_panic(status) void print_bios_banner() { +#ifdef BX_QEMU + if (splash_enabled()) + return; +#endif printf(BX_APPNAME" BIOS - build: %s\n%s\nOptions: ", BIOS_BUILD_DATE, bios_cvs_version_string); printf( @@ -2021,65 +2047,77 @@ interactive_bootkey() Bit16u ss = get_SS(); Bit16u valid_choice = 0; +#ifdef BX_QEMU + if (splash_enabled()) { + Bit16u duration; + + splash_show(); + duration = splash_duration(); + if (!check_for_keystroke()) + delay_ticks_and_check_for_keystroke(TICKS_PER_SECONDS, duration / 1000); + splash_hide(); + if (!splash_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 +2744,9 @@ void ata_detect( ) break; } +#ifdef BX_QEMU + if (!splash_enabled()) { +#endif switch (type) { case ATA_TYPE_ATA: printf("ata%d %s: ",channel,slave?" slave":"master"); @@ -2727,6 +2768,9 @@ void ata_detect( ) printf("ata%d %s: Unknown device\n",channel,slave?" slave":"master"); break; } +#ifdef BX_QEMU + } +#endif } } diff --git a/bios/splash.c b/bios/splash.c new file mode 100644 index 0000000..07921b3 --- /dev/null +++ b/bios/splash.c @@ -0,0 +1,144 @@ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#include "splash.h" + +#define BIOS_CFG_IOPORT 0x0510 +#define BIOS_CFG_SIGNATURE 0x0000 +#define BIOS_CFG_SPLASH 0x4007 + +#define SPLASH_VALUE(_field) splash_offset( splash_offsetof(_field), \ + splash_sizeof(_field) ) +Bit16u +splash_offset(offset, size) + Bit8u offset; + Bit8u size; +{ + Bit16u word; + + outw(BIOS_CFG_IOPORT, BIOS_CFG_SPLASH); + outb(BIOS_CFG_IOPORT + 1, SPLASH_CMD_SET_OFFSET); + outb(BIOS_CFG_IOPORT + 1, offset); + + word = inb(BIOS_CFG_IOPORT + 1); + if (size == 2) + word = (inb(BIOS_CFG_IOPORT + 1) << 8) | word; + + return word; +} + +void +splash_show_bmp(step) + Bit16u step; +{ + outw(BIOS_CFG_IOPORT, BIOS_CFG_SPLASH); + outb(BIOS_CFG_IOPORT + 1, SPLASH_CMD_SHOW_BMP); + outb(BIOS_CFG_IOPORT + 1, step); + + return; +} + +Bit8u +splash_enabled() +{ + Bit8u fadein, fadeout, bootmenu; + Bit16u duration; + + /* 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 (SPLASH_VALUE(signature) != SPLASH_MAGIC) + return 0; + + /* Get options */ + + fadein = SPLASH_VALUE(fadein); + fadeout = SPLASH_VALUE(fadeout); + duration = SPLASH_VALUE(duration); + + return (fadein || fadeout || duration); +} + +void +splash_show() +{ + Bit8u fadein; + Bit16u i; + + set_video(0x12); /* 640x480 */ + + fadein = SPLASH_VALUE(fadein); + + if (fadein) + { + delay_ticks_and_check_for_keystroke(TICKS_PER_SECONDS / 18, 1); + /* "0" means unload image from memory, used in splash_hide() */ + for (i = 1; !check_for_keystroke() && i < SPLASH_SHOW_STEPS; i++) + { + splash_show_bmp(i); + delay_ticks_and_check_for_keystroke(TICKS_PER_SECONDS / 18, 1); + } + } + + if (!check_for_keystroke()) + splash_show_bmp(SPLASH_SHOW_STEPS); + + return; +} + +void +splash_hide() +{ + Bit8u fadeout; + Bit16u i; + + fadeout = SPLASH_VALUE(fadeout); + + if (fadeout) + { + for (i = SPLASH_SHOW_STEPS; !check_for_keystroke() && i > 0 ; i--) + { + splash_show_bmp(i); + delay_ticks_and_check_for_keystroke(TICKS_PER_SECONDS / 18, 1); + } + } + splash_show_bmp(0); + + set_video(0x03); /* text mode */ + + return; +} + +Bit8u +splash_display_boot_list() +{ + return SPLASH_VALUE(bootmenu); +} + +Bit16u +splash_duration() +{ + return SPLASH_VALUE(duration); +} diff --git a/bios/splash.h b/bios/splash.h new file mode 100644 index 0000000..1b34978 --- /dev/null +++ b/bios/splash.h @@ -0,0 +1,32 @@ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +struct splash_header { + Bit16u signature; + Bit16u duration; + Bit8u fadein; + Bit8u fadeout; + Bit8u bootmenu; + Bit8u pad; + Bit32u size; +}; + +#define SPLASH_MAGIC 0x66BB +#define SPLASH_CMD_NOP 0x00 +#define SPLASH_CMD_SET_OFFSET 0x01 +#define SPLASH_CMD_SHOW_BMP 0x02 +#define SPLASH_SHOW_STEPS 16 + +#define splash_offsetof(_field) (&((struct splash_header *)0)->_field) +#define splash_sizeof(_field) (sizeof(((struct splash_header *)0)->_field)) -- 1.5.6.5 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html