【UEFI实战】UEFI用户交互界面之C代码实现

提示:HII用户交互界面的c代码实现过程


前言

在查看build目录下的对应Pakage目录下的DEBUG目录下可以找到与VFR文件相对应的.c代码。
如下

unsigned char PciVfrBin[] = {
  // ARRAY LENGTH

  0x13,  0x01,  0x00,  0x00,  

  // PACKAGE HEADER

  0x0F,  0x01,  0x00,  0x02,  

  // PACKAGE DATA

  0x0E,  0xA7,  0xE8,  0x3E,  0x42,  0x21,  0xE1,  0x72,  0xCB,  0x49,  0xAD,  0xA0,  0xA4,  0xBC,  0xCD,  0xC8,  
  ……
  
};

那他是怎么生成的,又该怎么解析?


提示:只是个人理解可能会有一些错误,如果有错误的地方希望能够指出来共同进步

一、C代码的生成

C代码是根据VFR文件使用Basetools中VfrCompile工具和StringGather.py来生成的。

二、解读

定义AutogenPackageHeader

HiiLib.h文件中定义

#pragma pack (push, 1)
  typedef struct {
    UINT32                  BinaryLength;
    EFI_HII_PACKAGE_HEADER  PackageHeader;
  } EDKII_AUTOGEN_PACKAGES_HEADER;
  #pragma pack (pop)

c文件的代码中

// ARRAY LENGTH

  0x13,  0x01,  0x00,  0x00,

数据0x00000113 即 BinaryLength = 275 Bytes

定义PackageHeader

typedef struct {
  UINT32  Length:24;
  UINT32  Type:8;
  // UINT8  Data[...];
} EFI_HII_PACKAGE_HEADER;

c文件代码中

 // PACKAGE HEADER

  0x0F,  0x01,  0x00,  0x02, 
  

在文件UefiInternalFormRepresentation.h定义Package Type。

#define EFI_HII_PACKAGE_TYPE_ALL             0x00
#define EFI_HII_PACKAGE_TYPE_GUID            0x01
#define EFI_HII_PACKAGE_FORMS                0x02
#define EFI_HII_PACKAGE_STRINGS              0x04
#define EFI_HII_PACKAGE_FONTS                0x05
#define EFI_HII_PACKAGE_IMAGES               0x06
#define EFI_HII_PACKAGE_SIMPLE_FONTS         0x07
#define EFI_HII_PACKAGE_DEVICE_PATH          0x08
#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT      0x09
#define EFI_HII_PACKAGE_ANIMATIONS           0x0A
#define EFI_HII_PACKAGE_END                  0xDF
#define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN    0xE0
#define EFI_HII_PACKAGE_TYPE_SYSTEM_END      0xFF

数据PackageLength 0x00010F即长度为271Bytes ,PackageType 0x02 即本数据为Package Form数据。
它是一系列Package中最开始的数据,这些package中最重要的是二进制数据,这些二进制数据就是 String 、Fonts、Images和Forms等列出来的为显示框架的基础部分数据,生成的各类Package同时用HiiAddPackages()注册到PackageList,PackageList以mEndOfPackageList结束。基本数据排布为:
EFI_HII_PACKAGE_LIST_HEADER ->Package1->……->PackageN->mEndOfPackageList。PackageList的GUID就是HiiAddPackages传入的参数的GUID也用于标识整个Package表。

PACKAGE_LIST_HEADER

typedef struct {
  EFI_GUID               PackageListGuid;
  UINT32                 PackageLength;
} EFI_HII_PACKAGE_LIST_HEADER;

FORM_PACKAGE_HDR

typedef struct _EFI_HII_FORM_PACKAGE_HDR {
  EFI_HII_PACKAGE_HEADER       Header;
  // EFI_IFR_OP_HEADER         OpCodeHeader;
  // More op-codes follow
} EFI_HII_FORM_PACKAGE_HDR;

自动生成的文件在edkii\Build\EmulatorIA32\DEBUG_VS2015x86\IA32\MdeModulePkg\Library\BootManagerUiLib\BootManagerUiLib\DEBUG目录下的xxxVfr.c文件。

STRING_PACKAGE_HDR

typedef struct _EFI_HII_STRING_PACKAGE_HDR {
  EFI_HII_PACKAGE_HEADER  Header;
  UINT32                  HdrSize;
  UINT32                  StringInfoOffset;
  CHAR16                  LanguageWindow[16];
  EFI_STRING_ID           LanguageName;
  CHAR8                   Language[1];
} EFI_HII_STRING_PACKAGE_HDR;

String编译的二进制数据在编译后生成的AutoGen.c文件内。
如:

//
//Unicode String Pack Definition
//
unsigned char BootManagerUiLibStrings[] = {

// STRGATHER_OUTPUT_HEADER
  0x34,  0x04,  0x00,  0x00,

// PACKAGE HEADER

  0x40,  0x02,  0x00,  0x04,  0x34,  0x00,  0x00,  0x00,  0x34,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x65,  0x6E,  
  0x2D,  0x55,  0x53,  0x00,

// PACKAGE DATA

// 0x0001: $PRINTABLE_LANGUAGE_NAME:0x0001
  0x14,  0x45,  0x00,  0x6E,  0x00,  0x67,  0x00,  0x6C,  0x00,  0x69,  0x00,  0x73,  0x00,  0x68,  0x00,  0x00, 
  ……

FONT_PACKAGE_HDR

typedef struct _EFI_HII_SIMPLE_FONT_PACKAGE_HDR {
  EFI_HII_PACKAGE_HEADER Header;
  UINT16                 NumberOfNarrowGlyphs;
  UINT16                 NumberOfWideGlyphs;
  // EFI_NARROW_GLYPH       NarrowGlyphs[];
  // EFI_WIDE_GLYPH         WideGlyphs[];
} EFI_HII_SIMPLE_FONT_PACKAGE_HDR;

它在UiApp.inf中有使用到。

FONT_PACK_BIN mFontBin = {
  sizeof (FONT_PACK_BIN),
  {
    sizeof (FONT_PACK_BIN) - sizeof (UINT32),
    EFI_HII_PACKAGE_SIMPLE_FONTS,
  },
  NARROW_GLYPH_NUMBER,
  0,
  {     // Narrow Glyphs
    {
      0x05d0,
      0x00,
      {
        0x00,
        0x00,
        0x00,
        ……

注册HII数据库。

EFI_HII_HANDLE
ExportFonts (
  VOID
  )
{
  return HiiAddPackages (
           &mFontPackageGuid,
           gImageHandle,
           &mFontBin,
           NULL
           );
}
///
/// The fixed header consists of a standard record header,
/// then the character values in this section, the flags
/// (including the encoding method) and the offsets of the glyph
/// information, the glyph bitmaps and the character map.
///
typedef struct _EFI_HII_FONT_PACKAGE_HDR {
  EFI_HII_PACKAGE_HEADER Header;
  UINT32                 HdrSize;
  UINT32                 GlyphBlockOffset;
  EFI_HII_GLYPH_INFO     Cell;
  EFI_HII_FONT_STYLE     FontStyle;
  CHAR16                 FontFamily[1];
} EFI_HII_FONT_PACKAGE_HDR;

IMAGE_PACKAGE_HDR

//
// Definitions for Image Package
// Section 27.3.7
//

typedef struct _EFI_HII_IMAGE_PACKAGE_HDR {
  EFI_HII_PACKAGE_HEADER  Header;
  UINT32                  ImageInfoOffset;
  UINT32                  PaletteInfoOffset;
} EFI_HII_IMAGE_PACKAGE_HDR;

DEVICE_PATH_PACKAGE_HDR

///
/// The device path package is used to carry a device path
/// associated with the package list.
///
typedef struct _EFI_HII_DEVICE_PATH_PACKAGE_HDR {
  EFI_HII_PACKAGE_HEADER   Header;
  // EFI_DEVICE_PATH_PROTOCOL DevicePath[];
} EFI_HII_DEVICE_PATH_PACKAGE_HDR;

GUID_PACKAGE_HDR

//
// Definitions for GUID Package
// Section 27.3.5
//

///
/// The GUID package is used to carry data where the format is defined by a GUID.
///
typedef struct _EFI_HII_GUID_PACKAGE_HDR {
  EFI_HII_PACKAGE_HEADER  Header;
  EFI_GUID                Guid;
  // Data per GUID definition may follow
} EFI_HII_GUID_PACKAGE_HDR;

KEYBOARD_PACKAGE_HDR

typedef struct {
  EFI_HII_PACKAGE_HEADER  Header;
  UINT16                  LayoutCount;
  // EFI_HII_KEYBOARD_LAYOUT Layout[];
} EFI_HII_KEYBOARD_PACKAGE_HDR;

ANIMATION_PACKAGE_HDR

///
/// HII animation package header.
///
typedef struct _EFI_HII_ANIMATION_PACKAGE_HDR {
  ///
  /// Standard package header, where Header.Type = EFI_HII_PACKAGE_ANIMATIONS.
  ///
  EFI_HII_PACKAGE_HEADER  Header;
  ///
  /// Offset, relative to this header, of the animation information. If
  /// this is zero, then there are no animation sequences in the package.
  ///
  UINT32                  AnimationInfoOffset;
} EFI_HII_ANIMATION_PACKAGE_HDR;

三、总结

 根据对PackageHeader的观察,header中注释掉的并不是不用而是为了提示后面的数据解析提供一个线索。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值