vfr文件

HII的实现涉及到多种不同类型的文件,vfr文件是其中最重要的一种,它构成了界面的结构样式。本文主要参考自《edk-ii-vfr-specification.pdf》,后面简称为参考文档。

UEFI代码操作UI界面,并不是直接使用vfr文件,而是称为IFR(Internal Forms Representation)的二进制,vfr文件只是IFR的字符串表示,方便通过可识别的字符串作为代码来编写界面,然后通过VFR编译器编译出IFR二进制,最终给UEFI代码使用。

以前面出现过的Front Page为例,图中界面的结构依赖于vfr文件MdeModulePkg\Application\UiApp\FrontPageVfr.Vfr,它构建了Front Page页面的骨架,该文件内容如下:

#define FORMSET_GUID  { 0x9e0c30bc, 0x3f06, 0x4ba6, 0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe }#define FRONT_PAGE_FORM_ID             0x1000#define LABEL_FRANTPAGE_INFORMATION    0x1000
#define LABEL_END                      0xffffformsetguid     = FORMSET_GUID,title    = STRING_TOKEN(STR_FRONT_PAGE_TITLE),help     = STRING_TOKEN(STR_EMPTY_STRING ),classguid = FORMSET_GUID,form formid = FRONT_PAGE_FORM_ID,title  = STRING_TOKEN(STR_FRONT_PAGE_TITLE);bannertitle = STRING_TOKEN(STR_FRONT_PAGE_COMPUTER_MODEL),line  1,align left;bannertitle = STRING_TOKEN(STR_FRONT_PAGE_CPU_MODEL),line  2,align left;bannertitle = STRING_TOKEN(STR_FRONT_PAGE_CPU_SPEED),line  2,align right;bannertitle = STRING_TOKEN(STR_FRONT_PAGE_BIOS_VERSION),line  3,align left;bannertitle = STRING_TOKEN(STR_FRONT_PAGE_MEMORY_SIZE),line  3,align right;bannertitle = STRING_TOKEN(STR_CUSTOMIZE_BANNER_LINE4_LEFT),line  4,align left;bannertitle = STRING_TOKEN(STR_CUSTOMIZE_BANNER_LINE4_RIGHT),line  4,align right;bannertitle = STRING_TOKEN(STR_CUSTOMIZE_BANNER_LINE5_LEFT),line  5,align left;bannertitle = STRING_TOKEN(STR_CUSTOMIZE_BANNER_LINE5_RIGHT),line  5,align right;label LABEL_FRANTPAGE_INFORMATION;//// This is where we will dynamically add a Action type op-code to show// the platform information.//label LABEL_END;endform;

它构成的结构基本样式如下:

STR_FRONT_PAGE_COMPUTER_MODEL
STR_FRONT_PAGE_CPU_MODEL                                STR_FRONT_PAGE_CPU_SPEED
STR_FRONT_PAGE_BIOS_VERSION                             STR_FRONT_PAGE_MEMORY_SIZE
STR_CUSTOMIZE_BANNER_LINE4_LEFT                         STR_CUSTOMIZE_BANNER_LINE4_RIGHT
STR_CUSTOMIZE_BANNER_LINE5_LEFT                         STR_CUSTOMIZE_BANNER_LINE5_RIGHT
LABEL_FRANTPAGE_INFORMATION
LABEL_END

对应到Front Page界面中(第四、五行没有使用):

红色字体部分是vfr文件中定义的标记,而显示的字符串有一部分是在uni文件中定义的,而红框部分是通过代码实现的,所以vfr文件构成了界面的静态框架,而代码又可以通过vfr文件中定义的标记来动态修改。

vfr文件通过特定的VFR编译器编译,最终得到的是中间文件。该中间文件是一个c文件(FrontPageVfr.c)或者hpk文件,里面就是一个变量用来表示VFR资源:

unsigned char FrontPageVfrBin[] = {// ARRAY LENGTH,0x143加上下述的头部长度,就是0x1470x47,  0x01,  0x00,  0x00,  // PACKAGE HEADER,对应的是EFI_HII_FORM_PACKAGE_HDR,0x13F加上下述的头部长度,就是0x143,占据3个字节;第4个字节0x02表示HII类型Form0x43,  0x01,  0x00,  0x02,  // PACKAGE DATA,319个字节,十六进制就是0x13F,注释已经加上// 第1个操作码,对应结构体EFI_IFR_FORM_SET0x0E,  // EFI_IFR_FORM_SET_OP,它的值就是0xE0xA7,  // 前面7位表示长度,即0x27=39个字节,总长度到第二个FORMSET_GUID为止刚好39个字节;第8位表示的是scope,该位为1则表示开始一个新的scope// Guid: FORMSET_GUID0xBC,  0x30,  0x0C,  0x9E,  0x06,  0x3F,  0xA6,  0x4B,  0x82,  0x88,  0x09,  0x17,  0x9B,  0x85,  0x5D,  0xBE,  0x02,  0x00,  // FormSetTitle:字符串Token,在AutoGen中定义,对应的是STR_FRONT_PAGE_TITLE,值就是0x00020x0C,  0x00,  // Help:字符串Token,在AutoGen中定义,对应的是STR_EMPTY_STRING,值就是0x000C0x01,    // Flags:// ClassGuid: FORMSET_GUID0xBC,  0x30,  0x0C,  0x9E,  0x06,  0x3F,  0xA6,  0x4B,  0x82,  0x88,  0x09,  0x17,  0x9B,  0x85,  0x5D,  0xBE,// 第2个操作码,对应结构体EFI_IFR_DEFAULTSTORE0x5C,  // 操作码EFI_IFR_DEFAULTSTORE_OP0x06,  // 长度6个字节0x00,  0x00,  // DefaultName:字符串Token,似乎并不存在0x00,  0x00,  // DefaultId:表示EFI_HII_DEFAULT_CLASS_STANDARD// 第3个操作码,对应结构体EFI_IFR_DEFAULTSTORE0x5C,  // 操作码EFI_IFR_DEFAULTSTORE_OP0x06,  // 长度6个字节0x00,  0x00,  // DefaultName:字符串Token,似乎并不存在0x01,  0x00,  // DefaultId:表示EFI_HII_DEFAULT_CLASS_MANUFACTURING// 前面两个操作码并没有在vfr文件中声明,但是却创建了。// 第4个操作码,对应结构体EFI_IFR_FORM0x01,  // 操作码示EFI_IFR_FORM_OP0x86,  // 长度6个字节,新建scope0x00,  0x10,  // FormId:对应FRONT_PAGE_FORM_ID0x02,  0x00,  // FormTitle:对应字符串Token,STR_FRONT_PAGE_TITLE// 第5个操作码,对应结构体EFI_IFR_GUID_BANNER0x5F,  // 操作码示EFI_IFR_GUID_OP0x18,  // 长度24个字节,其中16个是GUID// EFI_IFR_TIANO_GUID,表示GUIDed opcodes defined for EDKII implementation,定义在MdeModulePkg\Include\Guid\MdeModuleHii.h0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF, 0x48,  0xCE,  0x01,  // ExtendOpCode,0x01表示EFI_IFR_EXTEND_OP_BANNER0x03,  0x00,  // Title,对应字符串Token,0x0003对应的是STR_FRONT_PAGE_COMPUTER_MODEL0x01,  0x00,  // LineNumber0x00,  // Alignment0x5F,  0x18,  0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF,  0x48,  0xCE,  0x01,  0x04,  0x00,  0x02,  0x00,  0x00,  0x5F,  0x18,  0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF,  0x48,  0xCE,  0x01,  0x05,  0x00,  0x02,  0x00,  0x02,  0x5F,  0x18,  0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF,  0x48,  0xCE,  0x01,  0x07,  0x00,  0x03,  0x00,  0x00,  0x5F,  0x18,  0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF,  0x48,  0xCE,  0x01,  0x06,  0x00,  0x03,  0x00,  0x02,  0x5F,  0x18,  0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF,  0x48,  0xCE,  0x01,  0x0E,  0x00,  0x04,  0x00,  0x00,  0x5F,  0x18,  0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF,  0x48,  0xCE,  0x01,  0x0F,  0x00,  0x04,  0x00,  0x02,  0x5F,  0x18,  0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF,  0x48,  0xCE,  0x01,  0x10,  0x00,  0x05,  0x00,  0x00,  0x5F,  0x18,  0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF,  0x48,  0xCE,  0x01,  0x11,  0x00,  0x05,  0x00,  0x02,  // 第14个操作码,对应结构体EFI_IFR_GUID_LABEL0x5F,  // 操作码示EFI_IFR_GUID_OP0x15,  // 长度21个字节,其中16个是GUID// EFI_IFR_TIANO_GUID,表示GUIDed opcodes defined for EDKII implementation,定义在MdeModulePkg\Include\Guid\MdeModuleHii.h0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF,  0x48,  0xCE,  0x00,  // ExtendOpCode,0x00表示EFI_IFR_EXTEND_OP_LABEL0x00,  0x10,  // Label Number.0x5F,  0x15,  0x35,  0x17,  0x0B,  0x0F,  0xA0,  0x87,  0x93,  0x41,  0xB2,  0x66,  0x53,  0x8C,  0x38,  0xAF,  0x48,  0xCE,  0x00,  0xFF,  0xFF,  0x29,  0x02,  0x29,  0x02
};

这些数据就是IFR二进制,它们通过HiiAddPackages()安装:

  //// Publish our HII data//gFrontPagePrivate.HiiHandle = HiiAddPackages (&mFrontPageGuid,gFrontPagePrivate.DriverHandle,FrontPageVfrBin,UiAppStrings,NULL);

这样就可以通过gFrontPagePrivate.HiiHandle来访问安装的资源了。

跟uni文件一样,vfr文件也有两种使用方式,一种是定义中间文件的变量,另一种是直接定义二进制。以上的代码使用的是中间文件的方式,除去前面的4个字节,剩余的部分对应到一个结构体:

///
/// The header found at the start of each package.
///
typedef struct {UINT32  Length:24;UINT32  Type:8;// UINT8  Data[...];
} EFI_HII_PACKAGE_HEADER;
///
/// The Form package is used to carry form-based encoding data.
///
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;

EFI_HII_PACKAGE_HEADERType有如下的类型,它表示的是所有HII的类型,比如结构、字体、字符串等:

//
// Value of HII 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

对于vfr文件描述的结构来说,其类型当然是EFI_HII_PACKAGE_FORMS,值是2。

头部之后的内容就是一个个的操作码,其结构体如下:

typedef struct _EFI_IFR_OP_HEADER {UINT8                    OpCode;UINT8                    Length:7;UINT8                    Scope:1;
} EFI_IFR_OP_HEADER;

该结构体也是不定长的,之后跟有数据,根据不同的操作码,数据也不一样,如下图所示:

操作码已经在IFR操作码列出;长度包含整个不定长结构体,即也包含头部的长度;Scope如果是1就表示开启了一个新的Scope,直到遇到EFI_IFR_END_OP为止。

语言基础

vfr文件也使用EBNF来描述,这里就不再多介绍,只是简单说明基本语言基础。

  • 通过//来注释;
  • 支持预定义指令:
    • #define:跟c语言中的使用差不多,就是定义宏;
    • #include:可以包含c语言头文件;
    • #pragma:c语言头文件中会使用到,比如对于头文件中的结构体,可以设置其对齐方式。
  • 支持基本数据类型和HII特定的数据类型,也支持结构体:
    • UINT8UINT16UINT32UINT64BOOLEAN等;
    • EFI_STRING_IDEFI_HII_DATAEFI_HII_TIMEEFI_HII_REF等。

VFR组件

本文介绍常用的组件,比如按钮、选择框、标签等等,这些将结合IFR操作码说明,本节说明VFR的最基础组件。

formset

每个vfr文件中都有且只有一个formset,它构成了界面的主体,其它的界面组件都在它内部,其结构如下:

formsetguid      = TCG_CONFIG_FORM_SET_GUID, // GUIDtitle     = STRING_TOKEN(STR_TPM_TITLE), // uni文件中定义的标记help      = STRING_TOKEN(STR_TPM_HELP), // uni文件中定义的标记classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID, // GUID,可选class     = EFI_NETWORK_DEVICE_CLASS, // 数值,可选subclass  = 0x03, // 数值,可选// 剩余组件写在这里endformset;

剩余组件可以是图片、变量、DisableIf、SuppressIf、扩展等,用BNF表示就是:

vfrFormSetList ::=
(vfrFormDefinition| vfrFormMapDefinition| vfrStatementImage| vfrStatementVarStoreLinear| vfrStatementVarStoreEfi| vfrStatementVarStoreNameValue| vfrStatementDefaultStore| vfrStatementDisableIfFormSet| vfrStatementSuppressIfFormSet| vfrStatementExtension
)*

formsetendformset配对使用。

具体的层级关系如下(目前的源代码中能够找到的vfr组件):

注意这里只包含了当前EDK代码中存在的组件,还有很多没有列举。

form

formset内可以有若干个form,下面是一个例子:

  form formid = FORM_MAIN_ID,title = STRING_TOKEN(STR_FORM_MAIN_TITLE);endform;

formid在一个formset中必须是唯一的;title来自uni文件中的标记。

变量

VFR使用的变量有3种,分别是varstoreefivarstorenamevaluevarstore,下面是示例:

  //// Define a Buffer Storage (EFI_IFR_VARSTORE)//varstore DRIVER_SAMPLE_CONFIGURATION,     // 数据结构,在头文件中定义varid = CONFIGURATION_VARSTORE_ID,      // 变量ID,可选,在创建操作码的函数中会用到,比如HiiCreateOneOfOpCode()name  = MyIfrNVData,                    // 变量名,CHAR16     VariableName[] = L"MyIfrNVData";guid  = DRIVER_SAMPLE_FORMSET_GUID;     // 变量GUID,跟变量名共同确定了UEFI变量//// Define a EFI variable Storage (EFI_IFR_VARSTORE_EFI)//efivarstore MY_EFI_VARSTORE_DATA,  // 数据结构,在头文件中定义attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,  // UEFI变量属性name  = MyEfiVar,  // 变量名,CHAR16     MyEfiVar[] = L"MyEfiVar";guid  = DRIVER_SAMPLE_FORMSET_GUID;  // 变量GUID,跟变量名共同确定了UEFI变量//// Define a Name/Value Storage (EFI_IFR_VARSTORE_NAME_VALUE)//namevaluevarstore MyNameValueVar,                // Define storage reference name in vfrname = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME0), // Define Name list of this storage, refer it by MyNameValueVar[0]name = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME1), // Define Name list of this storage, refer it by MyNameValueVar[1]name = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME2), // Define Name list of this storage, refer it by MyNameValueVar[2]guid = DRIVER_SAMPLE_FORMSET_GUID;             // GUID of this Name/Value storage

上述的变量可以设置默认值,且默认值也可以不同,这通过defaultstore来实现:

  defaultstore MyStandardDefault,prompt      = STRING_TOKEN(STR_STANDARD_DEFAULT_PROMPT),attribute   = 0x0000;                         // Default ID: 0000 standard defaultdefaultstore MyManufactureDefault,prompt      = STRING_TOKEN(STR_MANUFACTURE_DEFAULT_PROMPT),attribute   = 0x0001;                         // Default ID: 0001 manufacture default

使用示例,可以在上述3中变量中使用:

    numeric varid   = MyIfrNVData.HowOldAreYouInYears,  // varstoreprompt  = STRING_TOKEN(STR_NUMERIC_STEP_PROMPT),help    = STRING_TOKEN(STR_NUMERIC_HELP2),minimum = 0,maximum = 243,step    = 1,default = 18, defaultstore = MyStandardDefault,     // This is standard default valuedefault = 19, defaultstore = MyManufactureDefault,  // This is manufacture default valueendnumeric;    numeric varid   = MyEfiVar.Field8,                    // Reference of EFI variable storagequestionid  = 0x1111,prompt  = STRING_TOKEN(STR_TALL_HEX_PROMPT),help    = STRING_TOKEN(STR_NUMERIC_HELP1),flags   = DISPLAY_UINT_HEX | INTERACTIVE,     // Display in HEX format (if not specified, default is in decimal format)minimum = 0,maximum = 250,default = 18, defaultstore = MyStandardDefault,     // This is standard default valuedefault = 19, defaultstore = MyManufactureDefault,  // This is manufacture default valueendnumeric;//// Define numeric using Name/Value Storage//numeric varid   = MyNameValueVar[0],     // This numeric take NameValueVar0 as storageprompt  = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME0),help    = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME0_HELP),//// Size should be defined for numeric when use Name/Value storage// Valid value for numerice size are: NUMERIC_SIZE_1, NUMERIC_SIZE_2, NUMERIC_SIZE_4 and NUMERIC_SIZE_8//flags   = NUMERIC_SIZE_1,        // Size of this numeric is 1 byteminimum = 0,maximum = 0xff,step    = 0,locked,default = 16, defaultstore = MyStandardDefault,     // This is standard default valuedefault = 17, defaultstore = MyManufactureDefault,  // This is manufacture default valueendnumeric;

控制

有如下的3种控制显示的语句:

    disableif ideqval MyIfrNVData.SuppressGrayOutSomething == 0x2;orderedlistvarid       = MyIfrNVData.OrderedList,prompt      = STRING_TOKEN(STR_TEST_OPCODE),help        = STRING_TOKEN(STR_TEXT_HELP),flags       = RESET_REQUIRED,option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 3, flags = 0;option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 2, flags = 0;option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value = 1, flags = 0;default     = {1,2,3},endlist;endif;grayoutif NOT ideqval MyIfrNVData.SuppressGrayOutSomething == 0x1;suppressif questionref(MyOneOf) == 0x0;checkbox varid   = MyIfrNVData.ChooseToActivateNuclearWeaponry,prompt   = STRING_TOKEN(STR_CHECK_BOX_PROMPT),help     = STRING_TOKEN(STR_CHECK_BOX_HELP),//// CHECKBOX_DEFAULT indicate this checkbox is marked with EFI_IFR_CHECKBOX_DEFAULT// CHECKBOX_DEFAULT_MFG indicate EFI_IFR_CHECKBOX_DEFAULT_MFG.//flags    = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG,default  = TRUE,endcheckbox;endif;endif;

disableif表示不用,suppressif表示不显示,grayoutif表示显示但是不能操作(不能选中)。

还有控制跳转的语句:

       goto FORM_BOOT_DEL_ID,prompt = STRING_TOKEN(STR_FORM_BOOT_DEL_TITLE),help = STRING_TOKEN(STR_FORM_BOOT_IMMEDIATE_HELP),flags = INTERACTIVE,key = FORM_BOOT_DEL_ID;

FORM_BOOT_DEL_ID对应到一个formformid

  form formid = FORM_BOOT_DEL_ID,title = STRING_TOKEN(STR_FORM_BOOT_DEL_TITLE);label FORM_BOOT_DEL_ID;label LABEL_END;endform;

表达式

VFR中可以包含表达式,比如ORANDNOT等等,作用跟c语言中类似。

IFR操作码

操作码 描述
EFI_IFR_FORM_OP 0x01 Form
EFI_IFR_SUBTITLE_OP 0x02 Subtitle statement
EFI_IFR_TEXT_OP 0x03 Static text/image statement
EFI_IFR_IMAGE_OP 0x04 Static image
EFI_IFR_ONE_OF_OP 0x05 One-of question
EFI_IFR_CHECKBOX_OP 0x06 Boolean question
EFI_IFR_NUMERIC_OP 0x07 Numeric question
EFI_IFR_PASSWORD_OP 0x08 Password string question
EFI_IFR_ONE_OF_OPTION_OP 0x09 Option
EFI_IFR_SUPPRESS_IF_OP 0x0A Suppress if conditional
EFI_IFR_LOCKED_OP 0x0B Marks statement/question as locked
EFI_IFR_ACTION_OP 0x0C Button question
EFI_IFR_RESET_BUTTON_OP 0x0D Reset button statement
EFI_IFR_FORM_SET_OP 0x0E Form set
EFI_IFR_REF_OP 0x0F Cross-reference statement
EFI_IFR_NO_SUBMIT_IF_OP 0x10 Error checking conditional
EFI_IFR_INCONSISTENT_IF_OP 0x11 Error checking conditional
EFI_IFR_EQ_ID_VAL_OP 0x12 Return true if question value equals UINT16
EFI_IFR_EQ_ID_ID_OP 0x13 Return true if question value equals another question value
EFI_IFR_EQ_ID_VAL_LIST_OP 0x14 Return true if question value is found in list of UINT16s
EFI_IFR_AND_OP 0x15 Push true if both sub-expressions returns true
EFI_IFR_OR_OP 0x16 Push true if either sub-expressions returns true
EFI_IFR_NOT_OP 0x17 Push false if sub-expression returns true, otherwise return true
EFI_IFR_RULE_OP 0x18 Create rule in current form
EFI_IFR_GRAY_OUT_IF_OP 0x19 Nested statements, questions or options will not be selectable if expression returns true
EFI_IFR_DATE_OP 0x1A Date question
EFI_IFR_TIME_OP 0x1B Time question
EFI_IFR_STRING_OP 0x1C String question
EFI_IFR_REFRESH_OP 0x1D Interval for refreshing a question
EFI_IFR_DISABLE_IF_OP 0x1E Nested statements, questions or options will not be processed if expression returns true
EFI_IFR_ANIMATION_OP 0x1F Animation associated with question statement, form or form set
EFI_IFR_TO_LOWER_OP 0x20 Convert a string on the expression stack to lower case
EFI_IFR_TO_UPPER_OP 0x21 Convert a string on the expression stack to upper case
EFI_IFR_MAP_OP 0x22 Convert one value to another by selecting a match from a list
EFI_IFR_ORDERED_LIST_OP 0x23 Set question
EFI_IFR_VARSTORE_OP 0x24 Define a buffer-style variable storage
EFI_IFR_VARSTORE_NAME_VALUE_OP 0x25 Define a name/value style variable storage
EFI_IFR_VARSTORE_EFI_OP 0x26 Define a UEFI variable style variable storage
EFI_IFR_VARSTORE_DEVICE_OP 0x27 Specify the device path to use for variable storage
EFI_IFR_VERSION_OP 0x28 Push the revision level of the UEFI Specification to which this Forms Processor is compliant
EFI_IFR_END_OP 0x29 Marks end of scope
EFI_IFR_MATCH_OP 0x2A Push TRUE if string matches a pattern
EFI_IFR_GET_OP 0x2B Return a stored value
EFI_IFR_SET_OP 0x2C Change a stored value
EFI_IFR_READ_OP 0x2D Provides a value for the current question or default
EFI_IFR_WRITE 0x2E Change a value for the current question
EFI_IFR_EQUAL_OP 0x2F Push TRUE if two expressions are equal
EFI_IFR_NOT_EQUAL_OP 0x30 Push TRUE if two expressions are not equal
EFI_IFR_GREATER_THAN_OP 0x31 Push TRUE if one expression is greater than another expression
EFI_IFR_GREATER_EQUAL_OP 0x32 Push TRUE if one expression is greater than or equal to another expression
EFI_IFR_LESS_THAN_OP 0x33 Push TRUE if one expression is less than another expression
EFI_IFR_LESS_EQUAL_OP 0x34 Push TRUE if one expression is less than or equal to another expression
EFI_IFR_BITWISE_AND_OP 0x35 Bitwise-AND two unsigned integers and push the result
EFI_IFR_BITWISE_OR_OP 0x36 Bitwise-OR two unsigned integers and push the result
EFI_IFR_BITWISE_NOT_OP 0x37 Bitwise-NOT an unsigned integer and push the result
EFI_IFR_SHIFT_LEFT_OP 0x38 Shift an unsigned integer left by a number of bits and push the result
EFI_IFR_SHIFT_RIGHT_OP 0x39 Shift an unsigned integer right by a number of bits and push the result
EFI_IFR_ADD_OP 0x3A Add two unsigned integers and push the result
EFI_IFR_SUBTRACT_OP 0x3B Subtract two unsigned integers and push the result
EFI_IFR_MULTIPLY_OP 0x3C Multiply two unsigned integers and push the result
EFI_IFR_DIVIDE_OP 0x3D Divide one unsigned integer by another and push the result
EFI_IFR_MODULO_OP 0x3E Divide one unsigned integer by another and push the remainder
EFI_IFR_RULE_REF_OP 0x3F Evaluate a rule
EFI_IFR_QUESTION_REF1_OP 0x40 Push a question’s value
EFI_IFR_QUESTION_REF2_OP 0x41 Push a question’s value
EFI_IFR_UINT8_OP
EFI_IFR_UINT16_OP
EFI_IFR_UINT32_OP
EFI_IFR_UINT64_OP
0x42
0x43
0x44
0x45
Push an 8-bit/16-bit/32-bit/64-bit unsigned integer
EFI_IFR_TRUE_OP 0x46 Push a boolean TRUE.
EFI_IFR_FALSE_OP 0x47 Push a boolean FALSE
EFI_IFR_TO_UINT_OP 0x48 Convert expression to an unsigned integer
EFI_IFR_TO_STRING_OP 0x49 Convert expression to a string
EFI_IFR_TO_BOOLEAN_OP 0x4A Convert expression to a boolean
EFI_IFR_MID_OP 0x4B Extract portion of string or buffer
EFI_IFR_FIND_OP 0x4C Find a string in a string
EFI_IFR_TOKEN_OP 0x4D Extract a delimited byte or character string from buffer or string
EFI_IFR_STRING_REF1_OP 0x4E Push a string
EFI_IFR_STRING_REF2_OP 0x4F Push a string
EFI_IFR_CONDITIONAL_OP 0x50 Duplicate one of two expressions depending on result of the first expression
EFI_IFR_QUESTION_REF3_OP 0x51 Push a question’s value from a different form
EFI_IFR_ZERO_OP 0x52 Push a zero
EFI_IFR_ONE_OP 0x53 Push a one
EFI_IFR_ONES_OP 0x54 Push a 0xFFFFFFFFFFFFFFFF
EFI_IFR_UNDEFINED_OP 0x55 Push Undefined
EFI_IFR_LENGTH_OP 0x56 Push length of buffer or string
EFI_IFR_DUP_OP 0x57 Duplicate top of expression stack
EFI_IFR_THIS_OP 0x58 Push the current question’s value
EFI_IFR_SPAN_OP 0x59 Return first matching/non-matching character in a string
EFI_IFR_VALUE_OP 0x5A Provide a value for a question
EFI_IFR_DEFAULT_OP 0x5B Provide a default value for a question
EFI_IFR_DEFAULTSTORE_OP 0x5C Define a Default Type Declaration
EFI_IFR_FORM_MAP_OP 0x5D Create a standards-map form
EFI_IFR_CATENATE_OP 0x5E Push concatenated buffers or strings
EFI_IFR_GUID_OP 0x5F An extensible GUIDed op-code
EFI_IFR_SECURITY_OP 0x60 Returns whether current user profile contains specified setup access privileges
EFI_IFR_MODAL_TAG_OP 0x61 Specify current form is modal
EFI_IFR_REFRESH_ID_OP 0x62 Establish an event group for refreshing a forms-based element
EFI_IFR_WARNING_IF 0x63 Warning conditional
EFI_IFR_MATCH2_OP 0x64 Push TRUE if string matches a Regular Expression pattern

安装层级结构描述上述的操作码,结构如下:

安装表达式来描述上述的操作符,有如下的结构:

每种类型都有对应的结构体。对应的类型宏和结构体定义在MdePkg\Include\Uefi\UefiInternalFormRepresentation.h中。另外还需要特别关注下面这种:

#define EFI_IFR_GUID_OP                0x5F

其结构体定义如下:

typedef struct _EFI_IFR_GUID {EFI_IFR_OP_HEADER        Header;EFI_GUID                 Guid;//Optional Data Follows
} EFI_IFR_GUID;

可以看到它实际上也不是完整的版本,真正完整版本定义在MdeModulePkg\Include\Guid\MdeModuleHii.h,它有不同的种类:

///
/// GUIDed opcodes defined for EDKII implementation.
///
#define EFI_IFR_TIANO_GUID \{ 0xf0b1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce} }///
/// EDKII implementation extension opcodes, new extension can be added here later.
///
#define EFI_IFR_EXTEND_OP_LABEL       0x0
#define EFI_IFR_EXTEND_OP_BANNER      0x1
#define EFI_IFR_EXTEND_OP_TIMEOUT     0x2
#define EFI_IFR_EXTEND_OP_CLASS       0x3
#define EFI_IFR_EXTEND_OP_SUBCLASS    0x4

定义的Guid目前只有EFI_IFR_TIANO_GUID,后面的数据根据不同的类型值不同,对应的结构体也不同。

【UEFI实战】HII之vfr文件相关推荐

  1. UEFI实战--------HII之uni文件

    uni文件 HII的实现涉及到多种不同类型的文件,uni文件是其中最简单的一种,它用来存放各种语言的字符串以实现本地化.本节主要参考自<edk-ii-uni-specification.pdf& ...

  2. 【UEFI实战】HII之常用函数

    资源安装 HiiAddPackages 函数原型: /**Registers a list of packages in the HII Database and returns the HII Ha ...

  3. 【UEFI实战】HII之FrontPage

    写在前面 UEFI有自己的用户交互界面,它的实现基础被称为HII(Human Interface Infrastructure),本文是一系列介绍HII实现的第一篇.这里从开源EDK代码中的界面(称为 ...

  4. 浅谈UEFI中VFR文件开发

    废话不谈,通过三个实际的开发项目,分享一下VFR开发过程中的心得和应该注意的问题: 1.Set Data And Time 龙芯4000上的实现的原理: 之前4000上是在BdsDxe中实现的,熟悉L ...

  5. 【UEFI实战】EDK的编译流程说明

    前言 使用EDK进行UEFI开发,开始的时候很容易遇到的问题就是编译不过,并非代码的问题,而是编译环境存在异常. 本文主要介绍EDK是如何进行编译的,使用的平台是Windows.这里还想说一点,事实上 ...

  6. 【UEFI实战】LinuxBoot

    综述 LinuxBoot是一个开源的固件,用来替代UEFI BIOS加载Linux的系统. 官网是LinuxBoot. 对应的代码库位于LinuxBoot · GitHub. 另外,本文是在[UEFI ...

  7. 【UEFI实战】UART的初始化

    说明 UART全称是Universal Asynchronous Receiver/Transmitter,这里它表示的是一种实现串口通信的芯片,在整个串口系统中它的位置如下图所示: RS232 +- ...

  8. 【UEFI实战】FSP简介

    说明 在[UEFI实战]SlimBootloader简介中有说到,编译Slim Bootloader的时候需要使用到FSP,本文就是用来介绍FSP是什么,它的作用,以及如何编译等内容. 什么是FSP ...

  9. 云计算Python自动化运维开发实战 三、python文件类型

    为什么80%的码农都做不了架构师?>>>    云计算Python自动化运维开发实战 三.python文件类型 导语: python常用的有3种文件类型 1. 源代码     py ...

最新文章

  1. 荣耀手机现在是鸿蒙,荣耀适配鸿蒙最新消息出现,华为不会让大家失望的
  2. 单链表-删除并释放以L为表头指针的单链表的所有结点(双指针法)
  3. “cvSnakeImage”: 找不到标识符
  4. 【linux学习笔记三】链接命令
  5. 自己定义WinXP的时间校正服务器
  6. GAN对抗生成网络原始论文理解笔记
  7. Linux中断(interrupt)子系统之五:软件中断(softIRQ)
  8. POJ 1183 反正切函数的应用(数学代换,基本不等式)
  9. git clone 分支_Git 小团队的协作 (二)
  10. nofollow标签_网站Nofollow标签的应用场景
  11. Auto.js 如何WIFI连接VS Code插件
  12. 【thinkphp3.x】ThinkPHP/Lib/Core/Model.class.php文件分析
  13. vue状态管理存取数据_Vue中的数据通信和状态管理
  14. now.js 0.1.0 发布了
  15. Python网络爬虫第一弹《Python网络爬虫相关基础概念》
  16. DataGridView分页
  17. 教你怎样打领带(附图)绝对实用哦!!!【实用】
  18. 关于一些初级ACM竞赛题目的分析和题解(三)。
  19. linux网络服务配置说课,说课稿 LINUX.ppt
  20. 车道线检测预处理(1)------ 融合白线黄线+高斯

热门文章

  1. 【计算机毕业设计】视频教学管理系统
  2. 【C语言】之实现十进制转换为二进制
  3. 独立正交不相关定义关系
  4. Bloom Filter 布隆过滤器
  5. Unity实现多屏显示
  6. NS2仿真中nam节点颜色设置
  7. Big-man的Bootstrap篇(一)
  8. 【JZOJ4117】lhxsb(三角函数+凸壳+CDQ分治)
  9. 假如生活欺骗了你 - 生活总是美好的,摘诗一首以自勉。
  10. 新一线城市“抢人”大战:多地加快推进户籍改革