2023年11月25日发(作者:)

计算机的启动过程(详细)

零、boot的含义

先问⼀个问题,”启动”⽤英语怎么说?

1. 1 1-446字节:调⽤操作系统的机器码。

2. 2 447-510字节:分区表(Partition table)。

3. 3 511-512字节:主引导记录签名(0x550xAA)。

其中,第⼆部分”分区表”的作⽤,是将硬盘分成若⼲个区。

2.2 分区表

硬盘分区有很多好处。考虑到每个区可以安装不同的操作系统,”主引导记录”因此必须知道将控制权转交给哪个区。

分区表的长度只有64个字节,⾥⾯⼜分成四项,每项16个字节。所以,⼀个硬盘最多只能分四个⼀级分区,⼜叫做”主分区”。

每个主分区的16个字节,由6个部分组成:

1. 1 1个字节:如果为0x80,就表⽰该主分区是激活分区,控制权要转交给这个分区。四个主分区⾥⾯只能有⼀个是激活的。

2. 2 2-4个字节:主分区第⼀个扇区的物理位置(柱⾯、磁头、扇区号等等)。

3. 3 5个字节:主分区类型。

4. 4 6-8个字节:主分区最后⼀个扇区的物理位置。

5. 5 9-12字节:该主分区第⼀个扇区的逻辑地址。

6. 6 13-16字节:主分区的扇区总数。

最后的四个字节(”主分区的扇区总数”),决定了这个主分区的长度。也就是说,⼀个主分区的扇区总数最多不超过2的32次⽅。

如果每个扇区为512个字节,就意味着单个分区最⼤不超过2TB。再考虑到扇区的逻辑地址也是32位,所以单个硬盘可利⽤的空间最⼤也

不超过2TB。如果想使⽤更⼤的硬盘,只有2个⽅法:⼀是提⾼每个扇区的字节数,⼆是增加扇区总数。

三、第三阶段:硬盘启动

这时,计算机的控制权就要转交给硬盘的某个分区了,这⾥⼜分成三种情况。

3.1 情况A:卷引导记录

3.3 情况C:启动管理器

h) 到这⼀步为⽌,所有硬件都已经检测配置完毕了,多数系统BIOS会重新清屏并在屏幕上⽅显⽰出⼀个表格,其中概略地列出了系统中安

装的各种标准硬件设备,以及它们使⽤的资源和⼀些相关⼯作参数。

i) 接下来系统BIOS将更新ESCD(Extended System Configuration Data,扩展系统配置数据)。ESCD是系统BIOS⽤来与操作系统交换

在start过程将控制权转交后,接下来就是GRUB的核⼼过程了。该过程之所以区分stage1.5和stage2,主要原因是GRUB和GRUB2的区

别。在GRUB2中,将stage1.5过程集成到了stage2的过程中,所以stage1.5过程仅仅是针对GRUB的。下⾯将会分别介绍两种GRUB版

本的两种过程。

4.1 GRUB中stage1.5过程

Stage1.5过程很⽆辜,它的作⽤很单⼀,但是⾮常关键。它的主要功⽤就是构造⼀个boot分区系统对应的⽂件系统,这样可以通过⽂件系

统的路径(/boot/grub/)寻找stage2过程需要的,进⽽加载到内存中开始执⾏。

Stage1.5存在于0⾯0道3扇区开始的地⽅,并⼀直延续⼗⼏k字节的区域,具体的⼤⼩与相应的⽂件系统的⼤⼩有关(⽂中涉及到了0⾯0

道1-3+x扇区,这部分扇区为保留扇区,BIOS不会放置任何数据。正因为如此如果转换到GPT分区形式,系统将不能被正确引导,如上⽂

所⽰,MBR后⾯的扇区都被其他内容所占据)。Stage1.5过程被构建成多种不同类型,但是功能类似,下⾯简单介绍⼀下基本的stage1.5

过程的⽂件系统。e2fs_stage1_5(针对ext2fs,可引导ext2和ext3⽂件系统)、fat_stage1_5(针对fat⽂件系统,可引导fat32和

fat16)、ffs_stage1_5、jfs_stage1_5、minix_stage1_5、reiserfs_stage1_5、vstafs_stage1_5和xfs_stage1_5,这些⽂件被称

为stage1.5过程,这些⽂件每个⾄少都在11k以上。除此之外还有两个⽐较特殊的⽂件,分别为nbgrub和pxegrub,这两个⽂件主要是在

⽹络引导时使⽤,只是格式不同⽽已,他们很类似与stage2,只是需要建⽴⽹络来获取配置⽂件。

由于stage1.5过程中会涉及到多个⽂件系统对应的⽂件,因此本⽂中主要以ext2fs为例进⾏说明,其他⽂件系统与此类似,可以同样进⾏

在上⾯⼀节中介绍过,stage1.5过程中将boot分区的⽂件系统加载了,之后⼜做了⼀件事情,就是将控制权转交给stage2,⽽stage2⼊

⼝的地⽅就是stage2/asm.S⽂件。Stage2/asm.S⽂件属于汇编代码,主要作⽤是初始化C语⾔的运⾏环境,为下⾯执⾏C语⾔的函数做好准

备,在准备好之后,将执⾏init_bios_info(stage2/common.c)函数。init_bios_info函数的作⽤是执⾏⼀些底层的函数,然后跳转到cmain

执⾏,cmain函数位于stage2/stage2.c⽂件中。cmain函数内部进⾏⼀个死循环,在循环内部⾸先加载配置⽂件,显⽰给⽤户,在这同时循

环⼀个内层循环,在内层循环中,获取配置⽂件中的命令,并解析执⾏。过程中如果没有可⽤的配置⽂件,那么进⼊命令⾏模式

(enter_cmdline函数),如果找到可⽤的menu,那么开始执⾏menu的对应的内容(run_menu函数)。

对于enter_cmdline(stage2/stage2.c)函数,将调⽤find_command(stage2/cmdline.c),进⽽执⾏相应命令的函数。

对于run_menu(stage2/stage2.c)函数,将调⽤stage2/cmdline.c⽂件中的run_script函数,进⽽调⽤find_command,执⾏相应命令的

函数。

这两种⽅式虽然经过了不同的过程,对⽤户输⼊的⾏为进⾏分析和处理,最终调⽤的函数为find_command,在该函数中顺序循环⽐

较“输⼊”的命令是否与系统内部定义的相同,如果相同转到执⾏该函数。在这个⽐较的过程中包含了⼀个全局的数据结构为struct

builtin(stage2/shared.h),由该数据结构组成了⼀个table类型(stage2/builtins.c),将命令与相对应的builtin结构对应⼀起并进⾏串

联。下⾯描述⼀下builtin结构的定义:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

1. struct builtin {

2. /* 命令名称,重要,是搜索命令时的依据*/

3. char *name;

4. /* 命令函数,重要,是搜索匹配后调⽤的函数*/

5. int (*func) (char *, int);

6. /* 功能标⽰,⼀般未⽤到. */