一、从bios到Linux
从bios到Linux启动,grub引导就宛如点亮逻辑世界的火星。
从CPU架构过渡到OS,其中BIOS部分,我实在是没有资格聊。
因为我没有做过BIOS研发。
除了“硬件自检”、“EFI启动六阶段”、以及“物理地址空间初始化”“PCIE bus tree初始化”等等粗浅概念,我还略看过相关的资料,其他的我就了解甚少啦。
在我眼中,BIOS研发那些牛人充满着神秘感。
知乎里有一位老狼,这方面的文章较多。
——非亲非故,只是敬仰。
为了说明方便,这里的BIOS仍沿用传统的legacy模式、硬盘分区仍使用MBR方式。
将传统的OS legacy+MBR引导方式搞明白后,再将其中的某些部分替换一下,就对应了UEFI+GPT方式。——从pxe安装配置中就可以看出,只要将传统的pxelinux.0文件换成两个.efi文件,从OS的角度来讲,legacy和UEFI几乎没有什么不同。
好,言归正传。
当服务器的bios完成了自检和硬件初始工作以后,系统控制权便试图交给硬盘中的OS。
在某品牌的服务器中,ipmi sel日志中会有类似这样的一条记录:
——这是sel日志中经典的启动时间戳,标志着bios将控制权交给硬盘中的OS。
在服务器无法启动时,我们常常根据这条语句粗略判断是硬盘、以及硬盘内的操作系统出现了问题,还是三大硬件(CPU,内存,主板)出现了问题。注意,这里是说粗略判断,判断是否因三大件严重故障,无法完成自检。
这里所谓“硬盘中的OS”是个非常笼统的说法,在本篇上下文中,其包括了许多程序组件。在OS引导、启动的各个阶段,每个组件各司其职。每一个组件,最重要的作用就是为下一阶段做好充分的准备。
如下图:
按照我的理解,操作系统的启动,分成了引导(bootloader)、内核启动 (vmlinuz+initramfs)、服务启动(service start)三个大阶段。
然后我们可以将上图中各个模块近似的放入这三个阶段中。
今后的一段时间,我将从图左边的BIOS出发,遍历整个OS的引导启动过程。
二、第一站Bootloader
说起Boot Loader,也就是在linux资料中俗称的grub。
如果我们将Boot Loader充分展开,redhat的资料又给我们展示了如下的操作系统的启动过程:
当然,不同的人不同的视角,在某些资料的定义中:
1、 上图中红框所示部分,被统称为GRUB第一阶段引导和GRUB第1.5阶段引导。
2、 而后面的GRUB,被称为GRUB第二阶段引导。
——但1,2合并起来,统称为GRUB引导阶段。
Grub,绝对不能理解成某个目录下的某个文件中的某几行代码。
想想看吧:grub介于bios和OS内核之间,绝对属于底层啊。
所以Grub应该理解成是分布在硬盘某几个扇区之中的低级代码,一定注意grub的载体是硬盘扇区,而不是文件系统。
所以,若是聊bootloader也就是grub,就不得不说说硬盘的MBR结构了。
MBR全称为Main Boot Record,代表着x86下的一种硬盘分区结构。MBR模式下,硬盘的第一个扇区(也就是LBA0)的512字节中,含有主引导程序bootloader。
先引用MBR中第一个磁盘扇区LBA0的结构说明:
1、 LBA0中的前446字节(0x000~0x1BD)就是bootloader部分。
2、 LBA0从0x1BE开始剩余的64字节则为硬盘的分区表。
说明到这里,传统的MBR资料,将顺着64字节的硬盘分区表描述,走向了硬盘分区说明。
——而今天,我们将从操作系统启动的角度,关注前446字节bootloader部分。
所谓的OS启动之引导,就是要让启动逻辑能够找到硬盘的/boot区以及/boot区内的内核文件:vmlinuz,initramfs。
区区446字节用来拉起OS内核,是远远不够的。所以:
1、MBR LBA0 的446字节,只能称为GRUB的boot.img,这部分代码的运行又称为GRUB第一阶段引导,用来引导GRUB内核(grub 其他两部分:kernel.img+core.img)。
2、然后GRUB内核开始识别基本的/boot文件系统,找到硬盘中的/boot区,这叫GRUB第1.5阶段引导。
3、最后GRUB内核获取到了linux内核文件vmlinuz,initramfs,并且生成了grub选择菜单:
总而言之,bootloader也好,grub也罢,就意味着“引导”,引导启动逻辑能够找到磁盘/boot区内的内核文件。
boot loader的过程近似如下:
——当操作人员选择启动相关内核启动项时,grub将会拉起OS内核vmlinuz。自此grub退场而OS内核开始登上舞台。
于是下一篇,我们去下一站,说一说linux内核vmlinuz,initramfs。
TIPS:
1、 首先,grub的实现和运行,其实是非常复杂的。关于grub的结构和分布,我也看到了互相矛盾的资料(grub kernel.img和core.img究竟是在硬盘的LBA1的32k字节内还是在/boot区内?到现在我还不敢确定)
另外grub运行还分成了实模式,保护模式两个阶段,其运行地址又与X86 system physical address 知识拧在了一起,理解起来较复杂。
2、 为什么我要写Linux启动过程系列?
那是因为,我认为如果不学习linux启动过程,所谓搞linux系统恢复,linux诊断,以及pxe安装都是比着葫芦画瓢,人云亦云而已。
就如同,分析x86 PECI黑盒日志却不懂CPU寄存器结构,纯属扯淡。