计算机启动的基本过程详解
对于一台安装了Linux系统的主机来说,当用户按下开机按钮之后一共经历4个过程。
按下电源——》BIOS自检——》系统引导lilo/grub——》启动内核
其中,对每个过程都执行了自己该做的初始化部分,有些过程又可分为好几个子过程。
一、按下电源
按下电源,其实更科学的称呼是上电,因为有些嵌入式系统是通过波动电源开关来上电的,没有按下的按钮。任何Linux系统启动必然是从上电开始的。上电后CPU的RESET引脚会由特殊的硬件电路产生一个逻辑值,这就是CPU的复位,此时CPU唤醒了,CPU将在0ffffffff0处执行一条长跳转指令,直接跳到固化在ROM中的启动代码处(这个启动代码叫做BIOS),并开始执行BIOS代码。
二、BIOS自检
20世纪70年代初,“只读内存”(Read-Only Memory,ROM)发明后,开机程序被刷入ROM芯片,计算机通电后,第一件事就是读取它。如图所示就是一个BIOS芯片。
![](https://i-blog.csdnimg.cn/blog_migrate/9e7d19360bbb121be90c178381d5cdf2.jpeg#pic_center)
这块芯片里面放着BIOS代码。有计算机基础的人都应该听过BIOS(Basic Input /Output System),又称基础输入输出系统,可以视为一个永久地记录在ROM(只读存储器)中的软件,是操作系统输入输出的一部分,早期的BIOS芯片确实是“只读”的,里面的内容是用一种烧录器写入的,一旦写入就不能更改,除非更换芯片。现在主板都使用一种叫Flash EPROM的芯片来存储BIOS,里面的内容可使用主板厂商提供的擦写程序擦除后重新写入,这样就给用户升级BIOS带来的极大的方便。
2.1 硬件自检
BIOS程序的主要作用是硬件自检(简称BIOS自检),然后将控制权转交给下一阶段的启动程序。BIOS程序的硬件自检也称硬件自检(Power-On SelfTest,POST),主要负责检测系统外围的关键设备(如CPU、内存、显卡、I/O、键盘鼠标等)。例如最常见的是内存松动的情况,BIOS自检阶段会报错,系统无法自动起来。自检中如果发现错误,将按两种情况处理:对于严重故障(致命性故障),会直接停机,此时由于各种初始化还没有完成,因此不能给出任何的提示信号;对于非严重的故障则给出提示或者声音报警信号,等待用户处理。如果没有问题,屏幕就会显示CPU、内存、硬盘等信息。如图所示就是自检过程中打印的一些信息。
![](https://i-blog.csdnimg.cn/blog_migrate/2ede93b8db3dac31fd8f0509044a4dd2.jpeg#pic_center)
2.2 查找引导设备
硬件自检完成后,BIOS将把控制权交给下一阶段的启动程序。这时间,BIOS需要知道,“下一阶段的启动程序”具体在那一个设备。也就是说,BIOS需要一个外部的存储设备的顺序,排在前面的设备就是优先转交控制权的设备。这种顺序叫作“启动顺序”(Boot Sequence)。打开BIOS的操作界面,里面有一项是“设定启动顺序”。
三、 系统引导
BIOS代码基本运行结束了,现在要将引导程序代码载入内存运行。那么引导程序代码在哪里呢?这里讲的是PC上的引导。PC上的引导代码(bootloader程序)分为两部分,第一个部分位于主引导记录(MBR)上,这部分先启动,作用是引导位于某一个分区上的第二部分引导程序,如果NTKLDR、BOOTMGR和GRUB等。所以我们经常见到的GRUB属于bootloader,不属于BIOS。
BIOS按照“启动顺序”,把控制权交给排在第一位的存储设备。这时,计算机读取该设备的第一个扇区,也就是读取最前面的512字节。如果者512字节的最后两个字节是0x55和0xAA,这就表明这个设备可以被启动;如果不是,表明设备不能被启动,控制权于是被转交给“启动顺序”中的下一个设备。最前面的512字节就叫做“主引导记录”(Master Boot Record,MBR)。“主引导记录”只有512个字节,放不了太多东西。他的主要作用就是,告诉计算机到硬盘的那个位置找操作系统。引导记录由以下3个部分组成。
- 第1~446字节:调用操作系统的的机器码(第一部分引导代码)。
- 第447~510字节:分区表(Partition Table)。
- 第511、512字节:主引导记录签名(0x55,0xAA)。
BIOS把第一部分引导代码装入内存后,他就退出了,此时第一部分引导就启动了。第二部分“分区表”的作用就是将硬盘分成若干分区。将硬盘进行分区有很多好处。考虑到每个分区可以按照不同的操作系统,因此“主引导记录”必须知道将控制权交给那个区。分区表的长度只有64个字节,里面又分为4项,每项16字节。所以,硬盘最多只能分4个一级分区,又叫“主分区”。每个分区的16个字节由以下6部分组成。
- 第一个字节:如果是0x80,就代表该分主分区是激活分区,控制权转交给这个分区。四个主分区里面只能有一个是激活的。
- 第2~4个字节:主分区的第一个扇区的物理位置(柱面、磁头、扇区号等)。
- 第5个字节:主分区类型。
- 第6~8个字节:主分区最后一个扇区的物理位置。
- 第9~12个字节:该分区第一个扇区的逻辑地址。
- 第13~16个字节:主分区的扇区总数。
最后4个字节(主分区的扇区总数)决定了这个主分区的长度。也就是说,一个主分区的扇区总数最多不超过2的32次方。如果每个扇区为512字节,也就意味着单个分区最大不超过2TB。在考虑到扇区的逻辑地址也是32位,所以单个扇区的可利用的最大空间也不超过2TB。如果想使用更大的磁盘,只有两个方法:一是提高每个扇区的字节数;二是增加扇区总数。
介绍了一些分区表的的概念后,我们继续计算机的引导。现在计算机的控制权要交给硬盘的某个分区了,这里又分成2种情况。
-
要引导的操作系统位于激活的主分区里。4个主分区里面只有一个是激活的。计算机会读取激活分区的第一个扇区,这个分区叫做“卷引导记录”(Volume Boot Record,VBR)。“卷引导记录”的主要作用就是,告诉计算机,操作系统在这个分区里的位置。随后,计算机就会加载操作系统了。
-
要引导的操作系统位于逻辑分区里。随着硬盘越来越大,4个分区已经不够了,需要更多的分区。但是分区表只有4项,因此规定有且只有一个分区可以被定义成“扩展分区”(Extended Partition)。所谓“扩展分区”,就是指这个区里面又分为好多区。这种分区里面又有分区就叫做“逻辑分区”(Logical Partition)。扩展分区包含一个或多个逻辑分区。
计算机先读取扩展分区的第一个扇区,叫做“扩展引导记录”(Extended Boot Record,EBR)。它里面也包含一张64字节的分区表,但是最多只有两个分区项,第一个分区项描述第一个逻辑分区,第二个分区项描述第二个逻辑分区。如果不存在下一个逻辑分区,第二个分区项项就不需要使用。如果有两个分区项,计算机就可以找到第二个分区项,接着读取第二个分区项的分区表的第一个扇区,再从里面的分区表找到第三个逻辑分区的位置,以此类推,直到某个逻辑分区表只包含自己为止(只有一个分区)。因此,扩展分区可以包含无数个逻辑分区。
如果要启动扩展分区上(逻辑分区)的操作系统,计算机读取“主引导记录”前面446字节的机器码后,不再把控制权交给某一个分区,而是运行事先安排好的“启动管理器”程序(比如GRUB),这意味着第二部分引导代码启动了。它提示用户选择哪一个操作系统。Linux环境中,目前最流行的管理器是GRUB。
用户选择后,就可以直接启动所选的操作系统了。系统引导也就结束了,下面也就到了操作系统内核登场。