Add support for up to 35 boot menu entries (2 pages if >18). To solve the
">10" problem currently experienced by SeaBIOS users (there are no 11, 12, etc.
keys on a keyboard - so impossible to choose the last menu entries if you got
>10 entries because of multiple hard drives / secondary payloads / floppies)
- the boot menu has been extended to the letter keys. NOTE: TPM menu has been
moved from T to M letter: it is at the end of keyboard's 3rd row of letters and
"Trusted" is adjective while "Module" is a noun; alternatively could press '-'.
Also, add support for a numpad. Small USB numpad could be really convenient for
choosing the boot entries at coreboot boards used as (maybe headless) servers.
'/' char on numpad could be used to open the boot menu or to exit it. If there
are >10 boot menu entries - the numpad console interface will be enabled: press
one or two digit keys and then ENTER to confirm your choice, or remove a digit
by pressing the '.Del' key. Also you could call TPM with '-' key at any moment,
or boot with a single key press of your fullsize keyboard.
Signed-off-by: Mike Banon <mikebdp2 at gmail.com>
(patch body is after the testing instructions below)
This "advanced_bootmenu" patch is much more useful when used together
with my "multiple_floppies" patch:
[SeaBIOS] [PATCH v2] ramdisk: search for all available floppy images
instead of one
https://mail.coreboot.org/pipermail/seabios/2018-December/012670.html
Sadly I haven't done the suggestions by Kevin (I have so many unfinished tasks)
so the "multiple_floppies" patch is also not merged yet. But you could install
both patches to your coreboot by executing this script while at ./coreboot dir:
https://pastebin.com/raw/hv9sSuMU
And here is a coreboot image for QEMU with these two patches applied and my
collection of wonderful and useful floppies added to popular the entries list:
https://github.com/mikebdp2/floparchive/blob/master/coreboot.rom?raw=true
Descriptions of the most prominent floppies could be found here:
http://dangerousprototypes.com/docs/Lenovo_G505S_hacking#Useful_floppies
Run this coreboot.rom by executing this QEMU command: (some floppies are 64-bit)
qemu-system-x86_64 -L . -m 768 -localtime -vga vmware -net nic,model=rtl8139 \
-net user -soundhw ac97 -bios ./coreboot.rom -boot menu=on -serial stdio
Best regards,
Mike Banon
diff --git a/src/boot.c b/src/boot.c
index 9f82f3c..f94dd27 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -463,6 +463,7 @@ get_keystroke(int msec)
* Boot menu and BCV execution
****************************************************************/
+#define BOOTMENU_PAGE_SIZE 18
#define DEFAULT_BOOTMENU_WAIT 2500
// Show IPL option menu.
@@ -478,59 +479,282 @@ interactive_bootmenu(void)
;
char *bootmsg = romfile_loadfile("etc/boot-menu-message", NULL);
- int menukey = romfile_loadint("etc/boot-menu-key", 1);
- printf("%s", bootmsg ?: "\nPress ESC for boot menu.\n\n");
+ int menukey = romfile_loadint("etc/boot-menu-key", 1); // custom menukey
+ printf("%s", bootmsg ?: "\nPress ESC or \\ / slash for boot menu.\n\n");
free(bootmsg);
u32 menutime = romfile_loadint("etc/boot-menu-wait",
DEFAULT_BOOTMENU_WAIT);
enable_bootsplash();
int scan_code = get_keystroke(menutime);
disable_bootsplash();
- if (scan_code != menukey)
+ if (scan_code != menukey && // custom menukey
+ scan_code != 1 && // ESC
+ scan_code != 43 && // '\' char on keyboard
+ scan_code != 53 && // '/' char on keyboard
+ scan_code != 98) { // '/' char on numpad
+ if (scan_code == -1)
+ printf("No key pressed.\n");
+ else
+ printf("Not a menukey pressed.\n");
return;
+ }
while (get_keystroke(0) >= 0)
;
- printf("Select boot device:\n\n");
wait_threads();
- // Show menu items
+ char keyboard_keys[35] = {'1','2','3','4','5','6','7','8','9','0',
+ 'q','w','e','r','t','y','u','i','o','p',
+ 'a','s','d','f','g','h','j','k','l',
+ 'z','x','c','v','b','n'}; /* m = TPM */
+ int numpad_scancodes[10] = { 82, 79, 80, 81, 75, 76, 77, 71, 72, 73 };
+ int numpi = 0; // Key index: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
+ int digits = 0; // Numerical length of a current choice number.
+ int decode = 0; // Decode the current choice number into a letter?
+ int entry_id = 0;
+ char desc[77];
+
+ printf("Select boot device");
+
+ // Show menu items after counting them and determining a number of pages.
+ // Only 35 boot menu items (36 if to count a TPM) are supported currently.
+
int maxmenu = 0;
struct bootentry_s *pos;
- hlist_for_each_entry(pos, &BootList, node) {
- char desc[77];
+ hlist_for_each_entry(pos, &BootList, node)
maxmenu++;
- printf("%d. %s\n", maxmenu
+
+ if (maxmenu > 10) {
+ if (maxmenu > 35)
+ maxmenu = 35;
+ if (maxmenu > BOOTMENU_PAGE_SIZE)
+ printf(" - page 1 :");
+ else
+ printf(": ");
+ printf(" // press ENTER after your numpad input");
+ if (maxmenu > BOOTMENU_PAGE_SIZE)
+ printf(" - if any -\n "
+ " // - or to switch between the pages...\n");
+ else
+ printf(" (if any)\n\n");
+ } else {
+ printf(":\n\n");
+ }
+
+ hlist_for_each_entry(pos, &BootList, node) {
+ if (entry_id == BOOTMENU_PAGE_SIZE) // Show only the first page.
+ break;
+ printf("%c. %s\n", keyboard_keys[entry_id]
, strtcpy(desc, pos->description, ARRAY_SIZE(desc)));
+ entry_id++;
}
+ int tpm_cshm = 0;
if (tpm_can_show_menu()) {
- printf("\nt. TPM Configuration\n");
+ tpm_cshm = 1;
+ printf("\nm-. TPM Configuration");
}
-
- // Get key press. If the menu key is ESC, do not restart boot unless
- // 1.5 seconds have passed. Otherwise users (trained by years of
- // repeatedly hitting keys to enter the BIOS) will end up hitting ESC
- // multiple times and immediately booting the primary boot device.
- int esc_accepted_time = irqtimer_calc(menukey == 1 ? 1500 : 0);
+ printf("\n> ");
+
+ // Do not restart boot on menukey press, unless DEFAULT_BOOTMENU_WAIT msecs
+ // have passed. Otherwise users (trained by years of repeatedly
hitting keys
+ // to enter the BIOS) will end up hitting menukey multiple times and
+ // immediately booting the primary boot device.
+ int esc_accepted_time = irqtimer_calc(DEFAULT_BOOTMENU_WAIT);
+ int choice = 0, kb_choice = 0;
+ int page_num = 1;
+ int enter = 0;
+ int backspace = 0;
+ int tpm_show_menu = 0;
for (;;) {
scan_code = get_keystroke(1000);
- if (scan_code == 1 && !irqtimer_check(esc_accepted_time))
- continue;
- if (tpm_can_show_menu() && scan_code == 20 /* t */) {
+ if (scan_code == menukey || // custom menukey
+ scan_code == 1 || // ESC
+ scan_code == 43 || // '\' char on keyboard
+ scan_code == 53 || // '/' char on keyboard
+ scan_code == 98) { // '/' char on numpad
+ if (!irqtimer_check(esc_accepted_time))
+ continue;
+ if (digits == 2) // Remove the decoded "(*)"
+ printf(" \b\b\b");
+ /* Remove the existing input before printing a message. */
+ for (; digits > 0; digits--)
+ printf("\b \b");
+ printf("Menukey pressed.\n");
+ return;
+ }
+ kb_choice = 0;
+ /* 4 rows of keyboard_keys: 1 row with numbers, 3 rows with letters.
+ Use any of them to select a boot device (except the TPM
'm-' keys) */
+ // 1st range: 1-9 and 0 (10) keys <==> 2-11 scan codes <==>
1-10 choice
+ if (scan_code >= 2 && scan_code <= 11) kb_choice = scan_code - 1;
+ // 2nd range: Q-P row of letters <==> 16-25 scan codes <==>
11-20 choice
+ if (scan_code >= 16 && scan_code <= 25) kb_choice = scan_code - 5;
+ // 3rd range: A-L row of letters <==> 30-38 scan codes <==>
21-29 choice
+ if (scan_code >= 30 && scan_code <= 38) kb_choice = scan_code - 9;
+ // 4th range: Z-N row of letters <==> 44-49 scan codes <==>
30-35 choice
+ if (scan_code >= 44 && scan_code <= 49) kb_choice = scan_code - 14;
+ // ENTER: (28) on keyboard, (96) on numpad.
+ if (scan_code == 28 || scan_code == 96)
+ enter = 1;
+ // BCKSPC: '<-'(14) and 'Delete'(111) on keyboard, '.Del'(83)
on numpad.
+ if (scan_code == 14 || scan_code == 111 || scan_code == 83)
+ backspace = 1;
+ // TPM keys: 'm'(50) and '-'(12) chars on keyboard, '-'(74) on numpad.
+ if ((scan_code == 50 || scan_code == 12 || scan_code == 74)
&& tpm_cshm)
+ tpm_show_menu = 1;
+
+ if (kb_choice != 0 || tpm_show_menu) {
+ if (kb_choice > maxmenu) {
+ if (!tpm_show_menu)
+ continue;
+ } else {
+ choice = kb_choice;
+ }
+ if (digits == 2) // Remove the decoded "(*)"
+ printf(" \b\b\b");
+ /* Remove the existing input before printing a choice. */
+ for (; digits > 0; digits--)
+ printf("\b \b");
+ if (!tpm_show_menu) {
+ // Choice is any of the detected boot devices ==> lets boot!
+ break;
+ }
+ } else {
+ // Internal/USB Numpad console interface.
+ if (digits < 9) {
+ for (numpi = 0; numpi < 10; numpi++) {
+ if (scan_code == numpad_scancodes[numpi]) {
+ if (maxmenu <= 10) { // Console interface is
not needed.
+ if ((numpi != 0 && numpi <= maxmenu) ||
+ (numpi == 0 && 10 <= maxmenu)) { // 10(0)
+ choice = numpi;
+ enter = 1; // Fake ENTER to boot this
entry now.
+ } else { // If no such an entry, don't try to boot.
+ break;
+ }
+ } else {
+ if (digits == 2) {
+ printf(" \b\b\b"); // Remove the
decoded "(*)"
+ if (choice == 0) {
+ printf("\b\b \b\b"); // Remove "10".
+ digits = 0;
+ }
+ }
+ choice = 10 * choice + numpi;
+ }
+ if (choice > 0) {
+ printf("%d", numpi); // Print the entered digit.
+ digits++;
+ } else {
+ if (10 <= maxmenu)
+ printf("10(0)\b\b\b");
+ else
+ printf("10(?)\b\b\b");
+ digits = 2;
+ }
+ if (choice > 9 && digits == 2) // Decode into a letter.
+ decode = 1;
+ break;
+ }
+ }
+ }
+ if (backspace && digits > 0) {
+ backspace = 0;
+ choice = choice / 10;
+ if (digits == 2) {
+ printf(" \b\b\b"); // Remove the decoded "(*)"
+ // 0 turned into 10: one more Backspace is needed
to remove.
+ if (choice == 0) {
+ printf("\b \b");
+ digits--;
+ }
+ }
+ printf("\b \b"); // Remove the last entered digit.
+ digits--;
+ if (choice > 9 && digits == 2) // Decode into a letter.
+ decode = 1;
+ }
+ if (decode) { // Decode the current choice number into a letter.
+ decode = 0;
+ if (choice <= maxmenu) {
+ printf("(%c)", keyboard_keys[choice-1]);
+ } else {
+ if (tpm_cshm && choice == 36)
+ printf("(m)"); // For TPM.
+ else
+ printf("(?)"); // No matching letter found.
+ }
+ printf("\b\b\b"); // Move a cursor before the "(*)"
+ }
+ }
+
+ if (enter) {
+ enter = 0;
+ if (choice == 0) {
+ if (digits == 2) { // for 0 that turned into 10
+ if (10 <= maxmenu)
+ break;
+ else
+ continue;
+ }
+ // If there are two pages - switch between them.
+ if (maxmenu > BOOTMENU_PAGE_SIZE) {
+ entry_id = 0;
+ page_num = 3 - page_num; // 3 - 1 = 2; 3 - 2 = 1.
+ printf("\n\nSelect boot device - page %d :"
+ " // press ENTER after your numpad input"
+ " - if any -\n "
+ " // - or to switch between the pages...\n",
+ page_num);
+ hlist_for_each_entry(pos, &BootList, node) {
+ if ((page_num == 1 && entry_id ==
BOOTMENU_PAGE_SIZE) ||
+ (page_num == 2 && entry_id == 35))
+ break;
+ if (page_num == 1 || entry_id >= BOOTMENU_PAGE_SIZE)
+ printf("%c. %s\n", keyboard_keys[entry_id],
+ strtcpy(desc, pos->description,
ARRAY_SIZE(desc)));
+ entry_id++;
+ }
+ if (tpm_cshm)
+ printf("\nm-. TPM Configuration");
+ printf("\n> ");
+ }
+ } else {
+ if (choice > maxmenu) {
+ if (tpm_cshm && choice == 36)
+ tpm_show_menu = 1;
+ } else {
+ // Choice is any of the detected boot devices ==>
lets boot!
+ break;
+ }
+ }
+ }
+
+ if (tpm_show_menu) {
+ tpm_show_menu = 0;
+ choice = 0;
+ if (digits == 0)
+ printf("TPM key pressed.");
+ else
+ digits = 0;
printf("\n");
tpm_menu();
+ printf("> ");
}
- if (scan_code >= 1 && scan_code <= maxmenu+1)
- break;
+ }
+
+ if (choice == 0) // 10(0)
+ choice = 10;
+
+ if (digits == 0 && choice < 36) {
+ printf("%c", keyboard_keys[choice-1]);
+ if (choice > 9) // Decode into a number.
+ printf("(%d)", choice);
}
printf("\n");
- if (scan_code == 0x01)
- // ESC
- return;
// Find entry and make top priority.
- int choice = scan_code - 1;
hlist_for_each_entry(pos, &BootList, node) {
if (! --choice)
break;
diff --git a/src/config.h b/src/config.h
index 93c8dbc..f85cc14 100644
--- a/src/config.h
+++ b/src/config.h
@@ -19,7 +19,7 @@
// Space to reserve in high-memory for tables
#define BUILD_MAX_HIGHTABLE (256*1024)
// Largest supported externaly facing drive id
-#define BUILD_MAX_EXTDRIVE 16
+#define BUILD_MAX_EXTDRIVE 36
// Number of bytes the smbios may be and still live in the f-segment
#define BUILD_MAX_SMBIOS_FSEG 600
// Maximum number of bytes the mptable may be and still be copied to f-segment
Hi,
I'm working on stuffing a bootable Linux distro into coreboot. In QEMU I
already succeded by using coreboot's built-in kernel loading mechanism, but
that's without SeaBIOS.
I'd love to have it as a SeaBIOS payload so I can also boot other things,
but I guess I'd have to create a custom-sized floppy image for this or
figure out how to create an ELF payload out of a Linux kernel (I'm open to
either, but I wasn't able to find any documentation on the ELF method).
The guy who put Win 3.1 in coreboot attempted the floppy method, but
according to his article he did not find success with this method due to
unknown and complex issues in the floppy-side logic of SeaBIOS.
So, I'm making the question explicit: What would it take to support
custom-sized floppy images? In particular, I'm thinking of a 16MB device...
Alternatively, would it be possible to create an ELF file out of a Linux
kernel+initrd / bootable image?
Cheers,
Rafael
Windows kernel extracts various BIOS information at boot-time.
The method it uses to extract SystemBiosDate is very hueristic.
It is done by nt!CmpGetBiosDate().
nt!CmpGetBiosDate() works by scanning all BIOS memory from 0xF0000 to
0xFFFF5 (FSEG) in search for a string which is formatted like a date.
It then chooses the string which represents the most recent date, and
writes it to:
HKLM/HARDWARE/DESCRIPTION/System SystemBiosDate
This date should usually be BiosDate located at FSEG(0xFFF5).
BIOS_DATE and RELEASE_DATE_STR appear in FSEG together with BiosDate.
This makes Windows report BIOS_DATE, which is the most recent one, as
the date in HKLM/HARDWARE/DESCRIPTION/System SystemBiosDate.
In some cases we would like to control the value that Windows will
calculate and store in SystemBiosDate (This value is popular among
activation an licensing software).
To do that we must clean FSEG from date strings which may interfere
with our intended calculation.
In this commit we remove all static dates from FSEG which are not
BiosDate.
In the next commit we will deal with dynamic strings that may sometimes
appear in FSEG (from SMBIOS tables).
Removing BIOS_DATE and RELEASE_DATE_STR static strings from FSEG will
only affect machines using legacy SMBIOS:
* SystemBiosDate will change from 04/01/2014 (BIOS_DATE) to
01/01/2011 (RELEASE_DATE_STR).
For reference implementation of nt!CmpGetBiosDate(), see ReactOS:
https://doxygen.reactos.org/d5/dd2/i386_2cmhardwr_8c.html
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk(a)oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe(a)oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman(a)oracle.com>
Signed-off-by: Liran Alon <liran.alon(a)oracle.com>
---
src/fw/biostables.c | 2 +-
src/fw/smbios.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/fw/biostables.c b/src/fw/biostables.c
index fe8626ef..269b8582 100644
--- a/src/fw/biostables.c
+++ b/src/fw/biostables.c
@@ -401,7 +401,7 @@ smbios_new_type_0(void *start,
}
#define BIOS_NAME "SeaBIOS"
-#define BIOS_DATE "04/01/2014"
+static const char BIOS_DATE[] = "04/01/2014";
static int
smbios_romfile_setup(void)
diff --git a/src/fw/smbios.c b/src/fw/smbios.c
index f3b5ad9d..6f33a329 100644
--- a/src/fw/smbios.c
+++ b/src/fw/smbios.c
@@ -134,7 +134,7 @@ get_external(int type, char **p, unsigned *nr_structs,
end += size; \
p->field = ++str_index; \
} else { \
- memcpy(end, def, sizeof(def)); \
+ memcpy(end, (void*)def, sizeof(def)); \
end += sizeof(def); \
p->field = ++str_index; \
} \
@@ -161,7 +161,7 @@ get_external(int type, char **p, unsigned *nr_structs,
} while (0)
/* Type 0 -- BIOS Information */
-#define RELEASE_DATE_STR "01/01/2011"
+static volatile const char RELEASE_DATE_STR[] = "01/01/2011";
static void *
smbios_init_type_0(void *start)
{
--
2.13.3
Windows kernel extracts various BIOS information at boot-time.
The method it uses to extract SystemBiosDate & SystemBiosVersion which
are then stored in:
* "HKLM\HARDWARE\DESCRIPTION\System" "SystemBiosDate"
* "HKLM\HARDWARE\DESCRIPTION\System" "SystemBiosVersion"
is very hueristic and depends on data contained in the BIOS's data
section.
The implementation resides in:
* nt!CmpGetBiosVersion()
* nt!CmpGetBiosDate()
respectively.
For reference implementation, see ReactOS:
https://doxygen.reactos.org/d5/dd2/i386_2cmhardwr_8c.html
This patch series aims to make SeaBIOS's data section interact better
with the Windows OS and report correct date & version values.
Liran Alon (4):
bios_date: Make all dates in BIOS consistent
bios_date: Make bios date appear once in the ROM
bios_date: Change BiosDate to SMBIOS bios date
bios_version: Remove misinterpreted version string
Sam Eiderman (2):
bios_date: Add bios date checks in checkrom.py
bios_version: Add bios version checks in checkrom.py
scripts/checkrom.py | 45 +++++++++++++++++++++++++++++++++++++++++++++
src/config.h | 11 +++++++++++
src/fw/biostables.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
src/fw/pciinit.c | 2 +-
src/fw/smbios.c | 21 +++++++++++++++++++--
src/misc.c | 2 +-
src/util.h | 5 +++++
7 files changed, 129 insertions(+), 8 deletions(-)
--
2.13.3
Check whenever pnp roms attempt to redirect int19, and in case it does
log a message and undo the redirect.
A pnp rom should not need this, we have BEVs and BCVs for that.
Nevertheless there are roms in the wild which are redirecting int19.
At least some BIOS implementations for physical hardware have a config
option in the setup to allow/disallow int19 redirections, so just not
allowing this seems to be the way to deal with this situation.
Buglink: https://bugzilla.redhat.com//show_bug.cgi?id=1642135
Signed-off-by: Gerd Hoffmann <kraxel(a)redhat.com>
---
src/optionroms.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/src/optionroms.c b/src/optionroms.c
index fc992f649fe1..e906ab97f433 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -8,6 +8,7 @@
#include "bregs.h" // struct bregs
#include "config.h" // CONFIG_*
#include "farptr.h" // FLATPTR_TO_SEG
+#include "biosvar.h" // GET_IVT
#include "hw/pci.h" // pci_config_readl
#include "hw/pcidevice.h" // foreachpci
#include "hw/pci_ids.h" // PCI_CLASS_DISPLAY_VGA
@@ -308,6 +309,19 @@ fail:
return NULL;
}
+static int boot_irq_captured(void)
+{
+ return GET_IVT(0x19).segoff != FUNC16(entry_19_official).segoff;
+}
+
+static void boot_irq_restore(void)
+{
+ struct segoff_s seabios;
+
+ seabios = FUNC16(entry_19_official);
+ SET_IVT(0x19, seabios);
+}
+
// Attempt to map and initialize the option rom on a given PCI device.
static void
init_pcirom(struct pci_device *pci, int isvga, u64 *sources)
@@ -327,8 +341,18 @@ init_pcirom(struct pci_device *pci, int isvga, u64 *sources)
if (! rom)
// No ROM present.
return;
+ int irq_was_captured = boot_irq_captured();
+ struct pnp_data *pnp = get_pnp_rom(rom);
setRomSource(sources, rom, RS_PCIROM | (u32)pci);
init_optionrom(rom, pci->bdf, isvga);
+ if (boot_irq_captured() && !irq_was_captured &&
+ !file && !isvga && pnp) {
+ // This PCI rom is misbehaving - recapture the boot irqs
+ char *desc = MAKE_FLATPTR(FLATPTR_TO_SEG(rom), pnp->productname);
+ dprintf(1, "PnP optionrom \"%s\" (bdf %pP) captured int19, restoring\n",
+ desc, pci);
+ boot_irq_restore();
+ }
}
--
2.18.1
Check whenever pnp roms attempt to redirect int19, and in case it does
log a message and undo the redirect.
A pnp rom should not need this, we have BEVs and BCVs for that.
Nevertheless there are roms in the wild which are redirecting int19.
At least some BIOS implementations for physical hardware have a config
option in the setup to allow/disallow int19 redirections, so just not
allowing this seems to be the way to deal with this situation.
Buglink: https://bugzilla.redhat.com//show_bug.cgi?id=1642135
Signed-off-by: Gerd Hoffmann <kraxel(a)redhat.com>
---
src/optionroms.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/src/optionroms.c b/src/optionroms.c
index fc992f649f..e90900b790 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -8,6 +8,7 @@
#include "bregs.h" // struct bregs
#include "config.h" // CONFIG_*
#include "farptr.h" // FLATPTR_TO_SEG
+#include "biosvar.h" // GET_IVT
#include "hw/pci.h" // pci_config_readl
#include "hw/pcidevice.h" // foreachpci
#include "hw/pci_ids.h" // PCI_CLASS_DISPLAY_VGA
@@ -308,6 +309,24 @@ fail:
return NULL;
}
+static int boot_irq_captured(void)
+{
+ struct segoff_s current, seabios;
+
+ current = GET_IVT(0x19);
+ seabios = FUNC16(entry_19_official);
+ return ((current.seg != seabios.seg) ||
+ (current.offset != current.offset));
+}
+
+static void boot_irq_restore(void)
+{
+ struct segoff_s seabios;
+
+ seabios = FUNC16(entry_19_official);
+ SET_IVT(0x19, seabios);
+}
+
// Attempt to map and initialize the option rom on a given PCI device.
static void
init_pcirom(struct pci_device *pci, int isvga, u64 *sources)
@@ -327,8 +346,18 @@ init_pcirom(struct pci_device *pci, int isvga, u64 *sources)
if (! rom)
// No ROM present.
return;
+ int irq_was_captured = boot_irq_captured();
+ struct pnp_data *pnp = get_pnp_rom(rom);
setRomSource(sources, rom, RS_PCIROM | (u32)pci);
init_optionrom(rom, pci->bdf, isvga);
+ if (boot_irq_captured() && !irq_was_captured &&
+ !file && !isvga && pnp) {
+ // This PCI rom is misbehaving - recapture the boot irqs
+ char *desc = MAKE_FLATPTR(FLATPTR_TO_SEG(rom), pnp->productname);
+ dprintf(1, "PnP optionrom \"%s\" (bdf %pP) captured int19, restoring\n",
+ desc, pci);
+ boot_irq_restore();
+ }
}
--
2.9.3
v2:
Offer a better commit for:
"bios_version: Remove misinterpreted version string"
Which doesn't change the debug string but rather creates the original
one dynamically.
Thanks, Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006(a)gmx.net>.
v1:
Windows kernel extracts various BIOS information at boot-time.
The method it uses to extract SystemBiosDate & SystemBiosVersion which
are then stored in:
* "HKLM\HARDWARE\DESCRIPTION\System" "SystemBiosDate"
* "HKLM\HARDWARE\DESCRIPTION\System" "SystemBiosVersion"
is very hueristic and depends on data contained in the BIOS's data
section.
The implementation resides in:
* nt!CmpGetBiosVersion()
* nt!CmpGetBiosDate()
respectively.
For reference implementation, see ReactOS:
https://doxygen.reactos.org/d5/dd2/i386_2cmhardwr_8c.html
This patch series aims to make SeaBIOS's data section interact better
with the Windows OS and report correct date & version values.
Liran Alon (4):
bios_date: Make all dates in BIOS consistent
bios_date: Make bios date appear once in the ROM
bios_date: Change BiosDate to SMBIOS bios date
bios_version: Remove misinterpreted version string
Sam Eiderman (2):
bios_date: Add bios date checks in checkrom.py
bios_version: Add bios version checks in checkrom.py
scripts/checkrom.py | 45 +++++++++++++++++++++++++++++++++++++++++++++
src/config.h | 11 +++++++++++
src/fw/biostables.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
src/fw/pciinit.c | 3 ++-
src/fw/smbios.c | 21 +++++++++++++++++++--
src/misc.c | 2 +-
src/util.h | 5 +++++
7 files changed, 130 insertions(+), 8 deletions(-)
--
2.13.3
Switch get_raw_keystroke() to return ax instead of ah, so it returns
both scan code and ascii code of the key pressed.
Add get_keystroke_full() function which passes up ax to the caller.
The get_keystroke() function continues to return the scancode only like
it did before. It is a thin wrapper around get_keystroke_full() now
though.
Signed-off-by: Gerd Hoffmann <kraxel(a)redhat.com>
---
src/util.h | 1 +
src/boot.c | 16 ++++++++++++++--
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/util.h b/src/util.h
index 9c06850353a4..e2afc80c425a 100644
--- a/src/util.h
+++ b/src/util.h
@@ -36,6 +36,7 @@ int bootprio_find_pci_rom(struct pci_device *pci, int instance);
int bootprio_find_named_rom(const char *name, int instance);
struct usbdevice_s;
int bootprio_find_usb(struct usbdevice_s *usbdev, int lun);
+int get_keystroke_full(int msec);
int get_keystroke(int msec);
// bootsplash.c
diff --git a/src/boot.c b/src/boot.c
index 9f82f3ca0c3e..013d407a6449 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -441,12 +441,13 @@ get_raw_keystroke(void)
memset(&br, 0, sizeof(br));
br.flags = F_IF;
call16_int(0x16, &br);
- return br.ah;
+ return br.ax;
}
// Read a keystroke - waiting up to 'msec' milliseconds.
+// returns both scancode and ascii code.
int
-get_keystroke(int msec)
+get_keystroke_full(int msec)
{
u32 end = irqtimer_calc(msec);
for (;;) {
@@ -458,6 +459,17 @@ get_keystroke(int msec)
}
}
+// Read a keystroke - waiting up to 'msec' milliseconds.
+// returns scancode only.
+int
+get_keystroke(int msec)
+{
+ int keystroke = get_keystroke_full(msec);
+
+ if (keystroke < 0)
+ return keystroke;
+ return keystroke >> 8;
+}
/****************************************************************
* Boot menu and BCV execution
--
2.18.1