计算机的开机启动流程详解!

2019-04-14 15:47发布

今天来谈谈计算机开机的启动流程,在我们按下电源键直到出现登录界面,计算机到底是怎样运转的。

零、boot的含义


我们都知道启动的英文单词是boot,但是boot在字典里的翻译一般是靴子,“启动”和“靴子”有什么关系呢?其实,boot是bootstrap(鞋带)的缩写,它来自一句谚语“pull oneself by ones bootstrap”,“拽着鞋带把自己拉起来”,很显然这是不太可能的事情。最早的时候,工程师们用它来比喻,计算机的启动是一个很矛盾的过程:必须先运行程序,然后计算机才能启动,而计算机不启动就无法运行程序。
早期确实是这样,工程师们想进各种办法,把一段小程序装进内存,然后计算机才能正常运行。工程师们把这个过程叫做“拉鞋带”,久而久之就简称boot了。
一、BIOS
1.0 概念解释
在此首先解释两个概念,BIOS以及内存地址。
BIOS:即“BIOS Input/Output System”(基本输入输出系统),它是一组被固化在计算机主板中,直接与硬件打交道的程序,它为操作系统提供了控制硬件设备的基本功能。BIOS包括系统BIOS(即主板BIOS),显卡BIOS和其他设备(如IDE控制器,SCSI卡或网卡等)的BIOS,其中,系统BIOS控制计算机的启动过程。BIOS一般被存放在ROM中,即使在关机或者断电后这段程序也不会消失,计算机在通电后,第一件事就是读取它。
内存的地址:
我们的机器中一般安装有32MB、64MB或者128MB内存,这些内存的每一个字节都被赋予了一个地址,以便CPU访问内存,如32MB的地址范围用十六进制表示就是0~1FFFFFFH。其中低端1MB内存0~FFFFFH非常特殊,因为最初的8086处理器能够访问的内存最大只有1MB,其中低端的640KB被称为基本内存,而A0000H ~ BFFFFH保留给显示卡的显存使用,C0000H ~ FFFFFH则被保留给BIOS使用,其中系统BIOS一般占用了最后的64KB或更多一点的空间,显卡BIOS一般在C0000H ~ C7FFFH处,IDE控制器的BIOS在C8000H ~ CBFFFH处。
1.1 系统BIOS初始化
按下电源开关时,计算机的启动就开始了。当主板启动后,它开始初始化它自己的固件 —— 芯片组和其他东西 —— 并且试图让 CPU 运行起来。假设CPU正常运行,在一个多处理器或者多核系统中,会动态的选择一个 CPU 作为启动CPU(bootstrap processor, BSP)来运行 BIOS内部程序 。启动CPU通电后会马上从地址FFFF0H处开始执行指令,由前面可知,此地址在系统BIOS地址范围内。接着,CPU开始执行BIOS代码,进行一些硬件的初始化。
1.2 POST
系统BIOS的启动代码首先要做的事情就是进行POST(Power-on Self Test,加电自检),POST的主要任务是检测系统中一些关键设备是否存在以及能否正常工作,如CPU、BIOS芯片、内存等。此时显卡还没有初始化,还是黑屏状态,信息不能在屏幕上显示,所以如果POST自检时硬件出现问题,系统的喇叭就会发出警报声,声音的长短和次数代表了错误的类型。
1.3 初始化显卡等其他设备
如果自检通过,系统BIOS会查找显卡BIOS,找到后会调用显卡BIOS的初始化代码,由显卡BIOS来初始化显卡。此时,屏幕上将会显示出一些显卡的信息,如生产厂商、芯片类型等,通常是一闪而过的画面。接着,系统BIOS将会查找其他设备的BIOS程序,找到后同样调用其内部的初始化代码来初始化对应设备。
1.4 标准硬件检测及即插即用设备检测
下一步BIOS将开始检测系统中安装的一些标准硬件设备:硬盘、CD-ROM、串行和并行接口等设备。之后会接着检测即插即用设备,每找到一个设备,系统BIOS会在屏幕上显示设备的名称和型号等信息,并为其分配中断、DMA通道和I/O端口等资源。到了这里,所有设备都已检测完成了,多数系统BIOS会重新清屏并在屏幕上方显示一个表格,概略地列出了系统中安装的各种标准硬件设备及其使用的资源和工作参数。
1.5 更新ESCD
接下来系统BIOS将更新ESCD(Extended System Configuration Data, 扩展系统配置数据)。ESCD是系统BIOS用来与操作系统交换硬件配置信息的一种手段,这些数据存放在CMOS(一小块特殊的RAM,由主板上的电池来供电)之中。通常ESCD数据只在系统硬件配置发生改变之后才会更新,所以不是每次启动机器都能看到“Update ESCD... Success”之类的信息。
1.6 启动顺序
当上面的所有步骤都顺利进行之后,BIOS将把控制权转交给下一阶段的启动程序。这是,BIOS需要知道“下一阶段的启动程序”放在哪一设备,也就是说,BIOS需要有一个外部存储设备的排序,BIOS优先将控制权交给排在前面的设备。而这个排序就叫做“启动顺序(Boot Sequence)”。 启动顺序可以由用户进行设置,一般排在第一位的设备为硬盘,即从硬盘开始启动,如果需要安装系统,还会设为从光驱或USB设备启动。若设置为从光驱启动,而光驱中没有光盘,系统将把控制权交给排第二的存储设备,如硬盘。
二、主引导记录(MBR)
系统BIOS按照“启动顺序”读取第一个设备(如硬盘)上的第一个扇区即0号扇区,也就是起始的512字节,这个扇区就被称为主引导记录(Master Boot Record,MBR)。有时也将其开头的446字节内容特指为MBR,下方的MBR都指前512字节。
2.1 MBR的结构
1. 启动代码(446字节):启动代码中硬盘引导程序的主要作用是检查分区表是否正确,并且在系统硬件完成自检以后将控制权交给 2. 硬盘分区表(64字节) 3. 结束标记字(2字节):55,AA为最后两字节,是检验主引导记录是否有效的标志。 下图可以帮助理解MBR的结构:
(图片来自http://liaoph.com/how-computers-boot-up/) 2.2 硬盘分区表
硬盘分区表占据主引导扇区的64字节,里面又分为四项,每项16字节。所以一个硬盘最多只能有四个一级分区,又叫做“主分区”。每个分区都可以安装不同的操作系统,因此MBR必须知道将控制权转交给哪个分区,将在下方详细说明。 每个主分区的16个字节,由以下几个部分组成:

2.3 MBR的读取流程   1. BIOS读完磁盘上的MBR之后会把它拷贝到内存0x7C00处。 2. CPU检查0x7CFEH-7CFFH(MBR的结束标志位)是否等于55AAH,若不等于则转去尝试“启动顺序”中的下一个设备,若没有启动设备满足要求则显示“NO ROM BASIC”,然后死机。 3. 当检测到满足要求的设备后,BIOS将控制权交给该启动设备。启动设备的MBR将自己复制到0600H处,然后继续执行。 4. 根据MBR中的引导程序代码,检查分区表是否正确,并确定哪个分区为引导分区,在程序结束时把该分区的启动程序调入内存加以执行。
三、Boot Loader

MBR中的引导程序代码需要确定某一分区作为引导分区,而此处有如下几种情况。


3.1 情况一:卷引导记录

2.2中的表格中提到,四个主分区里只有一个活动分区,此时计算机就会读取活动分区的第一个扇区,叫做“卷引导记录”(Volume Boot Record, VBR)。VBR的主要作用是,告诉计算机,操作系统在这个分区的位置,然后计算机就会加载操作系统了。

3.2 情况二:扩展分区和逻辑分区

随着硬盘越来越大,四个主分区已经不够了,需要更多的分区。但是,分区表只有四项,因此规定有且仅有一个区可以被定义成扩展分区(Extended Partiton)。所谓“扩展分区”,就是指这个区中又可以分成多个分区,而这些分区又被叫做“逻辑分区”(Logical Partiton)。

如果操作系统安装在扩展分区中的某个逻辑分区,计算机将以以下方式寻找该分区。

计算机选读取扩展分区的第一个扇区,里面也包含一张64字节的分区表,但是最多只有两项(即两个逻辑分区)。计算机接着读第二个逻辑分区的第一个扇区,再从里面的分区表中找到第三个逻辑分区的位置,以此类推,直到某个逻辑分区只有一个分区项(即只包含自身分区)。由此可见,扩展分区可以包含无数个逻辑分区。

事实上,很少通过这种方式启动操作系统。如果操作系统确实安装在扩展分区,一般采用下一种方式启动。

3.3 情况三:启动管理器
在这种情况下,计算机读取“主引导记录”前446字节的机器码之后,不再把控制权转交给某个分区,而是运行事先安装的“启动管理器”(Boot Loader),由用户选择启动哪一个操作系统。现在一般都是采用这一种启动方式。
Linux环境中,目前最流行的启动管理器有GRUB和LILO。
四、Kernel
kernel,内核,实际上是一个用来操作计算机的程序,它是计算机操作系统的内核,主要任务是管理计算机的硬件资源,充当软件和硬件的接口,操作系统上的任何操作都要通过kernel传达给硬件。Windows和Linux都有各自的kernel。狭义的操作系统就是指kernel,广义的操作系统包括kernel以及kernel之上的各种应用。
任务管理器Boot Loader如GRUB会帮我们加载kernel。如果我们加载的是Linux kernel,Linux kernel开始工作。
kernel首先预留自己运行所需的内存空间,然后通过驱动程序(driver)检测计算机硬件。这样,操作系统就可以知道自己有哪些硬件用。随后,kernel会启动一个init process,它是Linux系统中的1号进程(Linux系统没有0号进程)。到此,kernel就完成了在计算机启动阶段的工作,交给init来管理。
五、init process
根据boot loader的选项,Linux此时可以进入单用户模式(single user mode)。在此模式下,初始脚本还没有开始执行,我们可以检测并修复计算机可能存在的错误。
随后,init会执行一系列的初始脚本(startup scripts),这些脚本是Linux中常见的shell scripts。这些脚本执行如下功能:设置计算机名称,时区,检测文件系统,挂载硬盘,清空临时文件,设置网络......          当这些初始脚本执行完毕时,操作系统已经完全准备好了,只是还不能登录。init会给出登录(login)对话框,或者是图形化的登录界面。
输入用户名、密码!
至此,全部启动过程完成。


                                                             华丽丽的分割线                                                                   
以上,操作系统的第一个大作业。 参考各种现有网络资料整合而成。以下为参考网址: 1. http://www.ruanyifeng.com/blog/2013/02/booting.html
2. http://duartes.org/gustavo/blog/post/how-computers-boot-up/
3. http://www.360doc.com/content/09/1227/10/629172_12083703.shtml
4. http://www.bkjia.com/LINUXxt/874615.html
5. http://www.chuquan.me/2016/12/14/computer-boot-process/

kernel、init进程的参考资料较少,之后有机会重新补全。由于资料都是自己理解后整合,有任何不对的地方,恳请大家评论指出。(双手合并,放于胸前,90°鞠躬)