UEFI开发学习 31 – UEFI Hii基础及编程实例

 多数人对主板固件的第一印象是蓝底白字的Setup界面——它作为UEFI固件与用户交互的唯一“可见层”,提供了CPU、内存、PCIe等设备的调整选项,支持用户定制化配置。

对于开发者而言,修改现有菜单可通过VFR文件轻松实现;但若需新增控件并联动硬件寄存器,就必须理解IFR、HII Package、Callback Protocol这一整套机制,显著提升了开发门槛。UEFI HII的核心精髓在于将界面定义与业务逻辑彻底解耦:

层面
实现方式
输出结果
类比机制
界面定义
VFR声明式语言
IFR字节码
HTML页面的DOM结构
业务逻辑
标准C代码 + 回调协议
硬件寄存器操作
JavaScript后端API

这套架构类似浏览器运行网页并提交表单:
1.注册资源:固件驱动将字符串/字体/IFR资源打包为HII Package,注册到系统HII Database
2.渲染界面:Form Browser(UEFI内置浏览器)从Database检索资源,解析IFR字节码渲染为界面
3.交互提交:用户修改配置后,Browser通过EFI_HII_CONFIG_ACCESS_PROTOCOL将数据提交给后端C代码,后者处理硬件操作

Setup本质是固件内的“微型Web服务”——声明式UI配合一次性提交模式,兼顾多语言/多皮肤的灵活性,同时保留硬件控制精度。

 一、HII 基础 

1. HII 的概念与作用

HII(Human Interface Infrastructure)是 UEFI 规范中定义的人机交互基础设施,为固件提供标准化的用户界面管理框架。

核心设计理念
资源与逻辑分离:将UI资源(字符串、表单、字体等)与驱动业务逻辑完全解耦
国际化支持:通过多语言字符串包实现本地化,同一驱动可适配不同语言环境
动态界面构建:使用IFR(Internal Forms Representation)二进制格式描述表单,支持运行时动态生成UI
标准化接口:提供统一的协议接口,驱动无需关心底层渲染实现

2. HII 的核心组成

协议/组件
UEFI规范定义
主要功能
HII Database Protocol EFI_HII_DATABASE_PROTOCOL
管理Package List的注册、查询、更新、移除
HII String Protocol EFI_HII_STRING_PROTOCOL
多语言字符串的存储、检索、更新
HII Config Routing Protocol EFI_HII_CONFIG_ROUTING_PROTOCOL
配置数据路由,处理/格式转换
HII Config Access Protocol EFI_HII_CONFIG_ACCESS_PROTOCOL
驱动侧回调接口,处理表单事件和数据交换
HII Font Protocol EFI_HII_FONT_PROTOCOL
字体渲染和文本绘制服务
Form Browser2 Protocol EFI_FORM_BROWSER2_PROTOCOL
Setup Browser实现,负责表单渲染和用户交互

3. HII 数据结构与资源类型

核心数据结构
Package:HII中的最小资源单位,每个Package包含特定类型的数据
Package List:由EFI_HII_PACKAGE_LIST_HEADER开头,包含一个或多个Package的集合
HII Handle:Package List在HII Database中的唯一标识符

标准Package类型(UEFI规范定义):

Package类型
标识符
数据来源
用途
Strings Package EFI_HII_PACKAGE_STRINGS .uni

文件编译
多语言字符串资源
Forms Package EFI_HII_PACKAGE_FORMS .vfr

文件编译生成IFR
表单界面定义
Fonts Package EFI_HII_PACKAGE_FONTS
字体文件
自定义字体资源
Images Package EFI_HII_PACKAGE_IMAGES
图像文件
图标、背景等图像资源
Simple Fonts Package EFI_HII_PACKAGE_SIMPLE_FONTS
简单字体定义
基础字符集字体
Device Path Package EFI_HII_PACKAGE_DEVICE_PATH
设备路径
关联的设备路径信息

 二、HII 编程 

本节内容以一个HiiDemo源码为例,讨论Hii编程中,涉及的文件结构,语法,控件等内容。源码将附于文末链接中。

1. HII 编程的代码结构

文件类型
作用说明
示例
.c
业务逻辑与协议实现
HiiDemo.c
.vfr
界面定义(VFR语言)
HiiDemoVfr.vfr
.uni
多语言字符串资源
HiiDemoStrings.uni
.inf
模块构建配置
HiiDemo.inf

2. 文件编译与转换流程

在 EDK II 的构建过程中,这些源文件会被特殊的编译器和工具处理,最终转换为 C 语言的字节数组,链接到最终的 EFI 文件中。

HiiDemo 编译后,Build 目录下将生成相应的目录,如BuildMdeModuleDEBUG_VS2019X64MdeModulePkgApplicationHiiDemoHiiDemo,该目录下的中间文件涉及vfr和uni文件的转换。

1.UNI 文件的转换

• HiiDemoStrings.uni 文件会被 EDK II 的构建工具处理。
• 所有的字符串(包括各种语言版本)会被编译成一个遵循 HII String Package 格式的字节数组 HiiDemoStrings[],并存储在 AutoGen.c 文件中。
• 同时,每个字符串会被分配一个唯一的数字 ID(Token),这些 ID 的宏定义会生成在 HiiDemoStrDefs.h 文件中,例如:


#define STR_FORM_SET_TITLE          0x0002  
#define STR_FORM_SET_TITLE_HELP     0x0003  
// ... more string IDs

这些宏将在 VFR 文件中被引用,从而将界面控件与具体的字符串关联起来。

2.VFR 文件的转换

• HiiDemoVfr.vfr 文件由 VfrCompile 工具进行编译。
• 编译器将 VFR 源码转换成 IFR (Internal Form Representation) 字节码。
• 这些字节码最终会以一个 C 数组的形式存储起来,例如 unsigned char HiiDemoVfrBin[],并保存在 HiiDemoVfr.c 文件中。这个数组就是一个标准的 HII Form Package。

3.资源的使用
   在 HiiDemo.c 中,这些自动生成的 C 数组(HiiDemoStrings 和 HiiDemoVfrBin)将作为资源被注册到 HII Database 中。这一步通常通过调用 HiiAddPackages 函数完成:




// mDriverHandle 是当前驱动的句柄  
// HiiDemoStrings 和 HiiDemoVfrBin 是编译生成的数组  
HiiHandle = HiiAddPackages (  
              &mHiiDemoFormSetGuid, // 唯一的 FormSet GUID  
              mDriverHandle,  
              HiiDemoStrings,  
              HiiDemoVfrBin,  
              NULL // 可以添加其他 Package,如 Image Package  
              );

此函数执行后,HiiDemo 模块的界面资源就对整个系统可见了。Form Browser 可以随时根据需要来加载并显示它。

 三、VFR 文件 

1. VFR 文件的作用

定义 HII 表单界面
编译生成 IFR 二进制数据
包含 FormSet、VarStore、Form、控件、字符串 Token 引用

2. VFR 文件示例




/** @file
  VFR file for HII Demo Application.

**/

#include 

#define HII_DEMO_FORMSET_GUID 
  { 
    0x85b75607, 0xf7ce, 0x471e, { 0xb7, 0xe4, 0x2a, 0xea, 0x5f, 0x72, 0x32, 0xee } 
  }

#define HII_DEMO_FORM_ID     0x1000

typedefstruct {
  UINT8   CheckboxValue;
  UINT16  NumericValue;
  UINT16  OneOfValue;
  CHAR16  StringValue[20];
  UINT8   OrderedListValue[3];
  CHAR16  PasswordValue[16];
} HII_DEMO_CONFIGURATION;

formset
  guid     = HII_DEMO_FORMSET_GUID,
  title    = STRING_TOKEN(STR_FORM_SET_TITLE),
  help     = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),
  classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,

  varstore HII_DEMO_CONFIGURATION,
    varid = 0x1234,
    name  = HiiDemoConfig,
    guid  = HII_DEMO_FORMSET_GUID;

  form formid = HII_DEMO_FORM_ID,
       title  = STRING_TOKEN(STR_MAIN_FORM_TITLE);

    subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT);

    text
      help   = STRING_TOKEN(STR_TEXT_HELP),
      text   = STRING_TOKEN(STR_TEXT_PROMPT);

    checkbox varid   = HiiDemoConfig.CheckboxValue,
             prompt  = STRING_TOKEN(STR_CHECKBOX_PROMPT),
             help    = STRING_TOKEN(STR_CHECKBOX_HELP),
             flags   = CHECKBOX_DEFAULT,
    endcheckbox;

    numeric varid   = HiiDemoConfig.NumericValue,
            prompt  = STRING_TOKEN(STR_NUMERIC_PROMPT),
            help    = STRING_TOKEN(STR_NUMERIC_HELP),
            minimum = 0,
            maximum = 100,
            step    = 1,
            default = 50,
    endnumeric;

    oneof varid   = HiiDemoConfig.OneOfValue,
          prompt  = STRING_TOKEN(STR_ONEOF_PROMPT),
          help    = STRING_TOKEN(STR_ONEOF_HELP),
          option text = STRING_TOKEN(STR_ONEOF_OPTION1), value = 1, flags = DEFAULT;
          option text = STRING_TOKEN(STR_ONEOF_OPTION2), value = 2, flags = 0;
          option text = STRING_TOKEN(STR_ONEOF_OPTION3), value = 3, flags = 0;
    endoneof;

    string varid    = HiiDemoConfig.StringValue,
           prompt   = STRING_TOKEN(STR_STRING_PROMPT),
           help     = STRING_TOKEN(STR_STRING_HELP),
           minsize  = 0,
           maxsize  = 19,
    endstring;

    orderedlist varid   = HiiDemoConfig.OrderedListValue,
                prompt  = STRING_TOKEN(STR_ORDEREDLIST_PROMPT),
                help    = STRING_TOKEN(STR_ORDEREDLIST_HELP),
                option text = STRING_TOKEN(STR_ORDEREDLIST_OPTION1), value = 1, flags = 0;
                option text = STRING_TOKEN(STR_ORDEREDLIST_OPTION2), value = 2, flags = 0;
                option text = STRING_TOKEN(STR_ORDEREDLIST_OPTION3), value = 3, flags = 0;
    endlist;

    subtitle text = STRING_TOKEN(STR_SUBTITLE_ADVANCED);

    grayoutif TRUE;
      text
        help   = STRING_TOKEN(STR_GRAYOUT_HELP),
        text   = STRING_TOKEN(STR_GRAYOUT_TEXT);
    endif;

    suppressif ideqval HiiDemoConfig.CheckboxValue == 0;
      text
        help   = STRING_TOKEN(STR_SUPPRESS_HELP),
        text   = STRING_TOKEN(STR_SUPPRESS_TEXT);
    endif;

    password varid   = HiiDemoConfig.PasswordValue,
             prompt  = STRING_TOKEN(STR_PASSWORD_PROMPT),
             help    = STRING_TOKEN(STR_PASSWORD_HELP),
             minsize = 4,
             maxsize = 15,
    endpassword;

    text
      help   = STRING_TOKEN(STR_ACTION_HELP),
      text   = STRING_TOKEN(STR_ACTION_TEXT),
      flags  = INTERACTIVE,
      key    = 0x1001;

  endform;

endformset;

3. 语法结构解析

文件头与 GUID 定义




#include 
#define HII_DEMO_FORMSET_GUID { ... }
#define HII_DEMO_FORM_ID     0x1000

引入标准的 EFI_HII_PLATFORM_SETUP_FORMSET_GUID,用于标识这是一个 Setup 类的 FormSet
自定义了一个本示例的 FormSet GUID 和 Form ID

VarStore 定义



typedef struct {
  UINT8   CheckboxValue;
  UINT16  NumericValue;
  UINT16  OneOfValue;
  CHAR16  StringValue[20];
  UINT8   OrderedListValue[3];
  CHAR16  PasswordValue[16];
} HII_DEMO_CONFIGURATION;

定义了一个结构体 HII_DEMO_CONFIGURATION,作为表单数据存储(VarStore)
每个字段对应一个控件的变量绑定

FormSet 声明



formset
  guid     = HII_DEMO_FORMSET_GUID,
  title    = STRING_TOKEN(STR_FORM_SET_TITLE),
  help     = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),
  classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,

guid:本 FormSet 的唯一标识
title / help:标题与帮助文本(引用 .uni 文件中的字符串)
classguid:指定这是一个平台 Setup 类型的 FormSet

VarStore 声明



varstore HII_DEMO_CONFIGURATION,
  varid = 0x1234,
  name  = HiiDemoConfig,
  guid  = HII_DEMO_FORMSET_GUID;

绑定结构体类型 HII_DEMO_CONFIGURATION
varid:VarStore ID(在控件 varid 属性中引用)
name:变量名
guid:与 FormSet 关联的 GUID

Form 定义



form formid = HII_DEMO_FORM_ID,
     title  = STRING_TOKEN(STR_MAIN_FORM_TITLE);

定义一个表单页面(Form)
formid:唯一 ID
title:页面标题

各类控件

• subtitle:副标题
• text:静态文本
• checkbox:复选框(绑定 CheckboxValue,默认选中)
• numeric:数值输入(0~100,步长 1,默认 50)
• oneof:单选列表(3 个选项,Option1 为默认)
• string:字符串输入(最大 19 个字符)
• orderedlist:可排序列表(3 个选项)
• password:密码输入(4~15 个字符)
• text + INTERACTIVE + key:可交互文本,按键触发回调

条件显示控制

grayoutif TRUE; ... endif;
  → 永远灰显(不可用)
suppressif ideqval HiiDemoConfig.CheckboxValue == 0; ... endif;
  → 当复选框值为 0 时隐藏内容

Flags 详解与最佳实践

常用Flags及其UEFI规范定义

Flag 名称
UEFI规范常量
适用控件
作用机制
实际应用场景
DEFAULT EFI_IFR_OPTION_DEFAULT oneof

/orderedlist
标记该选项为默认选中项
option text=STRING_TOKEN(STR_OPTION1), value=1, flags=DEFAULT;
CHECKBOX_DEFAULT EFI_IFR_CHECKBOX_DEFAULT checkbox
复选框初始状态为选中
checkbox varid=Config.Enable, flags=CHECKBOX_DEFAULT;
INTERACTIVE EFI_IFR_FLAG_CALLBACK
所有输入控件
值变化时立即触发EFI_BROWSER_ACTION_CHANGED回调
实现动态选项、实时验证等
RESET_REQUIRED EFI_IFR_FLAG_RESET_REQUIRED
所有配置控件
标记修改后需要系统重启生效
BIOS设置中的硬件配置项
MANUFACTURING EFI_IFR_OPTION_DEFAULT_MFG oneof

选项
制造模式下的默认值(与标准默认值并存)
工厂测试与量产配置分离

高级Flags组合使用



// 示例1:交互式数值控件,修改后需要重启
numeric varid = Config.CpuRatio,
        prompt = STRING_TOKEN(STR_CPU_RATIO),
        help = STRING_TOKEN(STR_CPU_RATIO_HELP),
        flags = INTERACTIVE | RESET_REQUIRED,
        key = KEY_CPU_RATIO,
        minimum = 8, maximum = 50, step = 1,
        default = 16,
endnumeric;

// 示例2:制造模式与标准模式不同默认值
oneof varid = Config.TestMode,
      prompt = STRING_TOKEN(STR_TEST_MODE),
      help = STRING_TOKEN(STR_TEST_MODE_HELP),
      option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT;
      option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = MANUFACTURING;
endoneof;

Flags使用注意事项
INTERACTIVE控件必须指定key值,用于在Callback中识别事件源
RESET_REQUIRED会在Setup Browser中显示重启提示
多个Flags可以用|操作符组合使用
DEFAULTMANUFACTURING可以同时存在于不同选项中

交互与 questionid / key

在 HII 中,每个能够与用户交互的控件都需要一个唯一的标识符,以便后端的 C 代码能够识别是哪个控件触发了事件。这个标识符就是 questionid。根据控件是否绑定到 varstore,questionid 的分配方式有所不同:

绑定 varstore 的控件 (varid)

隐式 Question ID (默认行为): 对于使用 varid 关键字绑定到 varstore 的控件(如 checkbox, numeric),系统会自动为其分配一个 questionid,其值等于该控件绑定的成员在 C 结构体中的偏移量 (offset)。这是最常见的基础用法。

显式 Question ID (高级实践): 尽管有隐式的 questionid,但在大型项目中,直接在 C 代码中使用偏移量(如 case 0x1A:)会降低代码的可读性和可维护性。因此,VFR 允许开发者为这些控件显式地指定一个 questionid(通常使用一个宏),从而覆盖默认的偏移量值。这样做的好处是:
增强可读性: C 代码可以使用有意义的宏名称(如 case MY_SETTING_ID:)代替晦涩的数字。
提升可维护性: 如果 varstore 的 C 结构体发生变化(如增删成员),所有后续成员的偏移量都会改变。如果 C 代码中硬编码了偏移量,就需要手动修改多处,极易出错。而使用显式的 questionid 则不受此影响。

未绑定 varstore 的控件 (key):

• 对于不存储数据、仅用于触发动作的交互式控件(如标记为 INTERACTIVE 的 text 或 action 控件),它们没有 varid。因此,必须使用 key 关键字为其显式地指定一个唯一的数字 ID。
• 当事件触发时,这个 key 的值就会作为 QuestionId 传递给 Callback 函数。

 四、C 文件处理表单事件 

1. 表单事件的来源与处理机制

HII Config Access Protocol的三大核心接口

接口函数
调用时机
数据格式
主要用途
ExtractConfig
Setup Browser需要显示当前配置时

 → 
将驱动内部配置数据导出为标准格式
RouteConfig
用户提交表单修改时

 → 内部数据结构
将Setup Browser的配置更改导入到驱动
Callback
用户与INTERACTIVE控件交互时
事件参数结构
处理实时交互、动态更新、数据验证

事件触发的典型场景
表单打开:Setup Browser调用ExtractConfig获取当前值
用户输入:INTERACTIVE控件触发Callback进行实时处理
表单提交:Setup Browser调用RouteConfig保存用户修改
表单关闭:可能再次调用ExtractConfig确认最终状态

2. EFI_HII_CONFIG_ACCESS_PROTOCOL 详解

协议结构定义



typedef struct _EFI_HII_CONFIG_ACCESS_PROTOCOL {
    EFI_HII_ACCESS_EXTRACT_CONFIG ExtractConfig;
    EFI_HII_ACCESS_ROUTE_CONFIG   RouteConfig;
    EFI_HII_ACCESS_FORM_CALLBACK  Callback;
} EFI_HII_CONFIG_ACCESS_PROTOCOL;

// 协议GUID
#define EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID 
  {0x330d4706, 0xf2a0, 0x4e4f, {0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85}}

ExtractConfig接口详解



EFI_STATUS ExtractConfig(
    IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
    IN  CONST EFI_STRING Request,      // 格式
    OUT EFI_STRING *Progress,          // 解析进度指针
    OUT EFI_STRING *Results            // 格式输出
);

Request格式示例GUID=

 

 

&NAME=&PATH=&OFFSET=0&WIDTH=4


Results格式示例GUID=&NAME=&PATH=&OFFSET=0&WIDTH=4&VALUE=12345678
特殊情况:Request为NULL时,返回所有配置项

RouteConfig接口详解



EFI_STATUS RouteConfig(
    IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
    IN  CONST EFI_STRING Configuration,  // 格式
    OUT EFI_STRING *Progress             // 解析进度指针
);

Configuration:包含用户修改后的配置值
实现要点:需要验证数据有效性,更新内部VarStore

Callback接口详解



EFI_STATUS Callback(
    IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
    IN  EFI_BROWSER_ACTION Action,        // 动作类型
    IN  EFI_QUESTION_ID QuestionId,       // 控件ID
    IN  UINT8 Type,                       // 数据类型
    IN  EFI_IFR_TYPE_VALUE *Value,        // 当前值
    OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest  // 返回动作
);

Action类型定义

Action常量
数值
触发时机
典型用途
EFI_BROWSER_ACTION_CHANGING
0
控件值即将改变
数据验证、阻止无效输入
EFI_BROWSER_ACTION_CHANGED
1
控件值已经改变
动态更新其他控件、联动逻辑
EFI_BROWSER_ACTION_RETRIEVE
2
需要获取控件值
动态生成选项列表
EFI_BROWSER_ACTION_FORM_OPEN
3
表单页面打开
初始化、权限检查
EFI_BROWSER_ACTION_FORM_CLOSE
4
表单页面关闭
清理资源、保存状态
EFI_BROWSER_ACTION_SUBMITTED
5
表单提交
最终验证、应用配置

3. 完整的HII系统初始化流程

初始化

HiiDemo 驱动加载,在其入口函数中:

1.初始化一个 HII_DEMO_CONFIGURATION 结构体(mHiiDemoConfiguration)的默认值。

2.安装 EFI_DEVICE_PATH_PROTOCOL 和 EFI_HII_CONFIG_ACCESS_PROTOCOL 协议。这两个协议通常通过 InstallMultipleProtocolInterfaces 一同安装在驱动的 Handle 上。
   Device Path 的作用: 为驱动创建一个唯一的“地址”。这非常重要,因为它让 HII Database 知道这个界面配置属于哪个设备或驱动。Form Browser 等系统组件通过这个路径来识别和管理特定的 HII 资源。没有它,HII Package 就像一个没有地址的信封,无法被准确投递和管理。
   Config Access Protocol 的作用: 将 ExtractConfig, RouteConfig, Callback 函数的地址暴露出去,为界面提供后端数据处理能力。

3.调用 HiiAddPackages,将 VFR 和 UNI 编译好的二进制资源注册到 HII Database,并获得一个 HiiHandle。

显示表单

用户进入 UEFI Setup。Platform BDS(启动设备选择)代码会启动 Form Browser,并指示它显示所有 classguid 为 EFI_HII_PLATFORM_SETUP_FORMSET_GUID 的 formset。

数据加载

Form Browser 找到了 HiiDemo 注册的 formset:
Browser 调用 HiiDemo 的 ExtractConfig 函数。
ExtractConfig 内部使用 BlockToConfig 将 mHiiDemoConfiguration 结构体的内容转换成字符串,返回给 Browser。

界面渲染

Browser 拿到数据后,开始解析 Form Package (IFR 字节码):
它根据 IFR 的描述,逐一创建 checkbox, numeric 等控件,并将从 ExtractConfig 获得的值填充到这些控件中。
最终,一个完整的、带有当前配置值的界面呈现给用户。

用户交互

用户尝试修改 numeric 控件的值:
每次改动,Browser 都会调用 HiiDemo 的 Callback 函数,Action 为 EFI_BROWSER_ACTION_CHANGING 或 EFI_BROWSER_ACTION_CHANGED。
Callback 函数中的 C 代码可以根据 QuestionId 判断是哪个控件被修改,并执行相应的逻辑(如合法性检查、更新其他控件状态等)。

保存配置

用户完成所有修改,按下保存键(如 F10):
Browser 将所有被用户修改过的配置项打包成一个 config-string。
Browser 调用 HiiDemo 的 RouteConfig 函数,并将这个字符串作为参数传入。
RouteConfig 内部使用 ConfigToBlock 将字符串解析回 mHiiDemoConfiguration 结构体,完成了内存中数据的更新。
(可选)如果设计为持久化存储,RouteConfig 接下来会调用 gRT->SetVariable() 将更新后的 mHiiDemoConfiguration 结构体写入 NVRAM。

退出与清理

HiiDemo 驱动在被卸载时,会调用 HiiRemovePackages 从 HII Database 中移除它的资源,并卸载相关协议,完成清理工作。

 五、总结 

UEFI HII 提供了一套强大而灵活的框架,用于在固件层面构建现代化的用户界面。其核心优势在于:

解耦:  彻底分离了 UI 表现(VFR)和后端逻辑(C),使得两者可以独立开发和维护。

标准化: 提供了一套标准的控件和交互模型,确保了不同厂商固件之间的一致用户体验。

可扩展性: 轻松支持多语言本地化,并且可以通过自定义 Callback 逻辑实现极其复杂的动态交互。

HiiDemo 源码:https://gitee.com/ay123net/uefistudy

 

 

 

版权声明:
作者:bin
链接:https://ay123.net/mystudy/1909/
来源:爱影博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
海报
UEFI开发学习 31 – UEFI Hii基础及编程实例
 多数人对主板固件的第一印象是蓝底白字的Setup界面——它作为UEFI固件与用户交互的唯一“可见层”,提供了CPU、内存、PCIe等设备的调整选项,支持用户定制化配置……
<<上一篇
下一篇>>
文章目录
关闭
目 录