按下开机键,开始自检!

参考:

开机是很复杂的事情…

电路部分

当开机键按下的时候,本质上是发生了一次电平的变化,并向一个针脚(这个在台式机上针脚一般是要你连到开机键上的)发送信号,信号最后会传到一个控制芯片(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选择启动项,或者依赖gurb选择启动项,微软默认启动项可以死一死