3-系统启动流程梳理
1. 分区引导
1.1 基本概念
引导扇区:硬盘的0柱面、0磁头、1扇区(也叫主引导记录MBR),大小为512Byte。
分区表(DPT):位于主引导分区,从偏移01BEH开始到偏移01FDH结束的64字节。
活动分区DBR:DBR(DOS BOOT RECORD,原意为DOS引导记录),位于柱面0,磁头1,扇区1(操作系统可以访问的第一个扇区),即逻辑扇区0。DBR分为两部分:DOS引导程序和BPB(BIOS参数块)
设备的第一个扇区叫做“主引导记录“,512个字节的最后两个字节是0x55和0xAA,表明这个设备可以用于启动。第一个扇区也被称作为MBR。
MBR的分区表总共有64个字节,里面又分成四项,每项16个字节,MBR只存在四个主分区。每个主分区存的16字节,每一位都有不同的意义:
字节位 |
含义 |
第1字节 |
引导标志。若值为80H表示活动分区,若值为00H表示非活动分区。 |
第2、3、4字节 |
本分区的起始磁头号、扇区号、柱面号。其中: 磁头号——第2字节; 扇区号——第3字节的低6位; 柱面号——为第3字节高2位+第4字节8位。 |
第5字节 |
分区类型符。 00H——表示该分区未用(即没有指定); 06H——FAT16基本分区; 0BH——FAT32基本分区; 05H——扩展分区; 07H——NTFS分区; 0FH——(LBA模式)扩展分区(83H为Linux分区等)。 |
第6、7、8字节 |
本分区的结束磁头号、扇区号、柱面号。其中: 磁头号——第6字节; 扇区号——第7字节的低6位; 柱面号——第7字节的高2位+第8字节。 |
第9、10、11、12字节 |
逻辑起始扇区号 ,本分区之前已用了的扇区数。 |
第13、14、15、16字节 |
本分区的总扇区数。 |
1.2 执行流程
系统上电,biso要做的第一件事情是进行基本的硬件自检。将系统上连接的存储设备进行上报,按照UEFI的上报流程,若是检测到可以存储设备,会通过安装的passthru协议,将存储设备上报成为BLK块设备。若对应的BLK块设备是存在分区的,UEFI会将系统系统的标识符号上报上来,如下所示:
可以在系统的BIOS的启动优先级中设置启动的顺序:
BIOS引导系统启动,会根据设置好的启动顺序,顺序选择启动项。若启动项是系统盘,则读系统磁盘0柱面、0磁头、1扇区的主引导扇区MBR的内容到内存指定单元0:7C00 首地址开始的区域,并执行MBR程序段。
主引导代码实现下列功能:
(1)扫描分区表查找活动分区;
(2) 寻找活动分区的起始扇区;
(3) 将活动分区的引导扇区读到内存;
(4) 执行引导扇区的运行代码。
DBR(Dos Boot Record)原意为DOS引导记录,通常位于磁盘0磁道1柱面1扇区(操作系统可以访问的第一个扇区),其逻辑扇区号为0。
DBR分为两个部分:DOS引导程序和BPB(BIOS Parameter Block ,BIOS参数块)
DOS引导程序的主要任务是当MBR将系统控制权交给它时,判断本分区根目录前两个文件是不是操作系统的引导文件,如果确定存在,就把它读入内存,并把控制权交给它。
BPB用来描述本DOS分区的磁盘信息,它位于DBR偏移0BH处,共13字节。 它的记录包括本分区的起始扇区、结束扇区、文件存储格式、硬盘介质描述符、根目录大小、FAT个数,分配单元的大小等重要参数。
备注:现在的系统引导程序是grub
1.3 流程图
1.4 分区查看方式
在虚拟机上进行操作,查看块设备
将系统盘的MBR导出来,进行查看:
查看信息显示如下:
若是只判断是否分为受损,查看最后两个byte是否是0xaa55就可以。
2. 程序引导
2.1 基本概念
GRUB是许多Linux发行版的默认引导加载程序。grub会往引导扇区(可以是MBR, 也可以是每一个分区里面的引导扇区)里面写入部分内容,对于剩余的部分,它会写入到我们的硬盘分区里面的;在启动时,首先运行引导扇区里的程序, 然后在运行硬盘分区里的程序,最后引导操作系统;
2.2 执行流程
- grub引导阶段
参考网上的多方面资料grub的启动分为三个阶段,分别被成为stage1,stage1.5,和stage2
stage1:
stage1的程序放在mbr分区的机械代码中,446字节的机器码也干不了太多东西,只是负责把后续的内容加载到内存在执行而已。这个写到mbr的是stage1,它加载的是写在mbr之后62个扇区中的stage1.5,是以计算扇区绝对偏移的方法加载stage1.5。
stage1.5:
stage1.5的程序在mbr之后的62个扇区中。过去磁盘是按磁道还划分分区的,一个碰道63个扇区,因为mbr占据了第一个磁道的第一个扇区,所以第一个分区只能从第二个磁道开始,这样在mbr和第一个分区之间就留下了62个扇区的空间,62*512byte=31KB。stage1.5的grub程序就可以识别文件系统了。Grub1.5基本也只够一种类型的文件系统,所以stage1.5是有好几个,分别对应ext4,xfs等等,在grub安装时根据需要写入。因为GPT分区表占用了后62个扇区的相当一部分位置,导致空间不够写下stage1.5,所以需要额外分出一个非常小的分区来存放剩下的升序,也就是子stage2中。
stage2:
stage1.5可以识别文件系统,然后根据安装时写到里面的系统路径(hexdump可以看到)找到stage2,然后这个stage2才是真正负责干活的。stage2过程中,主要会把系统切换到保护模式,设置好C运行时环境,找到config文件(事实上就是menulist文件),如果没有找到就执行一个shell,等待用户的执行。然后的工作就变成了输入命令->解析命令->执行命令的循环中。当然该阶段引导的最终状态就是执行boot命令,将内核和initrd镜像加载进入内存中,进而将控制权转交给内核。
2. 系统启动阶段
先载入/boot目录下面的kernel。内核加载成功后,第一个运行的程序是/sbin/init。它根据配置文件产生init进程。这是Linux启动后的第一个进程,pid进程编号为1。init线程加载系统的各个模块,比如窗口程序和网络程序,直至执行/bin/login程序,跳出登录界面,等待用户输入用户名和密码。
若是要详细划分,这一步的启动,会先挂载ramfs文件系统,加载最基础的驱动信息。再由最基础的ramfs文件系统引导整个正式的系统。