当前位置: 首页 > news >正文

用 LVGL 给 UEFI Setup 换一套图形界面:架构、实现与 QEMU 验证

一、为什么做这件事

用过 UEFI 固件设置界面的人都知道,UiApp里的 Setup 页面是典型的文本式交互:标题栏、提示/取值两栏布局、帮助面板、底部快捷键一行字。它由 EDK II 的DisplayEngineDxe(文本渲染引擎)+SetupBrowserDxe(表单浏览器)协作完成,几十年来样式几乎没有变化。

本文介绍一个实验性项目:把 LVGL 当作 UEFI 下的一个普通库,用它替换DisplayEngineDxe的渲染实现,为 Setup 界面带来图形化能力——卡片式行布局、主题化配色、开关控件、品牌化页头页脚。关键点在于:只替换渲染层UiAppSetupBrowserDxe、HII 数据库、IFR 表达式求值器、现有 VFR 表单包全部保持不变。

  • LVGL 版本:9.4.0(vendor 到LvglPkg/ThirdParty/lvgl,upstream commitc016f72
  • EDK2 版本:b03a21a63e3bd001f52c527e5a57feddb53a690b(edk2-stable202605 之后)
  • 集成方式:edk2 侧OvmfPkgX64.dsc/fdf通过LVGL_UI_ENABLE宏把DisplayEngineDxe换成LvglDisplayEngineDxe

二、总体架构

项目以 EDK2 包(LvglPkg)形式组织,核心模块:

LvglPkg/ ├── Universal/ │ ├── LvglDisplayEngineDxe/ # 替换 DisplayEngineDxe 的入口(驱动) │ └── QemuUsbTabletDxe/ # QEMU 下的 USB 触控板输入(验证辅助) ├── Library/ │ ├── LvglUefiPortLib/ # GOP 帧缓冲对接 + 输入事件桥接 + 刷新 │ ├── LvglVfrAdapterLib/ # IFR 语句 → LVGL 控件模型(文本转移+释放) │ ├── LvglFormUiLib/ # 页面拓扑/行组合(Default / Modern 双实现) │ ├── LvglThemeLib/ # 主题度量与样式(颜色/尺寸/档位缩放) │ ├── LvglFontLib/ # 中文字体(生成后的 C 数组,共享) │ ├── LvglUiTextLib/ # 全部界面文案(本地化入口) │ └── LvglCoreLib/ # LVGL 源树编译(含裁剪的 lv_conf.h) ├── Include/ │ ├── lv_conf.h # LVGL 配置(64KB 定制内存分配器) │ └── Dsc/LvglPkgLibraries.dsc.inc # 双布局 profile 选择 ├── Patches/Lvgl/ # 对 LVGL 源码的 0001-0005 补丁系列 └── Test/LvglVfrDemoDxe/ # 演示 VFR 表单(覆盖全部控件类型)

SetupBrowser 的 IFR 表单 → LvglVfrAdapterLib 转成轻量模型 → LvglDisplayEngineDxe 按模型逐行创建 LVGL 对象 → LvglUefiPortLib 把 GOP 帧缓冲交给 LVGL 绘制 → 按键/触摸经输入桥接回 SetupBrowser

三、几个关键点

1. 只替换渲染层,不改浏览器逻辑

LvglDisplayEngineDxe实现的是 EDK2 定义的EFI_DISPLAY_ENGINE_PROTOCOLFormDisplay/FormExit),SetupBrowser 调它时传入 HII 句柄与表单 ID,返回时带回用户操作(提交/放弃/跳转等)。因此替换是"接口级"的:HII 数据库、IFR 求值、SetupBrowserDxe的行为(如BROWSER_ACTION_REQUEST_RECONNECT三态对话框语义)原样保留。

2. 输入与帧缓冲:LvglUefiPortLib

  • 显示:拿到 GOP 模式后把帧缓冲注册为 LVGL 的lv_display(支持 partial buffer,见补丁 0001),LvglUefiPortRefresh触发刷新。
  • 输入:把SimpleTextInEx按键与 QEMU USB 触控板事件统一桥接成lv_indev事件;Modern 布局下鼠标右键/Esc 在状态对话框中等价于"忽略"。
  • 内存:lv_conf.hLV_MEM_SIZE = 64KB,走 EDK2 内存分配(补丁 0002/0004 对齐整数类型并加固分配器)。

3. IFR → 模型:LvglVfrAdapterLib

VFR 表单里同一份 statement 会被多次访问(取值、校验、提交),但 LVGL 是"一次性建对象、整页重建"的模型。适配器在首次构建时把 IFR 语句转移成轻量视图(提示文本、帮助文本、类型、可选择性、默认值),并负责所有权(页面销毁时统一释放),避免 DisplayEngine 侧重复解析。

4. 双布局 profile:DEFAULT 与 MODERN

LVGL_UI_LAYOUT环境变量在构建时选择(写入LvglBuildInfo.txt):

  • DEFAULT:复刻传统 Setup 结构——标题栏、提示/取值两栏、帮助面板、快捷键底栏,作为回归基线;
  • MODERN:图形化布局——品牌页头(Logo 标记 + 产品名 +STANDARD VFR标签)、独立表单列与帮助面板、单列卡片行、Checkbox 轨道开关、底栏快捷键胶囊([Up/Down] Move等)、640×480 紧凑模式自动隐藏帮助面板。

布局与样式完全由LvglFormUiLib/LvglThemeLib两个库实现,且都有 Default/Modern 两份实现——换皮肤不换逻辑

5. 中文字体

CJK 字体由生成脚本把 TTF 转成 LVGL 字体 C 数组(LvglFontLib共享),1280×800 与 640×480 使用不同的字号档位,1920×1080 走 125% 缩放档——三个分辨率下字体自动换档。

四、QEMU 辅助验证环境

开发阶段主要用QEMU + OVMF做验证,它只是一个辅助验证环境:目标是实机移植,QEMU 用于快速、可重复地验证行为与视觉。

  • 启动:qemu-system-x86_64 -machine q35,配bochs-display显式 EDID(精确控制帧缓冲尺寸),-debugcon file:输出日志,QMP socket 做自动化控制;
  • 分辨率:640×480 / 1280×800 / 1920×1080 三档都测

五、构建方法(简要)

# 环境:edk2(版本见文首)已就绪,PACKAGES_PATH 包含本仓库exportEDK2_ROOT=/path/to/edk2exportLVGL_UI_LAYOUT=MODERN# 或 DEFAULTbashScripts/build-ovmf-lvgl.sh full

产物OVMF_CODE.fd可直接启动 QEMU;固件体积与原生 OVMF 相当(LVGL 图形引擎替换文本引擎,模块级增量约 +4KB,FV 对齐后总体积不变)。

六、现状与下一步

当前 v0.1 基线:默认与现代双布局、IFR 全控件类型(Checkbox/OneOf/Numeric/String/Password/Date/Time/OrderedList/REF/Reset)、标准协议语义(提交/放弃/重置/重连三态对话框)与原生 SetupBrowser 一致、三分辨率全部验证。

下一步方向:实机平台移植(把LvglUefiPortLib的 GOP/输入对接换成目标平台实现)、控件交互增强(Numeric 步进器独立点击区)。

附:运行截图(QEMU 验证环境)


经典布局(LVGL_UI_LAYOUT=DEFAULT):复刻传统 Setup 结构——标题栏、提示/取值两栏、右侧 Help 面板、底部快捷键行,Checkbox 仍是文本式[X]


MODERN 布局主界面(1280×800):品牌页头(Logo + LVGL Firmware Setup + STANDARD VFR 标签)、左侧单列卡片表单、右侧帮助面板(圆形 ? 图标 + 标题 + 说明)、底栏 5 个快捷键胶囊。


OneOf 选项对话框:居中模态卡片、蓝色选中边框、选项浅色文字(可读性由逐行像素断言覆盖)。


Modal 类型表单页:独立页面布局,帮助面板随焦点更新当前控件的 Prompt 与 HII Help。


640×480 紧凑模式:自动隐藏帮助面板与品牌副标题,表单占满宽度,快捷键胶囊完整不截字。


1920×1080:字体走 125% 缩放档位,布局与 1280 一致。

http://www.jsqmd.com/news/1336687/

相关文章:

  • BilibiliDown 终极指南:如何快速下载B站视频的完整教程
  • 【重磅】NVIDIA CMP 170HX 矿卡解锁:8GB→64GB、算力接近「真 A100」完整教程(含验证)
  • 三极管工作原理与共射极放大电路设计:从非线性特性到稳定偏置
  • KKCE: 基于 ETag 指纹碰撞与条件请求的网站测速缓存一致性审计-快快测
  • Python工作流引擎SpiffWorkflow完全指南:从入门到精通掌握BPMN流程自动化
  • 北京靠谱的旅游包车机构哪家强?本地老司机推荐 - 品牌优推
  • 电力系统碳排放优化调度模型设计与实践
  • CAD三维建模零基础入门:从软件选择到核心建模流程全解析
  • Java逻辑运算符深度解析:从短路求值到优先级陷阱与实战避坑
  • QTableWidget 实战:自动换行且行高自适应的完整方案
  • 学术研究者的高效翻译助手:Zotero PDF2zh插件完全指南
  • AUTOSAR架构如何实现汽车嵌入式软件代码复用:从分层设计到工程实践
  • 3步搞定微信公众号数据采集:Python爬虫实战指南
  • FastLED电源管理实战指南:高效控制LED电流的7大关键策略
  • 深度学习在智能交通系统中的应用与实践
  • 机动目标跟踪:Singer与当前统计模型原理及MATLAB仿真实践
  • 2026年广州潮汕肠粉加盟企业怎么选择?看实利更重要 - 品牌优推
  • 国内开发者合规访问主流AI大模型(Gemini/ChatGPT/Claude/Grok)实战指南
  • 3分钟学会AI全自动短视频制作:Pixelle-Video让你轻松成为内容创作者
  • 从原子钟到厘米级定位:GPS时间系统与高精度定位技术全解析
  • codex必用10大视频skill,从0到1做爆款
  • 链上套利残酷共学-DAY01
  • 臃肿工具箱里的“无用之重”
  • KKCE: 基于 BGP 路由收敛与 AS Path 预热的网站测速冷启动优化-快快测
  • 从手写 Hash 路由到 React Router:一个路由练习的关键实现
  • 74. 搜索二维矩阵:把二维结构映射成一维后做二分
  • ENVI 5.6安装与配置全攻略:从系统环境到性能优化的遥感数据处理基石
  • 如何轻松捕获网页视频:猫抓浏览器扩展终极使用指南
  • tchMaterial-parser架构解析:国家中小学智慧教育平台电子课本下载技术实现深度指南
  • 全屋一体式家用冷暖系统什么牌子好:【芬尼】一体集成 - 18002239949