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(-)
From: Liran Alon liran.alon@oracle.com
There are 2 places where SeaBIOS reports its release date:
1. SMBIOS Type 0 entry 2. Hard-coded address 0xFFFF5
Previous to this commit, each of these places defined it's own unique date which doesn't make sense.
Therefore, define the BIOS date in a single place and make sure all relevant places in code use it.
Reviewed-by: Konrad Rzeszutek Wilk konrad.wilk@oracle.com Reviewed-by: Arbel Moshe arbel.moshe@oracle.com Signed-off-by: Sam Eiderman shmuel.eiderman@oracle.com Signed-off-by: Liran Alon liran.alon@oracle.com --- src/config.h | 11 +++++++++++ src/fw/biostables.c | 1 - src/fw/smbios.c | 3 +-- src/misc.c | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/config.h b/src/config.h index 93c8dbc2..6795440c 100644 --- a/src/config.h +++ b/src/config.h @@ -29,6 +29,17 @@ #define BUILD_SUBMODEL_ID 0x00 #define BUILD_BIOS_REVISION 0x01
+#define BIOS_DATE_MONTH "04" +#define BIOS_DATE_DAY "01" +#define BIOS_DATE_YEAR "14" +#define BIOS_DATE_YEAR_PREFIX "20" +#define BIOS_DATE (BIOS_DATE_MONTH "/" \ + BIOS_DATE_DAY "/" \ + BIOS_DATE_YEAR_PREFIX BIOS_DATE_YEAR) +#define BIOS_DATE_SHORT (BIOS_DATE_MONTH "/" \ + BIOS_DATE_DAY "/" \ + BIOS_DATE_YEAR) + // Various memory addresses used by the code. #define BUILD_STACK_ADDR 0x7000 #define BUILD_S3RESUME_STACK_ADDR 0x1000 diff --git a/src/fw/biostables.c b/src/fw/biostables.c index fe8626ef..b055c9b2 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -401,7 +401,6 @@ smbios_new_type_0(void *start, }
#define BIOS_NAME "SeaBIOS" -#define BIOS_DATE "04/01/2014"
static int smbios_romfile_setup(void) diff --git a/src/fw/smbios.c b/src/fw/smbios.c index 62a563b2..96104714 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -161,7 +161,6 @@ get_external(int type, char **p, unsigned *nr_structs, } while (0)
/* Type 0 -- BIOS Information */ -#define RELEASE_DATE_STR "01/01/2011" static void * smbios_init_type_0(void *start) { @@ -179,7 +178,7 @@ smbios_init_type_0(void *start)
p->bios_starting_address_segment = 0xe800;
- load_str_field_with_default(0, bios_release_date_str, RELEASE_DATE_STR); + load_str_field_with_default(0, bios_release_date_str, BIOS_DATE);
p->bios_rom_size = 0; /* FIXME */
diff --git a/src/misc.c b/src/misc.c index b5117304..189d487b 100644 --- a/src/misc.c +++ b/src/misc.c @@ -174,7 +174,7 @@ struct descloc_s rombios32_gdt_48 VARFSEG = { ****************************************************************/
// BIOS build date -char BiosDate[] VARFSEGFIXED(0xfff5) = "06/23/99"; +char BiosDate[] VARFSEGFIXED(0xfff5) = BIOS_DATE_SHORT;
u8 BiosModelId VARFSEGFIXED(0xfffe) = BUILD_MODEL_ID;
From: Liran Alon liran.alon@oracle.com
We find all the places which cause BIOS_DATE to appear in the data section and remove them - leaving the only place to contain the contents of BIOS_DATE to be BiosDate at FSEG(0xfff5).
We do this by removing the usages of BIOS_DATE and by changing strlen(BIOS_DATE) to sizeof(BIOS_DATE) which works at the preprocessing step - removing the need to add BIOS_DATE as a string in the data section.
We will use the fact that BiosDate is now the only place in FSEG containing the date in the next commit.
Reviewed-by: Konrad Rzeszutek Wilk konrad.wilk@oracle.com Reviewed-by: Arbel Moshe arbel.moshe@oracle.com Signed-off-by: Sam Eiderman shmuel.eiderman@oracle.com Signed-off-by: Liran Alon liran.alon@oracle.com --- src/fw/biostables.c | 14 +++++++++++--- src/util.h | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/fw/biostables.c b/src/fw/biostables.c index b055c9b2..546e83c6 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -439,7 +439,7 @@ smbios_romfile_setup(void) if (need_t0) { /* common case: add our own type 0, with 3 strings and 4 '\0's */ u16 t0_len = sizeof(struct smbios_type_0) + strlen(BIOS_NAME) + - strlen(VERSION) + strlen(BIOS_DATE) + 4; + strlen(VERSION) + sizeof(BIOS_DATE) + 3; ep.structure_table_length += t0_len; if (t0_len > ep.max_structure_size) ep.max_structure_size = t0_len; @@ -459,8 +459,16 @@ smbios_romfile_setup(void) ep.structure_table_address = (u32)tables;
/* populate final blob */ - if (need_t0) - tables = smbios_new_type_0(tables, BIOS_NAME, VERSION, BIOS_DATE); + if (need_t0) { + char bios_date[sizeof(BIOS_DATE)]; + memcpy(bios_date, BiosDate, sizeof("mm/dd/") - 1); + memcpy(bios_date + sizeof("mm/dd/") - 1, BIOS_DATE_YEAR_PREFIX, + sizeof("yy") - 1); + memcpy(bios_date + sizeof("mm/dd/yy") - 1, + BiosDate + sizeof("mm/dd/") - 1, + sizeof("yy")); + tables = smbios_new_type_0(tables, BIOS_NAME, VERSION, bios_date); + } memcpy(tables, qtables, qtables_len); free(qtables);
diff --git a/src/util.h b/src/util.h index 6dd080f6..68ba848d 100644 --- a/src/util.h +++ b/src/util.h @@ -2,6 +2,7 @@ #ifndef __UTIL_H #define __UTIL_H
+#include "config.h" // BIOS_DATE_SHORT #include "types.h" // u32
// apm.c @@ -243,6 +244,9 @@ void lpt_setup(void); // version.c extern const char VERSION[], BUILDINFO[];
+// misc.c +extern char BiosDate[sizeof(BIOS_DATE_SHORT)] __aligned(1); + // vgahooks.c void handle_155f(struct bregs *regs); void handle_157f(struct bregs *regs);
From: Liran Alon liran.alon@oracle.com
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).
In some cases when the SMBIOS tables are small enough (both in legacy and non-legacy mode) - These tables are allocated in FSEG instead of high-mem, specifically Type0->release_date string which might cause SystemBiosDate to change - depending on its value. This leads to an inconsistent behaviour that depends on the SMBIOS table sizes.
We fix this inconsistency by changing BiosDate to the same value provided by SMBIOS, regardless whether SMBIOS tables reside in FSEG or high-mem.
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@oracle.com Reviewed-by: Arbel Moshe arbel.moshe@oracle.com Signed-off-by: Sam Eiderman shmuel.eiderman@oracle.com Signed-off-by: Liran Alon liran.alon@oracle.com --- src/fw/biostables.c | 36 ++++++++++++++++++++++++++++++++++++ src/fw/smbios.c | 20 +++++++++++++++++++- src/util.h | 1 + 3 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/src/fw/biostables.c b/src/fw/biostables.c index 546e83c6..90bb3b92 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -268,6 +268,38 @@ smbios_next(struct smbios_entry_point *smbios, void *prev) return prev; }
+// Get string from the smbios table. +void * +smbios_get_str(struct smbios_entry_point *smbios, void *offset, u8 n) +{ + if (!smbios || !offset || n == 0) + return NULL; + void *start = (void*)smbios->structure_table_address; + void *end = start + smbios->structure_table_length; + void *prev = NULL; + struct smbios_structure_header *hdr = offset; + + if (offset + sizeof(*hdr) > end) + return NULL; + + offset += hdr->length; + + while (n > 0) { + prev = offset; + while (*(u8*)offset) { + if (offset + 3 > end) + return NULL; /* not enough space for "\0\0" */ + offset++; + } + if (prev == offset) + return NULL; /* reached end of table */ + n--; + offset++; + } + + return prev; +} + struct smbios_entry_point *SMBiosAddr;
void @@ -409,6 +441,7 @@ smbios_romfile_setup(void) struct romfile_s *f_tables = romfile_find("etc/smbios/smbios-tables"); struct smbios_entry_point ep; struct smbios_type_0 *t0; + char *release_date; u16 qtables_len, need_t0 = 1; u8 *qtables, *tables;
@@ -432,6 +465,9 @@ smbios_romfile_setup(void) for (t0 = smbios_next(&ep, NULL); t0; t0 = smbios_next(&ep, t0)) if (t0->header.type == 0) { need_t0 = 0; + /* Sync BIOS hardcoded date with the SMBIOS provided one */ + release_date = smbios_get_str(&ep, t0, t0->bios_release_date_str); + smbios_update_bios_date(release_date); break; }
diff --git a/src/fw/smbios.c b/src/fw/smbios.c index 96104714..7cb02dba 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -160,12 +160,26 @@ get_external(int type, char **p, unsigned *nr_structs, } \ } while (0)
+void +smbios_update_bios_date(const char *release_date) +{ + if (!release_date) + return; + if (strlen(release_date) == sizeof("mm/dd/yyyy") - 1) { + memcpy(BiosDate, release_date, sizeof("mm/dd/") - 1); + memcpy(BiosDate + sizeof("mm/dd/") - 1, + release_date + sizeof("mm/dd/yy") - 1, + sizeof("yy") - 1); + } +} + /* Type 0 -- BIOS Information */ static void * smbios_init_type_0(void *start) { struct smbios_type_0 *p = (struct smbios_type_0 *)start; char *end = (char *)start + sizeof(struct smbios_type_0); + char *release_date; size_t size; int str_index = 0;
@@ -178,7 +192,11 @@ smbios_init_type_0(void *start)
p->bios_starting_address_segment = 0xe800;
- load_str_field_with_default(0, bios_release_date_str, BIOS_DATE); + /* Sync BIOS hardcoded date with the SMBIOS provided one */ + release_date = end; + load_str_field_with_default(0, bios_release_date_str, BiosDate); + if (p->bios_release_date_str) + smbios_update_bios_date(release_date);
p->bios_rom_size = 0; /* FIXME */
diff --git a/src/util.h b/src/util.h index 68ba848d..81cddbbd 100644 --- a/src/util.h +++ b/src/util.h @@ -84,6 +84,7 @@ void copy_smbios(void *pos); void display_uuid(void); void copy_table(void *pos); void smbios_setup(void); +void smbios_update_bios_date(const char *release_date);
// fw/coreboot.c extern const char *CBvendor, *CBpart;
Check that only one bios date appears in the final ROM.
The check simulates nt!CmpGetBiosDate() in order to ensure that Windows sees the correct date.
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@oracle.com Reviewed-by: Arbel Moshe arbel.moshe@oracle.com Signed-off-by: Sam Eiderman shmuel.eiderman@oracle.com Signed-off-by: Liran Alon liran.alon@oracle.com --- scripts/checkrom.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/scripts/checkrom.py b/scripts/checkrom.py index aced5e2c..98cdfa7f 100755 --- a/scripts/checkrom.py +++ b/scripts/checkrom.py @@ -17,6 +17,23 @@ def checksum(data, start, size, csum): sumbyte = buildrom.checksum(data[start:start+size]) return subst(data, start+csum, sumbyte)
+def check_windows_bios_date(rawdata): + dates = [] + for i in xrange(len(rawdata)): + if (rawdata[i+0:i+2].isdigit() and + rawdata[i+2] == '/' and + rawdata[i+3:i+5].isdigit() and + rawdata[i+5] == '/' and + rawdata[i+6:i+8].isdigit()): + dates.append(rawdata[i:i+8]) + if len(dates) > 1: + print("Warning! More than one date was detected in rom.") + print(" This may cause Windows OS to report incorrect date:") + print(" %s" % (dates, )) + if len(dates) == 0: + print("Warning! No dates were detected in rom.") + print(" This may cause Windows OS to report incorrect date.") + def main(): # Get args objinfo, finalsize, rawfile, outfile = sys.argv[1:] @@ -46,6 +63,8 @@ def main(): sys.exit(1)
# Sanity checks + check_windows_bios_date(rawdata) + start = symbols['code32flat_start'].offset end = symbols['code32flat_end'].offset expend = layoutrom.BUILD_BIOS_ADDR + layoutrom.BUILD_BIOS_SIZE
From: Liran Alon liran.alon@oracle.com
This is a workaround for the Windows kernel wrongly extracting SystemBiosVersion.
Windows kernel extracts various BIOS information at boot-time. The method it use to extract SystemBiosVersion is very hueristic. It is done by nt!CmpGetBiosVersion().
nt!CmpGetBiosVersion() works by scanning all BIOS memory from 0xF0000 to 0xFFFFF in search for a string of the form x.y where x & y are digits. When it finds such a string, it goes a bunch of characters backwards until an unknown character is reached, checks whether the string contains any of "v 0", "v 1", "Rev ", etc... if it does - a match was found. It then continues to find the next matches.
In our case, this lead to a debug-print string "Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev 00:02.0" to be treated as BIOS version (Because of "2.0" at the end, and the "v 0" contained in it).
This can be seen by: * Typing "wmic bios get biosversion" in CMD * Reading "HKLM\HARDWARE\DESCRIPTION\System" "SystemBiosVersion"
Therefore, this commit solves the issue by just modifying "00:02.0" to "00:02:00".
For reference implementation of nt!CmpGetBiosVersion(), see ReactOS: https://doxygen.reactos.org/d5/dd2/i386_2cmhardwr_8c.html
Reviewed-by: Konrad Rzeszutek Wilk konrad.wilk@oracle.com Reviewed-by: Arbel Moshe arbel.moshe@oracle.com Signed-off-by: Sam Eiderman shmuel.eiderman@oracle.com Signed-off-by: Liran Alon liran.alon@oracle.com --- src/fw/pciinit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index c0634bcb..4ab9b724 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -328,7 +328,7 @@ static void intel_igd_setup(struct pci_device *dev, void *arg) pci_config_writel(bdf, 0x5C, cpu_to_le32((u32)addr));
dprintf(1, "Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev " - "00:02.0\n", (u32)addr, bdsm_size >> 20); + "00:02:00\n", (u32)addr, bdsm_size >> 20); } }
Check that no version string appear in the final ROM.
The check simulates nt!CmpGetBiosVersion() in order to ensure that Windows sees the correct versions.
For reference implementation of nt!CmpGetBiosVersion(), see ReactOS: https://doxygen.reactos.org/d5/dd2/i386_2cmhardwr_8c.html
Reviewed-by: Konrad Rzeszutek Wilk konrad.wilk@oracle.com Reviewed-by: Arbel Moshe arbel.moshe@oracle.com Signed-off-by: Sam Eiderman shmuel.eiderman@oracle.com Signed-off-by: Liran Alon liran.alon@oracle.com --- scripts/checkrom.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/scripts/checkrom.py b/scripts/checkrom.py index 98cdfa7f..a09203fe 100755 --- a/scripts/checkrom.py +++ b/scripts/checkrom.py @@ -34,6 +34,31 @@ def check_windows_bios_date(rawdata): print("Warning! No dates were detected in rom.") print(" This may cause Windows OS to report incorrect date.")
+def check_windows_bios_version(rawdata): + versions = [] + for i in xrange(len(rawdata)): + if (rawdata[i+0].isdigit() and + rawdata[i+1] == '.' and + rawdata[i+2].isdigit()): + p = i-1 + while ((p >= 0) and (p > i+2-127) + and ord(rawdata[p]) >= ord(' ') + and rawdata[p] != '$'): + p -= 1 + version = rawdata[p+1:i+3] + for s in ["Ver", "Rev", "Rel", + "v0", "v1", "v2", "v3", "v4", + "v5", "v6", "v7", "v8", "v9", + "v 0", "v 1", "v 2", "v 3", "v 4", + "v 5", "v 6", "v 7", "v 8", "v 9"]: + if s in version: + versions.append((rawdata[p+1:i+3], i)) + break + if len(versions) > 0: + print("Warning! Version strings were detected in rom.") + print(" This may cause Windows OS to report incorrect version:") + print(" %s" % (versions, )) + def main(): # Get args objinfo, finalsize, rawfile, outfile = sys.argv[1:] @@ -64,6 +89,7 @@ def main():
# Sanity checks check_windows_bios_date(rawdata) + check_windows_bios_version(rawdata)
start = symbols['code32flat_start'].offset end = symbols['code32flat_end'].offset
Am 17.05.19 um 22:57 schrieb Sam Eiderman:
From: Liran Alon liran.alon@oracle.com
This is a workaround for the Windows kernel wrongly extracting SystemBiosVersion.
Windows kernel extracts various BIOS information at boot-time. The method it use to extract SystemBiosVersion is very hueristic. It is done by nt!CmpGetBiosVersion().
nt!CmpGetBiosVersion() works by scanning all BIOS memory from 0xF0000 to 0xFFFFF in search for a string of the form x.y where x & y are digits. When it finds such a string, it goes a bunch of characters backwards until an unknown character is reached, checks whether the string contains any of "v 0", "v 1", "Rev ", etc... if it does - a match was found. It then continues to find the next matches.
In our case, this lead to a debug-print string "Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev 00:02.0" to be treated as BIOS version (Because of "2.0" at the end, and the "v 0" contained in it).
This can be seen by: * Typing "wmic bios get biosversion" in CMD * Reading "HKLM\HARDWARE\DESCRIPTION\System" "SystemBiosVersion"
Therefore, this commit solves the issue by just modifying "00:02.0" to "00:02:00".
For reference implementation of nt!CmpGetBiosVersion(), see ReactOS: https://doxygen.reactos.org/d5/dd2/i386_2cmhardwr_8c.html
Reviewed-by: Konrad Rzeszutek Wilk konrad.wilk@oracle.com Reviewed-by: Arbel Moshe arbel.moshe@oracle.com Signed-off-by: Sam Eiderman shmuel.eiderman@oracle.com Signed-off-by: Liran Alon liran.alon@oracle.com
src/fw/pciinit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index c0634bcb..4ab9b724 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -328,7 +328,7 @@ static void intel_igd_setup(struct pci_device *dev, void *arg) pci_config_writel(bdf, 0x5C, cpu_to_le32((u32)addr));
dprintf(1, "Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev "
"00:02.0\n", (u32)addr, bdsm_size >> 20);
}"00:02:00\n", (u32)addr, bdsm_size >> 20); }
This changed notation for a PCI device looks weird, and AFAICS it is also inconsistent with other places printing PCI device locations. Replacing "dev " with "device " would fix the issue as well, but people grepping for "dev " would have a problem.
Regards, Carl-Daniel
What about this?
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index c0634bcb..4ab9b724 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -328,7 +328,7 @@ static void intel_igd_setup(struct pci_device *dev, void *arg) pci_config_writel(bdf, 0x5C, cpu_to_le32((u32)addr));
dprintf(1, "Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev " - "00:02.0\n", (u32)addr, bdsm_size >> 20); + "%s\n", (u32)addr, bdsm_size >> 20, "00:02.0"); } }
Regards, Carl-Daniel
Am 18.05.19 um 13:26 schrieb Shmuel Eiderman:
Or better yet, replacing the numbers with format string specifiers, not changing the string at all.
Sam
On May 18, 2019 14:20, Shmuel Eiderman shmuel.eiderman@oracle.com wrote:
True, "device" is a good option. What about "size: , dev:" (with colon - grepping for "dev " will still not work) or "dev " (two spaces - grepping will work but debug string looks a bit weird). Sam
I wanted it to look more consistent with a dprintf just a few lines above:
dprintf(1, "Intel IGD OpRegion enabled at 0x%08x, size %dKB, dev " "%02x:%02x.%x\n", (u32)addr, opregion->size >> 10, pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf));
What do you think?
Sam
On 18 May 2019, at 21:28, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
What about this?
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index c0634bcb..4ab9b724 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -328,7 +328,7 @@ static void intel_igd_setup(struct pci_device *dev, void *arg) pci_config_writel(bdf, 0x5C, cpu_to_le32((u32)addr));
dprintf(1, "Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev "
"00:02.0\n", (u32)addr, bdsm_size >> 20);
}"%s\n", (u32)addr, bdsm_size >> 20, "00:02.0"); }
Regards, Carl-Daniel
Am 18.05.19 um 13:26 schrieb Shmuel Eiderman:
Or better yet, replacing the numbers with format string specifiers, not changing the string at all.
Sam
On May 18, 2019 14:20, Shmuel Eiderman shmuel.eiderman@oracle.com wrote:
True, "device" is a good option. What about "size: , dev:" (with colon - grepping for "dev " will still not work) or "dev " (two spaces - grepping will work but debug string looks a bit weird).
Sam
Am 18.05.19 um 20:58 schrieb Sam Eiderman:
I wanted it to look more consistent with a dprintf just a few lines above:
dprintf(1, "Intel IGD OpRegion enabled at 0x%08x, size %dKB, dev " "%02x:%02x.%x\n", (u32)addr, opregion->size >> 10, pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf));
What do you think?
Even better.
Sam
Regards, Carl-Daniel
On 18 May 2019, at 21:28, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
What about this?
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index c0634bcb..4ab9b724 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -328,7 +328,7 @@ static void intel_igd_setup(struct pci_device *dev, void *arg) pci_config_writel(bdf, 0x5C, cpu_to_le32((u32)addr));
dprintf(1, "Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev "
"00:02.0\n", (u32)addr, bdsm_size >> 20);
}"%s\n", (u32)addr, bdsm_size >> 20, "00:02.0"); }
Regards, Carl-Daniel
Am 18.05.19 um 13:26 schrieb Shmuel Eiderman:
Or better yet, replacing the numbers with format string specifiers, not changing the string at all.
Sam
On May 18, 2019 14:20, Shmuel Eiderman shmuel.eiderman@oracle.com wrote:
True, "device" is a good option. What about "size: , dev:" (with colon - grepping for "dev " will still not work) or "dev " (two spaces - grepping will work but debug string looks a bit weird). Sam
On Sat, May 18, 2019 at 09:58:59PM +0300, Sam Eiderman wrote:
I wanted it to look more consistent with a dprintf just a few lines above:
dprintf(1, "Intel IGD OpRegion enabled at 0x%08x, size %dKB, dev " "%02x:%02x.%x\n", (u32)addr, opregion->size >> 10, pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf));
What do you think?
I'd use the dprintf(1, "%pP", dev) form instead.
-Kevin
On Fri, May 17, 2019 at 11:57:20PM +0300, Sam Eiderman wrote:
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.
Thanks. What's the high-level implication of getting this support correct? (That is, from a user's perspective, what works better when these patches are applied?)
-Kevin
On Fri, May 17, 2019 at 11:57:21PM +0300, Sam Eiderman wrote:
From: Liran Alon liran.alon@oracle.com
There are 2 places where SeaBIOS reports its release date:
1. SMBIOS Type 0 entry 2. Hard-coded address 0xFFFF5
Previous to this commit, each of these places defined it's own unique date which doesn't make sense.
Therefore, define the BIOS date in a single place and make sure all relevant places in code use it.
Reviewed-by: Konrad Rzeszutek Wilk konrad.wilk@oracle.com Reviewed-by: Arbel Moshe arbel.moshe@oracle.com Signed-off-by: Sam Eiderman shmuel.eiderman@oracle.com Signed-off-by: Liran Alon liran.alon@oracle.com
src/config.h | 11 +++++++++++ src/fw/biostables.c | 1 - src/fw/smbios.c | 3 +-- src/misc.c | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/config.h b/src/config.h index 93c8dbc2..6795440c 100644 --- a/src/config.h +++ b/src/config.h @@ -29,6 +29,17 @@ #define BUILD_SUBMODEL_ID 0x00 #define BUILD_BIOS_REVISION 0x01
+#define BIOS_DATE_MONTH "04" +#define BIOS_DATE_DAY "01" +#define BIOS_DATE_YEAR "14" +#define BIOS_DATE_YEAR_PREFIX "20" +#define BIOS_DATE (BIOS_DATE_MONTH "/" \
BIOS_DATE_DAY "/" \
BIOS_DATE_YEAR_PREFIX BIOS_DATE_YEAR)
+#define BIOS_DATE_SHORT (BIOS_DATE_MONTH "/" \
BIOS_DATE_DAY "/" \
BIOS_DATE_YEAR)
// Various memory addresses used by the code. #define BUILD_STACK_ADDR 0x7000 #define BUILD_S3RESUME_STACK_ADDR 0x1000 diff --git a/src/fw/biostables.c b/src/fw/biostables.c index fe8626ef..b055c9b2 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -401,7 +401,6 @@ smbios_new_type_0(void *start, }
#define BIOS_NAME "SeaBIOS" -#define BIOS_DATE "04/01/2014"
Thanks, however, this would change the contents of the smbios tables for existing QEMU machine types. We've seen in the past that any change to these tables can cause some OSes to perform unwanted behavior. In general, if something in the smbios table needs to be modified, then it's the role of QEMU (or similar) to pass in the desired content.
[...]
static int smbios_romfile_setup(void) diff --git a/src/fw/smbios.c b/src/fw/smbios.c index 62a563b2..96104714 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -161,7 +161,6 @@ get_external(int type, char **p, unsigned *nr_structs, } while (0)
/* Type 0 -- BIOS Information */ -#define RELEASE_DATE_STR "01/01/2011" static void * smbios_init_type_0(void *start) { @@ -179,7 +178,7 @@ smbios_init_type_0(void *start)
p->bios_starting_address_segment = 0xe800;
- load_str_field_with_default(0, bios_release_date_str, RELEASE_DATE_STR);
- load_str_field_with_default(0, bios_release_date_str, BIOS_DATE);
Similarly, we don't want to make any content changes to the legacy src/fw/smbios.c file. At this point, we want the legacy smbios tables to remain identical in content.
p->bios_rom_size = 0; /* FIXME */
diff --git a/src/misc.c b/src/misc.c index b5117304..189d487b 100644 --- a/src/misc.c +++ b/src/misc.c @@ -174,7 +174,7 @@ struct descloc_s rombios32_gdt_48 VARFSEG = { ****************************************************************/
// BIOS build date -char BiosDate[] VARFSEGFIXED(0xfff5) = "06/23/99"; +char BiosDate[] VARFSEGFIXED(0xfff5) = BIOS_DATE_SHORT;
I'm concerned that this could cause regressions with old software. My vague understanding is that the 1999 date was used because some very old (DOS era) software would do a simple greater/less-than comparison on the year to test for certain bios features. If a small year (eg, "14") is used there is a fear that these old programs my change behavior.
As with the smbios tables, the goal of the dates in seabios is purely for compatibility.
-Kevin
u8 BiosModelId VARFSEGFIXED(0xfffe) = BUILD_MODEL_ID;
-- 2.13.3
On Fri, May 17, 2019 at 11:57:23PM +0300, Sam Eiderman wrote:
From: Liran Alon liran.alon@oracle.com
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).
FWIW, if you want to ensure a stable date is found, it's probably simpler to force a valid date string to be present in the f-segment. Something like: char win_bios_date[] VARFSEG = " 04/01/2014 ";
As with my previous emails, I'd recommend using a hard-coded date (not a build date) - as this tends to improve reproducibility.
-Kevin
On 20 May 2019, at 5:28, Kevin O'Connor kevin@koconnor.net wrote:
On Fri, May 17, 2019 at 11:57:23PM +0300, Sam Eiderman wrote:
From: Liran Alon liran.alon@oracle.com
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).
FWIW, if you want to ensure a stable date is found, it's probably simpler to force a valid date string to be present in the f-segment. Something like: char win_bios_date[] VARFSEG = " 04/01/2014 ";
As with my previous emails, I'd recommend using a hard-coded date (not a build date) - as this tends to improve reproducibility.
The thing is, if the date reported by smbios tables is 05/02/2015 (which is bigger than 04/01/2014) so: If smbios tables are in fseg - Windows will select the most recent date - 05/02/2015 If not - Windows will select the most recent date (the only one it found) - 04/01/2014
So 'char win_bios_date[] VARFSEG = " 04/01/2014 “‘ will not help.
Sam
-Kevin
Oh my. Use of non-ISO8601 format in any form of computer code need to be sanctioned.
On Wed, May 22, 2019 at 9:50 AM Sam Eiderman shmuel.eiderman@oracle.com wrote:
On 20 May 2019, at 5:28, Kevin O'Connor kevin@koconnor.net wrote:
On Fri, May 17, 2019 at 11:57:23PM +0300, Sam Eiderman wrote:
From: Liran Alon liran.alon@oracle.com
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).
FWIW, if you want to ensure a stable date is found, it's probably simpler to force a valid date string to be present in the f-segment. Something like: char win_bios_date[] VARFSEG = " 04/01/2014 ";
As with my previous emails, I'd recommend using a hard-coded date (not a build date) - as this tends to improve reproducibility.
The thing is, if the date reported by smbios tables is 05/02/2015 (which is bigger than 04/01/2014) so:
- If smbios tables are in fseg - Windows will select the most recent
date - 05/02/2015
- If not - Windows will select the most recent date (the only one it
found) - 04/01/2014
So 'char win_bios_date[] VARFSEG = " 04/01/2014 “‘ will not help.
Sam
-Kevin
SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
On Wed, May 22, 2019 at 04:49:35PM +0300, Sam Eiderman wrote:
On 20 May 2019, at 5:28, Kevin O'Connor kevin@koconnor.net wrote: On Fri, May 17, 2019 at 11:57:23PM +0300, Sam Eiderman wrote:
From: Liran Alon liran.alon@oracle.com
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).
FWIW, if you want to ensure a stable date is found, it's probably simpler to force a valid date string to be present in the f-segment. Something like: char win_bios_date[] VARFSEG = " 04/01/2014 ";
As with my previous emails, I'd recommend using a hard-coded date (not a build date) - as this tends to improve reproducibility.
The thing is, if the date reported by smbios tables is 05/02/2015 (which is bigger than 04/01/2014) so: If smbios tables are in fseg - Windows will select the most recent date - 05/02/2015 If not - Windows will select the most recent date (the only one it found) - 04/01/2014
So 'char win_bios_date[] VARFSEG = " 04/01/2014 “‘ will not help.
Why would the smbios tables have a newer date? If you mean that qemu is providing smbios table 0 and its date is newer, then seabios could do something like:
memcpy(win_bios_date, s->bios_release_date_str, sizeof(win_bios_date));
Also, what problem occurs if sometimes 04/01/2014 is found and sometimes 05/02/2015 is found?
-Kevin
See the v2 implementation of this patch.
I replaced:
--- @@ -328,7 +328,8 @@ static void intel_igd_setup(struct pci_device *dev, void *arg) pci_config_writel(bdf, 0x5C, cpu_to_le32((u32)addr));
dprintf(1, "Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev " - "00:02.0\n", (u32)addr, bdsm_size >> 20); + "%02x:%02x.%x\n", (u32)addr, bdsm_size >> 20, + 0, 2, 0); } } ---
So it will look like the format string a few lines above:
dprintf(1, "Intel IGD OpRegion enabled at 0x%08x, size %dKB, dev “ "%02x:%02x.%x\n", (u32)addr, opregion->size >> 10, pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf));
This solves the version problem
Sam
On 20 May 2019, at 5:10, Kevin O'Connor kevin@koconnor.net wrote:
On Sat, May 18, 2019 at 09:58:59PM +0300, Sam Eiderman wrote:
I wanted it to look more consistent with a dprintf just a few lines above:
dprintf(1, "Intel IGD OpRegion enabled at 0x%08x, size %dKB, dev " "%02x:%02x.%x\n", (u32)addr, opregion->size >> 10, pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf));
What do you think?
I'd use the dprintf(1, "%pP", dev) form instead.
-Kevin
Hi,
The thing is, if the date reported by smbios tables is 05/02/2015 (which is bigger than 04/01/2014) so: If smbios tables are in fseg - Windows will select the most recent date - 05/02/2015 If not - Windows will select the most recent date (the only one it found) - 04/01/2014
So 'char win_bios_date[] VARFSEG = " 04/01/2014 “‘ will not help.
Why would the smbios tables have a newer date? If you mean that qemu is providing smbios table 0 and its date is newer,
qemu doesn't provide table 0 (by default, possibly there is a obscure command line switch to change that), so seabios will generate it and the two dates should match.
I kind of fail to see the problem the patch series tries to solve ...
cheers, Gerd
Hi,
Many programs use SystemBiosDate registry key in order to verify the machine they are running on (mostly for activation/licensing purposes). This registry key is read only and is computed as explained before. When this date changes - this may break the behavior of the machine.
This date never changes - unless used in virtual environments such as qemu.
This series help with: * Ensuring this date never changes when smbios tables change * Letting the user choose the date which will appear in the SystemBiosDate registry key Under QEMU.
Before this patch: F-SEG contains the following dates: ['04/01/2014', '01/01/2011', '06/23/99’] F-SEG(0xfff5) contains '06/23/99’ Legacy SMBIOS Bios Date is '01/01/2011’ Non-Legacy SMBIOS Bios Date is '04/01/2014'
Running SeaBIOS on non-qemu machines gives: F-SEG(0xfff5) contains '06/23/99’ Legacy SMBIOS is used and thus smbios type 0 returns '01/01/2011’ Windows machines show SystemBiosDate of '04/01/2014’
* Notice how the SystemBiosDate has changed for non-qemu machines to '04/01/2014’ once biostables.c was introduced (non legacy smbios)
Running SeaBIOS on qemu "-machine pc-i440fx-2.0” without "smbios_type0.date” reporting machines gives: F-SEG(0xfff5) contains '06/23/99’ Legacy SMBIOS is used and thus smbios type 0 returns '01/01/2011’ Windows machines show SystemBiosDate of '04/01/2014’
* Notice how the SystemBiosDate has changed for qemu pc-i440fx-2.0 machines to '04/01/2014’ once biostables.c was introduced (non legacy smbios)
Same as running SeaBIOS on non-qemu machines.
Notice that if we do supply smbios_type0.date - if it is before '04/01/2014’ - SystemBiosDate will not change - since it selects the last date it encouters. If it is after '04/01/2014’, it will change SystemBiosDate only if smbios tables are allocated in FSEG - this depends on other smbios keys as well (for the total length check) this is implemented in smbios.c If it is after ’01/01/2080’ (not really interesting case), the ’06/23/99’ will be selected since MM/DD/80 is considered 1980 by SystemBiosDate.
Running SeaBIOS on on qemu "-machine pc-i440fx-2.1+” without "smbios_type0.date” reporting machines gives: F-SEG(0xfff5) contains '06/23/99’ Non-Legacy SMBIOS is used and thus smbios type 0 returns '04/01/2014’ Windows machines show SystemBiosDate of '04/01/2014’
Same as running SeaBIOS on non-qemu machines.
Notice that if we do supply smbios_type0.date - if it is before '04/01/2014’ - SystemBiosDate will not change - since it selects the last date it encouters. If it is after '04/01/2014’, it will change SystemBiosDate only if smbios tables are allocated in FSEG - this depends on other smbios keys as well (for the total length check) this is implemented in biostables.c If it is after ’01/01/2080’ (not really interesting case), the ’06/23/99’ will be selected since MM/DD/80 is considered 1980 by SystemBiosDate.
If we want to control the value in SystemBiosDate controllable/stable for qemu users - we must control all dates that appear in the FSEG section - which is impossible today. This helps fixing v2v migration scenarios and the editing of smbios tables.
It is true, like Kevin mentioned, that the current patch series might break existing qemu/non-qemu machines, so a better v3 is required, maybe introduce some new “/etc/win-systembiosdate” fw_cfg key, but I just wanted to explain what made us make the changes in SeaBIOS.
The SystemBiosVersion change was made since the debug string "'Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev 00:02.0’” was seen in the same registry path, fixing it is not expected to change guest behavior (SystemBiosVersion is a REG_MULTI_SZ key and may contain multiple version strings and it is not checked as the SystemBiosDate key which is REG_SZ) - so the changes for it can be taken from the v2 series.
Sam
On 23 May 2019, at 12:29, Gerd Hoffmann kraxel@redhat.com wrote:
Hi,
The thing is, if the date reported by smbios tables is 05/02/2015 (which is bigger than 04/01/2014) so: If smbios tables are in fseg - Windows will select the most recent date - 05/02/2015 If not - Windows will select the most recent date (the only one it found) - 04/01/2014
So 'char win_bios_date[] VARFSEG = " 04/01/2014 “‘ will not help.
Why would the smbios tables have a newer date? If you mean that qemu is providing smbios table 0 and its date is newer,
qemu doesn't provide table 0 (by default, possibly there is a obscure command line switch to change that), so seabios will generate it and the two dates should match.
I kind of fail to see the problem the patch series tries to solve ...
cheers, Gerd
On Thu, May 23, 2019 at 04:11:21PM +0300, Sam Eiderman wrote:
Many programs use SystemBiosDate registry key in order to verify the machine they are running on (mostly for activation/licensing purposes). This registry key is read only and is computed as explained before. When this date changes - this may break the behavior of the machine.
Okay, thanks.
This date never changes - unless used in virtual environments such as qemu.
This series help with:
- Ensuring this date never changes when smbios tables change
- Letting the user choose the date which will appear in the SystemBiosDate registry key
Under QEMU.
Before this patch:
[...]
I understand. If we ensured the smbios date is always in the f-segment, would that also solve the problem? (That is, using the 'char win_bios_date[] VARFSEG' method discussed previously.)
The SystemBiosVersion change was made since the debug string "'Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev 00:02.0’” was seen in the same registry path, fixing it is not expected to change guest behavior (SystemBiosVersion is a REG_MULTI_SZ key and may contain multiple version strings and it is not checked as the SystemBiosDate key which is REG_SZ) - so the changes for it can be taken from the v2 series.
Agreed, but I think using %pP is preferable. I sent a corresponding patch to the mailing list.
-Kevin
On 23 May 2019, at 18:54, Kevin O'Connor kevin@koconnor.net wrote:
On Thu, May 23, 2019 at 04:11:21PM +0300, Sam Eiderman wrote:
Many programs use SystemBiosDate registry key in order to verify the machine they are running on (mostly for activation/licensing purposes). This registry key is read only and is computed as explained before. When this date changes - this may break the behavior of the machine.
Okay, thanks.
This date never changes - unless used in virtual environments such as qemu.
This series help with:
- Ensuring this date never changes when smbios tables change
- Letting the user choose the date which will appear in the SystemBiosDate registry key
Under QEMU.
Before this patch:
[...]
I understand. If we ensured the smbios date is always in the f-segment, would that also solve the problem? (That is, using the 'char win_bios_date[] VARFSEG' method discussed previously.)
That would only be half of the solution, since F-SEG contains the following dates: ['04/01/2014', '01/01/2011', '06/23/99’] It means that no matter what is found in "char win_bios_date[] VARFSEG”, SystemBiosDate will always be a date of ’04/01/2014’ or later. To really control the output of SystemBiosDate, all dates in SeaBIOS’s F-SEG should be the desired SystemBiosDate (or older).
Sam
The SystemBiosVersion change was made since the debug string "'Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev 00:02.0’” was seen in the same registry path, fixing it is not expected to change guest behavior (SystemBiosVersion is a REG_MULTI_SZ key and may contain multiple version strings and it is not checked as the SystemBiosDate key which is REG_SZ) - so the changes for it can be taken from the v2 series.
Agreed, but I think using %pP is preferable. I sent a corresponding patch to the mailing list.
Took me a while to find the put_pci_device() implementation for %pP. Looks great.
-Kevin
On Thu, May 23, 2019 at 06:58:57PM +0300, Sam Eiderman wrote:
On 23 May 2019, at 18:54, Kevin O'Connor kevin@koconnor.net wrote: I understand. If we ensured the smbios date is always in the f-segment, would that also solve the problem? (That is, using the 'char win_bios_date[] VARFSEG' method discussed previously.)
That would only be half of the solution, since F-SEG contains the following dates: ['04/01/2014', '01/01/2011', '06/23/99’] It means that no matter what is found in "char win_bios_date[] VARFSEG”, SystemBiosDate will always be a date of ’04/01/2014’ or later. To really control the output of SystemBiosDate, all dates in SeaBIOS’s F-SEG should be the desired SystemBiosDate (or older).
Under normal circumstances, the 32bit init code is relocated out of the f-segment. Unfortunately, that doesn't work for anonymous strings. One simple trick, though, is to force these problematic strings into named variables (see patch below).
-Kevin
diff --git a/src/fw/biostables.c b/src/fw/biostables.c index fe8626e..269b858 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 62a563b..8e7ee6a 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -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 const char RELEASE_DATE_STR[] = "01/01/2011"; static void * smbios_init_type_0(void *start) {
I actually love this idea.
So we can now expect only ’06/23/99’ date string to reside in F-SEG at build time. This will allow setting the SystemBiosDate to all dates from 06/23/99 to 01/01/80 (2080) which is reasonable enough.
So now we will copy the smbios0.date to "char win_bios_date[] VARFSEG” and allow setting the SystemBiosDate to the smbios supplied one.
The only question now is what to do in the Legacy SMBIOS case where the SMBIOS value which is exposed today is 01/01/2011 but the value in SystemBiosDate is 04/01/2014?
Option A: Change the Legacy smbios0 date to 04/01/2014, not sure how this affects machines. Option B: win_bios_date will be 01/01/2011 too - but this will change the SystemBiosDate value - which might break applications that currently rely that it’s 04/01/2014 as reported now. Option C: win_bios_date will always be 04/01/2014, default legacy smbios0.date is 01/01/2011, overriding the legacy smbios0.date will override win_bios_date too.
I’m inclined to implement option C since it doesn’t break current functionality, what do you think?
Sam
On 23 May 2019, at 19:29, Kevin O'Connor kevin@koconnor.net wrote:
On Thu, May 23, 2019 at 06:58:57PM +0300, Sam Eiderman wrote:
On 23 May 2019, at 18:54, Kevin O'Connor kevin@koconnor.net wrote: I understand. If we ensured the smbios date is always in the f-segment, would that also solve the problem? (That is, using the 'char win_bios_date[] VARFSEG' method discussed previously.)
That would only be half of the solution, since F-SEG contains the following dates: ['04/01/2014', '01/01/2011', '06/23/99’] It means that no matter what is found in "char win_bios_date[] VARFSEG”, SystemBiosDate will always be a date of ’04/01/2014’ or later. To really control the output of SystemBiosDate, all dates in SeaBIOS’s F-SEG should be the desired SystemBiosDate (or older).
Under normal circumstances, the 32bit init code is relocated out of the f-segment. Unfortunately, that doesn't work for anonymous strings. One simple trick, though, is to force these problematic strings into named variables (see patch below).
-Kevin
diff --git a/src/fw/biostables.c b/src/fw/biostables.c index fe8626e..269b858 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 62a563b..8e7ee6a 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -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 const char RELEASE_DATE_STR[] = "01/01/2011"; static void * smbios_init_type_0(void *start) {
Hi,
- Letting the user choose the date which will appear in the SystemBiosDate registry key
Under QEMU.
Ah, *this* is why qemu provides a type0 table. What is the use case for this?
Legacy SMBIOS Bios Date is '01/01/2011’
Maybe it's time add a config option to compile out support for legacy acpi / smbios tables. The qemu versions which need that are a few years old meanwhile ...
cheers, Gerd
Kevin,
Notice that your patch changes SystemBiosDate for legacy smbios users from 04/01/14 to 01/01/11 - I’m okay with this change.
Also notice that the RELEASE_DATE_STR[] in smbios.c has to be volatile or else it is optimized, unlike BIOS_DATE[] which is used in a function call and is not optimized.
So the patch should be:
diff --git a/src/fw/biostables.c b/src/fw/biostables.c index fe8626ef..718926d7 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..fc4dcfe2 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c
@@ -134,7 +141,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 +168,7 @@ get_external(int type, char **p, unsigned *nr_structs, } while (0)
/* Type 0 -- BIOS Information */ -#define RELEASE_DATE_STR "01/01/2011" +const char volatile RELEASE_DATE_STR[] = "01/01/2011"; static void * smbios_init_type_0(void *start) { —
Sam
On 24 May 2019, at 7:52, Gerd Hoffmann kraxel@redhat.com wrote:
Hi,
- Letting the user choose the date which will appear in the SystemBiosDate registry key
Under QEMU.
Ah, *this* is why qemu provides a type0 table. What is the use case for this?
The thing is that SystemBiosDate is different than the value in smbios0.date, at least on a legacy bios.
Legacy SMBIOS Bios Date is '01/01/2011’
Maybe it's time add a config option to compile out support for legacy acpi / smbios tables. The qemu versions which need that are a few years old meanwhile …
I don’t know who uses legacy smbios at the moment except for qemu machines < 2.1 but adding a config option is always nice.
Actually I think we used legacy smbios in v2v scenarios from VMware/PhoenixBios to QEMU/SeaBIOS (with hwversion < 12).
cheers, Gerd
Kevin,
I have used your method to clean FSEG from unwanted date strings and added a new fw_cfg to control the date that will eventually appear in SystemBiosDate.
New patches submitted.
Thanks, Sam
On 24 May 2019, at 19:35, Sam Eiderman shmuel.eiderman@oracle.com wrote:
Kevin,
Notice that your patch changes SystemBiosDate for legacy smbios users from 04/01/14 to 01/01/11 - I’m okay with this change.
Also notice that the RELEASE_DATE_STR[] in smbios.c has to be volatile or else it is optimized, unlike BIOS_DATE[] which is used in a function call and is not optimized.
So the patch should be:
diff --git a/src/fw/biostables.c b/src/fw/biostables.c index fe8626ef..718926d7 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..fc4dcfe2 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c
@@ -134,7 +141,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 +168,7 @@ get_external(int type, char **p, unsigned *nr_structs, } while (0)
/* Type 0 -- BIOS Information */ -#define RELEASE_DATE_STR "01/01/2011" +const char volatile RELEASE_DATE_STR[] = "01/01/2011"; static void * smbios_init_type_0(void *start) { —
Sam
On 24 May 2019, at 7:52, Gerd Hoffmann kraxel@redhat.com wrote:
Hi,
- Letting the user choose the date which will appear in the SystemBiosDate registry key
Under QEMU.
Ah, *this* is why qemu provides a type0 table. What is the use case for this?
The thing is that SystemBiosDate is different than the value in smbios0.date, at least on a legacy bios.
Legacy SMBIOS Bios Date is '01/01/2011’
Maybe it's time add a config option to compile out support for legacy acpi / smbios tables. The qemu versions which need that are a few years old meanwhile …
I don’t know who uses legacy smbios at the moment except for qemu machines < 2.1 but adding a config option is always nice.
Actually I think we used legacy smbios in v2v scenarios from VMware/PhoenixBios to QEMU/SeaBIOS (with hwversion < 12).
cheers, Gerd
SeaBIOS mailing list -- seabios@seabios.org mailto:seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org mailto:seabios-leave@seabios.org