linux系统启动流程
系统启动简述
Linux 操作系统的启动首先从 BIOS 开始,接下来进入 boot loader,由 bootloader 载入内核,进行内核初始化。内核初始化的最后一步就是启动 pid 为 1 的 init 进程。这个进程是系统的第一个进程。它负责产生其他所有用户进程。
init 以守护进程方式存在,是所有其他进程的祖先。init 进程非常独特,能够完成其他进程无法完成的任务。
先通过一张图来简单了解下整个系统启动的流程,整个过程基本可以分为POST-->BIOS-->MBR(GRUB)-->Kernel-->Init-->Runlevel。下面会详细说明每个过程的作用。
第一阶段:硬件引导启动(BIOS加电自检)
- 第一步:检查硬件
BIOS是存储在主板芯片上的基本输入输出系统。计算机在开机时,会最先读取该系统进行加电自检。这个过程主要完成检查CPU和内存等计算机最基本的组成单元(控制器,运算器和存储器),如果检查没有异常就开始加载BIOS程序到内存。此时第一阶段第一步奏完成。 - 第二步:引导MBR启动Bootloader
在加电自检完成后BIOS会加载MBR并且运行grub(Bootloader程序);MBR主引导分区信息在硬盘的0柱面,0磁头,第一个扇,区,它由三个部分组成,主引导程序(bootloader),硬盘分区表DPT,和硬盘有效标志(55AA),它的结构图示如下:
第二阶段:grub启动引导
GRUB是系统引导程序,主要是加载内核到内存中运行,运行步奏如下:
-
Stage1:第一阶段是加载Bootloader程序,stage1是直接被写到MBR中的(主板上),此时系统在没有启动时stage1是识别不到文件系统的,
-
Stage1.5:为什么会有stage1.5的过程呢,由于stage1识别不了文件件系统,也就无法加载内核,stage1_5作为stage1和stage2中间的桥梁,stage1_5有识别文件系统的能力,此后grub才有能力去访问/boot分区/boot/grub目录下的 stage2文件,将stage2载入内存并执行。
-
Stage2: 当stage2被载入内存执行时,它首先会去解析grub的配置文件/boot/grub/grub.conf中的Kernel的信息,然后将Kernel加载到内存中运行,当Kernel程序被检测并在加载到内存中,GRUB就将控制权交接给了Kernel程序。
第三阶段:内核引导
- 加载内核
Kernel,内核,是linux系统中最主要的程序,当GRUB将内核加载到内存后,内核开始解压缩内核文件将内核启动。 Kernel会以只读方式挂载根文件系统,当根文件系统被挂载后,开始装载第一个进程(用户空间的进程),执行/sbin/init,之后就将控制权交接给了init程序。
第四阶段:init初始化
init是系统所有进程的父进程,pid为1,当init接管了系统的控制权后,init进程首先读取/etc/inittab文件来执行脚本进行相应系统初始化,要注意的是:/etc/inittab文件只定义系统默认运行级别,真正进行系统初始化工作的是/etc/rc.sysinit脚本,这是第一个被执行的脚本。它完成的工作如下:
- 激活udev和selinux;
- 根据/etc/sysctl.conf文件,来设定内核参数;
- 设定系统时钟;
- 装载硬盘映射;
- 启用交换分区;
- 设置主机名;
- 根文件系统检测,并以读写方式重新挂载根文件系统;
- 激活RAID和LVM设备;
- 启用磁盘配额;
- 根据/etc/fstab,检查并挂载其他文件系统;
执行完后,根据配置的启动级别,执行对应目录底下的脚本,最后执行/etc/rc.d/rc.local这个脚本,至此,系统启动完成。
runlevel
runlevel,系统运行级别,不同的级别会启动的服务不一样,init会根据定义的级别去执行相应目录下的脚本,Linux的启动级别分为以下几种:
0:关机模式
1:单一用户模式(直接以管理员身份进入)
2:多用户模式(无网络)
3:多用户模式(命令行)
4:保留
5:多用户模式(图形界面)
6:重启
执行/etc/rc.d/rc脚本
在不同的运行级别下,/etc/rc.d/rc这个脚本会分别执行不同目录下的脚本,rc.sysinit通过分析/etc/inittab文件来确定系统的启动级别,然后才去执行。
- Run level 0 – /etc/rc.d/rc0.d/
- Run level 1 – /etc/rc.d/rc1.d/
- Run level 2 – /etc/rc.d/rc2.d/
- Run level 3 – /etc/rc.d/rc3.d/
- Run level 4 – /etc/rc.d/rc4.d/
- Run level 5 – /etc/rc.d/rc5.d/
- Run level 6 – /etc/rc.d/rc6.d/
这些目录下的脚本只有K和S开头的文件,K开头的文件为开机需要执行关闭的服务,S开头的文件为开机需要执行开启的服务。如果要对某个运行级别中的服务进行更具体的定制,通过chkconfig命令来操作。这些shell脚本的启动或结束顺序是由S或K字母后面的数字决定,数字越小的脚本越先执行。例如,/etc/rc.d/rc3.d /S01sysstat就比/etc/rc.d/rc3.d /S99local先执行。
自定义引导程序rc.local
在/etc/rc.d/rc.local文件中可以让用户自定义开机要执行的指令或脚本,其实当执行/etc/rc.d/rc3.d/S99local时,它就是在执行/etc/rc.d/rc.local。S99local是指向rc.local的符号链接。就是一般来说,自定义的程序不需要执行上面所说的繁琐的建立shell增加链接文件的步骤,只需要将命令放在rc.local里面就可以了,这个shell脚本就是保留给用户自定义启动内容的。
login
当完成系统所有启动任务后启动shell进行用户登录操作,Linuix默认的shell是Bash,它会读入一系列的配置文件。
1)命令行登录:首先读入 /etc/profile,这是对所有用户都有效的配置;然后依次寻找下面三个文件,这是针对当前用户的配置。
~/.bash_profile
~/.bash_login
~/.profile
需要注意的是,这三个文件只要有一个存在,就不再读入后面的文件了。比如,要是 ~/.bash_profile 存在,就不会再读入后面两个文件了。
2)ssh登录:与第一种情况完全相同。
3)图形界面登录:只加载 /etc/profile 和 /.profile。也就是说,/.bash_profile 不管有没有,都不会运行。
在整个启动过程中要读取执行的脚本流程大致如下:
整个系统启动流程简述如上,最后附上一张非常完整的系统启动流程图: