news 2026/4/22 6:57:56

告别黑框!手把手教你用UEFI HII给固件写个图形化配置界面(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
告别黑框!手把手教你用UEFI HII给固件写个图形化配置界面(附完整代码)

从命令行到图形化:UEFI HII实战开发指南

在固件开发领域,命令行界面(CLI)长期以来是配置系统参数的主要方式。但随着用户对友好交互体验的需求增长,图形化配置界面已成为现代固件的标配。UEFI Human Interface Infrastructure(HII)框架为开发者提供了一套完整的解决方案,让传统黑框终端华丽转身为直观的图形界面。

1. UEFI HII核心概念解析

UEFI HII框架包含三个关键组件:

  • HII数据库:集中管理所有界面资源(字符串、字体、图像、表单)
  • VFR语言:描述界面布局和交互逻辑的声明式语言
  • 配置协议:处理用户输入与系统变量的双向绑定

典型开发流程如下:

// 初始化HII包示例 EFI_HII_HANDLE InitHiiPackage(EFI_HANDLE ImageHandle) { EFI_HII_PACKAGE_LIST_HEADER *PackageList; gBS->OpenProtocol(ImageHandle, &gEfiHiiPackageListProtocolGuid, (VOID**)&PackageList, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); return gHiiDatabase->NewPackageList(gHiiDatabase, PackageList, NULL, &HiiHandle); }

2. 构建第一个图形界面

2.1 基础表单结构

VFR文件采用分层结构设计:

formset guid = {0x76b732b8, 0xb777, 0x4ecf, 0xa8, 0x4e, 0x7a, 0x8c, 0xa2, 0x48, 0x45, 0x55}, title = STRING_TOKEN(STR_MAIN_TITLE), form formid = 0x1000, title = STRING_TOKEN(STR_BASIC_SETTINGS); subtitle text = STRING_TOKEN(STR_SYSTEM_CONFIG); checkbox varid = Config.EnableFeature, prompt = STRING_TOKEN(STR_ENABLE_FEATURE), flags = INTERACTIVE; endform; endformset;

2.2 变量存储机制

配置数据通过EFI变量持久化存储:

#pragma pack(1) typedef struct { UINT8 EnableFeature; CHAR16 AdminPassword[32]; UINT32 BootTimeout; } SYSTEM_CONFIG_DATA; #pragma pack() // 变量存储声明 efivarstore SYSTEM_CONFIG_DATA, attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS, name = SysConfig, guid = SYSTEM_FORMSET_GUID;

3. 高级交互组件实战

3.1 动态表单生成

利用LABEL实现运行时界面扩展:

form formid = 0x2000, title = STRING_TOKEN(STR_ADVANCED_SETTINGS); label LABEL_DYNAMIC_START; label LABEL_DYNAMIC_END; endform;

对应动态更新代码:

VOID UpdateNetworkSettings() { VOID *StartOpCode = HiiAllocateOpCodeHandle(); EFI_IFR_GUID_LABEL *StartLabel = HiiCreateGuidOpCode( StartOpCode, &gEfiIfrTianoGuid, NULL, sizeof(EFI_IFR_GUID_LABEL)); StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; StartLabel->Number = LABEL_DYNAMIC_START; // 添加动态控件 HiiCreateTextOpCode(StartOpCode, STRING_TOKEN(STR_NETWORK_CONFIG), 0, 0); HiiUpdateForm(HiiHandle, &SYSTEM_FORMSET_GUID, 0x2000, StartOpCode, EndOpCode); }

3.2 条件显示逻辑

使用grayoutif实现智能UI:

grayoutif ideqval Config.EnableFeature == 0; numeric varid = Config.RetryCount, prompt = STRING_TOKEN(STR_RETRY_COUNT), minimum = 1, maximum = 10; endif;

4. 完整项目架构设计

推荐模块化工程结构:

/PlatformPkg /Include ConfigForms.vfr # 界面描述文件 ConfigStrings.uni # 多语言字符串 /Application SetupConfig.c # 配置逻辑实现 SetupConfig.h # 数据结构定义 /Resources Setup.rc # 资源编译脚本

关键回调处理示例:

EFI_STATUS EFIAPI ConfigCallback( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) { switch (QuestionId) { case QUESTION_NETWORK_MODE: HandleNetworkModeChange(Value->u8); *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RECONNECT; break; case QUESTION_SAVE_SETTINGS: SaveToNvram(); break; } return EFI_SUCCESS; }

在实际项目中,我们发现表单元素ID的合理规划至关重要。建议采用分层编号方案(0x1000基础设置、0x2000高级设置等),并建立完整的ID-变量映射文档。调试时可启用EDK2的DEBUG_FORM_BROWSER标志,实时观察表单处理流程。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 6:52:00

STM32CubeMX+CLion配置串口打印,从中文乱码到完美显示的完整避坑指南

STM32CubeMXCLion配置串口打印:从中文乱码到完美显示的完整避坑指南 第一次在CLion中成功调用printf输出调试信息时,那种成就感很快被串口助手上的一堆乱码浇灭——这大概是每个从Keil转向CLion的STM32开发者都会经历的挫败。中文显示问题看似简单&#…

作者头像 李华
网站建设 2026/4/22 6:35:38

如何查询用户的对象权限_DBA_TAB_PRIVS与DBA_COL_PRIVS

查用户对象权限应优先用DBA_TAB_PRIVS查对象级权限,仅需确认列级权限时才查DBA_COL_PRIVS;二者需UNION ALL联合查询并字段对齐,且须同步排查角色权限、系统权限及对象属主身份。查用户对象权限该用 DBA_TAB_PRIVS 还是 DBA_COL_PRIVS看权限粒…

作者头像 李华
网站建设 2026/4/22 6:33:21

PostgreSQL WITH 子句详解

PostgreSQL WITH 子句详解 引言 在数据库查询中,WITH 子句(也称为公用表表达式或 Common Table Expressions,简称 CTE)是一种强大的工具,它允许开发者将查询结果集作为子查询或临时表使用。WITH 子句在 PostgreSQL 中有…

作者头像 李华
网站建设 2026/4/22 6:33:19

Go 语言循环语句

Go 语言循环语句 引言 Go 语言(也称为 Golang)是一种静态类型、编译型、并发型编程语言,由 Google 开发。它以其简洁的语法和高效的并发处理能力而受到许多开发者的喜爱。在编程中,循环语句是执行重复任务的常用工具。本文将详细介…

作者头像 李华