BIOS 和 UEFI

计算机启动(上电)后,需要固件(firmware)程序来 初始化硬件 以及选择 需要启动的 Operating System

曾经最流行的固件(firmware)程序是 BIOS(Basic Input Output System),最近 BIOS 正在逐渐被 UEFI(Unified Extensible Firmware Interface)取代。在同一个计算机上,他们只能使用一个(互斥)

UEFI 设计包含安全启动特性(Secure Boot Feature),他可以确保 只有所有组建都进行过有效签名的 OS 才能启动过程中被加载 。此特性也可以禁用以启动未经签名的 OS.

BIOS 或者 UEFI 的主要工作是 初始化硬件并将计算机控制权移交给 Boot Loader ,之后 Boot Loader 会寻找并启动 Operating System.

BIOS 或者 UEFI 通常可以在计算机上电启动后进行配置,一般通过特定的按键(如 F1、F2、F12 等)进入设定界面。主要包含 2 部分内容

  • Bios/UEFI 配置工具 : 可以修改 BIOS/UEFI 设定,如启用/禁止某些功能
  • Boot Order : 修改启动顺序,如从特定设备(CD、DVD、USB 等)启动

BIOS

BIOS 是位于主板(motherboard)上的一个芯片,负责初始化 CPU(Central Processing Unit)、RAM(Random Access Memory)、PCIE Card(Peripheral Component Interconnect Express Card)和 Network Devices. BIOS 通电后后会立即执行 POST(Power-on self test),确保硬件(CPU、RAM、PCIE、NIC等)配置正确并可正常运行。

  • BIOS 仅支持运行于 16 位处理器模式下 ,这限制了任一时刻固件上运行的软件命令(Software Commands)的数量。
  • BIOS 为任务运行只分配 1M 内存
  • BIOS 运行中的接口和设备(Interfaces and Devices)只能按顺序初始化 ,可能会导致开机缓慢
  • BIOS 查找 MBR(Master Boot Record)以确定 OS 的位置并运行 Boot Loader 。MBR 只有 32-bit 的空间用于描述分区(Partitions)的信息,这限制了基于 BIOS 启动的系统,最多支持 4 个主分区(3 个主分区和 1 个逻辑分区),并且分区最大不能超过 2TB.

UEFI

UEFI 最初由 Intel 提出并实现,包括 GPT(Globally Unique Identifier Partition Table),是 UEFI 的一部分。

UEFI 是一个软件(标准)或者说更像是一个微型的系统,用于连接 计算机固件(Computer’s firmware)OS(Operating System) 。UEFI 最终会替代 BIOS 但是向后兼容 BIOS。

UEFI 的功能是通过安装在主板(motherboard)上的特殊固件(firmware)实现的,和 BIOS 一样,其在(生产)出厂之时就已经安装,它是计算机开机(上电)运行的 第一个程序执行和 BIOS 同样的自检(POST)流程,但是它提供了比 BIOS 更多的灵活性 。 UEFI 解决了 BIOS 面临的一些限制,如 最大分区BIOS 执行任务的时间

大多数现代化的计算机都已经能同时支持 BIOS 和 UEFI(二选一)。

UEFI 定义了一种新的 OS 和 计算机固件(platform firmware)交流的方式,相比于 BIOS 只能提供 OS 启动过程中必须的信息,UEFI 可以提供更多的特性,如安全启动等。

UEFI 将其初始化数据存放在一个 EFI 分区中,而不是存放在固件(Firmware)中,这个 EFI 分区位于 Nonvolatile Flash Memory ,UEFI 甚至可以在启动时从一个共享网络位置加载。

UEFI 使用比 MBR 更灵活的分区方案,即著名的 GPT(Globally Unique Identifier Partition Table),GPT 使用了 64-bit 用于保留分区表信息,支持多达 128 个分区,并支持系统识别并安装于超过 2TB 的分区之上。

UEFI 能在一个 EFI 系统分区中支持多个 OS,如 Windows OS loader 或者 Debian-based OS loaders,BIOS 只允许存在一个 Boot Loader.

UEFI 是可编程的(Programmable),其相当于一个轻量的 OS.

UEFI 的安全启动(Secure Boot)支持计算机在启动时对其硬件和系统完整性进行校验,可以防止黑客在系统启动时安装 rootkits 并获得系统控制权,Secure Boot 甚至支持授权用户(网络)远程定位问题。

UEFI 包含了一个平台相关(platform-related)的 数据表(data table) ,以及 可以被 OS Loader 调用的 Boot and Runtime Service Calls 。这些信息定义了为支持 UEFI ,固件(Firmwares)或者计算机硬件(Hardwares)应该实现的接口和数据结构(Interfaces and Structures)。

UEFI Firmware 需要从一个有 GPT 标签(分区表)并包含 EFI System Partition(EFI 分区)的硬盘(Disk)上启动

# parted -l
Model: Alibaba Cloud Elastic Block Storage (nvme)
Disk /dev/nvme0n1: 215GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 1049kB 2097kB 1049kB bios_grub
2 2097kB 212MB 210MB fat32 boot, esp
3 212MB 215GB 215GB ext4

# mount | grep efi
/dev/nvme0n1p2 on /boot/efi type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)

检查计算机 Firmware 使用的是 BIOS 还是 UEFI

Windows

要检查 Windows 系统运行的计算机使用 Firmware 的是 BIOS 还是 UEFI,可以使用 Windows 快捷键 Windows + R 搜索 msinfo32 并运行,在 系统摘要 中查看 BIOS Mode,如果显示 UEFI,则表示使用了 UEFI,如果显示 Legacy,表示使用 BIOS

Linux

Linux 中要检查系统是从 BIOS 还是 UEFI 启动,可以使用以下方法之一:

  • 检查 /sys/firmware/efi 目录 。在 UEFI 启动模式下,系统会加载 EFI 相关的文件系统。可以通过检查 /sys/firmware/efi 目录是否存在来判断系统的启动模式。

    # ls /sys/firmware/efi/
    config_table efivars fw_platform_size fw_vendor mok-variables runtime runtime-map systab vars
    • 如果目录存在并包含文件,说明系统是通过 UEFI 启动的。
    • 如果目录不存在,则说明系统是通过 BIOS 启动的。
  • 检查系统启动日志 。使用命令 dmesg | grep -Ei 'efi|bios' 或者 journalctl -k -b | grep -Ei 'efi|bios' 检查系统启动时是使用 BIOS 还是 UEFI。以下示例中,计算机使用 BIOS

    # dmesg | grep -Ei 'efi|bios'
    [ 0.000000] BIOS-provided physical RAM map:
    [ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
    [ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
    [ 0.000000] BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
    [ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000bffe9fff] usable
    [ 0.000000] BIOS-e820: [mem 0x00000000bffea000-0x00000000bfffffff] reserved
    [ 0.000000] BIOS-e820: [mem 0x00000000e0000000-0x00000000e03fffff] reserved
    [ 0.000000] BIOS-e820: [mem 0x00000000fffc0000-0x00000000ffffffff] reserved
    [ 0.000000] BIOS-e820: [mem 0x0000000100000000-0x00000004343fffff] usable
    [ 0.000000] BIOS-e820: [mem 0x0000000434400000-0x000000043fffffff] reserved
    [ 0.000000] SMBIOS 2.7 present.
    [ 0.000000] DMI: Amazon EC2 t3.xlarge/, BIOS 1.0 10/16/2017


    # journalctl -k -b | grep -Ei 'efi|bios'
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: BIOS-provided physical RAM map:
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: BIOS-e820: [mem 0x0000000000100000-0x00000000bffe9fff] usable
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: BIOS-e820: [mem 0x00000000bffea000-0x00000000bfffffff] reserved
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: BIOS-e820: [mem 0x00000000e0000000-0x00000000e03fffff] reserved
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: BIOS-e820: [mem 0x00000000fffc0000-0x00000000ffffffff] reserved
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: BIOS-e820: [mem 0x0000000100000000-0x00000004343fffff] usable
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: BIOS-e820: [mem 0x0000000434400000-0x000000043fffffff] reserved
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: SMBIOS 2.7 present.
    Oct 24 09:48:37 U-3TSDMAL9IVFAQ kernel: DMI: Amazon EC2 t3.xlarge/, BIOS 1.0 10/16/2017

    以下示例是使用 UEFI 启动的计算机系统

    # journalctl -k -b | grep -i efi
    Nov 01 17:11:21 Aliyun kernel: efi: EFI v2.70 by EDK II
    Nov 01 17:11:21 Aliyun kernel: efi: SMBIOS=0x7ebcc000 ACPI=0x7ebfa000 ACPI 2.0=0x7ebfa014 MEMATTR=0x7d6a9018 MOKvar=0x7d6e5000
    Nov 01 17:11:21 Aliyun kernel: clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645519600211568 ns
    Nov 01 17:11:21 Aliyun kernel: pci 0000:00:01.0: BAR 0: assigned to efifb
    Nov 01 17:11:21 Aliyun kernel: Registered efivars operations
    Nov 01 17:11:21 Aliyun kernel: efifb: probing for efifb
    Nov 01 17:11:21 Aliyun kernel: efifb: framebuffer at 0x90000000, using 1876k, total 1875k
    Nov 01 17:11:21 Aliyun kernel: efifb: mode is 800x600x32, linelength=3200, pages=1
    Nov 01 17:11:21 Aliyun kernel: efifb: scrolling: redraw
    Nov 01 17:11:21 Aliyun kernel: efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
    Nov 01 17:11:21 Aliyun kernel: fb0: EFI VGA frame buffer device
    Nov 01 17:11:21 Aliyun kernel: EFI Variables Facility v0.08 2004-May-17
    Nov 01 17:11:21 Aliyun kernel: integrity: Loading X.509 certificate: UEFI:MokListRT (MOKvar table)
    Nov 01 17:11:21 Aliyun systemd[1]: Starting Load Kernel Module efi_pstore...
    Nov 01 17:11:21 Aliyun kernel: pstore: Registered efi as persistent store backend
  • 使用 efibootmgr 命令efibootmgr 是用于管理 UEFI 启动项的工具。如果系统是通过 UEFI 启动的,并且 efibootmgr 已安装,则可以通过以下命令检查:

    # efibootmgr 
    BootCurrent: 0003
    Timeout: 0 seconds
    BootOrder: 0005,0000,0001,0002,0003,0004
    Boot0000* UiApp
    Boot0001* UEFI Floppy
    Boot0002* UEFI Floppy 2
    Boot0003* UEFI Alibaba Cloud Elastic Block Storage 2vchy3fzriapb9kgio2t 1
    Boot0004* EFI Internal Shell
    Boot0005* ubuntu

    # efibootmgr
    EFI variables are not supported on this system.

    • 如果命令输出了 UEFI 启动项信息,说明系统是通过 UEFI 启动的。
    • 如果出现错误消息,例如 EFI variables are not supported on this system ,则系统是通过 BIOS 启动的。
  • 查看分区表类型 。在 UEFI 启动模式下,通常使用 GPT 分区表,而在 BIOS 启动模式下则使用 MBR 分区表。可以使用 lsblkfdisk 命令检查分区表类型:

    # fdisk -l
    Disk /dev/nvme0n1: 80 GiB, 85899345920 bytes, 167772160 sectors
    Disk model: Amazon Elastic Block Store
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 4096 bytes / 4096 bytes
    Disklabel type: gpt
    Disk identifier: CB1F8618-4331-4D62-B8DB-E0F326987595

    Device Start End Sectors Size Type
    /dev/nvme0n1p1 227328 167772126 167544799 79.9G Linux filesystem
    /dev/nvme0n1p14 2048 10239 8192 4M BIOS boot
    /dev/nvme0n1p15 10240 227327 217088 106M EFI System

    # parted -l
    Model: Amazon Elastic Block Store (nvme)
    Disk /dev/nvme0n1: 85.9GB
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt
    Disk Flags:

    Number Start End Size File system Name Flags
    14 1049kB 5243kB 4194kB bios_grub
    15 5243kB 116MB 111MB fat32 boot, esp
    1 116MB 85.9GB 85.8GB ext4

    BIOS 启动的系统也可能会使用 GPT 格式的分区表,因此使用 GPT 分区表的不一定是通过 BIOS 启动 ,有些系统中可能同时存在使用 GPT 和 MBR 格式的分区表的硬盘。如:

    # parted -l
    Model: Amazon Elastic Block Store (nvme)
    Disk /dev/nvme0n1: 85.9GB
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt
    Disk Flags:

    Number Start End Size File system Name Flags
    14 1049kB 5243kB 4194kB bios_grub
    15 5243kB 116MB 111MB fat32 boot, esp
    1 116MB 85.9GB 85.8GB ext4


    Model: Amazon Elastic Block Store (nvme)
    Disk /dev/nvme1n1: 107GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    Disk Flags:

    Number Start End Size Type File system Flags
    1 1049kB 53.7GB 53.7GB primary ext4

    有 2 快盘,分别为 /dev/nvme0n1/dev/nvme1n1,分别使用 GPT 分区表和 MBR 分区表,系统是使用 BIOS 启动。

    除了使用以上命令外,也可以使用 grub-probe 或者 grub2-probe 命令检测启动分区对应的分区表类型

    # grub-probe -t drive /boot/grub/
    (hostdisk//dev/nvme0n1,gpt1)

    # grub2-probe -t drive /home/
    (hostdisk//dev/nvme0n1,msdos1)

    # 以下示例表示分区类型为 GPT
    # grub-probe -t gpt_parttype /boot/
    0fc63daf-8483-4772-8e79-3d69d8477de4

    # grub-probe -t msdos_parttype /boot/

    # 以下示例表示分区类型非 GPT
    # grub-probe -t gpt_parttype /home/

    # grub-probe -t msdos_parttype /home/
    83

Coreboot

BIOS 的除 UEFI 之外的另一个替代者是 Coreboot,之前叫 LinuxBIOS,它是个基于社区的项目,主要有 Google 主导,它宣传有比 UEFI 更好的性能和安全性,Chromebook 设备从出现之初就使用了 Coreboot 替代了 BIOS.

参考链接

Linux Bible v10
UEFI