1.linux系统启动流程

1.加载BIOS的硬件信息,获取第一个启动设备
Power-On-Self-Test,加电自检,是BIOS功能的一个主要部分。负责完成对CPU、主板、内存、硬盘子系统、显示子系统、串并行接口、键盘、CD-ROM光驱等硬件情况的检测。
BIOS保存着有关计算机系统最重要的基本输入输出程序,系统信息设置、开机加电自检程序和系统启动自举程序等,这一程序知道一些直接连接在主板上的硬件,现在大部分BIOS允许从软盘,硬盘,光盘中选择一个来启动计算机,BIOS会获得其中一个设备,通常情况下是硬盘,特殊情况是光盘。
2.装载主引导程序boot loader
当BIOS获取到第一个启动设备后,计算机会读取这个设备的起始的512字节,这512字节叫做主引导记录MBR,MBR能够告诉计算机从该设备的某一个分区来装载引导加载程序boot loader。boot loader存储有操作系统的相关信息,我的计算机是装载硬盘上的,可以通过下面的命令查看硬盘的前512字节:

hexdump -C -v -n 512 /dev/sda

执行结果如下:
Linux系统启动流程_第1张图片
-C是以16进制方式显示,-v不忽略其中的0,-n 512 只显示前512字节,/dev/sda是我的硬盘。
3.boot loader加载内核
boot loader主要有三个功能,如下:
1.提供启动菜单
2.加载内核
3.将引导交给其他的loader
启动系统时,可以选择需要启动的操作系统,会列出一个启动菜单,这部分功能是boot loader提供的。其次是加载内核,内核加载成功后,boot loader会把引导交给别的loader,boot loader只能引导linux系统启动,并不能引导Windows等其他的操作系统启动,但是,boot loader有着其他loader不具有的特点,就是他可以将引导交给其他的loader,但Windows等操作系统的loader却没有这种功能。
我们先来看一下启动菜单:如下图:
Linux系统启动流程_第2张图片
我们可以通过上下键来选择我们想要的启动项,当然此处我们只有一个启动项。
第二步是加载内核,首先我们要知道当计算机开机的时候,文件系统模块还没有被加载,但我们的系统盘却是一个ext3或者ext4,xfs的文件系统,里面存放着我们的内核文件,具体是存在boot下,那我们在不知道boot没有文件系统的情况下如何去读取内核文件,并把它加载进内存呢?
我们先看加载内核的过程,加载内核一共是分为3个步骤,分别为stage1,stage1.5,stage2,上面我们看到的MBR分区表结构,我们知道,这一块硬盘的第一个扇区一共512字节,其中第447到512是我们的分区表和55aa,那么前446字节是什么呢,前446字节存放就是我们的stage1,他的功能是实现基本的引导,例如判断分区的文件系统类型。
我们知道现在文件系统还没有被加载,我们读取了第一个扇区的内容,知道了stage1的内容,如何去读取实现stage1.5呢?
通过stage1到stage1.5是通过硬件中断来实现的,具体不在研究。
stage1.5是通过stage1判断分区的文件系统类型,在stage1.5中加载对应的分区文件系统模块。我们可以看一下/boot下的内容如下:
Linux系统启动流程
我们的系统才用的是grub引导的,我们在/boot下可以看到有一个grub的目录,进入这个目录,我们可以看到下面的内容:
Linux系统启动流程
我们可以看到很多文件系统名下stage1_5的文件名,这些即是我们在stage1.5要加载的文件系统模块,stage1.5的功能也即是加载这些文件系统模块。
在grub下我么可以看到一个叫做grub.conf的文件,这就是我们的grub配置文件,也是stage2阶段要加载的文件,我们可以看一下这个文件中的内容如下:
Linux系统启动流程_第3张图片
default=0是默认加载第一个启动项,我们也只有这一个启动项。当我们有多个启动项是可以将默认设为别的,如下面的配置文件:
Linux系统启动流程_第4张图片
timeout是在多长时间内切换启动项,我们一般是不用修改的。
接下来的一行是启动时的背景图片,这个可以修改,但是意义不大。
接下来的是启动菜单,每一个title是一个启动项,title后面是启动项的名字,如上第一个title的名字是Red Hat Enterprise Linux Server 1111111 (2.6.18-164.el5)接下来的root (hd0,0)是指根是第一块硬盘的第一个分区,即我们的/boot,kernel后是我们的内核路径,然后加载内核,根是root=后面的内容,ro是以只读方式加载根,rhgb是以图形化加载,quite是保持安静,即不加载内核中的模块加载,initrd是我们需要加载的服务的映像文件,我们可以用下面的命令来生成镜像文件:

mkinitrd /boot/initrd-$(uname -r).img $(uname -r)
或者
mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)

4.启动init
我们可以查看/etc/inittab的内容如下:
Linux系统启动流程_第5张图片
这里面是我们的init级别,我们可以看到就一共有7个级别,我们分别说一下这七个级别:
init0,inin0和halt是一样的,所以不要把0设置为默认级别
init1,单用户模式,可以理解为救援模式
init2,没有网络服务的多用户模式
init3,多用户模式,我们一般将3设置为morenjibie
init4,保留的,并没有被使用的模式
init5,带有图形化的多用户模式
init6,init6和reboot一样,所以也不要将6设置为默认级别
我们可以看到上面有一行如下:

id:5:initdefault:

这代表当前的默认级别是5级别。
当内核启动后会读取init配置文件启动相应的服务。这时系统就完全启动完成了。