summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--CHANGELOG98
-rw-r--r--README7
-rw-r--r--biosdecode.c34
-rw-r--r--debian/README.source18
-rw-r--r--debian/changelog26
-rw-r--r--debian/compat2
-rw-r--r--debian/control17
-rw-r--r--debian/copyright4
-rw-r--r--debian/files1
-rw-r--r--debian/patches/series14
-rwxr-xr-xdebian/rules3
-rw-r--r--dmidecode.c410
-rw-r--r--dmiopt.c41
-rw-r--r--man/dmidecode.87
-rw-r--r--util.c69
-rw-r--r--util.h4
-rw-r--r--version.h2
18 files changed, 627 insertions, 132 deletions
diff --git a/AUTHORS b/AUTHORS
index d4badfa..748b985 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -19,6 +19,8 @@ Jarod Wilson <jarod@redhat.com>
Anton Arapov <anton@redhat.com>
Roy Franz <roy.franz@linaro.org>
Tyler Bell <tyler.bell@hp.com>
+Xie XiuQi <xiexiuqi@huawei.com>
+Petr Oros <poros@redhat.com>
MANY THANKS TO (IN CHRONOLOGICAL ORDER)
Werner Heuser
diff --git a/CHANGELOG b/CHANGELOG
index f0a51a4..6f9123d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,103 @@
2015-09-03 Jean Delvare <jdelvare@suse.de>
+ * version.h: Set version to 3.1.
+
+2017-05-23 Jean Delvare <jdelvare@suse.de>
+
+ * dmidecode.c, dmiopt.c: Add a new option to extract OEM strings, like
+ we already have for many other strings.
+ * dmidecode.8: Document the new option.
+
+2017-04-27 Jean Delvare <jdelvare@suse.de>
+
+ Update to support SMBIOS specification version 3.1.1.
+
+ * dmidecode.c: Add support for 3-digit versions.
+ * dmidecode.c: Add new enumerated values for processors (DMI type 4).
+
+2017-04-27 Jean Delvare <jdelvare@suse.de>
+
+ Update to support SMBIOS specification version 3.1.0.
+
+ * dmidecode.c: Add support for extended BIOS ROM size (DMI type 0).
+ * dmidecode.c: Add new enumerated values for chassis types
+ (DMI type 3).
+ * dmidecode.c: Add new enumerated values for processors (DMI type 4).
+ * dmidecode.c: Don't assume 8-bit processor family in dmi_processor_id
+ (DMI type 4).
+ * dmidecode.c: Decode the MIDR register on ARM processors
+ (DMI type 4).
+ * dmidecode.c: Add support for large cache sizes (DMI type 7).
+ * dmidecode.c: Add Mini PCIe system slot enumerated values
+ (DMI type 9).
+ * dmidecode.c: Clarify the memory speed unit (DMI type 17).
+ * dmidecode.c: Add support for structure type 43 (TPM Device).
+
+2017-04-11 Jean Delvare <jdelvare@suse.de>
+
+ * util.c: Don't leak a file descriptor in function read_file.
+ * util.c, util.c, dmidecode.c: Let callers pass an offset to function
+ read_file.
+ * dmidecode.c: Fix reading from SMBIOS 3 dump files using a 64-bit
+ entry point.
+
+2017-04-10 Jean Delvare <jdelvare@suse.de>
+
+ * dmidecode.c: Decode the processor ID of the Intel Core M, AMD
+ Athlon X4 and AMD Opteron X1000/X2000 processors (DMI type 4).
+ * dmidecode.c: Display the IPMI interrupt number as a decimal
+ number (DMI type 38).
+
+2017-01-20 Jean Delvare <jdelvare@suse.de>
+
+ * biosdecode.c: Decode the entry point defined in the Intel
+ Multiprocessor specification.
+
+2017-01-20 Jean Delvare <jdelvare@suse.de>
+
+ * dmidecode.c: Only decode one DMI table.
+ This fixes Savannah bug #50022:
+ https://savannah.nongnu.org/bugs/?50022
+
+2016-09-22 Jean Delvare <jdelvare@suse.de>
+
+ * README: Explain that we can no longer support Cygwin.
+
+2016-06-30 Petr Oros <poros@redhat.com>
+
+ * dmidecode.c: Unmask LRDIMM in memory type detail (DMI type 17).
+
+2015-11-02 Jean Delvare <jdelvare@suse.de>
+
+ * dmidecode.c, util.c, util.h: Let read_file return the actual data
+ size.
+ * dmidecode.c: Use read_file to read the DMI table from sysfs.
+ This fixes Savannah bug #46176:
+ https://savannah.nongnu.org/bugs/?46176
+ * dmidecode.c: Check the sysfs entry point length.
+
+2015-10-21 Xie XiuQi <xiexiuqi@huawei.com>
+
+ * dmidecode.c: Handle SMBIOS 3.0 entry points on EFI systems.
+
+2015-10-20 Jean Delvare <jdelvare@suse.de>
+
+ * dmidecode.c: Handle OEM-specific types in group associations
+ (DMI type 14).
+
+2015-10-14 Jean Delvare <jdelvare@suse.de>
+
+ * util.c: Avoid SIGBUS on mmap failure.
+ This fixes Savannah bug #46066:
+ https://savannah.nongnu.org/bugs/?46066
+ * util.c: Fix error paths in mem_chunk.
+
+2015-10-01 Roy Franz <roy.franz@linaro.org>
+
+ * dmiopt.c: Add "--no-sysfs" option description to -h output.
+
+2015-09-03 Jean Delvare <jdelvare@suse.de>
+
* version.h: Set version to 3.0.
2015-08-04 Tyler Bell <tyler.bell@hp.com>
diff --git a/README b/README
index 391a5cb..f612b36 100644
--- a/README
+++ b/README
@@ -28,7 +28,7 @@ and other interesting material, such as a list of related projects and
articles.
This program was first written for Linux, and has since been reported to work
-on FreeBSD, NetBSD, OpenBSD, BeOS, Cygwin and Solaris as well.
+on FreeBSD, NetBSD, OpenBSD, BeOS and Solaris as well.
There's no configure script, so simply run "make" to build dmidecode, and
"make install" to install it. You also can use "make uninstall" to remove
@@ -83,9 +83,8 @@ successfully run.
CYGWIN
-Dmidecode was reported to work under Cygwin. It seems that /dev/mem doesn't
-work properly before version 1.5.10 though, so you will need to use at least
-this version.
+Dmidecode used to work under Cygwin. However the /dev/mem interface was
+removed at some point in time so it no longer works.
** MISCELLANEOUS TOOLS **
diff --git a/biosdecode.c b/biosdecode.c
index 3bbfe28..ad3d4bc 100644
--- a/biosdecode.c
+++ b/biosdecode.c
@@ -2,7 +2,7 @@
* BIOS Decode
*
* Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
- * Copyright (C) 2002-2015 Jean Delvare <jdelvare@suse.de>
+ * Copyright (C) 2002-2017 Jean Delvare <jdelvare@suse.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -52,6 +52,9 @@
* - Fujitsu application panel technical details
* As of July 23rd, 2004
* http://apanel.sourceforge.net/tech.php
+ * - Intel Multiprocessor Specification
+ * Version 1.4
+ * http://www.intel.com/design/archives/processors/pro/docs/242016.htm
*/
#include <stdio.h>
@@ -546,6 +549,34 @@ static int fjkeyinf_decode(const u8 *p, size_t len)
}
/*
+ * Intel Multiprocessor
+ */
+
+static size_t mp_length(const u8 *p)
+{
+ return 16 * p[8];
+}
+
+static int mp_decode(const u8 *p, size_t len)
+{
+ if (!checksum(p, len))
+ return 0;
+
+ printf("Intel Multiprocessor present.\n");
+ printf("\tSpecification Revision: %s\n",
+ p[9] == 0x01 ? "1.1" : p[9] == 0x04 ? "1.4" : "Invalid");
+ if (p[11])
+ printf("\tDefault Configuration: #%d\n", p[11]);
+ else
+ printf("\tConfiguration Table Address: 0x%08X\n",
+ DWORD(p + 4));
+ printf("\tMode: %s\n", p[12] & (1 << 7) ?
+ "IMCR and PIC" : "Virtual Wire");
+
+ return 1;
+}
+
+/*
* Main
*/
@@ -562,6 +593,7 @@ static struct bios_entry bios_entries[] = {
{ "32OS", 0, 0xE0000, 0xFFFFF, compaq_length, compaq_decode },
{ "\252\125VPD", 0, 0xF0000, 0xFFFFF, vpd_length, vpd_decode },
{ "FJKEYINF", 0, 0xF0000, 0xFFFFF, fjkeyinf_length, fjkeyinf_decode },
+ { "_MP_", 0, 0xE0000, 0xFFFFF, mp_length, mp_decode },
{ NULL, 0, 0, 0, NULL, NULL }
};
diff --git a/debian/README.source b/debian/README.source
new file mode 100644
index 0000000..e4f2b3d
--- /dev/null
+++ b/debian/README.source
@@ -0,0 +1,18 @@
+Hello,
+
+now I use the branching model from Vincent Driessen[1].
+
+I use the gitflow-avh[2]. with the Documentation[3].
+The Debian package can be found here[4].
+
+Please upload unattended uploads use a branch feature/<your title>.
+
+
+Many thanks.
+
+ -- Jörg Frings-Fürst <debian@jff-webhosting.net> Fri, 02 Jun 2017 19:00:40 +0200
+
+[1] http://nvie.com/posts/a-successful-git-branching-model/
+[2] https://github.com/petervanderdoes/gitflow-avh
+[3] https://github.com/petervanderdoes/gitflow-avh/wiki
+[4] https://tracker.debian.org/pkg/git-flow
diff --git a/debian/changelog b/debian/changelog
index 207b2f0..708188a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,29 @@
+dmidecode (3.1-1) unstable; urgency=medium
+
+ * New upstream release (LP: #1688162) (Closes: #860897):
+ - Remove applied patches:
+ + debian/patches/0110-nosysfs.patch
+ + debian/patches/0115-no_smbios_DMI_entry_point.patch
+ + debian/patches/0120-return_actual_data_size.patch
+ + debian/patches/0125-use_read_file_to_read_DMI_table_from_sysfs.patch
+ + debian/patches/0130-use_DWORD_for_table_max_size.patch
+ + debian/patches/0135-hide_fixup_msg.patch
+ * debian/copyright:
+ - Add year 2017.
+ - Change upstream email address.
+ * debian/control:
+ - Change Homepage.
+ * Migrate to debhelper 10:
+ - Change debian/compat to 10.
+ - Bump minimum debhelper version in debian/control to >= 10.
+ * Use the automatic debug symbol packages:
+ - Remove dmidecode-dbg section from debian/control.
+ - Remove override_dh_strip from debian/rules.
+ * New README.source to explain the branching model used.
+ * Declare compliance with Debian Policy 4.0.0. (No changes needed).
+
+ -- Jörg Frings-Fürst <debian@jff-webhosting.net> Sat, 24 Jun 2017 23:21:09 +0200
+
dmidecode (3.0-4) unstable; urgency=medium
* debian/rules: Fix FTCBFS to pass suitable CC to make. (Closes: #835921).
diff --git a/debian/compat b/debian/compat
index ec63514..f599e28 100644
--- a/debian/compat
+++ b/debian/compat
@@ -1 +1 @@
-9
+10
diff --git a/debian/control b/debian/control
index 0cf55dc..b078c61 100644
--- a/debian/control
+++ b/debian/control
@@ -2,11 +2,11 @@ Source: dmidecode
Section: utils
Priority: optional
Maintainer: Jörg Frings-Fürst <debian@jff-webhosting.net>
-Build-Depends: debhelper (>= 9)
-Standards-Version: 3.9.8
+Build-Depends: debhelper (>= 10)
+Standards-Version: 4.0.0
Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/dmidecode.git
Vcs-Git: https://anonscm.debian.org/cgit/collab-maint/dmidecode.git
-Homepage: https://dmidecode.nongnu.org/
+Homepage: http://nongnu.org/dmidecode/
Package: dmidecode
Priority: important
@@ -26,17 +26,6 @@ Description: SMBIOS/DMI table decoder
Beware that DMI data have proven to be too unreliable to be blindly trusted.
Dmidecode does not scan the hardware, it only reports what the BIOS told it to.
-Package: dmidecode-dbg
-Section: debug
-Priority: extra
-Architecture: any-amd64 arm64 armhf ia64 any-i386
-Depends: ${misc:Depends}, dmidecode (= ${binary:Version})
-Description: SMBIOS/DMI table decoder (debug)
- Dmidecode reports information about the system's hardware as described in the
- system BIOS according to the SMBIOS/DMI standard.
- .
- This package contains the debugging symbols.
-
Package: dmidecode-udeb
Section: debian-installer
Architecture: any-amd64 arm64 armhf ia64 any-i386
diff --git a/debian/copyright b/debian/copyright
index 6432a7c..d17d1db 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -4,7 +4,7 @@ Upstream-Contact: dmidecode-devel@nongnu.org
Source: http://download.savannah.gnu.org/releases/demidecode/
Files: *
-Copyright: 2002-2016 Jean Delvare <khali@linux-fr.org>
+Copyright: 2002-2017 Jean Delvare <jdelvare@suse.de>
2002 Alan Cox <alan@redhat.com>
2010 Anton Arapov <anton@redhat.com>
2015 Xie XiuQi <xiexiuqi@huawei.com>
@@ -13,7 +13,7 @@ License: GPL-2+
Files: debian/*
Copyright: 2003-2007 Petter Reinholdtsen <pere@debian.org>
2011-2012 Daniel Baumann <daniel.baumann@progress-technologies.net>
- 2014-2016 Jörg Frings-Fürst <debian@jff-webhosting.net>
+ 2014-2017 Jörg Frings-Fürst <debian@jff-webhosting.net>
License: GPL-2+
License: GPL-2+
diff --git a/debian/files b/debian/files
new file mode 100644
index 0000000..628e131
--- /dev/null
+++ b/debian/files
@@ -0,0 +1 @@
+dmidecode_3.1-1_source.buildinfo utils optional
diff --git a/debian/patches/series b/debian/patches/series
index 1916e4c..e06432c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,10 +1,10 @@
0100-ansi-c.patch
0001-hurd.patch
0005-build.patch
-0105-dmidecode-avoid-sigbus.patch
-0110-nosysfs.patch
-0115-no_smbios_DMI_entry_point.patch
-0120-return_actual_data_size.patch
-0125-use_read_file_to_read_DMI_table_from_sysfs.patch
-0130-use_DWORD_for_table_max_size.patch
-0135-hide_fixup_msg.patch
+#0105-dmidecode-avoid-sigbus.patch
+#0110-nosysfs.patch
+#0115-no_smbios_DMI_entry_point.patch
+#0120-return_actual_data_size.patch
+#0125-use_read_file_to_read_DMI_table_from_sysfs.patch
+#0130-use_DWORD_for_table_max_size.patch
+#0135-hide_fixup_msg.patch
diff --git a/debian/rules b/debian/rules
index fce1c6c..a0cbc4d 100755
--- a/debian/rules
+++ b/debian/rules
@@ -22,6 +22,3 @@ override_dh_auto_install:
override_dh_install:
dh_install --fail-missing
-
-override_dh_strip:
- dh_strip --dbg-package=dmidecode-dbg
diff --git a/dmidecode.c b/dmidecode.c
index f41c85b..6559567 100644
--- a/dmidecode.c
+++ b/dmidecode.c
@@ -2,7 +2,7 @@
* DMI Decode
*
* Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
- * Copyright (C) 2002-2015 Jean Delvare <jdelvare@suse.de>
+ * Copyright (C) 2002-2017 Jean Delvare <jdelvare@suse.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
* are deemed to be part of the source code.
*
* Unless specified otherwise, all references are aimed at the "System
- * Management BIOS Reference Specification, Version 3.0.0" document,
+ * Management BIOS Reference Specification, Version 3.1.1" document,
* available from http://www.dmtf.org/standards/smbios.
*
* Note to contributors:
@@ -50,6 +50,12 @@
* - DMTF DSP0239 version 1.1.0
* "Management Component Transport Protocol (MCTP) IDs and Codes"
* http://www.dmtf.org/standards/pmci
+ * - "TPM Main, Part 2 TPM Structures"
+ * Specification version 1.2, level 2, revision 116
+ * https://trustedcomputinggroup.org/tpm-main-specification/
+ * - "PC Client Platform TPM Profile (PTP) Specification"
+ * Family "2.0", Level 00, Revision 00.43, January 26, 2015
+ * https://trustedcomputinggroup.org/pc-client-platform-tpm-profile-ptp-specification/
*/
#include <stdio.h>
@@ -69,13 +75,14 @@
#define out_of_spec "<OUT OF SPEC>"
static const char *bad_index = "<BAD INDEX>";
-#define SUPPORTED_SMBIOS_VER 0x0300
+#define SUPPORTED_SMBIOS_VER 0x030101
#define FLAG_NO_FILE_OFFSET (1 << 0)
#define FLAG_STOP_AT_EOT (1 << 1)
-#define SYS_ENTRY_FILE "/sys/firmware/dmi/tables/smbios_entry_point"
-#define SYS_TABLE_FILE "/sys/firmware/dmi/tables/DMI"
+#define SYS_FIRMWARE_DIR "/sys/firmware/dmi/tables"
+#define SYS_ENTRY_FILE SYS_FIRMWARE_DIR "/smbios_entry_point"
+#define SYS_TABLE_FILE SYS_FIRMWARE_DIR "/DMI"
/*
* Type-independant Stuff
@@ -169,10 +176,13 @@ static const char *dmi_smbios_structure_type(u8 code)
"Power Supply",
"Additional Information",
"Onboard Device",
- "Management Controller Host Interface", /* 42 */
+ "Management Controller Host Interface",
+ "TPM Device", /* 43 */
};
- if (code <= 42)
+ if (code >= 128)
+ return "OEM-specific";
+ if (code <= 43)
return type[code];
return out_of_spec;
}
@@ -292,6 +302,18 @@ static void dmi_bios_runtime_size(u32 code)
printf(" %u kB", code >> 10);
}
+static void dmi_bios_rom_size(u8 code1, u16 code2)
+{
+ static const char *unit[4] = {
+ "MB", "GB", out_of_spec, out_of_spec
+ };
+
+ if (code1 != 0xFF)
+ printf(" %u kB", (code1 + 1) << 6);
+ else
+ printf(" %u %s", code2 & 0x3FFF, unit[code2 >> 14]);
+}
+
static void dmi_bios_characteristics(u64 code, const char *prefix)
{
/* 7.1.1 */
@@ -550,12 +572,16 @@ static const char *dmi_chassis_type(u8 code)
"Blade Enclosing",
"Tablet",
"Convertible",
- "Detachable" /* 0x20 */
+ "Detachable",
+ "IoT Gateway",
+ "Embedded PC",
+ "Mini PC",
+ "Stick PC" /* 0x24 */
};
code &= 0x7F; /* bits 6:0 are chassis type, 7th bit is the lock bit */
- if (code >= 0x01 && code <= 0x20)
+ if (code >= 0x01 && code <= 0x24)
return type[code - 0x01];
return out_of_spec;
}
@@ -717,7 +743,9 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
{ 0x2A, "Core Solo Mobile" },
{ 0x2B, "Atom" },
{ 0x2C, "Core M" },
-
+ { 0x2D, "Core m3" },
+ { 0x2E, "Core m5" },
+ { 0x2F, "Core m7" },
{ 0x30, "Alpha" },
{ 0x31, "Alpha 21064" },
{ 0x32, "Alpha 21066" },
@@ -769,6 +797,9 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
{ 0x66, "Athlon X4" },
{ 0x67, "Opteron X1000" },
{ 0x68, "Opteron X2000" },
+ { 0x69, "Opteron A-Series" },
+ { 0x6A, "Opteron X3000" },
+ { 0x6B, "Zen" },
{ 0x70, "Hobbit" },
@@ -880,6 +911,8 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
{ 0xFA, "i860" },
{ 0xFB, "i960" },
+ { 0x100, "ARMv7" },
+ { 0x101, "ARMv8" },
{ 0x104, "SH-3" },
{ 0x105, "SH-4" },
{ 0x118, "ARM" },
@@ -891,6 +924,10 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
{ 0x15E, "DSP" },
{ 0x1F4, "Video Processor" },
};
+ /*
+ * Note to developers: when adding entries to this list, check if
+ * function dmi_processor_id below needs updating too.
+ */
/* Special case for ambiguous value 0x30 (SMBIOS 2.0 only) */
if (ver == 0x0200 && data[0x06] == 0x30 && h->length >= 0x08)
@@ -943,7 +980,7 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
}
}
-static void dmi_processor_id(u8 type, const u8 *p, const char *version, const char *prefix)
+static void dmi_processor_id(const struct dmi_header *h, const char *prefix)
{
/* Intel AP-485 revision 36, table 2-4 */
static const char *flags[32] = {
@@ -980,13 +1017,14 @@ static void dmi_processor_id(u8 type, const u8 *p, const char *version, const ch
NULL, /* 30 */
"PBE (Pending break enabled)" /* 31 */
};
- /*
- * Extra flags are now returned in the ECX register when one calls
- * the CPUID instruction. Their meaning is explained in table 3-5, but
- * DMI doesn't support this yet.
- */
+ const u8 *data = h->data;
+ const u8 *p = data + 0x08;
u32 eax, edx;
int sig = 0;
+ u16 type;
+
+ type = (data[0x06] == 0xFE && h->length >= 0x2A) ?
+ WORD(data + 0x28) : data[0x06];
/*
* This might help learn about new processors supporting the
@@ -1026,8 +1064,24 @@ static void dmi_processor_id(u8 type, const u8 *p, const char *version, const ch
return;
}
}
+ else if ((type >= 0x100 && type <= 0x101) /* ARM */
+ || (type >= 0x118 && type <= 0x119)) /* ARM */
+ {
+ u32 midr = DWORD(p);
+ /*
+ * The format of this field was not defined for ARM processors
+ * before version 3.1.0 of the SMBIOS specification, so we
+ * silently skip it if it reads all zeroes.
+ */
+ if (midr == 0)
+ return;
+ printf("%sSignature: Implementor 0x%02x, Variant 0x%x, Architecture %u, Part 0x%03x, Revision %u\n",
+ prefix, midr >> 24, (midr >> 20) & 0xF,
+ (midr >> 16) & 0xF, (midr >> 4) & 0xFFF, midr & 0xF);
+ return;
+ }
else if ((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */
- || (type >= 0x28 && type <= 0x2B) /* Intel */
+ || (type >= 0x28 && type <= 0x2F) /* Intel */
|| (type >= 0xA1 && type <= 0xB3) /* Intel */
|| type == 0xB5 /* Intel */
|| (type >= 0xB9 && type <= 0xC7) /* Intel */
@@ -1039,12 +1093,14 @@ static void dmi_processor_id(u8 type, const u8 *p, const char *version, const ch
|| type == 0x1F /* AMD */
|| (type >= 0x38 && type <= 0x3F) /* AMD */
|| (type >= 0x46 && type <= 0x4F) /* AMD */
+ || (type >= 0x66 && type <= 0x6B) /* AMD */
|| (type >= 0x83 && type <= 0x8F) /* AMD */
|| (type >= 0xB6 && type <= 0xB7) /* AMD */
|| (type >= 0xE4 && type <= 0xEF)) /* AMD */
sig = 2;
else if (type == 0x01 || type == 0x02)
{
+ const char *version = dmi_string(h, data[0x10]);
/*
* Some X86-class CPU have family "Other" or "Unknown". In this case,
* we use the version string to determine if they are known to
@@ -1062,9 +1118,14 @@ static void dmi_processor_id(u8 type, const u8 *p, const char *version, const ch
else
return;
}
- else /* not X86-class */
+ else /* neither X86 nor ARM */
return;
+ /*
+ * Extra flags are now returned in the ECX register when one calls
+ * the CPUID instruction. Their meaning is explained in table 3-5, but
+ * DMI doesn't support this yet.
+ */
eax = DWORD(p);
edx = DWORD(p + 4);
switch (sig)
@@ -1200,10 +1261,18 @@ static const char *dmi_processor_upgrade(u8 code)
"Socket LGA1150",
"Socket BGA1168",
"Socket BGA1234",
- "Socket BGA1364" /* 0x30 */
+ "Socket BGA1364",
+ "Socket AM4",
+ "Socket LGA1151",
+ "Socket BGA1356",
+ "Socket BGA1440",
+ "Socket BGA1515",
+ "Socket LGA3647-1",
+ "Socket SP3",
+ "Socket SP3r2" /* 0x38 */
};
- if (code >= 0x01 && code <= 0x30)
+ if (code >= 0x01 && code <= 0x38)
return upgrade[code - 0x01];
return out_of_spec;
}
@@ -1476,6 +1545,21 @@ static void dmi_cache_size(u16 code)
printf(" %u kB", code);
}
+static void dmi_cache_size_2(u32 code)
+{
+ if (code & 0x80000000)
+ {
+ code &= 0x7FFFFFFFLU;
+ /* Use a more convenient unit for large cache size */
+ if (code >= 0x8000)
+ printf(" %u MB", code >> 4);
+ else
+ printf(" %u kB", code << 6);
+ }
+ else
+ printf(" %u kB", code);
+}
+
static void dmi_cache_types(u16 code, const char *sep)
{
/* 7.8.2 */
@@ -1712,7 +1796,10 @@ static const char *dmi_slot_type(u8 code)
"MXM 3.0 Type A",
"MXM 3.0 Type B",
"PCI Express 2 SFF-8639",
- "PCI Express 3 SFF-8639" /* 0x20 */
+ "PCI Express 3 SFF-8639",
+ "PCI Express Mini 52-pin with bottom-side keep-outs",
+ "PCI Express Mini 52-pin without bottom-side keep-outs",
+ "PCI Express Mini 76-pin" /* 0x23 */
};
static const char *type_0xA0[] = {
"PC-98/C20", /* 0xA0 */
@@ -1744,7 +1831,7 @@ static const char *dmi_slot_type(u8 code)
* function dmi_slot_id below needs updating too.
*/
- if (code >= 0x01 && code <= 0x20)
+ if (code >= 0x01 && code <= 0x23)
return type[code - 0x01];
if (code >= 0xA0 && code <= 0xB6)
return type_0xA0[code - 0xA0];
@@ -1826,6 +1913,9 @@ static void dmi_slot_id(u8 code1, u8 code2, u8 type, const char *prefix)
case 0x13: /* AGP */
case 0x1F: /* PCI Express 2 */
case 0x20: /* PCI Express 3 */
+ case 0x21: /* PCI Express Mini */
+ case 0x22: /* PCI Express Mini */
+ case 0x23: /* PCI Express Mini */
case 0xA5: /* PCI Express */
case 0xA6: /* PCI Express */
case 0xA7: /* PCI Express */
@@ -2274,10 +2364,13 @@ static void dmi_memory_device_extended_size(u32 code)
{
code &= 0x7FFFFFFFUL;
- /* Use the most suitable unit depending on size */
+ /*
+ * Use the greatest unit for which the exact value can be displayed
+ * as an integer without rounding
+ */
if (code & 0x3FFUL)
printf(" %lu MB", (unsigned long)code);
- else if (code & 0xFFFFFUL)
+ else if (code & 0xFFC00UL)
printf(" %lu GB", (unsigned long)code >> 10);
else
printf(" %lu TB", (unsigned long)code >> 20);
@@ -2389,7 +2482,7 @@ static void dmi_memory_device_type_detail(u16 code)
"LRDIMM" /* 15 */
};
- if ((code & 0x7FFE) == 0)
+ if ((code & 0xFFFE) == 0)
printf(" None");
else
{
@@ -2406,7 +2499,7 @@ static void dmi_memory_device_speed(u16 code)
if (code == 0)
printf(" Unknown");
else
- printf(" %u MHz", code);
+ printf(" %u MT/s", code);
}
/*
@@ -2946,7 +3039,7 @@ static void dmi_64bit_memory_error_address(u64 code)
* first 5 characters of the device name to be trimmed. It's easy to
* check and fix, so do it, but warn.
*/
-static void dmi_fixup_type_34(struct dmi_header *h)
+static void dmi_fixup_type_34(struct dmi_header *h, int display)
{
u8 *p = h->data;
@@ -2954,7 +3047,10 @@ static void dmi_fixup_type_34(struct dmi_header *h)
if (h->length == 0x10
&& is_printable(p + 0x0B, 0x10 - 0x0B))
{
- printf("Invalid entry length (%u). Fixed up to %u.\n", 0x10, 0x0B);
+ if (!(opt.flags & FLAG_QUIET) && display)
+ fprintf(stderr,
+ "Invalid entry length (%u). Fixed up to %u.\n",
+ 0x10, 0x0B);
h->length = 0x0B;
}
}
@@ -3223,6 +3319,57 @@ static const char *dmi_management_controller_host_type(u8 code)
}
/*
+ * 7.44 TPM Device (Type 43)
+ */
+
+static void dmi_tpm_vendor_id(const u8 *p)
+{
+ char vendor_id[5];
+ int i;
+
+ /* ASCII filtering */
+ for (i = 0; i < 4 && p[i] != 0; i++)
+ {
+ if (p[i] < 32 || p[i] >= 127)
+ vendor_id[i] = '.';
+ else
+ vendor_id[i] = p[i];
+ }
+
+ /* Terminate the string */
+ vendor_id[i] = '\0';
+
+ printf(" %s", vendor_id);
+}
+
+static void dmi_tpm_characteristics(u64 code, const char *prefix)
+{
+ /* 7.1.1 */
+ static const char *characteristics[] = {
+ "TPM Device characteristics not supported", /* 2 */
+ "Family configurable via firmware update",
+ "Family configurable via platform software support",
+ "Family configurable via OEM proprietary mechanism" /* 5 */
+ };
+ int i;
+
+ /*
+ * This isn't very clear what this bit is supposed to mean
+ */
+ if (code.l & (1 << 2))
+ {
+ printf("%s%s\n",
+ prefix, characteristics[0]);
+ return;
+ }
+
+ for (i = 3; i <= 5; i++)
+ if (code.l & (1 << i))
+ printf("%s%s\n",
+ prefix, characteristics[i - 2]);
+}
+
+/*
* Main
*/
@@ -3257,8 +3404,9 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
dmi_bios_runtime_size((0x10000 - WORD(data + 0x06)) << 4);
printf("\n");
}
- printf("\tROM Size: %u kB\n",
- (data[0x09] + 1) << 6);
+ printf("\tROM Size:");
+ dmi_bios_rom_size(data[0x09], h->length < 0x1A ? 16 : WORD(data + 0x18));
+ printf("\n");
printf("\tCharacteristics:\n");
dmi_bios_characteristics(QWORD(data + 0x0A), "\t\t");
if (h->length < 0x13) break;
@@ -3382,7 +3530,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
dmi_processor_family(h, ver));
printf("\tManufacturer: %s\n",
dmi_string(h, data[0x07]));
- dmi_processor_id(data[0x06], data + 0x08, dmi_string(h, data[0x10]), "\t");
+ dmi_processor_id(h, "\t");
printf("\tVersion: %s\n",
dmi_string(h, data[0x10]));
printf("\tVoltage:");
@@ -3509,10 +3657,16 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
printf("\tLocation: %s\n",
dmi_cache_location((WORD(data + 0x05) >> 5) & 0x0003));
printf("\tInstalled Size:");
- dmi_cache_size(WORD(data + 0x09));
+ if (h->length >= 0x1B)
+ dmi_cache_size_2(DWORD(data + 0x17));
+ else
+ dmi_cache_size(WORD(data + 0x09));
printf("\n");
printf("\tMaximum Size:");
- dmi_cache_size(WORD(data + 0x07));
+ if (h->length >= 0x17)
+ dmi_cache_size_2(DWORD(data + 0x13));
+ else
+ dmi_cache_size(WORD(data + 0x07));
printf("\n");
printf("\tSupported SRAM Types:");
dmi_cache_types(WORD(data + 0x0B), "\n\t\t");
@@ -4234,7 +4388,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
}
if (data[0x11] != 0x00)
{
- printf("\tInterrupt Number: %x\n",
+ printf("\tInterrupt Number: %u\n",
data[0x11]);
}
break;
@@ -4331,6 +4485,43 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
}
break;
+ case 43: /* 7.44 TPM Device */
+ printf("TPM Device\n");
+ if (h->length < 0x1B) break;
+ printf("\tVendor ID:");
+ dmi_tpm_vendor_id(data + 0x04);
+ printf("\n");
+ printf("\tSpecification Version: %d.%d", data[0x08], data[0x09]);
+ switch (data[0x08])
+ {
+ case 0x01:
+ /*
+ * We skip the first 2 bytes, which are
+ * redundant with the above, and uncoded
+ * in a silly way.
+ */
+ printf("\tFirmware Revision: %u.%u\n",
+ data[0x0C], data[0x0D]);
+ break;
+ case 0x02:
+ printf("\tFirmware Revision: %u.%u\n",
+ DWORD(data + 0x0A) >> 16,
+ DWORD(data + 0x0A) && 0xFF);
+ /*
+ * We skip the next 4 bytes, as their
+ * format is not standardized and their
+ * usefulness seems limited anyway.
+ */
+ break;
+ }
+ printf("\tDescription: %s", dmi_string(h, data[0x12]));
+ printf("\tCharacteristics:\n");
+ dmi_tpm_characteristics(QWORD(data + 0x13), "\t\t");
+ if (h->length < 0x1F) break;
+ printf("\tOEM-specific Information: 0x%08X\n",
+ DWORD(data + 0x1B));
+ break;
+
case 126: /* 7.44 Inactive */
printf("Inactive\n");
break;
@@ -4364,6 +4555,21 @@ static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver
int key;
u8 offset = opt.string->offset;
+ if (opt.string->type == 11) /* OEM strings */
+ {
+ if (h->length < 5 || offset > data[4])
+ {
+ fprintf(stderr, "No OEM string number %u\n", offset);
+ return;
+ }
+
+ if (offset)
+ printf("%s\n", dmi_string(h, offset));
+ else
+ printf("%u\n", data[4]); /* count */
+ return;
+ }
+
if (offset >= h->length)
return;
@@ -4422,9 +4628,14 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
*/
if (h.length < 4)
{
- printf("Invalid entry length (%u). DMI table is "
- "broken! Stop.\n\n", (unsigned int)h.length);
- opt.flags |= FLAG_QUIET;
+ if (!(opt.flags & FLAG_QUIET))
+ {
+ fprintf(stderr,
+ "Invalid entry length (%u). DMI table "
+ "is broken! Stop.\n\n",
+ (unsigned int)h.length);
+ opt.flags |= FLAG_QUIET;
+ }
break;
}
@@ -4443,7 +4654,7 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
/* Fixup a common mistake */
if (h.type == 34)
- dmi_fixup_type_34(&h);
+ dmi_fixup_type_34(&h, display);
/* look for the next handle */
next = data + h.length;
@@ -4485,26 +4696,28 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
if (!(opt.flags & FLAG_QUIET))
{
if (num && i != num)
- printf("Wrong DMI structures count: %d announced, "
+ fprintf(stderr, "Wrong DMI structures count: %d announced, "
"only %d decoded.\n", num, i);
if ((unsigned long)(data - buf) > len
|| (num && (unsigned long)(data - buf) < len))
- printf("Wrong DMI structures length: %u bytes "
+ fprintf(stderr, "Wrong DMI structures length: %u bytes "
"announced, structures occupy %lu bytes.\n",
len, (unsigned long)(data - buf));
}
}
-static void dmi_table(off_t base, u32 len, u16 num, u16 ver, const char *devmem,
+static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem,
u32 flags)
{
u8 *buf;
if (ver > SUPPORTED_SMBIOS_VER && !(opt.flags & FLAG_QUIET))
{
- printf("# SMBIOS implementations newer than version %u.%u are not\n"
+ printf("# SMBIOS implementations newer than version %u.%u.%u are not\n"
"# fully supported by this version of dmidecode.\n",
- SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF);
+ SUPPORTED_SMBIOS_VER >> 16,
+ (SUPPORTED_SMBIOS_VER >> 8) & 0xFF,
+ SUPPORTED_SMBIOS_VER & 0xFF);
}
if (!(opt.flags & FLAG_QUIET))
@@ -4521,29 +4734,45 @@ static void dmi_table(off_t base, u32 len, u16 num, u16 ver, const char *devmem,
printf("\n");
}
- /*
- * When we are reading the DMI table from sysfs, we want to print
- * the address of the table (done above), but the offset of the
- * data in the file is 0. When reading from /dev/mem, the offset
- * in the file is the address.
- */
- if (flags & FLAG_NO_FILE_OFFSET)
- base = 0;
+ if ((flags & FLAG_NO_FILE_OFFSET) || (opt.flags & FLAG_FROM_DUMP))
+ {
+ /*
+ * When reading from sysfs or from a dump file, the file may be
+ * shorter than announced. For SMBIOS v3 this is expcted, as we
+ * only know the maximum table size, not the actual table size.
+ * For older implementations (and for SMBIOS v3 too), this
+ * would be the result of the kernel truncating the table on
+ * parse error.
+ */
+ size_t size = len;
+ buf = read_file(flags & FLAG_NO_FILE_OFFSET ? 0 : base,
+ &size, devmem);
+ if (!(opt.flags & FLAG_QUIET) && num && size != (size_t)len)
+ {
+ fprintf(stderr, "Wrong DMI structures length: %u bytes "
+ "announced, only %lu bytes available.\n",
+ len, (unsigned long)size);
+ }
+ len = size;
+ }
+ else
+ buf = mem_chunk(base, len, devmem);
- if ((buf = mem_chunk(base, len, devmem)) == NULL)
+ if (buf == NULL)
{
- fprintf(stderr, "Table is unreachable, sorry."
+ fprintf(stderr, "Failed to read table, sorry.\n");
#ifndef USE_MMAP
- " Try compiling dmidecode with -DUSE_MMAP."
+ if (!(flags & FLAG_NO_FILE_OFFSET))
+ fprintf(stderr,
+ "Try compiling dmidecode with -DUSE_MMAP.\n");
#endif
- "\n");
return;
}
if (opt.flags & FLAG_DUMP_BIN)
dmi_table_dump(buf, len);
else
- dmi_table_decode(buf, len, num, ver, flags);
+ dmi_table_decode(buf, len, num, ver >> 8, flags);
free(buf);
}
@@ -4580,13 +4809,13 @@ static void overwrite_smbios3_address(u8 *buf)
static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
{
- u16 ver;
+ u32 ver;
u64 offset;
if (!checksum(buf, buf[0x06]))
return 0;
- ver = (buf[0x07] << 8) + buf[0x08];
+ ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09];
if (!(opt.flags & FLAG_QUIET))
printf("SMBIOS %u.%u.%u present.\n",
buf[0x07], buf[0x08], buf[0x09]);
@@ -4599,7 +4828,7 @@ static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
}
dmi_table(((off_t)offset.h << 32) | offset.l,
- WORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT);
+ DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT);
if (opt.flags & FLAG_DUMP_BIN)
{
@@ -4633,14 +4862,16 @@ static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
case 0x021F:
case 0x0221:
if (!(opt.flags & FLAG_QUIET))
- printf("SMBIOS version fixup (2.%d -> 2.%d).\n",
- ver & 0xFF, 3);
+ fprintf(stderr,
+ "SMBIOS version fixup (2.%d -> 2.%d).\n",
+ ver & 0xFF, 3);
ver = 0x0203;
break;
case 0x0233:
if (!(opt.flags & FLAG_QUIET))
- printf("SMBIOS version fixup (2.%d -> 2.%d).\n",
- 51, 6);
+ fprintf(stderr,
+ "SMBIOS version fixup (2.%d -> 2.%d).\n",
+ 51, 6);
ver = 0x0206;
break;
}
@@ -4649,7 +4880,7 @@ static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
ver >> 8, ver & 0xFF);
dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C),
- ver, devmem, flags);
+ ver << 8, devmem, flags);
if (opt.flags & FLAG_DUMP_BIN)
{
@@ -4677,7 +4908,8 @@ static int legacy_decode(u8 *buf, const char *devmem, u32 flags)
buf[0x0E] >> 4, buf[0x0E] & 0x0F);
dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C),
- ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, flags);
+ ((buf[0x0E] & 0xF0) << 12) + ((buf[0x0E] & 0x0F) << 8),
+ devmem, flags);
if (opt.flags & FLAG_DUMP_BIN)
{
@@ -4748,9 +4980,17 @@ int main(int argc, char * const argv[])
int ret = 0; /* Returned value */
int found = 0;
off_t fp;
+ size_t size;
int efi;
u8 *buf;
+ /*
+ * We don't want stdout and stderr to be mixed up if both are
+ * redirected to the same file.
+ */
+ setlinebuf(stdout);
+ setlinebuf(stderr);
+
if (sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0)
{
fprintf(stderr, "%s: compiler incompatibility\n", argv[0]);
@@ -4817,22 +5057,23 @@ int main(int argc, char * const argv[])
* contain one of several types of entry points, so read enough for
* the largest one, then determine what type it contains.
*/
+ size = 0x20;
if (!(opt.flags & FLAG_NO_SYSFS)
- && (buf = read_file(0x20, SYS_ENTRY_FILE)) != NULL)
+ && (buf = read_file(0, &size, SYS_ENTRY_FILE)) != NULL)
{
if (!(opt.flags & FLAG_QUIET))
printf("Getting SMBIOS data from sysfs.\n");
- if (memcmp(buf, "_SM3_", 5) == 0)
+ if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0)
{
if (smbios3_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
found++;
}
- else if (memcmp(buf, "_SM_", 4) == 0)
+ else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0)
{
if (smbios_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
found++;
}
- else if (memcmp(buf, "_DMI_", 5) == 0)
+ else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0)
{
if (legacy_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
found++;
@@ -4864,8 +5105,16 @@ int main(int argc, char * const argv[])
goto exit_free;
}
- if (smbios_decode(buf, opt.devmem, 0))
- found++;
+ if (memcmp(buf, "_SM3_", 5) == 0)
+ {
+ if (smbios3_decode(buf, opt.devmem, 0))
+ found++;
+ }
+ else if (memcmp(buf, "_SM_", 4) == 0)
+ {
+ if (smbios_decode(buf, opt.devmem, 0))
+ found++;
+ }
goto done;
memory_scan:
@@ -4878,28 +5127,37 @@ memory_scan:
goto exit_free;
}
- for (fp = 0; fp <= 0xFFF0; fp += 16)
+ /* Look for a 64-bit entry point first */
+ for (fp = 0; fp <= 0xFFE0; fp += 16)
{
- if (memcmp(buf + fp, "_SM3_", 5) == 0 && fp <= 0xFFE0)
+ if (memcmp(buf + fp, "_SM3_", 5) == 0)
{
if (smbios3_decode(buf + fp, opt.devmem, 0))
{
found++;
- fp += 16;
+ goto done;
}
}
- else if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
+ }
+
+ /* If none found, look for a 32-bit entry point */
+ for (fp = 0; fp <= 0xFFF0; fp += 16)
+ {
+ if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
{
if (smbios_decode(buf + fp, opt.devmem, 0))
{
found++;
- fp += 16;
+ goto done;
}
}
else if (memcmp(buf + fp, "_DMI_", 5) == 0)
{
if (legacy_decode(buf + fp, opt.devmem, 0))
+ {
found++;
+ goto done;
+ }
}
}
diff --git a/dmiopt.c b/dmiopt.c
index 0d142d2..da42546 100644
--- a/dmiopt.c
+++ b/dmiopt.c
@@ -20,6 +20,7 @@
*/
#include <stdio.h>
+#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <getopt.h>
@@ -171,6 +172,10 @@ static const struct string_keyword opt_string_keyword[] = {
{ "processor-frequency", 4, 0x16 }, /* dmi_processor_frequency() */
};
+/* This is a template, 3rd field is set at runtime. */
+static struct string_keyword opt_oem_string_keyword =
+ { NULL, 11, 0x00 };
+
static void print_opt_string_list(void)
{
unsigned int i;
@@ -206,6 +211,34 @@ static int parse_opt_string(const char *arg)
return -1;
}
+static int parse_opt_oem_string(const char *arg)
+{
+ unsigned long val;
+ char *next;
+
+ if (opt.string)
+ {
+ fprintf(stderr, "Only one string can be specified\n");
+ return -1;
+ }
+
+ /* Return the number of OEM strings */
+ if (strcmp(arg, "count") == 0)
+ goto done;
+
+ val = strtoul(arg, &next, 10);
+ if (next == arg || val == 0x00 || val > 0xff)
+ {
+ fprintf(stderr, "Invalid OEM string number: %s\n", arg);
+ return -1;
+ }
+
+ opt_oem_string_keyword.offset = val;
+done:
+ opt.string = &opt_oem_string_keyword;
+ return 0;
+}
+
/*
* Command line options handling
@@ -225,6 +258,7 @@ int parse_command_line(int argc, char * const argv[])
{ "dump", no_argument, NULL, 'u' },
{ "dump-bin", required_argument, NULL, 'B' },
{ "from-dump", required_argument, NULL, 'F' },
+ { "oem-string", required_argument, NULL, 'O' },
{ "no-sysfs", no_argument, NULL, 'S' },
{ "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
@@ -255,6 +289,11 @@ int parse_command_line(int argc, char * const argv[])
return -1;
opt.flags |= FLAG_QUIET;
break;
+ case 'O':
+ if (parse_opt_oem_string(optarg) < 0)
+ return -1;
+ opt.flags |= FLAG_QUIET;
+ break;
case 't':
opt.type = parse_opt_type(opt.type, optarg);
if (opt.type == NULL)
@@ -314,6 +353,8 @@ void print_help(void)
" -u, --dump Do not decode the entries\n"
" --dump-bin FILE Dump the DMI data to a binary file\n"
" --from-dump FILE Read the DMI data from a binary file\n"
+ " --no-sysfs Do not attempt to read DMI data from sysfs files\n"
+ " --oem-string N Only display the value of the given OEM string\n"
" -V, --version Display the version and exit\n";
printf("%s", help);
diff --git a/man/dmidecode.8 b/man/dmidecode.8
index a64cf5d..bef204e 100644
--- a/man/dmidecode.8
+++ b/man/dmidecode.8
@@ -134,13 +134,18 @@ Read the DMI data from a binary file previously generated using
Do not attempt to read DMI data from sysfs files. This is mainly useful for
debugging.
.TP
+.BR " " " " "--oem-string N"
+Only display the value of the \s-1OEM\s0 string number \fBN\fR. The first
+\s-1OEM\s0 string has number 1. With special value "count", return the
+number of OEM strings instead.
+.TP
.BR "-h" ", " "--help"
Display usage information and exit
.TP
.BR "-V" ", " "--version"
Display the version and exit
.P
-Options --string, --type and --dump-bin
+Options --string, --type, --dump-bin and --oem-string
determine the output format and are mutually exclusive.
.P
Please note in case of
diff --git a/util.c b/util.c
index 8cafe5c..0aafcb1 100644
--- a/util.c
+++ b/util.c
@@ -2,7 +2,7 @@
* Common "util" functions
* This file is part of the dmidecode project.
*
- * Copyright (C) 2002-2015 Jean Delvare <jdelvare@suse.de>
+ * Copyright (C) 2002-2017 Jean Delvare <jdelvare@suse.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -89,15 +89,16 @@ int checksum(const u8 *buf, size_t len)
}
/*
- * Reads all of file, up to max_len bytes.
+ * Reads all of file from given offset, up to max_len bytes.
* A buffer of max_len bytes is allocated by this function, and
* needs to be freed by the caller.
* This provides a similar usage model to mem_chunk()
*
- * Returns pointer to buffer of max_len bytes, or NULL on error
+ * Returns pointer to buffer of max_len bytes, or NULL on error, and
+ * sets max_len to the length actually read.
*
*/
-void *read_file(size_t max_len, const char *filename)
+void *read_file(off_t base, size_t *max_len, const char *filename)
{
int fd;
size_t r2 = 0;
@@ -112,26 +113,34 @@ void *read_file(size_t max_len, const char *filename)
{
if (errno != ENOENT)
perror(filename);
- return(NULL);
+ return NULL;
}
- if ((p = malloc(max_len)) == NULL)
+ if (lseek(fd, base, SEEK_SET) == -1)
+ {
+ fprintf(stderr, "%s: ", filename);
+ perror("lseek");
+ p = NULL;
+ goto out;
+ }
+
+ if ((p = malloc(*max_len)) == NULL)
{
perror("malloc");
- return NULL;
+ goto out;
}
do
{
- r = read(fd, p + r2, max_len - r2);
+ r = read(fd, p + r2, *max_len - r2);
if (r == -1)
{
if (errno != EINTR)
{
- close(fd);
perror(filename);
free(p);
- return NULL;
+ p = NULL;
+ goto out;
}
}
else
@@ -139,7 +148,10 @@ void *read_file(size_t max_len, const char *filename)
}
while (r != 0);
+ *max_len = r2;
+out:
close(fd);
+
return p;
}
@@ -152,6 +164,7 @@ void *mem_chunk(off_t base, size_t len, const char *devmem)
void *p;
int fd;
#ifdef USE_MMAP
+ struct stat statbuf;
off_t mmoffset;
void *mmp;
#endif
@@ -165,10 +178,28 @@ void *mem_chunk(off_t base, size_t len, const char *devmem)
if ((p = malloc(len)) == NULL)
{
perror("malloc");
- return NULL;
+ goto out;
}
#ifdef USE_MMAP
+ if (fstat(fd, &statbuf) == -1)
+ {
+ fprintf(stderr, "%s: ", devmem);
+ perror("stat");
+ goto err_free;
+ }
+
+ /*
+ * mmap() will fail with SIGBUS if trying to map beyond the end of
+ * the file.
+ */
+ if (S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size)
+ {
+ fprintf(stderr, "mmap: Can't map beyond end of file %s\n",
+ devmem);
+ goto err_free;
+ }
+
#ifdef _SC_PAGESIZE
mmoffset = base % sysconf(_SC_PAGESIZE);
#else
@@ -199,19 +230,17 @@ try_read:
{
fprintf(stderr, "%s: ", devmem);
perror("lseek");
- free(p);
- return NULL;
+ goto err_free;
}
- if (myread(fd, p, len, devmem) == -1)
- {
- free(p);
- return NULL;
- }
+ if (myread(fd, p, len, devmem) == 0)
+ goto out;
+
+err_free:
+ free(p);
+ p = NULL;
-#ifdef USE_MMAP
out:
-#endif
if (close(fd) == -1)
perror(devmem);
diff --git a/util.h b/util.h
index 9d409cd..3094cf8 100644
--- a/util.h
+++ b/util.h
@@ -1,7 +1,7 @@
/*
* This file is part of the dmidecode project.
*
- * Copyright (C) 2003-2015 Jean Delvare <jdelvare@suse.de>
+ * Copyright (C) 2003-2017 Jean Delvare <jdelvare@suse.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
int checksum(const u8 *buf, size_t len);
-void *read_file(size_t len, const char *filename);
+void *read_file(off_t base, size_t *len, const char *filename);
void *mem_chunk(off_t base, size_t len, const char *devmem);
int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add);
u64 u64_range(u64 start, u64 end);
diff --git a/version.h b/version.h
index f3e8666..778ae5f 100644
--- a/version.h
+++ b/version.h
@@ -1 +1 @@
-#define VERSION "3.0"
+#define VERSION "3.1"