提示: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中注释掉的并不是不用而是为了提示后面的数据解析提供一个线索。