提示:HII使用者互動界面的c代碼實作過程
文章目錄
- 前言
- 一、C代碼的生成
- 二、解讀
- 定義AutogenPackageHeader
-
- 定義PackageHeader
- PACKAGE_LIST_HEADER
- FORM_PACKAGE_HDR
- STRING_PACKAGE_HDR
- FONT_PACKAGE_HDR
- IMAGE_PACKAGE_HDR
- DEVICE_PATH_PACKAGE_HDR
- GUID_PACKAGE_HDR
- KEYBOARD_PACKAGE_HDR
- ANIMATION_PACKAGE_HDR
- 三、總結
前言
在檢視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中注釋掉的并不是不用而是為了提示後面的資料解析提供一個線索。