1.第一阶段:BOIS(Basic Input Output System)初始化,如图1
首先加载的是BIOS ,通过bios程序去加载CMOS(用来保存BIOS的硬件配置和用户对某些参数的设定(如日期、时间、启动设置等)的芯片,是主板上的一块可读写的并行或串行FLASH芯片,是)的信息。取得cmos中的信息后,BIOS开始开机自检(POST),然后执行硬件的初始化,并设定Pnp(即插即用,U盘等)设备,再定义可以开机的设备顺序,接下来就是读取开机设备的数据(就是第一个开机设备内的第0个扇区内的MBR中的Bootloader)
图1
2.第二阶段:GRUB/GRUB2的启动引导
由于不同的操作系统,其文件系统的格式不一样,所以需要一个开机管理的程序来处理内核文件的加载。这个管理 程序及时BootLoader,安装在MBR 中!(MBR广义上是指整个扇区,狭义上是仅指引导程序,在硬盘的0柱 面,0磁头,1扇区;其中主要是有三部分的内容:主引导程序(446B),分区表(64B),硬盘有效标识 (2B),一共是512B)。BootLoader的作用是认识操作系统的文件格式,并加载内核到内存执行(读入的数据有setup程序和一个经过压缩的内核映像在zImage或bzImage)。因为MBR过于小了,所以启动引导工具往往还需要从其他地方进一步的读取数据,这就是所谓的第二阶段。这通常是一个可交互的界面。如图3
(1)GRUB
GRUB进行第二阶段引导时,读取/boot/grub/grub.conf中的配置文件,根据配置文件的参数,加载相应的内核模块,内核再加载相应的驱动,进行必要的硬件初始化。grub2取消了grub-legacy(即GRUB)中的stage1,stage1_5和stage2的概念。
stage1 : 这是grub-legacy写入MBR中的那部分(对应gurb2中的boot.img)。 其作用是装入stage1_5(对应grub2中的core.img)的第一个扇区,为后续引导过程做准备。
stage1_5:就是写入保留扇区的那部分,对应grub2中的core.img。(注意的是:标准MBR是在第0个扇区,而分区表中记录的第一个分区是在63扇区,中间有62个扇区是保留扇区,由于stage1(0扇区)不能直接识别stage2(63扇区),所以中间添加了一个stage1_5(62个扇区)来过渡引导!)如图2:
图2
stage2:也就是grub-legacy的最后阶段。直接给用户呈现的就是一个引导菜单,其中提供了操作系统的名称,内核参数,引导分区等内容。从现在开始, 才真正进行Linux的启动过程,之前的都是准备工作!
图3
(2)GRUB2
GRUB2的boot.img在MBR或者是启动分区中,boot.img会读取core.img的第一个扇区,用以读取core.img后面的部分,一旦完成读取,core.img就会读取默认的配置文件和其他需要的模块!(centos7就是gurb2引导的):如图4:
图4
3.第三阶段:内核引导(vmlinuz、initramfs)(图6)
(1)vmlinuz
内核的分类: 单片型内核、模块型内核
单片型内核:将各种硬件支持,网络协议于文件系统管理都编译入一个单一的文件中。
模块型内核:允许计算机字在使用某一项功能的时候自动加载,防止核心臃肿,是大部分情况下的标准构建。
通常内核文件以压缩的形式存储,并不是一个可执行的内核。因此,内核阶段首要工作就是自解压内核映像。
系统内核镜像文件(vmlinuz)是可引导,可压缩的内核,压缩后一般为bzImage(大内核,大于512KB)zImage(小内核,小于512KB)。Linux能使用硬盘空间作为虚拟内存,因此得名vm。 vmlinuz是可执行的内核文件,它的解压程序也在内核中。内核文件一般在/boot/vmlinuz目录中。 注意[vmlinux是未压缩的内核,是ELF文件,即编译出来的最原始的文件,不能用于直接加载,不能用于启动内核,只是启动过程中的一种中间媒体]
图5
(2)initramfs
初始化内存镜像盘(initramfs)称为初始化内存盘,为系统提供一系列的内核映像提供不了的模块,这些模块对正确引导系统很重要。他通常和文件系统和存储设备有关,也支持其他特性和硬件外设。initramfs文件是用mkinitrd创建的,这个命令是Redhat(centos)专有的,其他版本有相应的命令!bootloader将其加载到内存中后,initramfs文件被解压缩,并在内存中仿真一个根目录(虚拟文件系统),此虚拟文件系统可以提供一个可执行程序,通过改程序来加载开机过程中所需要的模块,通常这些模块就是USB、RAID、LVM、SCSI等文件系统于磁盘接口的 驱动程序!
#mkinitrd [--with=模块 ] initramfs-版本号.img 版本号
#mkinitrd [--with=模块 ] initramfs-$(uname --r).img $(uname -r)
图6
(3)内核初始化
由BootLoader读取内核文件后,将其解压到内存中,并利用内核的功能,检查硬件与加载驱动程序,即测试并且驱动各个周边的设备(cpu,存储设备,网卡,声卡等)。此时Linux内核会一自己有的功能重新检查一下硬件,而不一定是使用BIOS 中的硬件信息。也就是说内核从现在才开始接管BIOS 后的工作。然后将根分区以只读的方式挂载,接着就是载入初始进程systemd(/usr/sbin/systemd/systemd),此处在centos7一下版本中,初始进程是init(/usr/sbin/init)
图7
4.第四阶段:systemd(init)
在内核加载完毕,进行硬件的检查和驱动加载后,此时主机硬件已经准备就绪,这时候内核会启动第一个进程(/usr/sbin/systemd/systemd或者/etc/inittab)。这是调用的第一个使用标准C库编译的程序,其进程号始终为1。
init负责触发其他必须的进程,使系统进入可用状态。init的这些工作根据/etc/inittab文件来完成,包括设置getty进程接受用户登录,设置键盘,字图,网络等。若没有这些进程,内核即使成功启动,也没有多大的意义。如图8
图8
Redhat7系统上,/etc/inittab文件不再使用,改文件只有一些注释说明信息,如下:
[root@localhost ~]# cat /etc/inittab # inittab is no longer used when using systemd. # # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM. # # Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target # # systemd uses 'targets' instead of runlevels. By default, there are two main targets: # # multi-user.target: analogous to runlevel 3 # graphical.target: analogous to runlevel 5 # # To view current default target, run: # # To set a default target, run: # systemctl set-default TARGET.target # [root@localhost ~]#
参考文献:
[1] 张同光. Linux操作系统(REHL 7/Centos 7). 北京: 清华大学出版社,2014.
[2] 鸟哥. 鸟哥的Linux私房菜(第三版). 北京: 人民邮电出版社,2015.
[3] 吴国伟等. 深入理解Linux驱动程序设计. 北京: 清华大学出版社,2015.
[4] 任桥伟. Linux内核修炼之道. 北京: 人民邮电出版社,2010.