Unified Extensible Firmware Interface (UEFI) 探索
传统BIOS(Basic Input/Output System)由IBM 1981年在其第一代 IBM PC [1]中引入,负责启动时的硬件检测和初始化,并为操作系统提供硬件抽象层。这一设计被广泛模仿,成为PC行业的标准。但其局限性(如开发效率低、启动速度慢和MBR分区表缺陷)在新时代硬件面前愈发明显。
为解决BIOS的不足,并提升安全性,UEFI[2](Unified Extensible Firmware Interface)标准被引入。作为取代BIOS的现代化解决方案,UEFI不仅解决了BIOS的瓶颈,还引入了:
·模块化设计
·安全启动机制
·更好的大容量存储支持
·更多的启动设备支持
本文将简单介绍UEFI的背景、核心组件及基于spacemit K1 [3]平台的解决方案。
历史与演进
起源
UEFI的前身是Intel于1998年提出的EFI (Extensible Firmware Interface),旨在为Itanium服务器提供更高效的启动环境。2005年,UEFI论坛成立,由Intel、微软、AMD等厂商共同推动标准化。
版本
·UEFI 2.0(2006):UEFI论坛制定的首版规范,64位架构支持,奠定模块化驱动和网络协议基础。
·UEFI 2.4(2013):强化安全启动(Secure Boot)和ACPI集成。
·UEFI 2.8(2022):新增RISC-V架构支持。
·UEFI 2.11(2024):内存管理增强,错误处理改进,新增龙芯LoongArch架构的支持,新增国密算法(SM2, SM3)支持。
演进
UEFI标准未来会继续关注如下几个方向:
·新的硬件标准支持,如PCIe 6.0,DDR6等;
·安全性持续增加,加密算法和安全机制更新;
·启动速度提升,优化启动流程,减少启动时间;
·多架构兼容(x86/ARM/RISCV)
核心组件
UEFI通过规范定义了一整套完整的标准化接口和服务,对上屏蔽硬件细节;在硬件平台发生变更后,通过UEFI固件提供服务,确保操作系统不受影响。
UEFI组件总览 [4]
启动服务
启动服务(Boot Service)的主要功能是为操作系统加载前的系统初始化提供支持,启动服务在操作系统加载完成后会被终止,操作系统接管系统资源。这一过程通过调用 ExitBootServices 函数实现:
ExitBootServices:通知 UEFI 固件操作系统已准备好接管系统资源,启动服务将被禁用。
启动服务提供的service罗列如下。
内存管理
分配和释放内存,支持不同类型的物理内存(如常规内存和保留内存)。
事件处理
UEFI中只有timer中断,利用timer来创建和管理事件,支持异步操作和定时器功能。
协议管理
安装、卸载和查找协议(Protocol),用于驱动程序和应用程序之间的通信。
镜像加载
加载和启动操作系统内核或其他可执行镜像。
设备管理
提供对硬件设备的访问和控制。
运行时服务
运行时服务(Runtime Services) 在操作系统运行期间提供一系列关键功能,包括时间管理、变量服务和系统重置等。与启动服务不同,运行时服务在操作系统加载完成后仍然可用,为操作系统和应用程序提供与固件的交互接口。
时间管理
获取和设置系统时间。
变量服务
读写 UEFI 变量(如启动顺序、硬件配置等)。UEFI 变量通常用于存储系统配置信息,例如:
启动顺序(BootOrder):定义系统的启动设备顺序。
硬件配置:存储硬件相关的设置(如网络配置、安全设置等)。
系统重置
支持系统重启或关机(RISC-V架构下,系统重启和关机通过openSBI实现)。
虚拟内存管理
在操作系统运行期间管理虚拟内存映射。
SMBIOS
SMBIOS(System Management BIOS) 是由 DMTF(分布式管理任务组)制定的一项标准,旨在为操作系统和管理工具提供系统硬件信息的标准化接口。通过一种结构化的方式,将系统的硬件配置、固件版本、主板信息等数据传递给操作系统或管理工具。
SMBIOS 数据表由UEFI生成,存储在系统内存中,操作系统可以通过system table访问这些数据。
·硬件信息描述:提供系统硬件配置的详细信息,例如处理器、内存、主板、存储设备等。
·固件信息传递:传递固件版本、制造商信息等数据。
·系统管理支持:为系统管理工具(如 IPMI、Redfish)提供硬件信息支持。
SMBIOS 表的访问
操作系统或管理工具可以通过以下方式访问 SMBIOS 表:
·System table:kernel下通过EFI_SYSTEM_TABLE获取EFI_CONFIGURATION_TABLE,进而定位SMBIOS表的地址
·操作系统:用户可以通过工具(如 dmidecode)查询 SMBIOS 数据,获取系统的硬件信息。
·系统管理工具:IPMI、Redfish标准中使用 SMBIOS 数据监控硬件状态、诊断故障和管理系统资源。
ACPI
ACPI(Advanced Configuration and Power Interface,高级配置与电源接口)是由 Intel、Microsoft、Toshiba 等公司联合制定的一项标准,旨在取代传统的 BIOS 电源管理接口(如APM,Advanced Power Management)。
ACPI用于定义操作系统与硬件之间的电源管理和硬件配置接口。ACPI 提供了一种标准化的方式,使操作系统能够管理硬件资源、控制电源状态,并支持即插即用功能。其不仅定义了电源管理功能,还提供了硬件资源的描述和配置接口。
ACPI 表
ACPI 表是 ACPI 的核心数据结构,用于描述硬件资源和电源管理信息。ACPI 表通常在 UEFI 的 DXE(Driver Execution Environment)阶段生成,并由 UEFI 传递给操作系统。
ACPI框架 [5]
ACPI table以二进制格式存储,操作系统通过解析这些表获取硬件信息。常见的 ACPI 表包括:
·DSDT(Differentiated System Description Table):包含系统的硬件描述和电源管理信息。
·FADT(Fixed ACPI Description Table):描述固定的硬件资源和电源管理寄存器。
·SSDT(Secondary System Description Table):提供额外的硬件描述信息。
·MADT(Multiple APIC Description Table):描述多处理器系统的中断控制器配置。
·SRAT(System Resource Affinity Table):描述系统资源的亲和性(例如 NUMA 架构中的内存和 CPU 关系)。
·RHCT(RISC-V Hart Capabilities Table):描述RISC-V CPU核心(HARTs)的能力和配置信息,如 CPU ID、支持的 ISA 扩展等。
ACPI 电源管理
ACPI 定义了多种电源状态,用于管理系统的功耗和性能。
全局电源状态转换 [5]
全局电源状态(Global System States)
·G0(Working State):系统处于正常工作状态。
·G1(Sleeping State):系统处于睡眠状态,分为多个子状态(S1-S4)。
·S1:CPU 停止执行指令,但内存保持供电。
·S2:CPU 断电,内存保持供电。
·S3(Suspend to RAM):CPU 和大部分硬件断电,内存保持供电。
·S4(Suspend to Disk):系统状态保存到磁盘,内存断电。
·G2(Soft Off):系统处于软关机状态,部分硬件(如网络接口)可能保持供电。
·G3(Mechanical Off):系统完全断电。
设备电源状态(Device Power States)
·D0:设备处于正常工作状态。
·D1/D2:设备处于低功耗状态。
·D3:设备处于关闭状态。
Protocol
Protocol(协议) 是 UEFI中的一个核心概念,用于定义驱动程序、应用程序和固件之间的交互接口,通过 Protocol,UEFI 能够实现模块化设计和动态绑定,提供强大的硬件管理和扩展能力。
protocol的组成 [4]
Protocol 类似于面向对象编程中的接口或抽象类,提供了一种标准化的方式,使不同组件能够相互通信和协作。
每个 Protocol 包含一组函数指针和数据字段,用于实现特定的功能。
·标准化接口:Protocol 定义了统一的接口规范,使不同组件能够相互兼容。
·动态绑定:Protocol 通过句柄(Handle)绑定到特定设备或服务,支持动态加载和卸载。
·模块化设计:Protocol 支持模块化设计,便于扩展和维护。
OS LOADER
OS Loader(操作系统加载器) 是 UEFI 启动流程的一部分,依赖于 UEFI 的启动服务(Boot Services)和运行时服务(Runtime Services),从启动设备(如硬盘、光盘或网络)加载操作系统内核,并为其准备执行环境,将控制权从 UEFI 固件转移到操作系统。
OS Loader 的实现通常由操作系统开发者完成,以下是一些常见的 OS Loader 实现:
Windows Boot Manager
Windows的OS Loader是bootmgfw.efi,其主要功能包括:
·加载Windows内核
·准备 Windows 启动环境
GRUB(Grand Unified Bootloader)
GRUB 是 Linux 系统中常用的 OS Loader,其主要功能包括:
·加载 Linux 内核(vmlinuz)和ramdisk(initrd)
·支持多操作系统启动
·提供命令行界面,用于调试和配置
UEFI on Spacemit K1
Spacemit K1是一颗8核64位RISC-V AI CPU,基于开源Tianocore EDK2解决方案,完成了K1上的UEFI适配。
启动流程
K1上UFEI解决方案启动流程如下图。
基于RISC-V当前的firmware标准和开源实现:
1 | 简化EDK2中启动阶段实现,并将部分功能实现挪至FSBL中实现 |
2 | 部分runtime service由openSBI实现 |
bootloader
bootloader存储于spi nor flash上,包含如下图3个主要模块。
FSBL
FSBL基于uboot工程编译而来,实现UEFI PEI阶段的:
·DDR初始化
·加载opensbi与EDK2
·更新memory信息,并通过dtb传递给EDK2
openSBI
基于开源openSBI解决方案,提供machine态的基础服务:
·Cache管理
·TLB管理
·suspend/resume管理
EDK2
基于开源tianocore EDK2开源解决方案,提供:
·EFI boot service,提供系统启动相关服务
·存储驱动(emmc,sd,nvme)和USB驱动,支持从卡、emmc、NVME、U盘中启动
·GOP(Graphic Output Protocol),支持通过HDMI显示启动菜单
·Variable service,实现启动选项的配置,如启动顺序、启动时间等
grub
OS loader选择基于开源grub2的解决方案。
·grub作为一个EFI application,存储于ESP分区,经EDK2加载和运行;
·通过/boot/grub/grub.cfg配置文件,完成多系统识别与引导,并配置启动菜单;
·加载内核镜像和init ramdisk,完成系统加载和控制权切换;
·kernel镜像与rootfs存储于emmc或nvme等存储器上。
通过上述提供的解决方案,实现在K1方案板上,支持从多种启动介质上,完成linux系统的加载和启动;并能通过EDK2启动菜单,完成启动优先级的配置和修改。
参考
① IBM PC, https://zh.wikipedia.org/wiki/IBM_PC
② Unified Extensible Firmware Interface, https://en.wikipedia.org/wiki/UEFI
③ Sapcemit Key Stone K1, https://www.spacemit.com/key-stone-k1/
④ UEFI specification, https://uefi.org/specs/UEFI/2.11/
⑤ ACPI specification, https://uefi.org/specs/ACPI/6.5/