Unified Extensible Firmware Interface (简体中文)

From ArchWiki
Jump to: navigation, search
Summary
An overview of the Unified Extensible Firmware Interface.
Overview
为了启动 Arch Linux,一个与 Linux 兼容的启动引导程序,如 GRUB, GRUB2, LILO, 或者 Syslinux 必须被安装到主引导记录(MBR), 或者GUID 分区表(GPT)。启动引导程序的任务是初始化 Arch 启动过程,然后加载内核以及初始化内存盘
Related
GUID Partition Table
Master Boot Record
Arch Boot Process
翻译状态: 本文是英文页面 Unified_Extensible_Firmware_Interface翻译,最后翻译时间:2012-12-08,点击这里可以查看翻译后英文页面的改动。
Tango-preferences-desktop-locale.png 本页面或部分需要翻译,部分内容可能已经与英文文章脱节。如果您希望贡献翻译,请访问简体中文翻译组
附注: please use the first argument of the template to provide more detailed indications.
Tango-preferences-desktop-locale.png

统一可扩展固件界面(Unified Extensible Firmware Interface) (或简称为UEFI) 是一种新型固件,最初是由Intel设计(当时称为EFI),主要用于其基于安腾架构的系统。 它介绍了一种新的启动系统的方式,该方式有别于传统BIOS系统所使用的“MBR启动代码”。它起始于Intel EFI的1.x版本,之后被称作UEFI论坛的一群公司接管了它的开发工作。从此,它被称为统一的EFI,其版本始于2.0。自2013年7月24号起,UEFI规格2.4(在2013年7月11日发布)是最新的一个版本。

Note: 除非特别指定为EFI 1.x,否者EFI以及UEFI这两者是可以互换使用的,均是指UEFI 2.x固件。同样,除非明确指出,以下的说明是通用的,不过有些可能在 Mac 系统上不工作或者不一样。苹果的 EFI 实现既不是EFI 1.x 也不是 UEFI 2.x 而是一种混合。这类固件不归于任何一个 UEFI 版本,因此也不是标准的 UEFI 固件。

在理解 UEFI 之前,最好先理解在它之前的(BIOS)系统是如何启动的。这在随后的小节有解释。

Contents

BIOS

BIOS 又称 基本输入输出系统,是系统打开以后,最先被执行的程序(固件)。大多数时候它被保存在属于自己的一个flash存储器中,位于主板上,和系统的存储空间是独立的。

BIOS下的启动过程

  1. 当系统按下电源开关 - 系统加电自检,或POST过程。
  2. 在 POST 之后,BIOS 初始化必要的系统硬件,用于引导(boot)。(硬盘,键盘控制器之类)
  3. BIOS 执行第一块磁盘上最开始的440字节(MBR引导代码区域)。
  4. MBR 引导代码从 BIOS 接过控制权,启动它的下一阶段代码(如果有的话)(一般是引导程序(bootloader)代码)
  5. 启动的(第2阶段)代码(真正的引导程序)读取自己的支持和配置文件。
  6. 按照配置文件,引导程序加载 内核(kernel) 和 initramfs 到系统内存(RAM)中,然后启动内核。

BIOS中的多重引导

因为被塞进启动代码区域的440字节小程序能做的事情很少,所以使用 BIOS 做多重启动需要有多重引导能力的引导程序(多重引导指的是引导多个操作系统,不是GRUB开发者指的用于引导内核的多种引导格式)。 所以一般通用的引导程序,像GRUBSyslinuxLILO 能被BIOS装载,然后它再用 chain-loading 去装载一个操作系统,或者直接装载内核。

UEFI

UEFI 既能读取分区表也能识别文件系统。因为它不像 BIOS 系统要受限于440字节的启动代码限制(MBR引导代码)。UEFI 完全不使用MBR启动代码。

常用的 UEFI 固件既支持 MBR 也支持 GPT 分区表。苹果公司基于英特尔 CPU 的 MAC 系列的 EFI 除了支持 MBR 和 GPT 分区表外,还支持苹果公司分区映射。绝大部分的 UEFI 固件可以访问 FAT12(软盘)、 FAT16 和 FAT32 文件系统,在HDD以及符合 ISO9660(和 UDF) 规范的 CD/DVD中。Apple-Intel Mac 还可以访问 HFS/HFS+ 文件系统。

UEFI 不加载任何 MBR 的引导代码,无论其是否存在。代之以使用一个特殊的分区,该分区在分区表中称做“EFI系统分区”,其中存放固件加载所需的文件。每个设备提供者都可以把他们的文件存放在 <EFI 系统分区>/EFI/<提供者名称>/ 这个文件夹中,并由固件或其外壳程序(UEFI shell)加载引导程序。EFI 系统分区一般是 FAT32 格式。

在 UEFI 模式下,每一个程序,无论它是一个操作系统引导器还是一个工具程序(比如内存测试工具)抑或是一个独立于操作系统的系统恢复工具,它们都应该是 EFI 固件架构下的一个应用级程序,对应于EFI固件的位数/架构。大部分 UEFI 固件,包括最近的苹果 Mac,都使用 x86_64 EFI 固件。仅知的使用 IA32(32-bit) EFI 的设备是旧的(2008年以前)的苹果 Mac,已知一些最近的 Intel Cloverfield 超级本,以及一些旧的 Inter 服务器工作在 Intel EFI 1.10固件上。

x86_64 EFI 固件不支持加载32位的 EFI 应用(不像 x86_64 的 Linux 和 Windows 能支持)。因此,UEFI 应用程序必须被编译为对应架构的版本。

UEFI 引导过程

  1. 系统开机 - 上电自检(Power On Self Test 或 POST)。
  2. UEFI 固件被加载。固件初始化启动要用的硬件。
  3. 固件读取其引导管理器以确定从何处(比如,从哪个硬盘及分区)加载哪个 UEFI 应用。
  4. 固件按照引导管理器中的启动项目,加载UEFI 应用。
  5. 已启动的 UEFI 应用还可以启动其他应用(对应于 UEFI shell 或 rEFInd 之类的引导管理器的情况)或者启动内核及initramfs(对应于GRUB之类引导器的情况),这取决于 UEFI 应用的配置。
Note: 在有些 UEFI 系统中,唯一可行的启动时(如果应用没有在 UEFI 启动菜单定制条目的话)加载 UEFI 应用的方法是把它放在此固定位置:<EFI SYSTEM PARTITION>/EFI/boot/bootx64.efi (对于 64 位的 x86 系统)

UEFI 的多重引导

因为每个操作系统或者提供者都可以维护自己的 EFI 系统分区中的文件,同时不影响别人,所以 UEFI 的多重启动只是简单的运行不同的UEFI 程序,对应于特定操作系统的引导程序。这避免了依赖 chainloading 机制(通过一个引导程序加载另一个引导程序,来切换操作系统)。

启动 Microsoft Windows

Linux Windows x86_64 UEFI-GPT Multiboot

Windows Vista (SP1+) and 7 pr 8 x86_64 versions support booting natively using UEFI firmware. But for this they need GPT partitioning of the disk used for UEFI booting. Windows x86_64 versions support either UEFI-GPT booting or BIOS-MBR booting. Windows 32-bit versions support only BIOS-MBR booting. Follow the instructions provided in the forum link given in the references sections as to how to do this. See http://support.microsoft.com/default.aspx?scid=kb;EN-US;2581408 for more info.

This limitation does not exist in Linux Kernel but rather depends on the bootloader used. For the sake of Windows UEFI booting, the Linux bootloader used should also be installed in UEFI-GPT mode if booting from the same disk.

检测 UEFI 固件架构版本

非苹果公司 MAC 系列的 UEFI 系统,都是 x86_64 UEFI 2.x 版的固件。

已知的 x86_64 UEFI 2.x版固件有:Phoenix SecureCore Tiano、AMI Aptio、Insyde H2O。

已知使用这些固件的系统有:华硕公司 EZ 型号的 BIOS(用于 Sandy Bridge P67 和 H67 主板上);微星公司的 ClickBIOS; 惠普公司的 EliteBooks;索尼公司的 Vaio Z 系列;以及众多英特尔公司的服务器和桌面系统主板

2008年以前的 Macs 大都使用 i386-efi 固件, 2008年以后大都使用 x86_64-efi 。有能力运行 Mac OS X Snow Leopard 64-bit 内核的 Macs 都是 x86_64 EFI 1.x 版的固件。

在 Mac OS 下输入以下命令可以找出该 Mac 的 efi 固件:

ioreg -l -p IODeviceTree | grep firmware-abi

如果命令返回 EFI32 则对应的是 i386 EFI 1.x 版本的固件,返回 EFI64 对应的则是 x86_64 EFI 1.x 版的固件. Macs 没有 UEFI 2.x 固件,Apple's EFI 的实现也不完全跟 UEFI 标准兼容。

Linux 内核对 UEFI 的支持

Linux 内核中有关 UEFI 的配置选项

内核中必需的 UEFI 选项为:

CONFIG_EFI=y
CONFIG_EFI_STUB=y
CONFIG_RELOCATABLE=y
CONFIG_FB_EFI=y
CONFIG_FRAMEBUFFER_CONSOLE=y

UEFI 运行时变量/服务支持 - ‘efivars’内核模块。 这个选项对于“efibootmgr”之类的 UEFI 运行时管理工具而言十分重要

CONFIG_EFI_VARS=m
Note: 在 Arch Linux 的 core 和 testing 中,这个选项被编译为模块
Note: 为使 Linux 可访问 UEFI 运行时服务,UEFI 固件处理器架构与 Linux 内核处理器架构必须匹配。This is independent of the bootloader used.
Note: 如果UEFI 固件处理器架构与 Linux 内核处理器架构不同,则必须使用“noefi”内核参数,以避免 kernel panic 并正常完成引导过程。 “noefi”内核参数告诉内核不要访问 UEFI 运行时服务。

GUID 分区表GPT 选项 - 强制支持 UEFI

CONFIG_EFI_PARTITION=y
Note: 以 UEFI 引导 Linux 时,所有上述选项都是必须的,Archlinux 官方源中的内核均已打开

参见 http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob_plain;f=Documentation/x86/x86_64/uefi.txt;hb=HEAD .

UEFI 变量支持

UEFI 通过定义变量使操作系统可以与固件交互。 UEFI 的 Boot 类变量用于引导程序和操作系统早期引导过程。UEFI 的运行时类变量则允许操作系统管理固件的特定配置(如:UEFI 引导管理器或 UEFI 安全引导协议的密钥等)

Note: 如果系统以 BIOS 模式引导,或者 UEFI 支持的处理器架构与内核支持的处理器架构不匹配(例如:x86_64 UEFI + x86 32位内核 或相反),针对“efivars”内核模块和“efibootmgr”步骤的操作将无效。其它步骤(例如:upto setting up <UEFISYS>/EFI/arch/refind/{refindx64.efi,refind.conf} )即使在 BIOS/常规 引导模式下也可以完成

对 UEFI 运行时服务的访问由内核的“efivars”模块提供,通过打开内核的CONFIG_EFI_VAR=m选项实现。该模块将加载/sys/firmware/efi/vars目录下的变量。检查系统是否以 UEFI 模式引导的一个办法就是加载“efivars”内核模块,并检查/sys/firmware/efi/vars 目录中的内容是否类似下面这样:

输出范例 (x86_64-UEFI 2.3.1 与 x86_64 内核):

# ls -1 /sys/firmware/efi/vars/
Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c/
BootCurrent-8be4df61-93ca-11d2-aa0d-00e098032b8c/
BootOptionSupport-8be4df61-93ca-11d2-aa0d-00e098032b8c/
BootOrder-8be4df61-93ca-11d2-aa0d-00e098032b8c/
ConIn-8be4df61-93ca-11d2-aa0d-00e098032b8c/
ConInDev-8be4df61-93ca-11d2-aa0d-00e098032b8c/
ConOut-8be4df61-93ca-11d2-aa0d-00e098032b8c/
ConOutDev-8be4df61-93ca-11d2-aa0d-00e098032b8c/
ErrOutDev-8be4df61-93ca-11d2-aa0d-00e098032b8c/
Lang-8be4df61-93ca-11d2-aa0d-00e098032b8c/
LangCodes-8be4df61-93ca-11d2-aa0d-00e098032b8c/
MTC-eb704011-1402-11d3-8e77-00a0c969723b/
MemoryTypeInformation-4c19049f-4137-4dd3-9c10-8b97a83ffdfa/
PlatformLang-8be4df61-93ca-11d2-aa0d-00e098032b8c/
PlatformLangCodes-8be4df61-93ca-11d2-aa0d-00e098032b8c/
RTC-378d7b65-8da9-4773-b6e4-a47826a833e1/
del_var
new_var

如果在引导菜单中使用了“noefi”内核参数,UEFI 运行时变量对操作系统将不可见。这个参数将通知操作系统完全忽略 UEFI 运行时服务。

用户空间工具

有几个访问和编辑 UEFI 变量的工具如下:

  1. efibootmgr - 用于创建/编辑 UEFI 引导管理器中的引导项 - 见efibootmgrefibootmgr-git
  2. uefivars - 转储 UEFI 变量 - 见uefivars-git - 需用到 efibootmgr 库
  3. Ubuntu的固件测试套件(fwts)- 见fwts-git - uefidump 命令 - fwts uefidump

非Mac UEFI 系统

efibootmgr

警告: 如果在苹果公司MAC系统上使用efibootmgr将使其变“砖”,你只能重写主板 ROM 才能修复。There have been bug reports regarding this in Ubuntu/Launchpad bug tracker. Use bless command alone in case of Macs. Experimental "bless" utility for Linux by Fedora developers - mactel-boot.
Note: efibootmgr 命令仅当以 UEFI 模式引导以后才是可用的。概因其必须访问 UEFI 运行时变量,而后者仅当以 UEFI 模式引导时(同时“noefi”内核参数也没有使用的情况下)才是可访问的。否则将显示:Fatal: Couldn't open either sysfs or procfs directories for accessing EFI variables

Initially the user may be required to manually launch the boot-loader from the firmware itself (using maybe the UEFI Shell) if the UEFI boot-loader was installed when the system is booted in BIOS mode. Then efibootmgr should be run to make the UEFI boot-loader entry as the default entry in the UEFI Boot Manager.

To use efibootmgr, first load the 'efivars' kernel module:

# modprobe efivars

If you get no such device found error for this command, that means you have not booted in UEFI mode or due to some reason the kernel is unable to access UEFI Runtime Variables (noefi?).

Verify whether there are files in /sys/firmware/efi/vars/ directory. This directory and its contents are created by "efivars" kernel module and it will exist only if you have booted in UEFI mode, without the "noefi" kernel parameter.

If /sys/firmware/efi/vars/ directory is empty or does not exist, then efibootmgr command will not work. If you are unable to make the ISO/CD/DVD/USB boot in UEFI mode try #Create_UEFI_bootable_USB_from_ISO.

Note: The below commands use gummiboot boot-loader as example.

Assume the boot-loader file to be launched is /boot/efi/EFI/gummiboot/gummibootx64.efi. /boot/efi/EFI/gummiboot/gummibootx64.efi can be split up as /boot/efi and /EFI/gummiboot/gummibootx64.efi, wherein /boot/efi is the mountpoint of the UEFI System Partition, which is assumed to be /dev/sdXY (here X and Y are just placeholders for the actual values - eg:- in /dev/sda1 , X=a Y=1).

To determine the actual device path for the UEFI System Partition (should be in the form /dev/sdXY), try :

# findmnt /boot/efi
TARGET SOURCE  FSTYPE OPTIONS
/boot/efi  /dev/sdXY  vfat         rw,flush,tz=UTC

Then create the boot entry using efibootmgr as follows :

# efibootmgr -c -g -d /dev/sdX -p Y -w -L "Gummiboot" -l '\EFI\gummiboot\gummibootx64.efi'

In the above command /boot/efi/EFI/gummiboot/gummibootx64.efi translates to /boot/efi and /EFI/gummiboot/gummibootx64.efi which in turn translate to drive /dev/sdX -> partition Y -> file /EFI/gummiboot/gummibootx64.efi.

UEFI uses backward slash as path separator (similar to Windows paths).

The 'label' is the name of the menu entry shown in the UEFI boot menu. This name is user's choice and does not affect the booting of the system. More info can be obtained from efibootmgr GIT README .

FAT32 filesystem is case-insensitive since it does not use UTF-8 encoding by default. In that case the firmware uses capital 'EFI' instead of small 'efi', therefore using \EFI\gummiboot\gummibootx64.efi or \efi\gummiboot\gummibootx64.efi does not matter (this will change if the filesystem encoding is UTF-8).

Linux Bootloaders for UEFI

See UEFI Bootloaders.

Create an UEFI System Partition in Linux

Note: The UEFISYS partition can be of any size supported by FAT32 filesystem. According to Microsoft Documentation, the minimum partition/volume size for FAT32 is 512 MiB. Therefore it is recommended for UEFISYS partition to be atleast 512 MiB. Higher partition sizes are fine, especially if you use multiple UEFI bootloaders, or multiple OSes booting via UEFI, so that there is enough space to hold all the related files. If you are using Linux EFISTUB booting, then you need to make sure there is adequate space available for keeping the Kernel and Initramfs files in the UEFISYS partition.

For GPT partitioned disks

Two choices:

  • Using GNU Parted/GParted: Create a FAT32 partition. Set "boot" flag on for that partition.
  • Using GPT fdisk (aka gdisk): Create a partition with gdisk type code "EF00". Then format that partition as FAT32 using mkfs.vfat -F32 /dev/<THAT_PARTITION>
Note: Setting "boot" flag in parted in a MBR partition marks that partition as active, while the same "boot" flag in a GPT partition marks that partition as "UEFI System Partition".
Warning: Do not use util-linux fdisk, cfdisk or sfdisk to change the type codes in a GPT disk. Similarly do not use gptfdisk gdisk, cgdisk or sgdisk on a MBR disk, it will be automatically converted to GPT (no data loss will occur, but the system will fail to boot).

For MBR partitioned disks

Two choices:

  • Using GNU Parted/GParted: Create FAT32 partition. Change the type code of that partition to 0xEF using fdisk, cfdisk or sfdisk.
  • Using fdisk: Create a partition with partition type 0xEF and format it as FAT32 using mkfs.vfat -F32 /dev/<THAT_PARTITION>
Note: It is recommended to use always GPT for UEFI boot as some UEFI firmwares do not allow UEFI-MBR boot.

UEFI Shell

The UEFI Shell is a shell/terminal for the firmware which allows launching uefi applications which include uefi bootloaders. Apart from that, the shell can also be used to obtain various other information about the system or the firmware like memory map (memmap), modifying boot manager variables (bcfg), running partitioning programs (diskpart), loading uefi drivers, editing text files (edit), hexedit etc.

UEFI Shell download links

You can download a BSD licensed UEFI Shell from Intel's Tianocore UDK/EDK2 Sourceforge.net project.

Shell 2.0 works only in UEFI 2.3+ systems and is recommended over Shell 1.0 in those systems. Shell 1.0 should work in all UEFI systems irrespective of the spec. version the firmware follows. More info at ShellPkg and this mail

Launching UEFI Shell

Few Asus and other AMI Aptio x86_64 UEFI firmware based motherboards (from Sandy Bridge onwards) provide an option called "Launch EFI Shell from filesystem device" . For those motherboards, download the x86_64 UEFI Shell and copy it to your UEFI SYSTEM PARTITION as <UEFI_SYSTEM_PARTITION>/shellx64.efi (mostly /boot/efi/shellx64.efi) .

Systems with Phoenix SecureCore Tiano UEFI firmware are known to have embedded UEFI Shell which can be launched using either F6, F11 or F12 key.

Note: If you are unable to launch UEFI Shell from the firmware directly using any of the above mentioned methods, create a FAT32 USB pen drive with Shell.efi copied as (USB)/efi/boot/bootx64.efi . This USB should come up in the firmware boot menu. Launching this option will launch the UEFI Shell for you.

Important UEFI Shell Commands

More info at http://software.intel.com/en-us/articles/efi-shells-and-scripting/

bcfg

BCFG command is used to modify the UEFI NVRAM entries, which allow the user to change the boot entries or driver options. This command is described in detail in page 83 (Section 5.3) of "UEFI Shell Specification 2.0" pdf document.

Note: Users are recommended to try bcfg only if efibootmgr fails to create working boot entries in their system.
Note: UEFI Shell 1.0 does not support bcfg command.

To dump a list of current boot entries -

Shell> bcfg boot dump -v

To add a boot menu entry for rEFInd (for example) as 4th (numbering starts from zero) option in the boot menu

Shell> bcfg boot add 3 fs0:\EFI\arch\refind\refindx64.efi "Arch Linux (rEFInd)"

where fs0: is the mapping corresponding to the UEFI System Partition and \EFI\arch\refind\refindx64.efi is the file to be launched.

To remove the 4th boot option

Shell> bcfg boot rm 3

To move the boot option #3 to #0 (i.e. 1st or the default entry in the UEFI Boot menu)

Shell> bcfg boot mv 3 0

For bcfg help text

Shell> help bcfg -v -b

or

Shell> bcfg -? -v -b

edit

EDIT command provides a basic text editor with an interface similar to nano text editor, but slightly less functional. It handles UTF-8 encoding and takes care or LF vs CRLF line endings.

To edit, for example rEFInd's refind.conf in the UEFI System Partition (fs0: in the firmware)

Shell> fs0:
FS0:\> cd \EFI\arch\refind
FS0:\EFI\arch\refind\> edit refind.conf

Hardware Compatibility

Main page HCL/Firmwares/UEFI


从 ISO 文件创建一个支持 UEFI 的启动盘

提示: 下面的说明是专为 Archiso /官方介质; Archboot preparation is identical, sans the filesystem label requirement

Due to shortcomings in Archiso, it is necessary to rebuild installation media in order for it to be UEFI-bootable.

Creating a MBR partition table and FAT32 filesystem should provide the most compatibility with incomplete/flakey UEFI implementations, and you need not worry about partition type.

Mount installation media, and create FAT filesystem using the label used in the Archiso configuration.

# mkdir -p /mnt/{usb,iso}
# mount -o loop,ro archlinux-2012.12.01-dual.iso /mnt/iso
# awk -F"archisolabel=" 'NF>1{sub(/ .*/,"",$2);print $2}' /mnt/iso/loader/entries/archiso-x86_64.conf | xargs mkfs.vfat /dev/sdb1 -n

Mount the newly created FAT filesystem, and copy the contents of the installation media to the USB media.

# mount /dev/sdb1 /mnt/usb
# cp -r /mnt/iso/* /mnt/usb
# umount /mnt/{usb,iso}
# sync

Remove UEFI boot support from ISO

Warning: In the event that UEFI+isohybrid-MBR really causes problems, it would be better to just UEFI boot using the USB stick instructions in the previous section

Most of the 32-bit EFI Macs and some 64-bit EFI Macs refuse to boot from a UEFI(X64)+BIOS bootable CD/DVD. If one wishes to proceed with the installation using optical media, it might be necessary to remove UEFI support first.

Mount the official installation media and obtain the archisolabel as shown in the previous section.

Rebuild the ISO using xorriso from libisoburn:

$ xorriso -as mkisofs -iso-level 3 \
    -full-iso9660-filenames\
    -volid "ARCH_201212" \
    -appid "Arch Linux CD" \
    -publisher "Arch Linux <https://www.archlinux.org>" \
    -preparer "prepared like a BAWSE" \
    -eltorito-boot isolinux/isolinux.bin \
    -eltorito-catalog isolinux/boot.cat \
    -no-emul-boot -boot-load-size 4 -boot-info-table \
    -isohybrid-mbr "/mnt/iso/isolinux/isohdpfx.bin" \
    -output "~/archiso.iso" "/mnt/iso/"

Burn ~/archiso.iso to optical media and proceed with installation normally.

See also