ubuntu linux 启动过程

从第一次接触linux,陆陆续续在PC机上安装各种版本的linux已经不知道多少次。每次都是安装后,装下常用软件,玩几天就卸载了,图个新鲜。时间过的真快,从上大学到现在十多年了,没有好好去研究下linux的启动过程。现在由于工作需要接触的多了,今天有点时间来好好看一把。我刚在我的移动硬盘上安装了ubuntu 18.04 LTS版本(制作U盘安装盘安装,很方便!)。这个版本可是刚发布的,长期支持版本哦~

1 从哪里开始?

bootloader(grub)启动后,会去找到linux内核和根文件系统,然后加载到内存执行。内核和根文件系统在/boot目录下面:

szw@lnx:/boot$ ls
config-4.15.0-15-generic    #linux 内核编译选项.config文件--和启动无关
grub   #grub引导程序,grub可以识别各种文件系统,只需要指明系统镜像文件的路径,即可加载。                       
System.map-4.15.0-15-generic #map文件--和启动无关,是kernel符号和地址的映射文件
initrd.img-4.15.0-15-generic  #rootfs 根文件系统镜像文件:为了满足linux一切都是文件的高逼格抽象,启动的时候就需要有个基本的根文件系统,才能挂载设备哦! 大概50M. initrd就是initial ram disk的缩写,其实就是内存盘。
vmlinuz-4.15.0-20-generic  #8249080字节的linux内核,压缩过的,居然才8M!

启动linux内核的时候,会在bootloader中制定启动参数,里面会指定init 参数,如果指定了,linux启动后执行的第一个程序就是它了,如果没指定就执行下面的程序,有代码为证:

run_init_process("/sbin/init");  
  run_init_process("/etc/init");  
  run_init_process("/bin/init");  
  run_init_process("/bin/sh");

哪个先找到,就执行谁,执行成功后run_init_process是不会返回的。

OK! 我们找找ubuntu的启动的第一个程序。

szw@lnx:/boot$ ls /sbin/init -l
lrwxrwxrwx 1 root root 20 4月  27 21:38 /sbin/init -> /lib/systemd/systemd

原来是systemd!

2. 什么是systemd?

有空可以先看看官方的文档:https://wiki.ubuntu.com/systemd。我们先从简单处看看,d表示它是个daemon程序,即守护程序,或者说后台程序,类似win上的服务。这个服务功能可是很复杂的,找到一篇入门:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html,了解了下:

2.1. 它对应一组命令行

比如:
systemctl 管理系统
systemd-analyze命令用于查看启动耗时:

szw@lnx:~$ systemd-analyze
Startup finished in 4.782s (kernel) + 1min 23.476s (userspace) = 1min 28.258s
graphical.target reached after 51.515s in userspace

等等。。

2.2 它定义了基本单元及其依赖关系

systemd定义了target, Unit等对象。看看下面目录(删除了不少东西):

szw@lnx:/etc/systemd/system$ ll
drwxr-xr-x  2 root root 4096 4月  27 02:23  default.target.wants/
lrwxrwxrwx  1 root root   32 5月   1 19:08  display-manager.service -> /lib/systemd/system/gdm3.service
drwxr-xr-x  2 root root 4096 4月  27 02:24  display-manager.service.wants/
drwxr-xr-x  2 root root 4096 4月  27 02:23  emergency.target.wants/
drwxr-xr-x  2 root root 4096 5月   1 19:40  final.target.wants/
drwxr-xr-x  2 root root 4096 4月  27 02:18  getty.target.wants/
drwxr-xr-x  2 root root 4096 5月   1 19:40  graphical.target.wants/
drwxr-xr-x  2 root root 4096 5月   2 12:45  multi-user.target.wants/
drwxr-xr-x  2 root root 4096 4月  27 02:24  network-online.target.wants/

drwxr-xr-x  2 root root 4096 5月   1 19:40  sockets.target.wants/
drwxr-xr-x  2 root root 4096 4月  27 02:25  spice-vdagentd.target.wants/
drwxr-xr-x  2 root root 4096 5月   1 19:40  sysinit.target.wants/
lrwxrwxrwx  1 root root   35 5月   1 19:08  syslog.service -> /lib/systemd/system/rsyslog.service
drwxr-xr-x  2 root root 4096 4月  27 02:24  timers.target.wants/

简单看一下,default.target.wants意思就是default.target启动的时候需要启动ureadahead.service这个Unit:

szw@lnx:/etc/systemd/system/default.target.wants$ ll 
lrwxrwxrwx  1 root root   38 5月   1 19:08 ureadahead.service -> /lib/systemd/system/ureadahead.service

看一下syslog.service :

szw@lnx:/etc/systemd/system$ ls syslog.service -l
lrwxrwxrwx 1 root root 35 5月   1 19:08 syslog.service -> /lib/systemd/system/rsyslog.service

szw@lnx:/etc/systemd/system$ cat syslog.service 
[Unit]
Description=System Logging Service
Requires=syslog.socket
Documentation=man:rsyslogd(8)
Documentation=http://www.rsyslog.com/doc/

[Service]
Type=notify
ExecStart=/usr/sbin/rsyslogd -n  # 主要看这一句,本质上还是要去执行对应的程序
StandardOutput=null
Restart=on-failure

[Install]
WantedBy=multi-user.target
Alias=syslog.service

[1]:Systemd 定时器教程
[2]:Systemd 入门教程:实战篇