First steps in bare-metal programming using UEFI
257 points • 6 days ago • Article Link

在现代 PC 类硬件上开发 bare-metal 应用,需要直接与 UEFI firmware 进行交互;这是一项要求采用结构化方法的工作,目的是在传统 Linux 开发环境与系统 firmware 的底层需求之间搭起桥梁。本系列文章旨在为那些希望在操作系统限制之外进行编程、并且此前对 UEFI 环境复杂性毫无经验的资深 Linux 开发人员提供入门性的基础指引。

整个过程首先从必要的技术准备入手,重点介绍生成 UEFI 能够成功加载的可执行代码所需的工具、编译策略以及链接要求。由于 UEFI 的运行方式不同于常规应用程序环境,弄清楚如何为这种特定运行时准备代码,是从常规工作区切换到 bare-metal 执行的关键第一步。

要让这些应用程序能够顺利运行,还必须关注它们如何被存储,以及如何向 firmware 呈现。挑战之一在于正确配置 EFI system partition:它充当 firmware 定位并执行二进制文件的入口。本指南将说明如何组织该分区,并进一步教你创建可启动媒体,例如 USB 闪存驱动器或 DVD,确保硬件能够识别并引导开发过程中生成的自定义应用程序。

在介绍引导与链接机制之外,本系列还会讨论系统真正运行起来后如何与之交互的实际问题。这包括对该环境局限与可能性的务实分析,以及通过 Simple File Protocol 进行文件管理的实践。按照这些步骤依次推进,开发人员就能系统地理解如何在 bare-metal UEFI 场景中管理数据,并与存储设备进行交互。

57 comments • Comments Link

- UEFI 开发面临不小的挑战,包括缺乏标准库、 UTF-16 使用很普遍,以及一些古怪的调用约定,颇像历史上的 Windows 设计风格。

- EDK II 仍然是标准参考实现,但开发者必须保持警惕,关注诸如在 PXE 驱动中发现的近期问题这类安全漏洞。

- 不少人觉得 UEFI 规范臃肿且在技术上存在缺陷,尤其批评它对 FAT32/VFAT 等传统文件系统的依赖,以及在现代项目中仍然持续、不必要地使用 UTF-16 。

- 尽管 UEFI 经常被称为"裸金属",但也有人认为它提供的抽象层以及系统管理模式(SMM)的存在,让这个标签值得商榷,因为它限制了对硬件的直接控制。

- UEFI 开发的工具链差异很大:有人依赖诸如 LLVM/Clang 这种重量级、难以审计的依赖;也有人探索更精简、可独立自足的替代方案,或使用 Rust 、 Zig 等现代语言。

- 像 Multiboot2 或自定义引导加载器的实现这类项目,提供了可行的替代方案,让开发者能够绕开完整 UEFI 环境的复杂性,从而开展传统 UEFI 应用之外的开发。

- 现代计算硬件(包括基于 ARM 的 Windows 设备)几乎都采用 UEFI,使其在当下行业中几乎成为通用标准,尽管人们对其背负的历史包袱颇有怨言。

- LLM 越来越多地被用来弥合复杂、晦涩的系统编程任务之间的鸿沟,能显著加快与文档不足或接口被刻意隐藏 / 混淆的系统交互过程。

- 在 UEFI 领域工作的开发者,能够从 OSDev Wiki 这类成熟、由社区驱动的资源中获益,它们为构建自定义 boot-loader 或 EFI 应用提供了基础指导。

- 行业内仍存在分歧:UEFI 是否最终会被更精简、更透明的固件标准所取代,还是会继续作为主导(尽管复杂)的兼容层延续下去。

讨论反映出系统开发者内心深处的挫败感,源于 UEFI 的复杂度以及它在架构选择上的诸多问题。尽管它已成为现代启动流程的近乎通用标准,但它也被广泛认为是过度工程化且设计不佳的"遗留包袱"。参与者围绕各种应对方案展开争论,从使用 Rust 和 Zig,到借助 LLM 来自动化与其不透明接口的交互,体现出一种更广泛的趋势:想用更高效的方式去对接这种限制性很强的硬件环境。