UEFI开发实战用户交互界面使用说明VFR文件
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>1. 综述</li><li>2. 作用</li><li>3. 语法</li><ul class="second_class_ul"><li>3.1 注释</li><li>3.2 预定义</li><li>3.3 数据结构</li><li>3.4 Forms相关表达式总览</li><ul class="third_class_ul"><li>3.4.1 formset</li><li>3.4.2 formset list</li></ul><li>3.5 Form Set List</li><ul class="third_class_ul"><li>3.5.1 变量定义</li><li>3.5.2 控制语句</li><li>3.5.3 Question语句</li><li>3.5.4 form语句</li></ul><li>3.6 Forms表达式</li><ul class="third_class_ul"><li>3.6.1 vfrStatementImage</li><li>3.6.2 vfrStatementLocked</li><li>3.6.3 vfrStatementRules</li><li>3.6.4 vfrStatementDefault</li><li>3.6.5 vfrStatementStat</li><li>3.6.6 vfrStatementQuestions</li><li>3.6.7 vfrStatementConditional</li><li>3.6.8 vfrStatementLabel</li><li>3.6.9 vfrStatementBanner</li><li>3.6.10 vfrStatementExtension</li><li>3.6.11 vfrStatementModal</li></ul><li>3.7 VFR表达式</li><ul class="third_class_ul"><li>3.7.1 常量</li><li>3.7.2 操作符</li><li>3.7.3 内置函数</li></ul></ul></ul></div><p class="maodian"></p><h2>1. 综述</h2><p>UEFI用户交互界面的实现涉及到多种不同类型的文件,这里要讲的是VFR文件,相比UNI文件它要复杂得多,理解起来也更困难。</p>
<p>本文主要参考自《edk-ii-vfr-specification.pdf》(以下简称参考文档)和《UEFI Spec》。</p>
<p>它们可以在EDK II Specifications · tianocore/tianocore.github.io Wiki · GitHub下载到。</p>
<p>文本的代码示例来自EDK2017,由于版本更新等原因,示例中的代码可能跟实际GIT库中的代码有一定的差异。</p>
<p class="maodian"></p><h2>2. 作用</h2>
<p>在说明VFR文件得作用之前,首先需要祭出一张在之前用过多次的图:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080329.png" /></p>
<p>在UEFI用户交互界面使用说明之UNI文件中已经介绍过,那些字符串是来自UNI文件的(其实并不是全部来自UNI,也有部分是直接通过代码生成的),而整个窗体的框架部分则是来自VFR文件的。</p>
<p>在UEFI中,构成这样的窗体的组件大致有四种,分别是Strings,Forms,Fonts和Images,如下图所示:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080330.png" /></p>
<p>Strings就是前面讲到的UNI文件提供的,Forms就是本文的VFR文件提供的,后面两者暂时还未介绍,本文主要介绍的就是这个Forms,以及构成Forms的VFR文件。</p>
<p>关于Forms的定义,在《UEFI Spec》中有如下的说明:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080331.png" /></p>
<p>Forms描述了窗体的组织形式,提供了用户交互的方式和交互内容的存储方式等。</p>
<p>Forms是以二进制的形式提供的,这种二进制在EDK框架中被称为IFR(就是上述定义中提到的Internal Forms Representation)。</p>
<p>而IFR通过编译VFR来生成(关于编译工具,在EDK源代码中也有相应的源码,不过没有研究过不确定怎么用)。</p>
<p>因此,总的来说就是,我们通过编写VFR文件来完成对UEFI交互界面的组织形式和交互方式等相关内容的定义。</p>
<p class="maodian"></p><h2>3. 语法</h2>
<p>参考文档中给出了VFR的详细语法说明,这里简单介绍下。</p>
<p class="maodian"></p><h3>3.1 注释</h3>
<p>VFR文件中可以使用“//”来注释,同C语言和UNI文件。</p>
<p class="maodian"></p><h3>3.2 预定义</h3>
<p>VFR文件中可以使用几种预定义的指令,如#define、#include、#pragma等。</p>
<p>功能同C语言。</p>
<p>下面是一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080332.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080333.png" /></p>
<p>#pragma一般会在使用#include包含的C语言头文件中。</p>
<p class="maodian"></p><h3>3.3 数据结构</h3>
<p>前文中已经看到,VFR文件支持#include来包含C语言的头文件,因此C语言头文件中可以包含的数据结构VFR文件也都是支持的。</p>
<p>包括UINT8, UINT16, UINT32, UINT64, BOOLEAN等基本数据类型,和HII特定的数据类型,如EFI_STRING_ID, EFI_HII_DATA, EFI_HII_TIME, EFI_HII_REF,还有就是通过typedef自定义的结构体。</p>
<p>一维的数组也是支持的,但是不支持枚举和多维的数组。</p>
<p class="maodian"></p><h3>3.4 Forms相关表达式总览</h3>
<p>以上的内容都是基础内容,且都是属于C语言的范围。</p>
<p>下面的内容是VFR特有的表达式。</p>
<p class="maodian"></p><h4>3.4.1 formset</h4>
<p>formset的具体定义没有找到。</p>
<p>但是它属于组成窗口的主体,也是VFR文件中最重要的部分。</p>
<p>它的定义如下(也是使用BNF表达方式定义的):</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080434.png" /></p>
<p>下面是一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080435.png" /></p>
<p>guid就是通过#define定义的一个普通的GUID;</p>
<p>title中STRING_TOKE()括号中的就是在UNI文件中定义的字符串;</p>
<p>help同title;</p>
<p>classguid,class和subclass是可选的,作用不明。下面是class和subclass的一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080436.png" /></p>
<p>classguid的定义如下:</p>
<p style="text-align:center"><img alt="" height="54" src="https://img.jbzj.com/file_images/article/202206/2022060611080437.png" width="680" /></p>
<p>guidDefinition就是普通的GUID。</p>
<p>class的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080438.png" /></p>
<p>subclass的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080439.png" /></p>
<p class="maodian"></p><h4>3.4.2 formset list</h4>
<p>formset内部定义了很多的子选项,称为formset list,也就是上一节formset定义中的vfrFormSetList。</p>
<p>前面的例子中用到的form就是其中的一种。</p>
<p>formset list可以有如下的内容:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080440.png" /></p>
<p>上述的内容可以分为几种不同的类型:</p>
<ul><li>1. 变量定义,如defaultstore,varstore,efivarstore,namevaluevarstore等;</li><li>2. 控制语句,它会做if判断来确定其包含的formset list是否会被使用,主要有disableif,suppressif,grayoutif和goto语句等(上述的语句只在目前只在form类型语句中见到过,在其外没遇见过,不确定是否可以在它之外);</li><li>3. form语句,它们是formset里面的主体部分,有form,formmap等;</li><li>4. 其它语句;</li></ul>
<p class="maodian"></p><h3>3.5 Form Set List</h3>
<p>3.4.2节中已经介绍了Form Set List的大致分类,本节将进一步介绍各种类型的Form Set List。</p>
<p class="maodian"></p><h4>3.5.1 变量定义</h4>
<p>下面是各种变量的定义。</p>
<p>defaultstore:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080441.png" /></p>
<p>下面是一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080442.png" /></p>
<p>attribute的值如下:</p>
<div class="jb51code"><pre class="brush:cpp;">//
// Default Identifier of default store
//
#define EFI_HII_DEFAULT_CLASS_STANDARD 0x0000
#define EFI_HII_DEFAULT_CLASS_MANUFACTURING0x0001
#define EFI_HII_DEFAULT_CLASS_SAFE 0x0002
#define EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN 0x4000
#define EFI_HII_DEFAULT_CLASS_PLATFORM_END 0x7fff
#define EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN 0x8000
#define EFI_HII_DEFAULT_CLASS_HARDWARE_END 0xbfff
#define EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN 0xc000
#define EFI_HII_DEFAULT_CLASS_FIRMWARE_END 0xffff</pre></div>
<p>varstore:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080443.png" /></p>
<p>第一个StringIdentifier表示的是类型,第二个表示的是变量名,name和guid连起来就可以表示该特定的变量。</p>
<p>下面是一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080444.png" /></p>
<p>它定义的是一个数据结构体变量,类型就是DRIVER_SAMPLE_CONFIGURATION。</p>
<p>MyIfrNVData是变量的名称,后面的VFR表达式中会通过该名称去引用该变量。</p>
<p>efivarstore:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080545.png" /></p>
<p>下面是一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080546.png" /></p>
<p>这里定义的就是UEFI变量,还可以声明变量的属性。</p>
<p>namevaluevarstore:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080547.png" /></p>
<p>下面是一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080548.png" /></p>
<p class="maodian"></p><h4>3.5.2 控制语句</h4>
<p>VFR文件中可以包含如下的控制语句:</p>
<p>DisableIf语句,定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080549.png" /></p>
<p>SuppressIf语句,定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080550.png" /></p>
<p>GrayOutIf语句,定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080551.png" /></p>
<p>下面是一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080552.png" /></p>
<p>需要注意几点:</p>
<p>1. if条件之后有一个分号;</p>
<p>2. 最后有一个endif与之对应;</p>
<p>另外还有一个goto语句,其定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080553.png" /></p>
<p>下面是goto语句的一个例子:</p>
<div class="jb51code"><pre class="brush:cpp;">form formid = FORM_BOOT_SETUP_ID,
title = STRING_TOKEN(STR_FORM_BOOT_SETUP_TITLE);
goto FORM_MAIN_ID,
prompt = STRING_TOKEN(STR_FORM_GOTO_MAIN),
help = STRING_TOKEN(STR_FORM_GOTO_MAIN);
//flags = INTERACTIVE,
//key = FORM_MAIN_ID;
goto FORM_BOOT_SETUP_ID,
prompt = STRING_TOKEN(STR_FORM_BOOT_ADD_TITLE),
help = STRING_TOKEN(STR_FORM_BOOT_ADD_HELP),
flags = INTERACTIVE,
key = FORM_BOOT_ADD_ID;
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;
goto FORM_BOOT_CHG_ID,
prompt = STRING_TOKEN(STR_FORM_BOOT_CHG_TITLE),
help = STRING_TOKEN(STR_FORM_BOOT_IMMEDIATE_HELP),
flags = INTERACTIVE,
key = FORM_BOOT_CHG_ID;
endform;</pre></div>
<p>对应的界面如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080654.png" /></p>
<p>红框部分就是4个goto语句。</p>
<p class="maodian"></p><h4>3.5.3 Question语句</h4>
<p>在goto语句中,有一个vfrStatementQuestionOptionList需要介绍下。</p>
<p>它的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080655.png" /></p>
<p>其中的vfrStatementQuestionTag和vfrStatementQuestionOptionTag又是比较大的两块内容:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080656.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080657.png" /></p>
<p>顺便还提一个:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080658.png" /></p>
<p>上述的各个子元素的定义如下:</p>
<p>vfrStatementSuppressIfQuest:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080659.png" /></p>
<p>vfrStatementValue:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080660.png" /></p>
<p>vfrStatementDefault:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080661.png" /></p>
<p>vfrStatementOptions:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080762.png" /></p>
<p>vfrStatementRead:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080763.png" /></p>
<p>vfrStatementWrite:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080764.png" /></p>
<p>vfrStatementInconsistentIf:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080765.png" /></p>
<p>vfrStatementNoSubmitIf:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080766.png" /></p>
<p>vfrStatementDisableIfQuest:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080767.png" /></p>
<p>vfrStatementRefresh:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080768.png" /></p>
<p>vfrStatementVarstoreDevice:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080769.png" /></p>
<p>vfrStatementExtension:</p>
<p>无。</p>
<p>vfrStatementRefreshEvent:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080770.png" /></p>
<p>vfrStatementWarningIf:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080771.png" /></p>
<p class="maodian"></p><h4>3.5.4 form语句</h4>
<p>VFR文件中包含下述的form语句:</p>
<p>form语句定义:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080772.png" /></p>
<p>下面是一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080873.png" /></p>
<p>formmap语句定义:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080874.png" /></p>
<p>下面是一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080875.png" /></p>
<p>后续会较详细的介绍forms语句内部的定义。</p>
<p class="maodian"></p><h3>3.6 Forms表达式</h3>
<p>前面提到的formset,form,formmap等,其实都是抽象的概念,并不会实际得显示出来,而本节讲的是具体的概念,且大部分是能够看到和操作的内容。</p>
<p class="maodian"></p><h4>3.6.1 vfrStatementImage</h4>
<p>Image的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080876.png" /></p>
<p>目前不确定如何使用。</p>
<p class="maodian"></p><h4>3.6.2 vfrStatementLocked</h4>
<p>Locked的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080877.png" /></p>
<p>目前也不确定如何使用。</p>
<p class="maodian"></p><h4>3.6.3 vfrStatementRules</h4>
<p>Rules的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080878.png" /></p>
<p>这个Rules会在用户输入的时候做检测(引用StringIdentifier来完成)。</p>
<p class="maodian"></p><h4>3.6.4 vfrStatementDefault</h4>
<p>无。</p>
<p class="maodian"></p><h4>3.6.5 vfrStatementStat</h4>
<p>Stat有多种的形式,如下所示:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080879.png" /></p>
<p>vfrStatementSubTitle</p>
<p>SubTitle的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080880.png" /></p>
<p>下面是一个例子:</p>
<div class="jb51code"><pre class="brush:cpp;">form formid = DEVICE_MANAGER_FORM_ID,
title= STRING_TOKEN(STR_EDKII_MENU_TITLE);
subtitle text = STRING_TOKEN(STR_DEVICES_LIST);
label LABEL_DEVICES_LIST;
label LABEL_END;</pre></div>
<p>对应的界面如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080881.png" /></p>
<p>红框部分就是一个SubTitle。</p>
<p>vfrStatementStaticText</p>
<p>Text的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080982.png" /></p>
<p>这里的text是独立的部分,而不是SubTitle的子元素。</p>
<p>下面是一个例子:</p>
<div class="jb51code"><pre class="brush:cpp;"> text
help = STRING_TOKEN(STR_CONTINUE_HELP),
text = STRING_TOKEN(STR_CONTINUE_PROMPT),
flags = INTERACTIVE,
key = FRONT_PAGE_KEY_CONTINUE;</pre></div>
<p>对应的界面如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080983.png" /></p>
<p>vfrStatementCrossReference</p>
<p>Cross Reference的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080984.png" /></p>
<p>作用不明。</p>
<p class="maodian"></p><h4>3.6.6 vfrStatementQuestions</h4>
<p>Question有多种类型,如下所示:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080985.png" /></p>
<p>下面说明每一种类型。</p>
<p>vfrStatementBooleanType</p>
<p>BooleanType有两种类型:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080986.png" /></p>
<p>CheckBox的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080987.png" /></p>
<p>Action的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080988.png" /></p>
<p>vfrStatementNumericType</p>
<p>Numeric有两种类型:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080989.png" /></p>
<p>Numeric的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611080990.png" /></p>
<p>OneOf的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611081091.png" /></p>
<p>vfrStatementStringType</p>
<p>String包含两个小类型:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611081092.png" /></p>
<p>其中String的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611081093.png" /></p>
<p>Password的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611081094.png" /></p>
<p>vfrStatementOrderedList</p>
<p>OrderedList的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611081095.png" /></p>
<p>vfrStatementDate</p>
<p>Date的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611081096.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611081097.png" /></p>
<p>vfrStatementTime</p>
<p>Time的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611081098.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/2022060611081199.png" /></p>
<p class="maodian"></p><h4>3.6.7 vfrStatementConditional</h4>
<p>Conditional语句其实在之前已经介绍过:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/20220606110811100.png" /></p>
<p>这里不再介绍。</p>
<p class="maodian"></p><h4>3.6.8 vfrStatementLabel</h4>
<p>Label是一个占位符,真正显示的内容是代码动态产生的。</p>
<p>下面是定义:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/20220606110811101.png" /></p>
<p>下面是一个例子:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/20220606110811102.png" /></p>
<p>label之后接的是一个数值。</p>
<p>label对应到代码中的结构体如下:</p>
<div class="jb51code"><pre class="brush:cpp;">///
/// Label opcode.
///
typedef struct _EFI_IFR_GUID_LABEL {
EFI_IFR_OP_HEADER Header;
///
/// EFI_IFR_TIANO_GUID.
///
EFI_GUID Guid;
///
/// EFI_IFR_EXTEND_OP_LABEL.
///
UINT8 ExtendOpCode;
///
/// Label Number.
///
UINT16 Number;
} EFI_IFR_GUID_LABEL;</pre></div>
<p class="maodian"></p><h4>3.6.9 vfrStatementBanner</h4>
<p>Banner的形式如下图红框部分所示:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/20220606110811103.png" /></p>
<p>它是一个可显示的字符串,比普通的字符串要显眼一点。</p>
<p>它的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/20220606110811104.png" /></p>
<p><code>title</code>是具体显示的内容;</p>
<p><code>line</code>表示具体在哪一行显示;</p>
<p><code>align</code>表示字符显示在行的哪个位置,又左中右三种情况;</p>
<p><code>timeout</code>不能跟line和align合用,作用不明。</p>
<p><code>banner</code>对应到代码中的结构体如下:</p>
<div class="jb51code"><pre class="brush:cpp;">///
/// Banner opcode.
///
typedef struct _EFI_IFR_GUID_BANNER {
EFI_IFR_OP_HEADER Header;
///
/// EFI_IFR_TIANO_GUID.
///
EFI_GUID Guid;
///
/// EFI_IFR_EXTEND_OP_BANNER
///
UINT8 ExtendOpCode;
EFI_STRING_ID Title; ///< The string token for the banner title.
UINT16 LineNumber; ///< 1-based line number.
UINT8 Alignment; ///< left, center, or right-aligned.
} EFI_IFR_GUID_BANNER;</pre></div>
<p class="maodian"></p><h4>3.6.10 vfrStatementExtension</h4>
<p>Extension的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/20220606110811105.png" /></p>
<p class="maodian"></p><h4>3.6.11 vfrStatementModal</h4>
<p>Model的定义如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/20220606110811106.png" /></p>
<p>它只能用在form内部。</p>
<p>具体意义不明。</p>
<p class="maodian"></p><h3>3.7 VFR表达式</h3>
<p>VFR表达式跟C语言差别不大。</p>
<p>下面简单说明。</p>
<p class="maodian"></p><h4>3.7.1 常量</h4>
<p>常量:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202206/20220606110811107.png" /></p>
<p class="maodian"></p><h4>3.7.2 操作符</h4>
<ul><li>OR:或操作,对应到EFI_IFR_OR;</li><li>AND:与操作,对应EFI_IFR_AND;</li><li>|:位或操作,对应EFI_IFR_BITWISE_OR;</li><li>&:位与操作,对应EFI_IFR_BITWISE_AND;</li><li>~:位反,对应EFI_IFR_BITWISENOT;</li><li>==:等于操作,对应EFI_IFR_EQUAL;</li><li>!=:不等于操作,对应EFI_IFR_NOT_EQUAL;</li><li><,<=,>,>=:比较操作,对应EFI_IFR_LESS_THAN,EFI_IFR_LESS_EQUAL,EFI_IFR_IFR_GREATER_EQUAL和EFI_IFR_GREATER_THAN;</li><li><<,>>:位移操作,对应EFI_IFR_SHIFT_LEFT和EFI_IFR_SHIFT_RIGHT;</li><li>+,-:加减操作,对应EFI_IFR_ADD和EFI_IFR_SUBTRACT;</li><li>*,/,%:乘余除操作,对应EFI_IFR_MULTIPLY,EFI_IFR_MODULO和EFI_IFR_DIVIDE;</li><li>():括号;</li><li>(UINTX/BOOLEAN):强制转换操作;</li></ul>
<p class="maodian"></p><h4>3.7.3 内置函数</h4>
<ul><li>dup:复制操作,对应EFI_IFR_DUP;</li><li>ideqval x==y:判断x和y的值是否相等,对应EFI_IFR_EQ_ID_VAL;</li><li>ideqid x==y:判断x和y的ID是否相等,对应EFI_IFR_EQ_ID_ID;</li><li>ideqvallist x==y+:判断x和y+(表示多个值)是否相同,对应EFI_IFR_EQ_ID_LIST;</li><li>questionref(x):Question引用,对应EFI_IFR_QUESTION_REF1;</li><li>questionrefval(s):作用不明,对应EFI_IFR_QUESTION_REF2或EFI_IFR_QUESTION_REF2;</li><li>ruleref(x):Rule引用,对应EFI_IFR_RULE_REF;</li><li>stringref(x):字符串引用,对应EFI_IFR_STRING_REF1;</li><li>stringrefval(s):作用不明,对应EFI_IFR_STRING_REF2;</li><li>pushthis:作用不明,对应EFI_IFR_THIS;</li><li>security(x):作用不明,对应EFI_IFR_SECURITY;</li><li>get(x):获取变量,对应EFI_IFR_GET;</li><li>set(x,y):设置变量,对应EFI_IFR_SET;</li><li>boolval(s):转BOOLEAN,对应EFI_IFR_TO_BOOLEAN;</li><li>unintval(s):转UINT整型,对应EFI_IFR_TO_UINT;</li><li>tolower(s):字符串变小写,对应EFI_IFR_TO_LOWER;</li><li>toupper(s):字符串变大写,对应EFI_IFR_TO_UPPER;</li><li>catenate(x,y):字符串连接,对应EFI_IFR_CATENATE;</li><li>cond(x?y:z):就是If (Expr1) then x = Expr3 else Expr2,对应EFI_IFR_CONDITIONAL;</li><li>find(format,s1,s2,x):字符串寻找,对应EFI_IFR_FIND;</li><li>mid(a,b,c):作用不明,对应EFI_IFR_MID;</li><li>token(a,b,c):作用不明,对应EFI_IFR_TOKEN;</li><li>span(flag=x,a,b,c):作用不明,对应EFI_IFR_SPAN;</li><li>map(a:(b)*):作用不明,对应EFI_IFR_MAP;</li><li>match(a,b):字符串比较,对应EFI_IFR_MATCH;</li><li>match2(pattern,string,guid):字符串比较,对应EFI_IFR_MATCH2;</li><li>length(x):字符串长度计算;</li></ul>
<p>以上就是VFR文件说明的全部内容。</p>
<p>由于《参考文档》也有不少内容没有解释清楚,加上个人能力有限,所以目前对VFR也只是一个大致的了解,更多关于UEFI用户交互界面VFR文件的资料请关注琼殿技术社区其它相关文章!</p>
<div class="art_xg">
<b>您可能感兴趣的文章:</b><ul><li>UEFI开发实战用户交互界面基础说明</li><li>UEFI开发实战用户交互界面使用说明UNI文件</li><li>UEFI开发基础HII代码示例</li><li>UEFI开发基础汇编代码的使用</li><li>UEFI开发实战SlimBootloader中调用FSP</li></ul>
</div>
</div>
<!--endmain-->
頁:
[1]