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 场景中管理数据,并与存储设备进行交互。
Developing bare-metal applications on modern PC-type hardware involves interfacing directly with UEFI firmware, a task that requires a structured approach to bridge the gap between traditional Linux development environments and the low-level requirements of system firmware. This series of articles serves as a foundational guide for experienced Linux developers who wish to explore programming outside the constraints of an operating system, assuming they have no prior familiarity with the complexities of the UEFI environment.
The process begins with the essential technical setup, focusing on the software tools, compilation strategies, and linking requirements necessary to generate executable code that UEFI can successfully load. Since UEFI operates differently than standard application environments, understanding how to prepare the code for this specific runtime is the critical first step in moving from a standard workspace to bare-metal execution.
Successfully running these applications requires attention to how they are stored and presented to the firmware. Part of the challenge lies in correctly configuring the EFI system partition, which acts as the gateway for the firmware to locate and execute binary files. The guide details how to organize this partition and subsequently create bootable media, such as USB flash drives or DVDs, ensuring that the hardware can recognize and boot the custom applications created during development.
Beyond the mechanics of booting and linking, the series addresses the practical aspects of interacting with the system once it is active. This includes a pragmatic look at the limitations and possibilities of the environment, as well as an exploration of file management using the Simple File Protocol. By following these steps in order, developers can build a comprehensive understanding of how to manage data and interact with storage devices from within a bare-metal UEFI context.
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 来自动化与其不透明接口的交互,体现出一种更广泛的趋势:想用更高效的方式去对接这种限制性很强的硬件环境。 • UEFI development presents significant challenges, including a lack of a standard library, the prevalence of UTF-16, and idiosyncratic calling conventions that resemble historical Windows design patterns.
• EDK II remains the standard reference implementation, though developers must remain vigilant regarding security vulnerabilities, such as recent issues found in the PXE driver.
• Many find the UEFI specification bloated and technically flawed, specifically criticizing the reliance on legacy file systems like FAT32/VFAT and the persistent, unnecessary use of UTF-16 in modern projects.
• While UEFI is frequently described as "bare metal," some argue that the abstraction layer it provides—and the presence of System Management Mode (SMM)—makes this label debatable, as it limits direct hardware control.
• Tooling for UEFI development varies widely, with some relying on heavy, un-auditable dependencies like LLVM/Clang, while others explore minimal, self-contained alternatives or use modern languages like Rust and Zig.
• Projects like Multiboot2 or custom boot-loader implementations offer viable alternatives to traditional UEFI application development, allowing developers to bypass the complexity of the full UEFI environment.
• Modern computing hardware, including ARM-based Windows devices, almost exclusively utilizes UEFI, making it a nearly universal standard in the current industry despite its perceived historical baggage.
• LLMs are increasingly used to bridge the gap in complex, recondite system programming tasks, significantly accelerating the process of interacting with poorly documented or obfuscated interfaces.
• Developers working in the UEFI space benefit from established, community-driven resources like the OSDev Wiki, which provide foundational guidance for those building custom boot-loaders or EFI applications.
• The industry remains divided on whether UEFI will eventually be succeeded by more streamlined, transparent firmware standards or if it will continue to persist as the dominant, albeit complex, compatibility layer.
The discussion highlights a deep-seated frustration among systems developers regarding the complexity and architectural choices of UEFI. While it serves as the near-universal standard for modern boot processes, it is widely viewed as an over-engineered and poorly designed legacy burden. Participants debated the merits of various workarounds, from using Rust and Zig to leveraging LLMs for automating the interaction with its opaque interfaces, reflecting a broader trend of seeking more efficient ways to interface with restrictive hardware environments.