Linux系统从开机开始到用户登录界面,需要启动一系列的进程,分为几个步骤。具体启动的过程如下
1. 载入内核
即把Linux内核载入到内存,Linux内核保存在/boot目录,/boot目录的内容大致如下
2. 启动init进程
运行/sbin/init程序,这个是Linux第一个进程,这个进程读取相应的配置文件并启动一系列进程,这个进程的PID为1,所有的进程都由它衍生,都是它的子进程。
这个进程读取/etc/inittab文件,根据文件中设置的启动层级和执行项来启动对应的程序。
文件头内容大致如下
# Default runlevel. The runlevels used by RHS are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:5:initdefault:
...
表示0-6的文件中说明了不同的启动层级,以及设定的启动层级。0为关机,1为单用户模式(维护模式),较为常用的是3和5,3为普通用户登陆的字符终端模式,5为带图形界面的用户终端模式。
上述示例,其中设定的行
id:5:initdefault:
表示启动的层级为5,即图形界面终端模式。
3. 执行系统初始化脚本(/etc/rc.d/rc.sysinit)
之后/etc/inittab第一个执行项,通常为
si::sysinit:/etc/rc.d/rc.sysinit
表示启动脚本/etc/rc.d/rc.sysinit,这个脚本对系统进行一系列的初始化,包括时钟、键盘、磁盘、文件系统等初始化。
其中/etc/inittab每一行代表一个执行项,格式如下
id:runlevels:action:process
id: 表示该执行项的id,为符合命名规则的标识符
runlevels: 符合执行条件的运行层级,为0-6数字的组合
action: 启动进程的方式,有initdefault, wait, respawn等选项
process: 表示需要执行的进程
4. 执行启动层级对应脚本(rc*.d)
之后启动不同层级的初始化进程,/etc/inittab执行项通常如下
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
这个执行项执行不同启动层级对应的程序,启动程序放在/etc/rcN.d目录下,N为0-6,比如层级3对应/etc/rc3.d目录。init进程依次执行对应目录下的脚本文件。
rcN.d目录下的文件通常是链接文件,指向/etc/init.d目录下的文件,实际执行的是/etc/init.d目录下的文件。如下为/etc/rc3.d目录下的文件list示例
/etc/init.d的.d表示目录的意思,与启动程序/etc/init区分开,表示都是启动程序或目录。/etc/rcN.d的.d也表示目录的意思,rc大致为run-level command的意思,表示不同启动层级的程序。可以在init.d目录下查看,这里的程序其实都是脚本程序。这些脚本程序基本上都是服务程序,能接受start、stop、restart、status等参数。
4. 启动终端
rc执行完毕之后,系统环境已经设置完成,各种服务进程也已经启动。init开始启动终端程序。inittab文件中执行项通常如下
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
这里表示2345层级的启动以respawn方式启动6个mingetty终端进程。
终端响应键盘鼠标显示器等设备实现与用户进行交互。终端程序会启动登录界面,提示输入用户名和口令。运行级别5的系统模式会启动图形界面的终端程序。
6个终端进程之间可以通过键盘CTRL+ALT+F1~F6进行切换。
终端启动之后,用户就可以通过键盘、鼠标或者网络连接等登录系统进行操作了。
5. 总结
整体的启动过程总结大体如下图。
总体上的流程就是
1 载入内核之后启动第一个进程/sbin/init进行初始化
2 /sbin/init调用/etc/inittab文件,根据文件配置进行系统初始化
3 /etc/inittab文件完成
a) 设定运行层级
b) 运行初始化脚本/etc/rc.d/rc.sysinit
c) 执行运行层级对应目录/etc/rcN.d下的脚本
d) 启动终端进程
不同版本的Linux配置方式,文件目录等可能略有不同,大体上启动流程则如上所述。
基于systemd的启动机制
随着Linux系统版本的更新与迭代,不同版本的Linux系统启动机制开始有所不同,一些新版本的Linux系统(如CentOS 7,Debian,Ubuntu等)开始采用systemd为基础的启动机制。
这种启动机制是一个守护进程的概念,启动一系列服务,以/lib/systemd/sytemd为第一个启动进程,以/lib/systemd/system等目录为配置目录。参考如下
https://blog.csdn.net/feccc/article/details/103049975
https://blog.csdn.net/feccc/article/details/103051336
比较主要的点是
1 系统第一个启动的进程为/lib/systemd/systemd(替代init进程)
systemd是一个系统守护进程,为Linux内核载入后的第一个进程,替代原来的init进程。以Ubuntu 18.04为例,可以查看/sbin/init文件,发现它是一个指向/lib/systemd/systemd的链接
2 启动进程通过配置目录进行配置(替代/etc/inittab配置方式)
配置目录为
/etc/systemd/system
/run/systemd/system
/lib/systemd/system
优先级从高到低,systemd进程依次从这些目录读取配置文件,启动配置文件设定的相应进程。参考https://www.jianshu.com/p/32c7100b1b0c。
目录中包含了几种类型的文件,其中主要的为
1) service文件,描述需要启动的服务进程,可以进行启动、停止、查看状态等操作
2) target文件,运行目标,相当于程序组,用以设定需要启动的系列进程,可以设定不同的启动进程组,对应原来的run level。
常用的target有basic.target、multi-user.target、graphical.target、default.target等。里面也有runlevel*.target文件,分别对应原来的0-6的运行层级。通过ls -l可以看到它们是指向不同target的软链接。
default.target是systemd启动之后默认运行的目标,相当于原来启动方式中默认的启动层级。
在Ubuntu系统中通过ls -l查看,实际上它是指向graphical.target的链接。表示它指代的默认启动层级为图像界面方式。
其它文件如device、mount、socket、path等类型,这里不再赘述。
如果需要添加自己定义的服务程序,可以在配置目录(通常/etc/systemd/system)添加服务描述service文件,在文件中描述需要启动的服务程序,并设置启动。
总体上,新的机制用systemd管理启动服务,systemd通过target文件来确定需要启动的服务,需要启动的服务由service文件来进行描述。
参考链接:https://www.jianshu.com/p/e1442913eb0e
https://www.runoob.com/linux/linux-system-boot.html
https://blog.csdn.net/u011857683/article/details/81395893