SMBIOS学习总结

SMBIOS的内容在物理地址000F0000h到000FFFFFh之间,想要访问SMBIOS,需要在32-bit 或 64-bit protected-mode之下。

在一个EFI系统中,SMBIOS Entry Point structure类似于EFI Configuration Table的布局。具体详见smbios spec。

SMBIOS structure开始于一个4-byte header。

00h,Type,1-BYTE,指定structure的type

01h,Length,1-BYTE,指定structure formatted area的长度

02h,Handle,2-BYTE,指定其handle

之后的内容为Text Strings。

 

IN SMBIOS,Every string is separated by NULL byte.

在SMBIOS的entry point table中,18h定义了string的存储位置。

Board上的设备信息均被记录在SMBIOS table中,记录的过程是由BIOS完成的。

SMBIOS entry point table 一般记录在F段中,而string的信息一般记录在E段中。

 

SMBIOS event log format

Event Log中的00位表示该Event Log为何type。

Trace code中如何实现SMBIOS type 15.

static EFI_SYSTEM_EVENT_LOG_TYPE_15 SystemEventLogType15Table = {
  15,                                   // Type
  0x17+(2*NumOfSupportedSmbiosTypes),   // Length
  0x0000,                               // Handle or instance number
  (UINT16)LOCAL_EVENT_LOG_LENGTH,       // Length, in bytes, of the overall 
                                        // event log area, 1st byte of header
                                        // to last of data
  0x0000,                               // offset of event log header from 
                                        // access method address
  sizeof(EFI_GPNV_ERROR_HEADER_TYPE1),  // offset of event log data from 
                                        // access method address
  0x03,                                 // defines method of higher-level 
                                        // software accessing table
  0x01,                                 // current status of the system event
                                        // log
  0x00000001,                           // unique token changed every time log
                                        // changes
  LOCAL_EVENT_LOG_PHY_ADDR,             // address associated with access 
                                        // method
  0x01,                                 // identifies the format of the log 
                                        // header area
  NumOfSupportedSmbiosTypes,            // number of supported event log type
                                        // descriptors that follow
  0x02                                  // Always 2

  // SupportedEventLogTypesList[] to be added here 
  // to build final type 15 entry
};

 

DXE阶段在dispatch每个driver时,会执行SMBIOS elog的driver。

借执行这个driver,系统会初始化SMBIOS log。

InitializeSmbiosElog()

在这个过程中,会安装event log的protocol

mRedirSmbiosPrivate->SmbiosElog.ActivateEventLog  = EfiActivateSmbiosElog;
      mRedirSmbiosPrivate->SmbiosElog.EraseEventLogData = EfiEraseSmbiosElogData;
      mRedirSmbiosPrivate->SmbiosElog.GetEventLogData   = EfiGetSmbiosElogData;
      mRedirSmbiosPrivate->SmbiosElog.SetEventLogData   = EfiSetSmbiosElogData;
      NewHandle = NULL;

      Status = EfiInstallProtocolInterface (
                      &NewHandle,
                      &gEfiRedirElogProtocolGuid,
                      EFI_NATIVE_INTERFACE,
                      &mRedirSmbiosPrivate->SmbiosElog );
      ASSERT_EFI_ERROR (Status);

在memory中,为event log分配一段空间

然后添加一个type15的SMBIOS structure,即为event log

AddSMBIOSType15Structure()

 

SMBIOS event log是如何记录到一条error信息的呢?

追code的最大感触就是code中实做部分大概占code的一般,另一半则是判断每一段code执行的状态是否正确。思考来也是必要的,如果发生错误,就可以快速定位排错了。所以code中提供了很多记录error的函数。

以ReportStatusCode()这个函数为例,它在PEI,DXE或是SMM等各种模式下均有对应函数。

在DXE阶段,系统会对PEI传来的HOB进行处理。Error通常以record的形式存在DataHub中。DataHub在DXE阶段建立,每条record都有自己的RecordID。

CoreGetPeiProtocol(&gEfiStatusCodeRuntimeProtocolGuid,(VOID**)&gStatusCode->ReportStatusCode);
  if (gStatusCode->ReportStatusCode != NULL) {
    gRT->ReportStatusCode = gStatusCode->ReportStatusCode;
  }

每条record还有其type,这样调用event log的protocol即可以抓到需要显示的error的信息。这样就可以在setup下显示出来。

//
    // all protocols available, continue with displaying all errors
    //
    DataSize = 0xFF;
    Status = GenericElogProtocol->GetEventLogData( GenericElogProtocol, 
                                                   &ElogData[0], 
                                                   EfiSmSMBIOS, 
                                                   &DataSize, 
                                                   &RecordId );

 

最后展示一张图,编程读取到的SMBIOS信息:

 

posted on 2018-03-14 10:04  米兰达莫西  阅读(7225)  评论(0编辑  收藏  举报