UEFI 基础教程 (十一) - Shell下读取SMBIOS信息

一、 编写源代码

  1. 编写UEFI Application
    代码C:\edkii\OvmfPkg\MyHelloWorldSMBios\MyHelloWorldSMBios.c,
EFI_STATUS
EFIAPI
MyHelloWorldSMBiosEntry(
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
)
{ 
  DUMP_LOG ("MyHelloWorldSmbiosAppEntry Start\n")
  Print (L"[MyHelloWorldSmbios]  MyHelloWorldSmbiosAppEntry Start..\n");
  //
  // 1. 找到 SMBIOS protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiSmbiosProtocolGuid,
                  NULL,
                  (VOID**)&Smbios
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  // 2.配合下面while循环,轮询所有SMBIOS Table
  Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
  while (!EFI_ERROR(Status)) {
      DUMP_LOG ("SMBIOS Type %d ..\n", Record->Type);
      Print (L"[MyHelloWorldSmbios] SMBIOS Type %d ..\n", Record->Type);
   
    //SMBIOS_TYPE_BIOS_INFORMATION 0
    if (Record->Type == SMBIOS_TYPE_BIOS_INFORMATION) {
       Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;
       ....
    //SMBIOS_TYPE_SYSTEM_INFORMATION 1
    // 3. 指定SMBIOS type过滤 SMBIOS table
    }else if (Record->Type == SMBIOS_TYPE_SYSTEM_INFORMATION){
       Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;
       DUMP_LOG ("Manufacturer |ProductName |Version |SerialNumber |WakeUpType |SKUNumber |Family\n")
       DUMP_LOG ("%04x         |%04x        |%04x    |%04x         |%04x       |%04x      |%04x  \n", 
            Type1Record->Manufacturer ,
            Type1Record->ProductName ,
            Type1Record->Version ,
            Type1Record->SerialNumber ,
            Type1Record->WakeUpType ,
            Type1Record->SKUNumber ,
            Type1Record->Family 
        )
    //SMBIOS_TYPE_SYSTEM_ENCLOSURE 3
    }else if (Record->Type == SMBIOS_TYPE_SYSTEM_ENCLOSURE)
      ......
    //SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY 16
    }else if (Record->Type == SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY){      
      ......
    //SMBIOS_TYPE_MEMORY_DEVICE 17
    }else if (Record->Type == SMBIOS_TYPE_MEMORY_DEVICE){
      ......
    //SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS 19
    }else if (Record->Type == SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS)  {
      ......
    //SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION 32
    }else if (Record->Type == SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION){
      ......
    }
    Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
  }

  DEBUG ((EFI_D_ERROR, "[MyHelloWorldSmbios] MyHelloWorldSmbiosAppEntry End..\n"));

}
  1. 修改 C:\code\local_edkrepo_10nm\Edk2\OvmfPkg\MyHelloWorldSMBios\MyHelloWorldSMBios.inf
[Defines] 
  INF_VERSION = 0x00010006 
  BASE_NAME = MyHelloWorldSmbios
  FILE_GUID = 69A69543-FA9F-485E-9A3E-EA70FDCFC82F
  MODULE_TYPE = UEFI_APPLICATION
  VERSION_STRING = 1.0
  ENTRY_POINT = MyHelloWorldSmbiosAppEntry 

[Sources] 
  MyHelloWorldSmbios.c 
  ....
  
[Protocols]
  gEfiSmbiosProtocolGuid                      # PROTOCOL ALWAYS_CONSUMED

[Depex]
  gEfiSmbiosProtocolGuid

  1. 修改C:\edkii\OvmfPkg\OvmfPkgX64.dsc
...
# 
[Components]
  OvmfPkg/MyHelloWorldSmbios/MyHelloWorldSmbios.inf
...

二、 编译生成EFI文件

运行edksetup.bat && build -a X64 -p OvmfPkg\OvmfPkgX64.dsc -D DEBUG_ON_SERIAL_PORT -t VS2013x86编译整个OvmfPkg Package

三、 运行 UEFI APP MyHelloWorldSmbios.efi

UEFI 基础教程 (十一) - Shell下读取SMBIOS信息_第1张图片
UEFI 基础教程 (十一) - Shell下读取SMBIOS信息_第2张图片

四、 小结

在主板上电后,UEFI会将HW信息包括, CPU、Memory、FW、PM等信息以SMBIOS table形式上存储到一段内存区域中,进入OS后,OS通过解析该段内存即可获取相关配置。在UEFI Shell中,可以通过SmbiosProtocol 访问整段SMBIOS table, 本文给出了Demo实现。

你可能感兴趣的:(15_固件开发)