27. dmem/EFI_SMBIOS_PROTOCOL/smbiosview를 통해서 SMBIOS 정보 가져오기

이전 장에서 확인한 시스템 테이블 중 SMBIOS에 대해서 알아보도록 하겠다.\

"System Management BIOS(SMBIOS) 참조 스펙"의 최신 버전은 아래의 사이트에서 확인할 수 있으며 현재는 3.6.0이 최신 버전인 것을 알 수 있다. https://www.dmtf.org/dsp/DSP0134

이전 시간에 우리는 SMBIOS 테이블이 gEfiSmbiosTableGuid 에 선언된 것을 확인했다.

해당 테이블의 주소를 인쇄하는 간단한 앱을 만들어 보겠다.

#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;
}

해당 코드에서 사용된 CompareGuid 함수는 아래의 코드에서 정의가 되어있다. 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
  );

잊지 말고 inf파일에GUID에 값을 추가 해주자.

[Guids]
  gEfiSmbiosTableGuid

빌드 후 실행하면 아래와 같이 주소가 나오는 것을 볼 수 있다.

FS0:\> SmbiosInfo.efi
SMBIOS table is placed at BF53F000

dmem을 통한 SMBIOS 테이블 가져오기

UEFI Shell에는 메모리를 덤프하는 dmem이라는 명령어가 존재한다.

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

SMBIOS 테이블 포인터로 출력된 0x793F000주소에서 0x30 바이트를 출력해보겠다.

FS0:\> dmem BF53F000 30
Memory Address 00000000BF53F000 30 Bytes
  BF53F000: 5F 53 4D 5F 26 1F 02 08-53 00 00 00 00 00 00 00  *_SM_&...S.......*
  BF53F010: 5F 44 4D 49 5F 2B 91 01-00 E0 93 07 09 00 28 AF  *_DMI_+........(.*
  BF53F020: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF  *................*

SMBIOS 스펙에 나와있는 SMBIOS Entry point 구조에 따르면 _SM__DMI_가 해당 구조에서 미리 정의된 값임을 알 수 있다.

SMBIOS에 대한 구조는 EDKII에서 또한찾을 수 있다. 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;

해당 구조를 따라서 덤프된 메모리를 계산하면 아래와 같이 볼 수 있다. 시스템에는 0xBF53E000에서 (0xBF53E000+0x1B2)까지 배치된 0xA개의 SMBIOS 구조가 존재한다. (환경별로 상이할 가능성 존재)

SMBIOS구조의 주소를 구하는 것이 가능하기 때문에 이를 통해서 덤프도 가능해진다.

EFI_SMBIOS_PROTOCOL을 사용하여 SMBIOS 데이터 파싱하기

위에서 한 방식대로 직접 포인터를 이용하여 SMBIOS 테이블을 계산을 통하여 구할 수 있지만, 매우 비합리적인 일이다. 다행히 UEFI PI 스펙은 SMBIOS 데이터를 가져오는데 사용할 수 있는 EFI_SMBIOS_PROTOCOL을 정의하고 있다.

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.

지금 우리는 SMBIOS 테이블의 파싱을 하기 위해서 GetNext 함수를 사용하겠다.

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.

우선 해당 프로토콜을 불러와야 한다.

EFI_SMBIOS_PROTOCOL* SmbiosProtocol;
EFI_STATUS Status = gBS->LocateProtocol (
                &gEfiSmbiosProtocolGuid,
                NULL,
                (VOID**)&SmbiosProtocol
                );
if (EFI_ERROR (Status)) {
  return Status;
}

해당 기능을 사용하기 위해서는 헤더 파일을 명시해야 한다. https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Protocol/Smbios.h

#include <Protocol/Smbios.h>

그리고 프로토콜의 GUID 값을 inf 파일에 작성한다.

[Protocols]
  gEfiSmbiosProtocolGuid

이제 SMBIOS 테이블을 가져오도록 하겠다. 프로토콜 호출에서 SMBIOS_HANDLE_PI_RESERVED(0 xFFE)EFI_SMBIOS_HANDLE로 사용할 것이다. SMBIOS_HANDLE_PI_RESERVED에 대한 설명은 아래의 링크에서 볼 수 있다. https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/SmBios.h

SMBIOS_HANDLE_PI_RESERVED를 사용하는 이유는 GetNext()함수의 두번째 파라미터인 SmbiosHandle을 충족하기 위해서다.

///
/// 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

또한 코드 작성전 GetNext 호출에서 파라미터로 사용되는 EFI_SMBIOS_TABLE_HEADER 구조의 정의를 살펴보겠다. 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;

이를 통해서 몇가지 코드 작성 준비가 되었다. 시스템에 있는 모든 유형의 SMBIOS 테이블을 인쇄하는 코드를 작성하겠다.

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);
}

빌드 후 실행시 아래와 같은 결과를 볼 수 있다.

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

이제는 이 테이블의 정보를 파싱할 수 있는 코드를 Type 0 테이블부터 시작하겠다. 아래 링크에 EDKII에서 해당 구조의 정의에대한 설명이 존재한다. 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;

해당 구조에서 SMBIOS_STRUCTURE Hdr은 프로토콜 함수 호출에서 수신한 EFI_SMBIOS_TABLE_HEADER와 동일하게 필수적인 필드이다. 또한 SMBIOS_TABLE_STRING은 ASCII 문자열 배열의 문자형 숫자를 정의하는 UINT8 값이다.

///
/// 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;

따라서 EFI_SMBIOS_TABLE_HEADER* 및 문자형 숫자에서 실제 ASCII 문자열을 반환하는 간단한 함수를 작성하겠다.

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;
}

해당 함수에서는 아래의 링크에 정의된 AsciiStrSize 함수를 사용했다. https://github.com/tianocore/edk2/blob/master/MdePkg/Library/BaseLib/String.c

/**
  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
  )

위의 모든 것을 바탕으로 while문을 이용해서 실제적으로 파싱을 하는 코드를 작성할 수 있다.

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);
}

여기서 ASCII 문자열을 인쇄하기 위해서 Print 함수의 %a 옵션을 사용했다. 이후 빌드를 하면 아래와 같은 결과가 나온다.

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

해당 결과는 dmem을 통해서 dump한 결과가 실제로 메모리에 존재하는 문자열임을 알 수 있다. Type 0 이외에도 다른 SMBIOS 테이블을 parse하는 코드를 추가해보겠다.

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;
}

이번에는 Type 1에 대해서 파싱하는 코드를 추가했고, 이에 대한 구조는 아래와 같다.

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

빌드 후 실행시 아래와 같은 결과가 나온다.

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

이러한 SMBIOS 테이블에 있는 정보와 동일한 정보가 기본 BIOS 메뉴에 존재하는 것을 기억하고 있어야 한다. 해당 SMBIOS 구조에 대한 정보의 위치와 EFI_SMBIOS_PROTOCOL의 구현은 아래의 링크에 위치한다. https://github.com/tianocore/edk2/blob/master/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c

smbiosview 명령어

EFI_SMBIOS_PROTOCOL을 사용하여 SMBIOS 테이블 정보를 파싱할 수 있지만 실제로 SMBIOS 정보만 보려면 더 좋은 옵션이 있다. UEFI Shell에는 정확히 필요한 작업을 수행하는 smbiosview라는 명령어가 있다. 이는 아래의 소스를 통해서 확인이 가능하다. https://github.com/tianocore/edk2/tree/master/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView

해당 명령어에 대한 설명을 확인하자.

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

위에서 파싱한 구조 중 하나를 명령어를 통해서 덤프 해보겠다.

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

보다시피 EFI_SMBIOS_PROTOCOL을 사용한 것과 동일한 정보가 나왔다. 이외에도 SMBIOS 구조 내부에 무엇이 있는지 확인하는 명령어도 존재한다. 해당 결과 값은 너무 크기 때문에 직접 확인해보자.

FS0:\> smbiosview -b
...

Last updated