UEFI
2024-04-16 11:10:08 阿炯

统一可扩展固件接口(英语:Unified Extensible Firmware Interface,缩写UEFI)是一种个人电脑系统规格,用来定义操作系统与系统固件之间的软件界面,作为BIOS的替代方案。可扩展固件接口负责加电自检(POST)、联系操作系统以及提供连接操作系统与硬件的接口。

UEFI的前身是Intel在1998年开始开发的Intel Boot Initiative,后来被重命名为可扩展固件接口(Extensible Firmware Interface,缩写EFI)。Intel在2005年将其交由统一可扩展固件接口论坛(Unified EFI Forum)来推广与发展,为了凸显这一点,EFI也更名为UEFI(Unified EFI)。UEFI论坛的创始者是11家知名电脑公司,包括Intel、IBM等硬件厂商,软件厂商Microsoft,及BIOS厂商安迈科技、Insyde、Phoenix。


可扩展固件接口在软件层次中的位置


规格

可扩展固件接口(EFI)最初是由英特尔开发,于2002年12月英特尔释出其订定的版本——1.1版,之后英特尔不再有其他关于EFI的规范格式发布。有关EFI的规范,英特尔已于2005年将此规范格式交由UEFI论坛来推广与发展,后来并更改名称为Unified EFI(UEFI)。UEFI论坛于2007年1月7日释出并发放2.1版本的规格,其中较1.1版本增加与改进了加密编码(cryptography)、网络认证(network authentication)与用户接口架构(User Interface Architecture)。

2009年5月9日,发布2.3版本;2022年8月释出2.10版本。

历史

EFI引导管理器与 EFI drivers 的沟通方式


众所周知,英特尔在近二十年来引领以x86系列处理器为基础的PC技术潮流,其产品如CPU,芯片组等在PC生产线中占据绝对领导的位置。因此,不少人认为此举显示英特尔公司欲染指固件产品市场的野心。事实上,EFI技术源于英特尔安腾处理器(Itanium)平台的推出。安腾处理器是英特尔瞄准服务器高端市场投入近十年研发力量设计产生的与x86系列完全不同的64位新架构。在x86系列处理器进入32位的时代,由于兼容性的原因,新的处理器(80386)保留16位的运行方式(实模式),此后多次处理器的升级换代都保留这种运行方式。甚至在包含EM64T技术的至强系列处理器中,处理器加电启动时仍然会切换到16位的实模式下运行(BIOS)。英特尔将这种情况归咎于BIOS技术的发展缓慢。自从IBM PC兼容机厂商通过净室的方式复制出第一套BIOS源程序,BIOS就以16位汇编代码,寄存器参数调用方式,静态链接,以及1MB以下内存固定编址的形式存在十几年。虽然由于各大BIOS厂商近年来的努力,有许多新元素添加到产品中,如PnP BIOS、ACPI、传统USB设备支持等等,但BIOS的根本性质没有得到任何改变。这迫使英特尔在开发新的处理器时,都必须考虑加进使性能大大降低的兼容模式。

然而,安腾处理器并没有这样的顾虑,它是一个新生的处理器架构,系统固件和操作系统之间的接口都可以完全重新定义。并且这一次,英特尔将其定义为一个可扩展的,标准化的固件接口规范,不同于传统BIOS的固定的,缺乏文档的,完全基于经验和晦涩约定的一个事实标准。基于EFI的第一套系统产品的出现至今已经有五年的时间,如今,英特尔试图将成功运用在高端服务器上的技术推广到市场占有率更有优势的PC产品线中,并承诺在2006年间会投入全力的技术支持。

与BIOS的比较

二者显著的区别就是UEFI是用模块化,C语言风格的参数堆栈传递方式,动态链接的形式构建的系统,较BIOS而言更易于实现,容错和纠错特性更强,缩短了系统研发的时间。它可以执行于x86-64、IA32、ARM等架构上(在个人电脑上通常是x86-64平台),突破传统16位代码的寻址能力,达到处理器的最大寻址。它利用加载UEFI驱动程序的形式,识别及操作硬件,不同于BIOS利用挂载实模式中断的方式增加硬件功能。后者必须将一段类似于驱动程序的16位代码(如RAID卡的Option ROM)放置在固定的0x000C0000至0x000DFFFF之间存储区中,运行这段代码的初始化部分,它将挂载实模式下约定的中断向量向其他程序提供服务。例如,VGA图形及文本输出中断(INT 10h),磁盘访问中断服务(INT 13h)等等。BIOS以实模式执行,因此这段存储器空间很有限(在实模式下仅能寻址最多1MB的存储器),BIOS对于所需放置的驱动程序代码大小超过空间大小的情况无能为力。另外,BIOS的硬件服务程序都以16位代码的形式存在,这就给运行于保护模式或长模式的操作系统访问其服务造成了困难。因此BIOS提供的中断调用在现实中只能提供给操作系统的启动程序或MS-DOS类操作系统使用。而UEFI系统下的驱动程序可以由EFI Byte Code(EBC)编写而成,EFI Byte Code是一组专用于EFI驱动程序的虚拟机器语言,必须在UEFI驱动程序运行环境(Driver Execution Environment,DXE)下被解释运行。由于UEFI驱动程序开发简单,所有的PC部件提供商都可以参与,情形非常类似于现代操作系统的开发模式,这个开发模式曾使Windows在短短的两三年时间内成为功能强大,性能优越的操作系统。基于UEFI驱动模型(UEFI driver model,UDM)可以使UEFI系统接触到所有的硬件功能,在操作系统执行以前浏览万维网站,实现图形化、多语言的BIOS设置界面,或者无需执行操作系统即可在线更新BIOS等等不再是天方夜谭,甚至实现起来也非常简单。这对基于传统BIOS的系统来说是件难以实现的任务,在BIOS中添加几个简单的USB设备支持都曾使很多BIOS设计师痛苦万分,更何况除了添加对无数网络硬件的支持外,还得凭空构建一个16位模式下的TCP/IP协议栈。

一些人认为BIOS只不过是由于兼容性问题遗留下来的无足轻重的部分,不值得为它花费太大的升级努力。而反对者认为,当BIOS的出现约制了PC技术的发展时,必须有人对它作必要的改变。

与操作系统的关系

UEFI在概念上类似于一个低阶的操作系统,并且具有操控所有硬件资源的能力。不少人感觉它的不断发展将有可能代替现代的操作系统。事实上,EFI的缔造者们在第一版规范出台时就将EFI的能力限制于不足以威胁操作系统的统治地位。首先,它只是硬件和预启动软件间的接口规范;其次,UEFI环境下不提供中断的机制,也就是说每个UEFI驱动程序必须用轮询(polling)的方式来检查硬件状态,并且需要以解释的方式运行,较操作系统下的机械码驱动效率更低;再则,UEFI系统不提供复杂的缓存器保护功能,它只具备简单的缓存器管理机制,具体来说就是指运行在x64或x86处理器的长模式或保护模式下,以最大寻址能力为限把缓存器分为一个平坦的段(Segment),所有的程序都有权限访问任何一段位置,并不提供真实的保护服务。当UEFI所有组件加载完毕时,便会启动操作系统的启动程序,如果UEFI固件内置UEFI Shell,也可以启动UEFI Shell命令提示。UEFI应用程序(UEFI Application)和UEFI驱动程序(UEFI driver)是PE格式的.efi文件,可用C语言编写。在UEFI引导模式下,操作系统的启动程序也是UEFI应用程序,启动程序的EFI文件存储在EFI系统分区(ESP)上。

UEFI固件区分架构,在UEFI引导模式下,通常只能执行特定架构的UEFI操作系统和特定架构的EFI应用程序(EBC程序除外)。比如,采用64位UEFI固件的PC,在UEFI引导模式下只能执行64位操作系统启动程序;而在Legacy引导模式(即BIOS兼容引导模式)下,既可以执行16位的操作系统(如DOS),也可以执行32位操作系统和64位操作系统。

组成

一般认为,UEFI由以下几个部分组成:
Pre-EFI初始化模块(PEI)
UEFI驱动程序执行环境(DXE)
UEFI驱动程序(UEFI driver)
兼容性支持模块(CSM)
UEFI高层应用(UEFI Application)
GUID磁盘分区表
系统管理模式(SMM)

Pre-EFI初始化程序在系统开机的时候最先得到执行,它负责最初的CPU,芯片组及主存的初始化工作,紧接着加载UEFI的驱动程序执行环境(DXE)。当DXE被加载运行时,系统便具有了枚举并加载其他UEFI驱动程序的能力。DXE枚举并加载各种总线(包括PCI、SATA、USB、ISA)及硬件的UEFI驱动程序。例如一个具PCI-E总线接口的RAID存储适配器,其UEFI驱动程序一般会放置在这个设备的Option ROM中。在UEFI规范中,一种突破传统MBR磁盘分区结构限制的GUID磁盘分区系统(GPT)被引入,新结构中,磁盘的主分区数不再受限制(在MBR结构下,只能存在4个主分区),另外UEFI+GPT结合还可以支持2.1 TB以上硬盘。在众多的分区类型中,EFI系统分区可以被UEFI固件访问,可用于存放操作系统的引导程序。UEFI固件通过执行EFI系统分区中的启动程序启动操作系统。CSM是在x86平台UEFI系统中的一个特殊的模块,它将为不具备UEFI引导能力的操作系统以及16位的传统Option ROM提供类似于传统BIOS的系统服务。在加载操作系统后,UEFI的SMM程序继续执行,提供ACPI等服务。

发展

英特尔无疑是推广EFI的积极因素,近年来由于业界对其认识的不断深入,更多的厂商正投入这方面的研究。包括英特尔,AMD在内的一些PC生产厂家联合成立了UEFI论坛。另外各大BIOS提供商如Insyde,Phoenix,AMI等,他们原先被认为是EFI发展的阻碍力量,现在也不断的推出各自的解决方案。分析人士指出,这是由于BIOS厂商在EFI架构中重新找到了诸如Pre-EFI启动环境之类的市场位置,然而随着EFI在PC系统上的成功运用,以及英特尔新一代芯片组的推出,这一部分市场份额将会不出意料的在英特尔的掌控之中。2011年以后生产的零售主板大多数采用UEFI技术。随后,微软又要求,预装Windows 8的电脑,必须采用UEFI引导模式,以及Secure Boot。部分采用EFI技术的BIOS并不支持EFI引导。

操作系统支持

Linux内核自2000年开始,已经支持EFI启动。早期使用ELILO作为EFI下的启动程序。现在,GRUB的EFI版本已代替ELILO,大多数Linux发行版已使用GRUB作为UEFI下的启动程序。从Linux版本3.15起,来自英代尔的工程师Matt Fleming将64位核心提供了支持32位UEFI固件的可能,前提只需要UEFI操作系统启动程序支持EFI handover协议,譬如流行的GRUB2。同样流行的32位版Linux,譬如Ubuntu 16.04.3 LTS,也可以使用这类启动程序在64位版UEFI固件的机器上使用。

安腾版本的Windows 2000已于2002年加入对EFI 1.10的支持。安腾版本的Windows Server 2003和Windows XP 64-Bit Edition(以IA-64架构作为执行平台)已支持EFI。

从Windows Vista SP1开始,x86-64架构的Windows操作系统已支持UEFI。但是,若在UEFI模式下安装和启动Windows Vista SP1或Windows 7,需要在UEFI固件设置中开启CSM[6],因为在Windows 8之前的版本中,均不支持UEFI标准的“图形输出协议”(GOP),只支持用于传统BIOS的VESA BIOS Extension。32位的Windows Vista和Windows 7不支持UEFI启动。从Windows 8开始,支持Secure Boot,UEFI模式下的启动亦无须CSM。

现在,x86-64架构的FreeBSD、OpenBSD和NetBSD已支持UEFI。GUID 分区表 (GPT) 系 UEFI 支持的强制需求。

虚拟机对UEFI的模拟

VMware Workstation支持对UEFI的模拟,但是在VMware Workstation 11以前并未正式支持UEFI,需要手动编辑虚拟机的.vmx文件以开启虚拟机的UEFI。VMware Workstation 11及以后的版本正式支持对UEFI的模拟。从VMware Workstation 14开始支持Secure Boot。

VirtualBox支持对UEFI的模拟,但是VirtualBox的UEFI并不支持Windows Vista和Windows 7。

QEMU/KVM可通过OVMF支持对UEFI的模拟。

微软Hyper-V的第二代虚拟机支持对UEFI的模拟,以及Secure Boot。

Parallels Desktop不仅提供全规格的UEFI支持,并支持在操作系统不支持“图形输出协议”(GOP)的情况下回退至传统BIOS。

采用UEFI固件的x86/x64系统类别

类别0,这类系统使用x86 BIOS固件,只支持传统操作系统。

类别1,这类系统采用支持UEFI和Pi规范的固件,激活CSM层功能,只支持传统操作系统。

类别2,这类系统采用支持UEFI和Pi规范的固件,激活CSM层功能,同时支持传统和UEFI启动的操作系统。

类别3,这类系统采用支持UEFI和Pi规范的固件,不再提供或完全关闭CSM层功能,只支持由UEFI启动的操作系统。

类别3+,在类别3的系统基础上提供并激活Secure Boot功能。

微软公司的Windows 11仅可用于类别3+型电脑,Windows 8及10适用于上述所有类别的电脑,x64型版的Windows Vista SP1和Windows 7,以及不支持UEFI固件的操作系统仅可用于类别0至类别2型电脑。所有支持UEFI启动的Linux操作系统适用于类别0至类别3型电脑,多数现行分发版也支持类别3+中的Secure Boot功能,譬如Ubuntu等。 Intel计划将于2020年推出的UEFI Class 3规范中,将CSM层功能舍弃,不再支持由当年IBM公司制定的BIOS平台,Intel旗下的所有产品将遵循UEFI类别3(有一部分产品可能是3+)型规范。

批评

Ronald G. Minnich(Coreboot的共同作者)和 Cory Doctorow(科幻小说家)和数字权利运动者批评EFI是企图借由禁止用户完整控制他们的电脑,来保护知识产权。它并没有解决BIOS长期以来对多数硬件需要两种不同驱动程序的问题--一个给固件,一个给操作系统。

TianoCore(一个提供制作基于UEFI自由固件工具的开放源代码项目)缺乏用来启动芯片组的专门的驱动程序,因此需要芯片组厂商提供额外的功能。TianoCore是coreboot的一个附加选项,它包含了启动芯片组的代码。

由于UEFI比起原先的BIOS技术可以对远程网络引导提供更高的弹性,因此在标准的安全规定有一些疑虑。

Secure Boot

中文名又译作“安全启动”,该协议定义在UEFI 2.3.1 Errata C规范中。Secure Boot只允许加载有适当数字签名的EFI驱动程序和EFI启动程序,因此Secure Boot可让引导过程更安全。

但是Red Hat开发者Matthew Garrett在他的文章"UEFI secure booting"中忧虑UEFI的Secure Boot功能可能会影响Linux(贴有Windows 8认证贴纸的机器,默认Secure Boot启动,只预载了OEM和微软密钥,可能无法以Linux引导)。微软回应称顾客可以停用UEFI固件中的secure boot。然而,某些OEM厂商仍然可能在其产品中省略这项功能。不久,报告指出微软显然禁止在ARM系统上实现停用Secure Boot的功能。

自由软件基金会(FSF)的Josh Gay对UEFI的"Secure Boot"实现提出忧虑,并发表公开声明及连署说:我们—连署者—敦促所有实现了UEFI中称为"Secure Boot"的电脑制造商立即允许自由的操作系统可以被安装。基于尊重用户的自由权以及确切保护用户安全,制造商必须允许电脑拥有者停用引导限制,或是提供一个确切可能的方法让他们安装并执行自由的操作系统。我们承诺我们将不会购买、也不会推荐剥夺用户重要自由的电脑,并且,我们将积极地敦促社会大众避免如此禁锢用户的系统。

2012年1月,微软发布一份关于OEM硬件认证的文件,指出所有的x86和x86-64设备应该将UEFI Secure Boot启动,不过可以改用一个可让用户增加数字签名的自定义Secure Boot模式。然而,无法在运行Windows的ARM设备上修改或禁用Secure Boot。这份称为Windows硬件认证需求(Windows Hardware Certification Requirements)证实了执行Windows 8、基于ARM的设备被禁止了任何安装其他操作系统的可能性。现在,Ubuntu、Fedora、openSUSE、RHEL7+、CentOS7+、Debian10+等Linux发行版已经支持Secure Boot。Windows 8、8.1、10支持Secure Boot。

常用指令

UEFI相关的命令通常用于管理计算机的引导配置和启动项,以下是一些常用的UEFI命令:

bcdedit: 用于管理Windows引导配置数据库(BCD),包括添加、删除、编辑引导项等。常见的用法包括:
bcdedit /enum: 列出当前系统中的所有引导项。
bcdedit /enum firmware: 列出UEFI固件中的启动项。
bcdedit /set: 设置引导配置数据库中的属性,例如设置默认启动项。
bcdedit /delete: 删除引导配置数据库中的引导项。
bcdedit /bootsequence: 设置引导项的启动顺序。
bootrec: 用于修复引导问题,通常用于修复损坏的引导配置或修复引导加载器。一些常见的用法包括:
bootrec /fixmbr: 修复主引导记录(MBR)。
bootrec /fixboot: 修复启动分区的引导扇区。
bootrec /rebuildbcd: 重建引导配置数据库。
diskpart: 磁盘分区工具,可用于创建、删除、格式化分区等。在UEFI环境下,通常用于准备磁盘以安装Windows系统。

efibootmgr:Linux系统中的UEFI引导管理器,可以用于查看和修改UEFI引导项。常见的用法包括:
efibootmgr -v: 列出当前系统中的UEFI引导项及其详细信息。
efibootmgr -b XXXX -B: 删除指定的UEFI引导项。

在运行Linux 4.0及以上内核的发行版中,可以通过 sysfs 接口查看 UEFI 系统位数。试着运行:
$ cat /sys/firmware/efi/fw_platform_size

如果返回 64 则代表 64 位(x86_64) UEFI 系统,如果返回 32 则代表 32 位(IA32) UEFI 系统。如果文件不存在,那么代表并没有进入 UEFI 模式。

这些命令可以帮助在UEFI环境下管理引导配置和启动项,进行引导修复以及安装操作系统。请注意,对于某些命令,可能需要以管理员或超级用户权限运行。

除了上面提到的命令外,还有一些其他的UEFI相关命令,这些命令在不同的操作系统或环境中可能有所不同。以下是一些其他常见的UEFI命令:

efibootmgr:在Linux系统中用于管理UEFI引导项的工具,可以列出、添加、删除UEFI引导项等。

fwsetup 或 setup: 有些计算机或主板厂商提供的UEFI固件设置工具,用于在UEFI固件中配置各种设置选项,例如引导顺序、启用/禁用安全启动等。

efi-shell:提供了一个UEFI环境下的命令行界面,可以在其中执行各种UEFI相关的操作。您可以通过启动UEFI Shell来访问它,有时也可以在UEFI设置界面中找到。

EFI variables: UEFI固件中的变量,用于存储各种配置信息,例如启动选项、安全设置等。您可以使用类似efivar的工具来读取、修改这些变量。

UEFI firmware更新工具:一些主板厂商提供专门的工具用于更新UEFI固件。这些工具通常是独立于操作系统的,并提供了在UEFI环境中执行固件更新的功能。

UEFI配置文件:一些高级的UEFI固件支持配置文件,可以用于自动化配置UEFI设置。您可以通过创建和编辑配置文件来定制UEFI设置,然后通过相应的命令加载和应用这些配置文件。

这些是一些常见的UEFI相关命令和工具,它们可用于在UEFI环境中管理引导配置、固件设置和UEFI变量等。具体可用的命令和工具可能会根据您使用的操作系统、计算机型号和UEFI固件版本而有所不同。

除了上面提到的命令和工具,还有一些其他的UEFI相关命令和工具。以下是其中一些:

UEFI Development Kit (EDK II): 一个用于开发UEFI固件的开源工具包,包括了一系列的工具和库,用于编写、编译和调试UEFI固件。

GRUB命令: GNU GRUB(GRand Unified Bootloader)是一个常用的引导加载器,支持在UEFI环境下启动。在GRUB的命令行界面中,您可以执行各种UEFI相关的操作,例如设置启动项、启动其他操作系统等。

UEFI Shell扩展命令:UEFI Shell提供了一系列的扩展命令,用于执行各种高级操作,例如加载驱动程序、访问文件系统、执行脚本等。这些命令通常用于在UEFI环境下进行更深层次的系统管理和调试。

UEFI网络堆栈命令:如果您的计算机支持UEFI网络启动,那么您可能会在UEFI环境下使用一些特定的命令来配置网络设置、启动网络引导等。

UEFI固件调试工具:一些高级的UEFI固件可能提供了专门的调试工具,用于分析和调试UEFI固件的运行时行为,例如跟踪引导过程、分析内存映像等。

这些是一些额外的UEFI相关命令和工具,它们可以用于在UEFI环境下进行更深层次的系统管理、固件开发和调试。具体可用的命令和工具可能会根据您的系统配置和需求而有所不同。

Unified Extensible Firmware Interface Forum