:p
atchew
Login
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 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100644 --- a/src/config.h +++ b/src/config.h @@ -XXX,XX +XXX,XX @@ #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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -XXX,XX +XXX,XX @@ 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) { @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/src/misc.c +++ b/src/misc.c @@ -XXX,XX +XXX,XX @@ 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; -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/src/util.h +++ b/src/util.h @@ -XXX,XX +XXX,XX @@ #ifndef __UTIL_H #define __UTIL_H +#include "config.h" // BIOS_DATE_SHORT #include "types.h" // u32 // apm.c @@ -XXX,XX +XXX,XX @@ 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); -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/src/util.h +++ b/src/util.h @@ -XXX,XX +XXX,XX @@ 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; -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100755 --- a/scripts/checkrom.py +++ b/scripts/checkrom.py @@ -XXX,XX +XXX,XX @@ 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:] @@ -XXX,XX +XXX,XX @@ 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 -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -XXX,XX +XXX,XX @@ 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); } } -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100755 --- a/scripts/checkrom.py +++ b/scripts/checkrom.py @@ -XXX,XX +XXX,XX @@ 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:] @@ -XXX,XX +XXX,XX @@ def main(): # Sanity checks check_windows_bios_date(rawdata) + check_windows_bios_version(rawdata) start = symbols['code32flat_start'].offset end = symbols['code32flat_end'].offset -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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@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 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100644 --- a/src/config.h +++ b/src/config.h @@ -XXX,XX +XXX,XX @@ #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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -XXX,XX +XXX,XX @@ 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) { @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/src/misc.c +++ b/src/misc.c @@ -XXX,XX +XXX,XX @@ 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; -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/src/util.h +++ b/src/util.h @@ -XXX,XX +XXX,XX @@ #ifndef __UTIL_H #define __UTIL_H +#include "config.h" // BIOS_DATE_SHORT #include "types.h" // u32 // apm.c @@ -XXX,XX +XXX,XX @@ 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); -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/src/util.h +++ b/src/util.h @@ -XXX,XX +XXX,XX @@ 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; -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100755 --- a/scripts/checkrom.py +++ b/scripts/checkrom.py @@ -XXX,XX +XXX,XX @@ 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:] @@ -XXX,XX +XXX,XX @@ 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 -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 creating the "00:02.0" string dynamically, like in the rest of the file. 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 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index XXXXXXX..XXXXXXX 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -XXX,XX +XXX,XX @@ 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); } } -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 XXXXXXX..XXXXXXX 100755 --- a/scripts/checkrom.py +++ b/scripts/checkrom.py @@ -XXX,XX +XXX,XX @@ 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:] @@ -XXX,XX +XXX,XX @@ def main(): # Sanity checks check_windows_bios_date(rawdata) + check_windows_bios_version(rawdata) start = symbols['code32flat_start'].offset end = symbols['code32flat_end'].offset -- 2.13.3 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org