U-boot 对UEFI的支持
UEFI on U-Boot
Unified Extensible Firmware Interface Specification (UEFI) 已经成为 AArch64 和 X86系统的默认boot接口。它为固件上drivers和applications之间的交互提供了稳定的API。这些API 那囊括了 block storage、network和console 等设备的访问。Linux Kernel和诸如GRUB 、 FreeBSD loader 之类的boot loader都可以被执行。
[1] 开发目标
在U-Boot对UEFI的实现力争达到“Embedded Base Boot Requirements (EBBR) Specification - Release v1.0”EBBR规范规定的要求。主要参考EBBR中“Server Base Boot Requirements System Software on ARM Platforms” 章节。
一个完全成熟的UEFI实现将与U-Boot“保持规模小”的设计原则相矛盾。
因此可以得出结论:U-Boot中主要目标是实现EBBR规范规定的UEFI集合,并非full UEFI。
[2] Building U-Boot for UEFI
UEFI标准只支持小端系统。可以通过下面定义来使能ARM和x86对UEFI的支持:
CONFIG_CMD_BOOTEFI=y
CONFIG_EFI_LOADER=y
以上配置在.config文件生效。
此外,还支持虚拟block 设备挂在,例如 iSCSI drives 可以被加载的UEFI application connected。需要以下配置:
CONFIG_BLK=y
CONFIG_PARTITIONS=y
[3] 执行UEFI binary
U-Boot中bootefi命令用于启动UEFI applications 或者install UEFI drivers.该命令采用两个参数:
bootefi [fdt address]
- image address - UEFI binary的ne内存地址。
- fdt address - FDT的内存地址。
当从内存某个位置boot时,我们不知道它是从哪个文件load的。因此bootefi 命令采用设备路径(block设备分区的设备路径或网适配器的设备路径)和最近加载的PE-COFF文件的文件名。
[4] 配置UEFI安全启动
UEFI规范定义了一组安全执行UEFI Images的方法,通过校验image签名和认证的方式。改功能在U-Boot上通过如下配置使能:
CONFIG_EFI_SECURE_BOOT=y
为了确保启动序列安全,需要创建信任链;在UEFI 安全启动中信任链通过如下UEFI 变量定义:
- PK - Platform Key
- KEK - Key Exchange Keys
- db - white list database
- dbx - black list database
其余详见U-Boot22:doc\develop\uefi\uefi.rst
[5] U-Boot 运行edk2
由于需要实现UEFI variable services。U-Boot可以在自己的代码中实现改服务,也可以由安全世界的OP-TEE[1]模块实现。EDK2可以充当U-Boot中的OP-TEE。
关于EDKII如何和U-Boot交互,可以看U-Boot文档。
U-Boot on EFI
前面介绍了如何在U-Boot环境下执行UEFI 驱动或应用程序。 下面主要介绍,如何在EFI环境下将U-Boot作为一个应用程序来执行,或者将U-Boot嵌入到新的平台。
[1] 动机
在EFI上运行U-Boot, 在以下几种情况下很有用:
- board上可以运行EFI,但不完全支持U-Boot。可以从EFI引导到U-Boot,并使用它,直到U-Boot完全移植。
- 需要使用EFI实现(例如UEFI),因为您的供应商需要它来提供支持。
- 计划使用coreboot启动到U-Boot,但是我们的平台没有coreboot。可以先在EFI上运行U-Boot,后面再实现从coreboot启动U-Boot。
- 您已经使用EFI,但想尝试使用更简单的替代方案,如U-Boot。
[2] 状态
目前只在X86上支持。由于我们主要基于ARM 平台工作,后面就不看了。