UEFI开发探索60-VFR文件和其他资源文件1(在BIOS setup上增加项)

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】

如何使用VFR文件,是我这一段时间比较感兴趣的课题。包括VFR文件在内,UNI文件、IDF文件,都属于资源文件。UNI文件的使用,在之前Hii的例子中,已经讨论过了。而如何使用VFR文件,一直没有涉及到。

接下来的几篇博客,将以修改BIOS Setup(当然,还是以OvmfPkg编译的镜像来做BIOS文件)为例,演示如何使用VFR文件和相关的资源文件。

图1 OVMF镜像的BIOS界面

本篇的例子以Intel提供的示例驱动MyWizardDriver为基础,添加了字符串和窗体,修改步骤如下。

1 修改MyWizardDriverNVDataStruc.h

增加GUID的声明(MYWIZARDDRIVER_FORMSET_GUID):

#define MYWIZARDDRIVER_FORMSET_GUID { 0x5411db09, 0xe5f7, 0x4158, {0xa5, 0xc5, 0x2d, 0xbe, 0xa4,0x95, 0x34, 0xff} }

在示例的修改中,都以“robin add”的方式标记了修改部分,如果是多行修改,则添加了“begin”和“end”的注释。

2 修改MyWizardDriver.vfr

将VFR文件中其他的内容全部删除,并添加自定义的窗体定义,内容如下:

#include “MyWizardDriverNVDataStruc.h”
formset
  guid = MYWIZARDDRIVER_FORMSET_GUID,
  ……
endform;
endformset;

VFR文件中的定义,在程序演示之后,再描述其语法及如何与显示的对应关系。

3 修改MyWizardDriver.uni

添加自定义的字符串,在之前的博客中描述过UNI文件和字符串定义,这里就不详细解释了。

#string STR_SAMPLE_FORM_SET_TITLE #language en “My Wizard DriverSample Formset”
#string STR_SAMPLE_FORM_SET_HELP #language en “Help for SampleFormset”
……

4 修改MyWizardDriver.h

添加头文件:

#include <Protocol/HiiConfigRouting.h>
#include <Protocol/FormBrowser2.h>
#include <Protocol/HiiString.h>
#include <Library/DevicePathLib.h>

并增加自定义的数据结构,代码添加后如下图:

图2 MyWizardDriver.h 代码添加

5 修改MyWizardDriver.c

添加全局变量定义:

图3 源文件全局变量添加

修改函数MyWizardDriverDriverEntryPoint()。修改的内容较多,注意查看源代码。最主要的代码,是通过SetVariable()把窗体添加到了BIOS Setup中。

代码准备完毕,需要将其编译,同时必须编译OVMF镜像。代码仍旧放在RobinPkg中,编译命令如下:

build -p RobinPkg\RobinPkg.dsc -m RobinPkg\Drivers\MyWizardDriver\MyWizardDriver.inf -a X64

以及编译OVMF镜像:

build -p OvmfPkg\OvmfPkgX64.dsc -a X64

奇怪的是,我编译出来的几个OVMF镜像都有点问题,测试的时候不正常,用以前编译的某个OVMF镜像可以正常测试。现在搞不清楚到底是什么原因导致的,在文末所提供的链接中,我把测试环境全部给出了,包括OVMF镜像和批处理。

把编译好的MyWizardDriver.efi拷贝到指定的文件夹hd-contents中,启动Qemu模拟环境:

qemu-system-x86_64.exe   -bios OVMF.fd -hda fat:rw:hda-contents -net none

进入UEFI Shell,执行如下命令:

Shell> FS0:
FS0:\> load MyWizardDriver.efi
FS0:\> exit

进入到BIOS Setup中,依次选择Device Manager-My Wizard DriverSample Formset,可以看到如图4所示的界面,表示添加窗体成功:

图4 窗体添加示意图

可以使用空格或者回车键,修改选项。修改选项的时候,右下角会出现“Configuration changed”的黄色字符串。

More: VFR文件语法

窗体(Forms)是用户交互的组织形式,最终是以IFR(Internal Forms Representation)的二进制形式进入到EDK2的框架中的。IFR是由VFR文件生成的,类似于obj文件相对于源文件的关系。从平台框架的角度,窗体处于交互的中心位置:

图5 平台架构的人机交互结构图

站在程序员的角度,所有资源文件,最终都是用户UI的一部分,其结构图如下:

图6 资源文件

VFR文件采用的是BNF语法,与DSC文件采用“#”作为注释标志不同,它使用“//”作为注释标志。另外还有两个关键字是“#define”和“#include”,用来定义和包含头文件的,类似于C的语法。

formset是VFR文件中最重要的部分,用来组成窗体的最常用的结构。其示例如下:

formset
guid     = {0xcc5ebb4f, 0xf562, 0x11e7, {0x92, 0x11, 0xf4, 0x8c, 0x50, 0x49, 0xe3, 0xa4}},
title    = STRING_TOKEN(STR_SAMPLE_FORM_SET_TITLE),
help     = STRING_TOKEN(STR_SAMPLE_FORM_SET_HELP),
  classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID
form formid = 1, title = STRING_TOKEN(STR_SAMPLE_FORM1_TITLE);
  …
endform;
endformset;

formset是关键字,用来标志整个窗体的开始,与标志窗体结束的endformset成对出现。其中各关键字的含义为:

guid: 标志本formset的GUID值;
title:在界面中标志本formset的字符串标题;
help:在界面上显示本formset的帮助信息;
classguid: 本formaset所挂载页面的GUID值。

本formset的选择项,在最初始页面的Device Manager下,如图7所示。

图7 VFR文件中定义的formset

在formaset的集合中,可以用“form”和“endform”定义一个完整的页面,比如这篇博客中给出的示例(RobinPkg\Drivers\MyWizardDriver\MyWizardDriver.vfr):

form formid = 1, title = STRING_TOKEN(STR_SAMPLE_FORM1_TITLE); // “My Wizard Driver”
  subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT); //”My Wizard DriverConfiguration”
  subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT2); //”Device XYZ Configuration”
  checkbox varid =MWD_IfrNVData.MyWizardDriverChooseToEnable,
      prompt =STRING_TOKEN(STR_CHECK_BOX_PROMPT),  //”Enable My XYZ Device”
      help = STRING_TOKEN(STR_CHECK_BOX_HELP), //”This is the help message …
      flags = CHECKBOX_DEFAULT ,
      key = 0,
      default = 1,
    endcheckbox;
  endform;

在界面上是这样的:

图8 VFR文件中定义的form

VFR文件的内容比较多,特别是其使用方法,需要仔细研究UEFI spec中Hii部分,才能大致掌握。我在日常的开发中,基本不会用到VFR文件,这些相对比较新的知识,很能让我沉迷其中。

后续还会不定期研究VFR文件、UNI文件和IDF文件的用法,特别是我最关心的本地化显示部分。

另外,由于原来提供代码的百度云,所取的名字比较不雅观(女儿当时乱按的,我没注意……),我会逐渐将代码转移到gitee上去。

本篇的代码:
Gitee地址:
https://gitee.com/luobing4365/uefi-exolorer
项目代码位于:/RobinPkg/Drivers/ MyWizardDriver
其他工具和测试环境:/60 VFR file and other Res

76 total views, 6 views today

发表评论

电子邮件地址不会被公开。