深入Linux/Unix系统引导过程
深入Linux/Unix系统引导过程
最近一直在专注的学习一样技术,主要就是Linux/Unix系统的引导过程,从最基本的机器加电一直到最终系统能够正确的使用为止,这个过程中涉及到了相当多的技术,以及各种技术的推陈出新,都在这个重要的过程中得以体现。我之所以对这部分进行了分析,主要是工作上面需要这方面的知识,同时觉得很有意思,所以广泛的深入研究了一下。
好了,废话不多说了,开始来点干货吧,本文并非全部原创,参考了一些文章,具体请查看“参考”部分。
深入Linux/Unix系统引导过程
Linux/Unix系统的引导过程包含了很多阶段,但是对于一个标准的系统的引导,大致的阶段是类似的,不同的平台会有一些不同之处(x86平台下主要使用LILO、SYSLINUX或是grub,SPARC平台下主要使用OBP作为loader)。在接下来的章节中,我将从系统加电开始直至Linux/Unix内核被正式加载运行。
1 概述
首先从高层的架构分析一下Linux/Unix引导流程,下面的图作为一种更加形象的说明,这样你可以从上次梗概的了解整个流程,为下面深入的分析打下基础。
从这张图中,总结一下大概的流程,分别是:系统启动、阶段1引导、阶段2引导、内核加载和用户态的初始化。在系统启动阶段主要用的技术包括BIOS(最新的发展为EFI),阶段1引导主要用的技术包括Master Boot Record(最近的发展为GPT),阶段2引导主要用的技术包括LILO、GRUB、SYSLINUX、GRUB2(x86平台下)和OBP(SPARC平台下)。这张图属于比较古老的一种介绍,在目前的技术发展下,每个阶段都有了一些变化。
这里。
2.2 EFI启动
与传统MBR相比,GPT采用了不同的分区方式。
对于传统MBR,其结构主要如下:
上图即对上文中所述的很形象的说明,在图中看到MBR被分成三个部分,分别是:Bootloader、分别表以及Magic Number。其中Bootloader部分为stage1中被执行的起始部分,程序在这里被作为GRUB程序执行,详细的关于GRUB的内容将再下面章节中进行详细阐述。
相反,对于EFI系统中所采用的GPT分区方式,则采用了不同于MBR分区方式的形式,从下图中可以发现:
如上图所示,GPT分区表主要包括:保护MBR、首要GPT头、首要GPT、备用GPT、备用GPT头和磁盘数据区。保护MBR与正常的MBR区别不大,主要是分区表上的不同,在保护MBR中只要一个表示为0xEE的分区,以此来表示这块硬盘使用GPT分区表。首要GPT头包含了众多信息,具体内容如下:
偏移 |
字节长度 |
说明 |
0x00 |
8 |
签名,固定为ASCII码"EFI PART",16进制表示0x5452415020494645。 |
0x08 |
4 |
版本号,目前的版本为V1.0,16进制表示0x00010000。 |
0x0C |
4 |
分区表头的大小(单位是字节,通常是92字节,即5C 00 00 00) |
0x10 |
4 |
GPT头中字节的CRC32校验 |
0x14 |
4 |
固定值00 00 00 00 |
0x18 |
8 |
当前LBA(这个分区表头的位置) |
0x20 |
8 |
备份LBA(另一个分区表头的位置) |
0x28 |
8 |
第一个可用于分区的LBA(主分区表的最后一个LBA + 1) |
0x30 |
8 |
最后一个可用于分区的LBA(备份分区表的最后一个LBA−1) |
0x38 |
16 |
磁盘GUID |
0x48 |
8 |
分区表项的起始LBA |
0x50 |
4 |
分区表项的数量 |
0x54 |
4 |
一个分区表项的大小(通常是128) |
0x58 |
4 |
分区表CRC32校验 |
0x5C |
420 |
保留,剩余的字节必须是0(对于512字节LBA的硬盘即是420个字节) |
分区表头定义了硬盘的可用空间以及组成分区表的项的大小和数量。分区表头还记录了这块硬盘的GUID,记录了分区表头本身的位置和大小(位置总是在LBA1)以及备份分区表头和分区表的位置和大小(在硬盘的最后)。它还存储着它本身和分区表的CRC32校验。固件、引导程序和操作系统在启动时可以根据这个校验值来判断分区表是否有错误,如果出错了,可以使用软件从硬盘最后的备份GPT分区表恢复整个分区表,如果备份GPT也校验错误,那么磁盘将不可用,系统拒绝启动。
接下来主要是128个分区表项,GPT分区表使用简单而直接的方式表示分区。一个分区表项的前16字节是分区类型GUID。例如,EFI系统分区的GUID类型是{C12A7328-F81F-11D2-BA4B-00A0C93EC93B} 。接下来的16字节是该分区的唯一的GUID(这个指的是该分区本身,而之前的GUID指的是该分区的类型)。在接下来是分区其实和末尾的64位LBA编号,以及分区的名字和属性。具体结构如下表:
偏移 |
字节长度 |
说明 |
0x00 |
16 |
分区类型GUID |
0x10 |
16 |
唯一的分区GUID |
0x20 |
8 |
开始LBA |
0x28 |
8 |
结束LBA |
0x30 |
8 |
分区属性 |
0x38 |
72 |
分区名称(Unicode码) |
|
评论暂时关闭