这篇文章是回答知乎上一个朋友的问题:Systemd 的详细启动过程是怎样的 。
回答这个问题前需要了解一下计算机的启动过程和Linux 的启动过程,才能完整串起来。
关于计算机的启动,可以先阅读一下阮一峰的文章:计算机是如何启动的?,这篇文章在系统启动部分,大概提到了Linux 系统的启动,
不过不是十分详细,可以再看他的另一篇文章:Linux 的启动过程,文章所介绍的Init 程序是传统的Sysv。
而使用Systemd 的Linux 系统的差别就是在 Init 程序这一阶段。
在加载内核之前的阶段,这篇文章讲的挺细,可以顺便读一读:详解linux系统的启动过程及系统初始化。
然后可以读一下这篇文章,对Systemd 的基础介绍,非常不错:浅析 Linux 初始化 init 系统,第 3 部分: Systemd,感觉IBM developerworks 的文章质量都挺不错的。
虚拟文件系统Initrd,启动到这一步之后,通过Switch-root 转到 Init 程序,即Systemd(也可以是Sysv 之类的),后面就是Systemd 如何启动服务进程的问题。
Initrd 这一步,Systemd 其实也可以接管,具体参考:initrd with systemd。
在传统的Sysv 中,有Runlevel(启动级别)的概念,在Systemd 里面有Target 的概念,如下图:
Systemd 有个单元文件(Unit)的概念,可以理解成一个单元文件就是一个服务单元,有很多类型的单元文件,Mount、Device、Service、Path、Timer 等,最常见的就是Service 单元:
例:/usr/lib/systemd/system/named.service,具体的解释请看官方文档:
[Unit]
Description=Berkeley Internet Name Domain (DNS)
Wants=nss-lookup.target
Wants=named-setup-rndc.service
Before=nss-lookup.target
After=network.target
After=named-setup-rndc.service
[Service]
Type=forking
EnvironmentFile=-/etc/sysconfig/named
Environment=KRB5_KTNAME=/etc/named.keytab
PIDFile=/run/named/named.pid
ExecStartPre=/usr/sbin/named-checkconf -z /etc/named.conf
ExecStart=/usr/sbin/named -u named $OPTIONS
ExecReload=/bin/sh -c '/usr/sbin/rndc reload > /dev/null 2>&1 || /bin/kill -HUP $MAINPID'
ExecStop=/bin/sh -c '/usr/sbin/rndc stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID'
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Target 也是一种单元文件,但是它是引用和组织其他的单元文件,定义组织各种依赖关系。所以,Target 肯定可以实现Runlevel 的作用,只要定义六个Target 就可以了嘛。 再看看下面这张图,就大致明白了启动的时候是怎么加载服务进程的:
更多细节,以及关机的过程请参考:bootup