Bootstrap

【EDKII笔记】VFR&SD

前言

uni文件声明了字符,vfr文件即是对setup的框架的搭建。
EDKII创建了BNF风格的VFR文件供开发者使用,编译器会把VFR文件编译成IFR(Internal Forms Representation)信息供Hii调用。

1.formset

/*spec定义*/
vfrFormSetDefinition ::= 
"formset"
"guid" "=" guidDefinition ","
"title" "=" getStringId ","
"help" "=" getStringId ","
{ "classguid" "=" classguidDefinition "," }
{ "class" "=" classDefinition "," }
{ "subclass" "=" subclassDefinition "," } 
vfrFormSetList
"endformset" ";"

/*code实例*/
#include "TcgConfigNvData.h"
formset
  guid      = TCG_CONFIG_FORM_SET_GUID,
  title     = STRING_TOKEN(STR_TPM_TITLE),
  help      = STRING_TOKEN(STR_TPM_HELP),
  classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,

1.1 include
vfr文件可以和c语言一样include其他的.h文件,使用.h文件中的结构体,宏和GUID等等。

1.2 formset
标志着窗体的开始,以endformset结束

1.3 guid
formset的GUID

1.4 title&help
formset的name和help文本,字串定义在uni文件中。

1.5 classguid
本formaset所挂载页面的GUID值。
可设置也可不设置,详见VfrSpecification,{}代表关键字是可选的。

2.FormSet List

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

在formset中有一条条子内容,即formset中定义的formlist,其中有varstore等各种store;form语句去设置窗体中的各个条目选项;还有disableif,suppressif,grayoutif和goto等。
以下挑选几个常见的(我见过的)关键字做说明。

2.1 varstore

/*code实例*/
  varstore TCG_CONFIGURATION,
    varid = TCG_CONFIGURATION_VARSTORE_ID,
    name  = TCG_CONFIGURATION,
    guid  = TCG_CONFIG_FORM_SET_GUID;

变量定义,后面的vfr和c等文件可以通过name去引用该变量进行设值等操作。其他还有defaultstore,efivarstore,namevaluevarstore等,暂时未见过。

2.2 form formid

/*spec定义*/
vfrFormDefinition ::=
"form" "formid" "=" Number "," "title" "=" getStringId ";"
(
vfrStatementImage
| vfrStatementLocked
| vfrStatementRules
| vfrStatementDefault
| vfrStatementStat
| vfrStatementQuestions
| vfrStatementConditional
| vfrStatementLabel
| vfrStatementBanner
| vfrStatementExtension
| vfrStatementModal
)*
"endform" ";"

/*code实例*/
  form formid = TCG_CONFIGURATION_FORM_ID,
    title = STRING_TOKEN(STR_TPM_TITLE);

是formset的主体部分,由endform结尾。formid必须是独一无二的,可以通过goto语句去跳转到此窗体。主要关键字有form,formmap。

2.3 text

/*code实例*/
    subtitle text = STRING_TOKEN(STR_NULL);

    text
      help   = STRING_TOKEN(STR_TPM_STATE_HELP),
      text   = STRING_TOKEN(STR_TPM_STATE_PROMPT),
        text   = STRING_TOKEN(STR_TPM_STATE_CONTENT);

    subtitle text = STRING_TOKEN(STR_NULL);

subtitle text 标题的子文本,不能被选择
text 纯文本,可以被选择

2.4 disableif,suppressif,grayoutif

/*code实例*/
    suppressif ideqvallist HDD_PASSWORD_CONFIG.SecurityStatus.Frozen == 0;
        text
            help   = STRING_TOKEN(STR_EMPTY),
            text   = STRING_TOKEN(STR_SEC_FROZEN),
            text   = STRING_TOKEN(STR_YES),
            flags  = 0,
            key    = 0;
    endif;

根据后面接的判断语句,对包含的formset list进行操作,都要有endif结尾。
disableif 禁用formset list
suppressif 隐藏formset list,不在窗体显示,但是还是存在的,选项可以生效
grayoutif 置灰formset list,在窗体上不能够进行修改

disableif 和suppressif 的区别:
我的理解是disableif相当于if 0而suppressif 是隐藏,但是suppressif 的选项值是可以生效的。
在网上找的大佬的解释如下:
在这里插入图片描述
网上找的大佬解释

2.5 goto

/*code实例*/
    goto FORMID_DELETE_FORM,
      prompt = STRING_TOKEN (STR_DEL_ATTEMPT_ENTRY),
      help   = STRING_TOKEN (STR_DEL_ATTEMPT_ENTRY_HELP),
      flags  = INTERACTIVE,
      key    = KEY_DELETE_ATTEMPT;

跳转到其他窗体,prompt 当前窗体上的字串名字。

3.选项类型varid

除了text,subtitle text等,Setup上的选项还可以设置其他类型。
会一直补充项目中我所见过的类型:

3.1 oneof
选项框模式,可以在几个选项中选择,可以通过name后面的变量在c文件中修改。

/*code实例*/
    oneof name = SecureBootMode,
          questionid = KEY_SECURE_BOOT_MODE,
          prompt = STRING_TOKEN(STR_SECURE_BOOT_MODE_PROMPT),
          help   = STRING_TOKEN(STR_SECURE_BOOT_MODE_HELP),
          flags  = INTERACTIVE | NUMERIC_SIZE_1,
          option text = STRING_TOKEN(STR_STANDARD_MODE),    value = SECURE_BOOT_MODE_STANDARD, flags = DEFAULT;
          option text = STRING_TOKEN(STR_CUSTOM_MODE),      value = SECURE_BOOT_MODE_CUSTOM,   flags = 0;
    endoneof;

3.2 string
字符串,可以编辑,也可以在c等其他文件通过变量修改,可以设置尺寸。

/*code实例*/
    string  varid   = SECUREBOOT_CONFIGURATION.SignatureGuid,
            prompt  = STRING_TOKEN(STR_SECURE_BOOT_SIGNATURE_GUID),
            help    = STRING_TOKEN(STR_SECURE_BOOT_SIGNATURE_GUID_HELP),
            flags   = INTERACTIVE,
            key     = KEY_SECURE_BOOT_KEK_GUID,
            minsize = SECURE_BOOT_GUID_SIZE,
            maxsize = SECURE_BOOT_GUID_SIZE,
    endstring;

3.3 numeric
数字,和string差不多

/*code实例*/
    numeric varid   = VlanNvData.Priority,
            prompt  = STRING_TOKEN(STR_VLAN_PRIORITY_PROMPT),
            help    = STRING_TOKEN(STR_VLAN_PRIORITY_HELP),
            minimum = 0,
            maximum = 7,
    endnumeric;

3.4 checkbox
勾选,只有true和false可以选择。

/*code实例*/
    checkbox varid = SECUREBOOT_CONFIGURATION.AttemptSecureBoot,
          questionid = KEY_SECURE_BOOT_ENABLE,
          prompt = STRING_TOKEN(STR_SECURE_BOOT_PROMPT),
          help   = STRING_TOKEN(STR_SECURE_BOOT_HELP),
          flags  = INTERACTIVE | RESET_REQUIRED,
    endcheckbox;

除了这些,选项还有在C文件里面设置,已及通过GUID跳转等等的操作,后续会继续补充!

结语

后续有更深理解,会继续补充。
学艺不精,错误请指正;
如有侵权,请联系删除。

参考文档
《edk2-VfrSpecification-release-1.92.pdf》
;