计算机启动过程
按下开机键,开始自检!
开机是很复杂的事情...
电路部分
当开机键按下的时候,本质上是发生了一次电平的变化,并向一个针脚(这个在台式机上针脚一般是要你连到开机键上的)发送信号,信号最后会传到一个控制芯片(Embedded Controller)上。
这个芯片会和供电电路通信,然后由电源控制单元(Power Supply Unit)开始向全计算机供电。
供电单元启动之后,会向 CPU、内存、南桥北桥、外设、存储设备供电。
这当中会涉及很多的时序的数字信号通信,感兴趣的同学可以进一步去了解。
Boot
这里分成 BIOS 和 UEFI 两种讲,现代系统基本都已经使用了 UEFI(当然也有其他的一些方式,可能包括 u-boot、coreboot 等)。
提要: BIOS 和 UEFI 的关系:这是两种固件系统,并没有 UEFI BIOS 的说法,UEFI 不是 BIOS 更不是 BIOS 的扩展。BIOS 在有些现代的 UEFI 当中会被称为 legacy 模式或者 CSM 兼容模式。
BIOS
Basic Input Output System
BIOS 是一个封闭的、没有明确标准的启动方式,依靠 MBR 分区表。
功能
BIOS 用于测试检查硬件、自检、选择启动设备,其本质是一个存有基本系统的 ROM,通过一步一步的交接最终把运行权交到系统手上。
加载
当 CPU 复位后,指令指针会复位然后指向 ROM 中的程序位置开始运行。此时的 CPU 处在实模式,这是一种继承自 8086 的运行模式(第一代 CPU 的含金量)。
BIOS 此时会做一些简单的检查工作,叫做自检(POST)。
当 ROM 中的 BIOS 代码处理结束过后会运行选择的启动盘,由启动盘中的程序进行下一步操作。
系统引导
这是软件系统提供的东西了,boot loader 做的事情就是运行系统内核(kernel),并把内存模式从实模式转换到保护模式(实模式功能有限,在内存寻址上并不能满足现代操作系统)。
因为 boot loader 是系统定制的,所以有很多种,这里就不列举了。
MBR 块当中的 boot loader 被加载到内存里后,依靠 MBR 指定的系统分区,随后再把需要引导的分区的卷引导记录(VBR)读取到内存并运行,最后运行内核,接下来的事情就是系统的驱动和用户界面运行。
UEFI
UEFI 是一个开放的、通用的固件标准,依靠 GPT 分区表。
Why
由于 BIOS 是没有明确标准的,为了统一和简化开发,搞出了 UEFI。他们两个的启动原理是不一样的。UEFI 可以兼容 BIOS 启动方式并不代表他是 BIOS 的扩展,而是他用 BIOS 风格启动了程序。而且,BIOS 并没有在固件层上提供一个可以选择启动方式的接口。
EFI 可执行文件: 一种规范的可执行文件,可以被 UEFI 执行。
安全验证 SEC
这一段会做一些安全上的事情不要问我可信的根是什么,我不知道,他会初始化一些缓存来当作内存使用,从而允许一些高级语言(比如 C)运行,然后把传一些参数给下一个阶段。
前期初始化 PEI
此时会初始化一些硬件设备,包括内存、CPU。
驱动执行环境 DXE
此时内存完全可以使用,此时会继续初始化剩下的东西,包括硬盘、PCI、USB 等。
加载操作系统前 TSL
此时,我们进入系统启动的环节,系统启动交到了启动管理器手上(就是 grub.efi 或者 bootmgr.efi),这一段运行结束之后进入系统。
系统运行 RT
此时就是操作系统运行。
灾难备份或关机 AL
如果遇到灾难性错误,固件应当提供恢复机制,但是规范协议貌似没有规定如何实现。
一些补充
关于安全启动
UEFI 引入了安全启动功能。
安全启动并不是一个坏东西,一个只需要运行一个系统的用户用这个东西可能会提高系统安全性(虽然用 bootloader 搞病毒实属是有点刁钻了)。整个过程是很复杂的你知道的,信息安全上的东西。简单来说,就是对将要启动的 EFI 可执行文件进行验证,如果他的签名是合法(受认证)的,那么就开始运行。
关于 ESP
这个分区里面存着 efi 文件和内核,我们原则上有一个原生的 efi 启动项,x86-64 上是 \EFI\BOOT\BOOTx64.EFI,此启动管理器将会根据一些设置来启动对应的其他 EFI 文件。
但是这样导致了混乱。按道理在 UEFI 的用户管理界面下,应当允许用户选择应该启动哪个启动项(不仅仅是哪个盘,而且应该包括哪个盘下面的哪个系统)。结果是大部分的 UEFI 做的都比较混乱,大部分是不能实现我们需要的多系统启动的要求的。
微软之恶
虽然有一篇参考文章的作者在为微软在 UEFI 方面上辩护,但是微软仍然做了很多恶。
他做的事情包括但不限于:
- 每次更新刷新 UEFI 默认启动项
- 联合固件厂商改变默认 efi 文件
- 偷摸通用 efi 文件
- 不允许 bootmgr.efi 引导非 win 系统
在 UEFI 下装多系统的建议
直接多硬盘,保证可以从 UEFI 选择启动项,或者依赖 grub 选择启动项。微软默认启动项可以死一死
参考:
- https://ruanyifeng.com/blog/2013/02/booting.html
- https://www.runoob.com/linux/linux-system-boot.html
- https://learn.microsoft.com/en-us/windows-hardware/drivers/bringup/boot-and-uefi
- UEFI官网
- 微软安全启动认证要求
- 较权威的解读
- 上面内容的翻译
- https://tech.hqew.com/news_1107232
- https://www.cnblogs.com/anywherego/p/17960904
- https://zhuanlan.zhihu.com/p/483888207