BIOS
电脑power on和start up有两种方式:传统的BIOS-MBR方法或者新的UEFI-GPT方法。这篇文章总结了传统BIOS电脑load操作系统的过程,包含了基本的BIOS,MBR和bootsector的内容。
1 BIOS/MBR启动概要
所有标准的电脑和操作系统启动的过程如下:
boot process被分为这几个主要功能模块,每一个都是一个完全分离的子系统。根据你的硬件和操作系统,每个模块的实现都可能有很大的不同,但是它们遵循的基本规则是一样的。
2 Boot Process的组成部分
2.1 BIOS
BIOS 是硬件和软件的第一次碰触,boot 是从这里开始的。 BIOS的代码写在你PC的主板的flash memory中,并且代码和你的硬件相关。BIOS是boot loader与OS kernel和硬件通信,并控制硬件的接口。
当你按下电源按钮时,每个相关电脑元件都接受到电流并进入initial 状态。简单的元件,如RAM和PSU通过逻辑电路(与或门等)接入,而复杂的元件,如显卡,则通过自己的微控制器来控制硬件、与电脑的其他部分交互。
2.1.1 POST 过程
当你的电脑通电后,BIOS开始运行POST(Power-On Self Test)。 它会将电脑各个部件链接、按要求与它们通信、video display接受basic VGA并显示在屏幕上、初始化memory bank、使CPU能访问所有硬件。它会检测连接的硬件、识别并map对连接的硬盘的访问。在较新的主板上的BIOS能够检测USB并使你能够通过USB启动。
在POST过程中会执行一些快速的测试来检测是否有不兼容硬件、未连接设备等错误。BIOS会将这些错误信息显示出来,如:键盘错误,mismatched/unrecognized memory。这时,大部分的BIOS工作就已经完成了。BIOS几乎已经准备好进行下一阶段的boot process。唯一剩余的是运行“Add-On ROMs”:一些连接主板的硬件需要用户的交互才能完成初始化。BIOS将对电脑的控制交给这些硬件,如显卡,RAID控制器。当你完成这些设置后,它们将控制权交还给BIOS。这时电脑进入了基本的可用状态。
2.1.2 BIOS Boot Handoff
当完成对基本输入输出设备的设置后,BIOS进入掌控电脑的最后阶段。此时你可以选择快速按某些键来进入BIOS设置页面,在该页面来进行硬件设置和启动控制。如果没有按键,则BIOS使用默认设置,并开始真正执行“booting”的第一步。
之前提到,BIOS会识别并map(映射)连接的硬盘,这时BIOS会从第一个硬盘中load一个很小的程序到内存中,并告诉CPU去执行该程序,同时移交对电脑的控制并结束自己在电脑启动中的角色。这个能在BIOS设置页面设置的硬盘被称为“the boot device”/"startup device“/"drive 0"。
2.2 The Boot Device
无论你设置BIOS从本地硬盘启动,还是从USB启动,BIOS的移交顺序都是一样的。当BIOS 的POST和AddOn ROM procedures完成后,BIOS都会从被选择boot device中读取前512字节,即MBR(Master Boot Record)。
2.3 MBR
MBR是基于BIOS的启动中,软件方面,第一个也是最重要的部分。每个硬盘都有MBR,它包含了一些重要信息。
2.3.1分区表(The Partition Table)
第一个也是最重要的是分区表。它是一个硬盘上分区的索引。每个硬盘最多有四个分区。没有分区表(如软盘),则这个硬盘只能有一个分区,意味着你无法在一个硬盘里有多个文件系统(filesystem),从而意味着你无法在同一个硬盘中安装window和linux系统等等。
2.3.2 Bootstrap Code
MBR中还包含了重要的、被称为bootstrap code的代码。MBR的512字节中前440字节(不同操作系统和平台有区别)能包含任何代码,BIOS会加载并执行其中代码,启动boot loader。440字节非常小,无法用来从硬盘中启动OS kernel。
它只能用来去从硬盘中寻找另一个文件并加载它,从而来实现真正的boot过程。因此,bootstrap code被称为第一阶段bootloader(“stage one bootloader”)。依据不同的操作系统,bootstrap code寻找第二阶段bootloader的位置会有所不同。在Windows中,第一阶段bootloader会在MBR分区表中找被标记为“active”(即“bootable”)的分区。在该分区的开始(bootsector)就包含了下一部分的启动程序。在一个正确的MBR硬盘里,在同一时间只有一个分区会被标记为“active”。
所以在MBR中的bootstrap code功能非常简单, 就是从分区表中寻找active的分区,并将该分区bootsector中的程序加载到内存中,作为启动链中下一个环节,使CPU能够运行它。依据运行的OS的不同,bootstrap code可能寻找一个写死的分区,而非标记为active的分区,并且分区中boot sector的偏移(offset)也可能会不同。由于旧版兼容问题,MBR会加载active分区的第一个sector,即又一个512字节。
2.3.3 Boot 签名 (Boot Signature)
在MBR最后两位,是boot signature,被BIOS用来判断被选中的启动盘是否bootable。含有有效bootstrap code的硬盘,MBR最后两位应该是0x55 0xAA。如果最后两位不对,则BIOS会回去从启动顺序表中(在BIOS setup 中设置)的下一个boot device启动。如果没有可启动盘,则抛出“No boot device is available” 或者“Reboot and select proper boot device.” 错误。
2.4 分区启动扇区(The Partition Boot Sector)
MBR中bootstrap code会从active分区的开始加载一些字节。分区的具体分布会根据filesystem的不同而有区别。但大体如下:
1. 一个JMP(jump)指令,相当于goto.
2. 文件系统头。包含该文件系统的重要信息
3. 另外一部分bootstrap code,包含boot loader进程的下一阶段
4. 扇区结束标记(An end-of-sector marker)
这些都储存在分区的第一扇区(sector)中,一般来说共251字节。MBR会加载这512字节到内存,并让CPU运行它们。CPU会根据JMP指令跳转到分区扇区中的bootstrap code并运行该代码。由于空间非常小,往往该段代码最后会指向此分区中的下一个扇区,直到有足够的空间来完成这一阶段的bootloader。
2.4.1 The second-stage bootloader (第二阶段bootloader)
第二阶段bootloader存在分区bootsector的bootstrap code中,并引出bootloader进程的下一阶段:寻找在该分区中储存的一个普通文件,并告诉CPU去执行它,从而开始启动程序的最后一部分。
不像MBR中bootstrap segments或者分区的bootsector,启动进程的下一步是一个存在该filesystem中像其他文件一样的普通文件。
这个明显更加复杂的bootstrap code必须去读并且理解filesystem, 如FAT32, NTFS, ext4 等等。 这个文件是bootloader的最后一部分,通常文件大小和内容都没有限制。这意味着这一部分代码能够实现从硬盘中加载操作系统内核,并且将对PC的控制移交给OS这样复杂的任务。
2.5 The Bootloader
硬盘上真正的bootloader文件是启动加载过程的最后一部分。当人们谈论起bootloaders 和 boot files(启动文件)的时候,一般都是指最后这部分。
综上,BIOS将对PC的控制权交给MBR中的bootstrap code, 再交给分区bootsector的bootstrap code,最后交给在active分区中的可执行的boot 文件。这时真正的OS启动才开始。因为这部分具决定加载那个操作系统、从哪里加载、传递什么参数/选项、完成与用户的互动等等这些逻辑。
2.5.1 Boot Configuration Files (启动配置文件)
绝大多数bootloader文件将真正的可执行bootloader和配置文件或者包含操作系统加载信息的数据库分开。所有的主要bootloader都支持加载多个操作系统,即“dual-booting”或者“multi-booting”.
2.5.2 主要的bootloader
每个操作系统都有自己专有的bootloader来读取它的filesystem和定位为了运行OS而必需加载的kernel。以下是一些主要的bootloader,以及它们主要的配置文件。
这里只介绍以下Grub和Grub2
5.2.2.1 GRUB
GRUB是在1990s-2000s最主要的Linux的bootloader。但它不仅能加载Linux,也能加载任何实现open multiboot specification规范的kernel的操作系统。GRUB的配置文件包含了一个空格分开的操作系统列表,即menu.lst 或者grub.lst。这个文件在/boot/ 或者 /boot/grub/下。其中的值能够改变。不同的Linux系统下,这个文件的位置会有不同。
5.2.2.2 GRUB 2
在2002年,GRUB 2取代了GRUB。原来的GRUB被称为“Legacy GRUB”。GRUB 2是一个功能强大的模块式bootloader, 它更像是一个操作系统,而不是一个传统的bootloader。它可以加载很多不同的操作系统,并且支持加载自定义模块,从而来扩展功能,支持更复杂的启动程序。
GRUB2真正的bootloader文件并不叫做GRUB2,而是叫做core.img。不像Legacy GRUB,GRUB 2的配置文件更像是一个script。grub.cfg位于boot分区的/boot/grub/grub.cfg,有点像shell script,并且支持functions。GRUB 2的核心功能由模块增补,这些模块在/boot/grub/ xia.
3 The Boot Process
Boot process相对而言比较复杂,主要是由于读filesystem所带来的困难。bootloader必须包含底层硬件的信息(从BIOS或自身获取),从而能够顺利的从正确的分区中加载想要的操作系统,以及提供必要的其他文件或信息。因为它必须能从位于boot分区的filesystem中的普通文件中读取自己的配置文件,所以它至少需要能够完全支持对它所在filesystem的读取功能。
4 总结
整个开机过程由按下按键开始,到OS的kernel被加载到内存中并被执行结束。