Step to UEFI (180)GetVbtData 取得 Vbt

之前的《Shell 下读取 VBT》【参考1】给出了一个读取VBT 的方法。Simon 留言表示可以使用 PLATFORM_GOP_POLICY_PROTOCOL提供的 GetVbtData 。可以在\Vlv2DeviceRefCodePkg\ValleyView2Soc\NorthCluster\Include\Protocol\PlatformGopPolicy.h 中看到如下定义:

#define EFI_PLATFORM_GOP_POLICY_PROTOCOL_GUID \
  { 0xec2e931b, 0x3281, 0x48a5, 0x81, 0x7, 0xdf, 0x8a, 0x8b, 0xed, 0x3c, 0x5d }
#define PLATFORM_GOP_POLICY_PROTOCOL_REVISION_01 0x01
#define PLATFORM_GOP_POLICY_PROTOCOL_REVISION_02 x0222
#pragma pack(1)

typedef enum {
  LidClosed,
  LidOpen,
  LidStatusMax
} LID_STATUS;

typedef enum {
  Docked,
  UnDocked,
  DockStatusMax
} DOCK_STATUS;

typedef
EFI_STATUS
(EFIAPI *GET_PLATFORM_LID_STATUS) (
  OUT LID_STATUS *CurrentLidStatus
  );

typedef
EFI_STATUS
(EFIAPI *GET_VBT_DATA) (
  OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
  OUT UINT32 *VbtSize
  );

#pragma pack()

typedef struct _PLATFORM_GOP_POLICY_PROTOCOL {
  UINT32                             Revision;
  GET_PLATFORM_LID_STATUS            GetPlatformLidStatus;
  GET_VBT_DATA                       GetVbtData;
} PLATFORM_GOP_POLICY_PROTOCOL;

根据上述定义编写代码,首先搜索 PLATFORM_GOP_POLICY_PROTOCOL ,然后调用它提供的GetVbtData 函数。

/** @file
    A simple, basic, EDK II native, "hello" application to verify that
    we can build applications without LibC.

    Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
    This program and the accompanying materials
    are licensed and made available under the terms and conditions of the BSD License
    which accompanies this distribution. The full text of the license may be found at
    http://opensource.org/licenses/bsd-license.

    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include  <Uefi.h>
#include  <Library/UefiLib.h>
#include  <Library/ShellCEntryLib.h>
#include  <Protocol/SimpleFileSystem.h>
#include  <Library/UefiBootServicesTableLib.h> //global gST gBS gImageHandle
#include  <Library/ShellLib.h>
#include  <Library/IoLib.h>

#include  "PlatformGopPolicy.h"

EFI_GUID gPlatformGOPPolicyGuid      = 
        { 0xec2e931b, 0x3281, 0x48a5, 
                { 0x81, 0x07, 0xdf, 0x8a, 0x8b, 0xed, 0x3c, 0x5d } };

//                        
//Save memory address to a file                        
//
EFI_STATUS 
SaveToFile(
        IN UINT8 *FileData, 
        IN UINTN FileDataLength)
{
    EFI_STATUS          Status;
    EFI_FILE_PROTOCOL   *FileHandle;
    UINTN               BufferSize;
    EFI_FILE_PROTOCOL   *Root;
    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;

    Status = gBS->LocateProtocol(
                &gEfiSimpleFileSystemProtocolGuid, 
                NULL,
                (VOID **)&SimpleFileSystem);
                
    if (EFI_ERROR(Status)) {
            Print(L"Cannot find EFI_SIMPLE_FILE_SYSTEM_PROTOCOL \r\n");
            return Status;
    }

    Status = SimpleFileSystem->OpenVolume(SimpleFileSystem, &Root);
    if (EFI_ERROR(Status)) {
        Print(L"OpenVolume error \r\n");
        return Status;
    }
    Status = Root->Open(
                Root, 
                &FileHandle, 
                L"dumpvbt.bin",
                EFI_FILE_MODE_READ |
                EFI_FILE_MODE_WRITE | 
                EFI_FILE_MODE_CREATE, 
                0);
    if (EFI_ERROR(Status)){
        Print(L"Error Open NULL  [%r]\n",Status);
        return Status;
    }
    
    BufferSize = FileDataLength;
    Status = FileHandle->Write(FileHandle, &BufferSize, FileData);
    if (EFI_ERROR(Status)){
        Print(L"Error write [%r]\n",Status);
        return Status;
    }
    else Print(L"VBT has been saved to 'dumpvbt.bin' \n");
    
    FileHandle->Close(FileHandle);
    
    return Status;
}


/***
  Print a welcoming message.

  Establishes the main structure of the application.

  @retval  0         The application exited normally.
  @retval  Other     An error occurred.
***/
INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
        PLATFORM_GOP_POLICY_PROTOCOL    *mPlatformGopPolicyProtocl;
        EFI_STATUS              Status;
        EFI_PHYSICAL_ADDRESS    VbtAddress;
        UINT32                  VbtSize;
        
        Print(L"*************************************************\n");
        Print(L"* VBT dump tool By Platform GOP Policy Protocol *\n");
        Print(L"*                                 May 4th 2019  *\n");
        Print(L"*                      Powered by www.lab-z.com *\n");
        Print(L"*************************************************\n");
        
        //
        // Locate the Cpu Arch Protocol.
        //
        Status = gBS->LocateProtocol(
                        &gPlatformGOPPolicyGuid, 
                        NULL, 
                        &mPlatformGopPolicyProtocl);
        if (EFI_ERROR (Status)) {
                Print(L"Can't find EFI_PLATFORM_GOP_POLICY_PROTOCOL_\n");
                return Status;
        }        
        
        mPlatformGopPolicyProtocl->GetVbtData(&VbtAddress,&VbtSize);
        SaveToFile((UINT8 *)VbtAddress,VbtSize);
        
        return(0);
}

在 Shell 下运行之后会生成dumpvbt.bin ,内容就是当前使用的 VBT。

完整的代码和 EFI 文件下载:

这个方法和之前相比优点是避免了计算便宜之类的问题更加简单明确,可以在一定程度上克服不同Chipset之间的差别;缺点是:并非公开的 Protcol 在使用的时候可能存在一定风险。

最后,再次感谢 Simon 先生的建议。

参考:

1. https://www.lab-z.com/stu175vbt/  Step to UEFI (175)Shell 下读取 VBT

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注