Let's try to get information from one of the system tables that we've discovered.
You can find the most recent version of the "System Management BIOS (SMBIOS) Reference Specification" on the DMTF site https://www.dmtf.org/dsp/DSP0134 For example now 3.4.0 is the most recent version https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.4.0.pdf
From the previous lesson we now, that SMBIOS table is declared under gEfiSmbiosTableGuid
.
Let's create an app, that would print the address of this table.
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
for (UINTN i=0; i<SystemTable->NumberOfTableEntries; i++) {
if (CompareGuid(&(SystemTable->ConfigurationTable[i].VendorGuid), &gEfiSmbiosTableGuid)) {
Print(L"SMBIOS table is placed at %p\n", SystemTable->ConfigurationTable[i].VendorTable);
}
}
return EFI_SUCCESS;
}
In this code we've used CompareGuid
function from the https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Library/BaseMemoryLib.h:
/**
Compares two GUIDs.
This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE is returned.
If there are any bit differences in the two GUIDs, then FALSE is returned.
If Guid1 is NULL, then ASSERT().
If Guid2 is NULL, then ASSERT().
@param Guid1 A pointer to a 128 bit GUID.
@param Guid2 A pointer to a 128 bit GUID.
@retval TRUE Guid1 and Guid2 are identical.
@retval FALSE Guid1 and Guid2 are not identical.
**/
BOOLEAN
EFIAPI
CompareGuid (
IN CONST GUID *Guid1,
IN CONST GUID *Guid2
);
Don't forget to add:
[Guids]
gEfiSmbiosTableGuid
to app *inf file.
Let's build our app and execute it under OVMF:
FS0:\> SmbiosInfo.efi
SMBIOS table is placed at 7941000
UEFI shell has a command dmem
for memory dump:
FS0:\> dmem -? -b
Displays the contents of system or device memory.
DMEM [-b] [address] [size] [-MMIO]
-b - Displays one screen at a time.
-MMIO - Forces address cycles to the PCI bus.
address - Specifies a starting address in hexadecimal format.
size - Specifies the number of bytes to display in hexadecimal format.
NOTES:
1. This command displays the contents of system memory or device memory.
2. Enter address and size in hexadecimal format.
3. If address is not specified, the contents of the UEFI System Table
are displayed. Otherwise, memory starting at the specified address is displayed.
4. Size specifies the number of bytes to display. If size is not specified,
512 bytes are displayed.
5. If MMIO is not specified, main system memory is displayed. Otherwise,
device memory is displayed through the use of the
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
EXAMPLES:
* To display the UEFI system table pointer entries:
fs0:\> dmem
* To display memory contents from 1af3088 with size of 16 bytes:
Shell> dmem 1af3088 16
* To display memory mapped IO contents from 1af3088 with a size of 16 bytes:
Shell> dmem 1af3088 16 -MMIO
Let's use it to print 0x30 bytes from the 0x7941000 address that we count as a SMBIOS table pointer.
FS0:\> dmem 7941000 30
Memory Address 0000000007941000 30 Bytes
07941000: 5F 53 4D 5F 26 1F 02 08-53 00 00 00 00 00 00 00 *_SM_&...S.......*
07941010: 5F 44 4D 49 5F 0A 91 01-00 00 94 07 09 00 28 AF *_DMI_.........(.*
07941020: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
If you look at SMBIOS specification for SMBIOS Entry Point structure you'll see, that _SM_
and _DMI_
are predefined values in this structure.
You can find definition for the structure itself in edk2 under https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/SmBios.h
typedef struct {
UINT8 AnchorString[4];
UINT8 EntryPointStructureChecksum;
UINT8 EntryPointLength;
UINT8 MajorVersion;
UINT8 MinorVersion;
UINT16 MaxStructureSize;
UINT8 EntryPointRevision;
UINT8 FormattedArea[5];
UINT8 IntermediateAnchorString[5];
UINT8 IntermediateChecksum;
UINT16 TableLength;
UINT32 TableAddress;
UINT16 NumberOfSmbiosStructures;
UINT8 SmbiosBcdRevision;
} SMBIOS_TABLE_ENTRY_POINT;
If you calculate offsets for different fields you can parse memory dump:
System has 9 SMBIOS structures placed from 0x07940000 to (0x07940000+0x191).
Now when we know address for SMBIOS structures, we can dump them as well.
FS0:\> dmem 07940000 191
Memory Address 0000000007940000 191 Bytes
07940000: 01 1B 00 01 01 02 03 00-00 00 00 00 00 00 00 00 *................*
07940010: 00 00 00 00 00 00 00 00-06 00 00 51 45 4D 55 00 *...........QEMU.*
07940020: 53 74 61 6E 64 61 72 64-20 50 43 20 28 69 34 34 *Standard PC (i44*
07940030: 30 46 58 20 2B 20 50 49-49 58 2C 20 31 39 39 36 *0FX + PIIX, 1996*
07940040: 29 00 70 63 2D 69 34 34-30 66 78 2D 66 6F 63 61 *).pc-i440fx-foca*
07940050: 6C 00 00 03 16 00 03 01-01 02 00 00 03 03 03 02 *l...............*
07940060: 00 00 00 00 00 00 00 00-00 51 45 4D 55 00 70 63 *.........QEMU.pc*
07940070: 2D 69 34 34 30 66 78 2D-66 6F 63 61 6C 00 00 04 *-i440fx-focal...*
07940080: 2A 00 04 01 03 01 02 63-06 00 00 FD FB 8B 07 03 **......c........*
07940090: 00 00 00 D0 07 D0 07 41-01 FF FF FF FF FF FF 00 *.......A........*
079400A0: 00 00 01 01 01 02 00 01-00 43 50 55 20 30 00 51 *.........CPU 0.Q*
079400B0: 45 4D 55 00 70 63 2D 69-34 34 30 66 78 2D 66 6F *EMU.pc-i440fx-fo*
079400C0: 63 61 6C 00 00 10 17 00-10 01 03 06 00 00 02 00 *cal.............*
079400D0: FE FF 01 00 00 00 00 00-00 00 00 00 00 00 11 28 *...............(*
079400E0: 00 11 00 10 FE FF FF FF-FF FF 80 00 09 00 01 00 *................*
079400F0: 07 02 00 00 00 02 00 00-00 00 00 00 00 00 00 00 *................*
07940100: 00 00 00 00 00 00 44 49-4D 4D 20 30 00 51 45 4D *......DIMM 0.QEM*
07940110: 55 00 00 13 1F 00 13 00-00 00 00 FF FF 01 00 00 *U...............*
07940120: 10 01 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *................*
07940130: 00 00 00 00 20 0B 00 20-00 00 00 00 00 00 00 00 *.... .. ........*
07940140: 00 00 1A 00 00 01 02 00-E8 03 00 08 00 00 00 00 *................*
07940150: 00 00 00 00 1C 00 00 FF-FF 00 00 45 46 49 20 44 *...........EFI D*
07940160: 65 76 65 6C 6F 70 6D 65-6E 74 20 4B 69 74 20 49 *evelopment Kit I*
07940170: 49 20 2F 20 4F 56 4D 46-00 30 2E 30 2E 30 00 30 *I / OVMF.0.0.0.0*
07940180: 32 2F 30 36 2F 32 30 31-35 00 00 7F 04 FF FE 00 *2/06/2015.......*
07940190: 00 *.*
We can use direct pointer arithmetics to parse SMBIOS tables, but that would be very tedious.
Luckily UEFI PI specification defines a EFI_SMBIOS_PROTOCOL
, that we can use to get SMBIOS data.
EFI_SMBIOS_PROTOCOL
Summary:
Allows consumers to log SMBIOS data records, and enables the producer to create the SMBIOS tables for a platform.
Protocol Interface Structure:
typedef struct _EFI_SMBIOS_PROTOCOL {
EFI_SMBIOS_ADD Add;
EFI_SMBIOS_UPDATE_STRINGUpdateString;
EFI_SMBIOS_REMOVE Remove;
EFI_SMBIOS_GET_NEXT GetNext;
UINT8 MajorVersion;
UINT8 MinorVersion;
} EFI_SMBIOS_PROTOCOL;
Member Description:
Add Add an SMBIOS record including the formatted area and the optional strings
that follow the formatted area.
UpdateString Update a string in the SMBIOS record.
Remove Remove an SMBIOS record.
GetNext Discover all SMBIOS records.
MajorVersion The major revision of the SMBIOS specification supported.
MinorVersion The minor revision of the SMBIOS specification supported.
Description:
This protocol provides an interface to add, remove or discover SMBIOS records. The driver which
produces this protocol is responsible for creating the SMBIOS data tables and installing the pointer
to the tables in the EFI System Configuration Table.
Right now we are interested in SMBIOS table parsing, so we need to utilize GetNext
function:
EFI_SMBIOS_PROTOCOL.GetNext()
Summary:
Allow the caller to discover all or some of the SMBIOS records.
Prototype
typedef
EFI_STATUS
(EFIAPI *EFI_SMBIOS_GET_NEXT) (
IN CONST EFI_SMBIOS_PROTOCOL *This,
IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle,
IN EFI_SMBIOS_TYPE *Type, OPTIONAL
OUT EFI_SMBIOS_TABLE_HEADER **Record,
OUT EFI_HANDLE *ProducerHandle OPTIONAL
);
Parameters:
This The EFI_SMBIOS_PROTOCOL instance.
SmbiosHandle On entry, points to the previous handle of the SMBIOS record. On exit, points to the
next SMBIOS record handle. If it is FFFEh on entry, then the first SMBIOS record
handle will be returned. If it returns FFFEh on exit, then there are no more SMBIOS
records.
Type On entry, it points to the type of the next SMBIOS record to return. If NULL, it
indicates that the next record of any type will be returned. Type is not modified by
the this function.
Record On exit, points to a pointer to the the SMBIOS Record consisting of the formatted area
followed by the unformatted area. The unformatted area optionally contains text
strings.
ProducerHandle On exit, points to the ProducerHandle registered by Add(). If no
ProducerHandle was passed into Add() NULL is returned. If a NULL pointer is
passed in no data will be returned
Description
This function allows all of the SMBIOS records to be discovered. It's possible to find
only the SMBIOS records that match the optional Type argument.
Status Codes Returned:
EFI_SUCCESS .SMBIOS record information was successfully returned in Record.
SmbiosHandle is the handle of the current SMBIOS record
EFI_NOT_FOUND The SMBIOS record with SmbiosHandle was the last available record.
First let's get this protocol in our app.
EFI_SMBIOS_PROTOCOL* SmbiosProtocol;
EFI_STATUS Status = gBS->LocateProtocol (
&gEfiSmbiosProtocolGuid,
NULL,
(VOID**)&SmbiosProtocol
);
if (EFI_ERROR (Status)) {
return Status;
}
To use it we need to add include to our app https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Protocol/Smbios.h:
#include <Protocol/Smbios.h>
And add protocol guid to our *.inf file:
[Protocols]
gEfiSmbiosProtocolGuid
Now let's try to get SMBIOS tables. We would be using SMBIOS_HANDLE_PI_RESERVED
as EFI_SMBIOS_HANDLE
in protocol calls. You can find explanation in https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/SmBios.h:
///
/// Reference SMBIOS 2.7, chapter 6.1.2.
/// The UEFI Platform Initialization Specification reserves handle number FFFEh for its
/// EFI_SMBIOS_PROTOCOL.Add() function to mean "assign an unused handle number automatically."
/// This number is not used for any other purpose by the SMBIOS specification.
///
#define SMBIOS_HANDLE_PI_RESERVED 0xFFFE
Also before we start writing code look at the definition of EFI_SMBIOS_TABLE_HEADER
structure, that we would receive on GetNext
calls.
https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Protocol/Smbios.h
typedef SMBIOS_STRUCTURE EFI_SMBIOS_TABLE_HEADER;
https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/SmBios.h
///
/// The Smbios structure header.
///
typedef struct {
SMBIOS_TYPE Type;
UINT8 Length;
SMBIOS_HANDLE Handle;
} SMBIOS_STRUCTURE;
Now we are ready to write some code. Write a code to print all types of Smbios tables that are present in the system:
EFI_SMBIOS_HANDLE SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
EFI_SMBIOS_TABLE_HEADER* Record;
Status = SmbiosProtocol->GetNext(SmbiosProtocol,
&SmbiosHandle,
NULL,
&Record,
NULL);
while (!EFI_ERROR(Status)) {
Print (L"SMBIOS Type %d \n", Record->Type);
Status = SmbiosProtocol->GetNext(SmbiosProtocol,
&SmbiosHandle,
NULL,
&Record,
NULL);
}
If you build our app and test it under OVMF you would get:
SMBIOS table is placed at 7941000
SMBIOS Type 1
SMBIOS Type 3
SMBIOS Type 4
SMBIOS Type 16
SMBIOS Type 17
SMBIOS Type 19
SMBIOS Type 32
SMBIOS Type 0
Ok, now let's write code that can parse information in these tables.
Let's start with Type 0 table. edk2 has a structure description at https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/SmBios.h:
///
/// BIOS Information (Type 0).
///
typedef struct {
SMBIOS_STRUCTURE Hdr;
SMBIOS_TABLE_STRING Vendor;
SMBIOS_TABLE_STRING BiosVersion;
UINT16 BiosSegment;
SMBIOS_TABLE_STRING BiosReleaseDate;
UINT8 BiosSize;
MISC_BIOS_CHARACTERISTICS BiosCharacteristics;
UINT8 BIOSCharacteristicsExtensionBytes[2];
UINT8 SystemBiosMajorRelease;
UINT8 SystemBiosMinorRelease;
UINT8 EmbeddedControllerFirmwareMajorRelease;
UINT8 EmbeddedControllerFirmwareMinorRelease;
//
// Add for smbios 3.1.0
//
EXTENDED_BIOS_ROM_SIZE ExtendedBiosSize;
} SMBIOS_TABLE_TYPE0;
In this structure SMBIOS_STRUCTURE Hdr
is a mandatory field that is the same as EFI_SMBIOS_TABLE_HEADER
that we receive from our protocol function call.
Also SMBIOS_TABLE_STRING
is just an UINT8 value that defines a string number in an ASCII string array that is placed directly after the structure.
///
/// Text strings associated with a given SMBIOS structure are returned in the dmiStrucBuffer, appended directly after
/// the formatted portion of the structure. This method of returning string information eliminates the need for
/// application software to deal with pointers embedded in the SMBIOS structure. Each string is terminated with a null
/// (00h) BYTE and the set of strings is terminated with an additional null (00h) BYTE. When the formatted portion of
/// a SMBIOS structure references a string, it does so by specifying a non-zero string number within the structure's
/// string-set. For example, if a string field contains 02h, it references the second string following the formatted portion
/// of the SMBIOS structure. If a string field references no string, a null (0) is placed in that string field. If the
/// formatted portion of the structure contains string-reference fields and all the string fields are set to 0 (no string
/// references), the formatted section of the structure is followed by two null (00h) BYTES.
///
typedef UINT8 SMBIOS_TABLE_STRING;
So let's write a simple function that returns actual ASCII string from a EFI_SMBIOS_TABLE_HEADER*
and a string number:
CHAR8* GetRecordString(EFI_SMBIOS_TABLE_HEADER* Record, UINTN number)
{
if (!number)
return "";
CHAR8* String = (CHAR8*)Record + Record->Length;
UINTN i=1;
while (i < number) {
String = String + AsciiStrSize(String);
i++;
}
return String;
}
Here we've used AsciiStrSize
function that is defined in https://github.com/tianocore/edk2/blob/master/MdePkg/Library/BaseLib/String.c file.
/**
Returns the size of a Null-terminated ASCII string in bytes, including the
Null terminator.
This function returns the size, in bytes, of the Null-terminated ASCII string
specified by String.
If String is NULL, then ASSERT().
If PcdMaximumAsciiStringLength is not zero and String contains more than
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
then ASSERT().
@param String A pointer to a Null-terminated ASCII string.
@return The size of String.
**/
UINTN
EFIAPI
AsciiStrSize (
IN CONST CHAR8 *String
)
Now we have everything to write actual parsing code in our while
loop:
while (!EFI_ERROR(Status)) {
Print (L"SMBIOS Type %d \n", Record->Type);
switch (Record->Type) {
case EFI_SMBIOS_TYPE_BIOS_INFORMATION: {
SMBIOS_TABLE_TYPE0* Type0Record = (SMBIOS_TABLE_TYPE0*) Record;
Print(L"\tVendor=%a\n", GetRecordString(Record, Type0Record->Vendor));
Print(L"\tBiosVersion=%a\n", GetRecordString(Record, Type0Record->BiosVersion));
Print(L"\tBiosReleaseDate=%a\n", GetRecordString(Record, Type0Record->BiosReleaseDate));
Print(L"\tBiosSegment=0x%x\n", Type0Record->BiosSegment);
Print(L"\tSystemBiosMajorRelease=0x%x\n", Type0Record->SystemBiosMajorRelease);
Print(L"\tSystemBiosMinorRelease=0x%x\n", Type0Record->SystemBiosMinorRelease);
break;
}
default:
Print(L"\tTODO: Parsing for this table is not ready yet\n");
break;
}
Status = SmbiosProtocol->GetNext(SmbiosProtocol,
&SmbiosHandle,
NULL,
&Record,
NULL);
}
To print ASCII strings here we've used %a
format code (https://github.com/tianocore/edk/blob/master/Foundation/Library/Pei/PeiLib/Print/Print.c).
If you build and execute our app under OVMF you would get:
FS0:\> SmbiosInfo.efi
SMBIOS table is placed at 7941000
SMBIOS Type 1
TODO: Parsing for this table is not ready yet
SMBIOS Type 3
TODO: Parsing for this table is not ready yet
SMBIOS Type 4
TODO: Parsing for this table is not ready yet
SMBIOS Type 16
TODO: Parsing for this table is not ready yet
SMBIOS Type 17
TODO: Parsing for this table is not ready yet
SMBIOS Type 19
TODO: Parsing for this table is not ready yet
SMBIOS Type 32
TODO: Parsing for this table is not ready yet
SMBIOS Type 0
Vendor=EFI Development Kit II / OVMF
BiosVersion=0.0.0
BiosReleaseDate=02/06/2015
BiosSegment=0xE800
SystemBiosMajorRelease=0x0
SystemBiosMinorRelease=0x0
If you look closely at dmem
dump from earlier, you'll see that these are the exact strings that were actually present in memory.
We can easily to add code to parse other SMBIOS tables.
For example here is some parsing code for table type 1 structure:
case EFI_SMBIOS_TYPE_SYSTEM_INFORMATION: {
SMBIOS_TABLE_TYPE1* Type1Record = (SMBIOS_TABLE_TYPE1*) Record;
Print(L"\tManufacturer=%a\n", GetRecordString(Record, Type1Record->Manufacturer));
Print(L"\tProductName=%a\n", GetRecordString(Record, Type1Record->ProductName));
Print(L"\tVersion=%a\n", GetRecordString(Record, Type1Record->Version));
Print(L"\tSerialNumber=%a\n", GetRecordString(Record, Type1Record->SerialNumber));
Print(L"\tUUID=%g\n", Type1Record->Uuid);
Print(L"\tWakeUpType=%d\n", Type1Record->WakeUpType);
Print(L"\tSKUNumber=%a\n", GetRecordString(Record, Type1Record->SKUNumber));
Print(L"\tFamily=%a\n", GetRecordString(Record, Type1Record->Family));
break;
}
Structure itself is:
typedef struct {
SMBIOS_STRUCTURE Hdr;
SMBIOS_TABLE_STRING Manufacturer;
SMBIOS_TABLE_STRING ProductName;
SMBIOS_TABLE_STRING Version;
SMBIOS_TABLE_STRING SerialNumber;
GUID Uuid;
UINT8 WakeUpType; ///< The enumeration value from MISC_SYSTEM_WAKEUP_TYPE.
SMBIOS_TABLE_STRING SKUNumber;
SMBIOS_TABLE_STRING Family;
} SMBIOS_TABLE_TYPE1;
Build and execute:
FS0:\> SmbiosInfo.efi
SMBIOS table is placed at 7941000
SMBIOS Type 1
Manufacturer=QEMU
ProductName=Standard PC (i440FX + PIIX, 1996)
Version=pc-i440fx-focal
SerialNumber=
UUID=00000000-0000-0000-0000-000000000000
WakeUpType=6
SKUNumber=
Family=
SMBIOS Type 3
TODO: Parsing for this table is not ready yet
SMBIOS Type 4
TODO: Parsing for this table is not ready yet
SMBIOS Type 16
TODO: Parsing for this table is not ready yet
SMBIOS Type 17
TODO: Parsing for this table is not ready yet
SMBIOS Type 19
TODO: Parsing for this table is not ready yet
SMBIOS Type 32
TODO: Parsing for this table is not ready yet
SMBIOS Type 0
Vendor=EFI Development Kit II / OVMF
BiosVersion=0.0.0
BiosReleaseDate=02/06/2015
BiosSegment=0xE800
SystemBiosMajorRelease=0x0
SystemBiosMinorRelease=0x0
As you remember the same information that is present in these SMBIOS tables is present in the main BIOS menu:
And in case you wonder where OVMF defines all these information for its SMBIOS structures, checkout https://github.com/tianocore/edk2/blob/master/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c and implementation of a EFI_SMBIOS_PROTOCOL
is placed here https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c
We can use EFI_SMBIOS_PROTOCOL
to parse SMBIOS table information, but actually if you just want to see SMBIOS information there is a better option.
UEFI shell has a smbiosview
command that does exactly what we need.
You can checkout sources for this command here: https://github.com/tianocore/edk2/tree/master/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView
First checkout help for this command:
FS0:\> smbiosview -?
Displays SMBIOS information.
SMBIOSVIEW [-t SmbiosType]|[-h SmbiosHandle]|[-s]|[-a]
-t - Displays all structures of SmbiosType.
-h - Displays structure of SmbiosHandle.
-s - Displays a statistics table.
-a - Displays all information.
SmbiosType - Specifies a SMBIOS structure type.
SmbiosHandle - Specifies a SMBIOS structure unique 16-bit handle.
NOTES:
1. The SmbiosType parameter supports the following types:
0 - BIOS Information
1 - System Information
2 - Baseboard Information
3 - System Enclosure
4 - Processor Information
5 - Memory Controller Information
6 - Memory Module Information
7 - Cache Information
8 - Port Connector Information
9 - System Slots
10 - On Board Devices Information
11 - OEM Strings
12 - System Configuration Options
13 - BIOS Language Information
14 - Group Associations
15 - System Event Log
16 - Physical Memory Array
17 - Memory Device
18 - 32-bit Memory Error Information
19 - Memory Array Mapped Address
20 - Memory Device Mapped Address
21 - Built-in Pointing Device
22 - Portable Battery
23 - System Reset
24 - Hardware Security
25 - System Power Controls
26 - Voltage Probe
27 - Cooling Device
28 - Temperature Probe
29 - Electrical Current Probe
30 - Out-Of-Band Remote Access
31 - Boot Integrity Services (BIS) Entry Point
32 - System Boot Information
33 - 64-Bit Memory Error Information
34 - Management Device
35 - Management Device Component
36 - Management Device Threshold Data
37 - Memory Channel
38 - IPMI Device Information
39 - System Power Supply
40 - Additional Information
41 - Onboard Devices Extended Information
42 - Management Controller Host Interface
43 - TPM Device
44 - Processor Additional Information
2. Enter the SmbiosHandle parameter in hexadecimal format.
Do not use the '0x' prefix format for hexadecimal values.
3. Internal commands:
:q -------- quit smbiosview
:0 -------- Change smbiosview display NONE info
:1 -------- Change smbiosview display OUTLINE info
:2 -------- Change smbiosview display NORMAL info
:3 -------- Change smbiosview display DETAIL info
/? -------- Show help
Try to dump one of the structures that we've tried to parse manually:
FS0:\> smbiosview -t 0
SMBIOS Entry Point Structure:
Anchor String: _SM_
EPS Checksum: 0x26
Entry Point Len: 31
Version: 2.8
Number of Structures: 9
Max Struct size: 83
Table Address: 0x7940000
Table Length: 401
Entry Point revision: 0x0
SMBIOS BCD Revision: 0x28
Inter Anchor: _DMI_
Inter Checksum: 0xA
Formatted Area:
00000000: 00 00 00 00 00 *.....*
=========================================================
Query Structure, conditions are:
QueryType = 0
QueryHandle = Random
ShowType = SHOW_DETAIL
=========================================================
Type=0, Handle=0x0
Dump Structure as:
Index=7,Length=0x4A,Addr=0x7940141
00000000: 00 1A 00 00 01 02 00 E8-03 00 08 00 00 00 00 00 *................*
FS0:\> 0: 00 00 00 1C 00 00 FF FF-00 00 45 46 49 20 44 65 *..........EFI De*
00000020: 76 65 6C 6F 70 6D 65 6E-74 20 4B 69 74 20 49 49 *velopment Kit II*
00000030: 20 2F 20 4F 56 4D 46 00-30 2E 30 2E 30 00 30 32 * / OVMF.0.0.0.02*
00000040: 2F 30 36 2F 32 30 31 35-00 00 */06/2015..*
Structure Type: BIOS Information
Format part Len : 26
Structure Handle: 0
Vendor: EFI Development Kit II / OVMF
BiosVersion: 0.0.0
BiosSegment: 0xE800
BiosReleaseDate: 02/06/2015
BiosSize: 64 KB
BIOS Characteristics:
BIOS Characteristics Not Supported
Bits 32:47 are reserved for BIOS Vendor
Bits 48:64 are reserved for System Vendor
BIOS Characteristics Extension Byte1:
BIOS Characteristics Extension Byte2:
Enable Targeted Content Distribution
UEFI Specification is supported
The SMBIOS table describes a virtual machine
Bits 5:7 are reserved for future assignment
SystemBiosMajorRelease: 0
SystemBiosMinorRelease: 0
EmbeddedControllerFirmwareMajorRelease: 255
EmbeddedControllerFirmwareMinorRelease: 255
As you can see it is all the same info that we've received using EFI_SMBIOS_PROTOCOL
.
You can use this command to see what is inside all of the SMBIOS structures using:
FS0:\> smbiosview -b
...
The output is too big to paste here, so check it out yourself!