Merikanto

一簫一劍平生意,負盡狂名十五年

Linux Boot Process

今天来简单总结一下 Linux 的启动流程。从主机设备加电开始一直到操作系统展开登录界面的过程,称为操作系统启动过程。Linux 在启动过程中默默完成了许多初始化任务,包括装载 Linux 内核模块启动网络服务设定时钟等。相关链接:

Linux 之 /etc/inittab 文件

关于 Ubuntu 修改默认运行级别


启动顺序

1. BIOS 自检:计算机加电后,系统将自动读取 BIOS 中的硬件信息(如:显卡、内存、主板、CPU 等)。然后查找启动设备并设置优先级。接着系统开始用 POST 自检 (Power On Self Test),若有问题会给出提示信息,没有问题就启动执行硬件初始化,并设置 PnP (Plug-and-Play)设备。最后启动驻留在硬盘主引导记录 MBR (MasterBoot Record,主引导分区)中的引导程序 GRUB 或 lilo。

2. GRUB / lilo 引导启动程序:用户通过 GRUB 或 lilo 引导加载程序启动 Linux 系统。引导程序只是将控制权交给内核,此时操作系统并未装入内存。其中,ubuntu 默认 GRUB 为引导加载程序。

3. 装载 Linux 内核:最初的引导过程完成后,引导程序开始加载 Linux 内核。ubuntu 的 Linux 内核在 /boot 目录下。

4. 系统初始化:Ubuntu 采用的是基于事件的启动管理器 —— Upstart,主要包括 3 个程序(init, telinit, runlevel)和相应配置文件目录(/etc/init/etc/rcN.d/etc/init.d)组成。系统内核首先会启动 init 进程,读取并运行 /etc/init 目录下的启动配置文件,init 启动任务时会读取默认的运行等级(runlevel),然后将结果传递给 upstart 的下一个组件 telinit 中。telinit 通过比较当前 runlevel 与将要进入的 runlevel 之间运行服务的不同,关闭不需要的服务项,启动目前未运行的服务,从而实现系统状态的转换。


初始化阶段完成后,系统就可以准备接受用户登录。下面是补充说明:

  • bios :接管主板所有自检工作,掌握系统的启动,部件之间的兼容和程序管理等多项任务。连接软件与硬件设备的“桥梁”。

  • boot loader :grub 实际上是一个 boot loader,开机管理程序可以指定使用哪个核心文件来开机,并实际载入核心(kernel)到内存当中解压缩与执行, 此时核心就能够开始在内存内活动,并侦测所有硬件信息与载入适当的驱动程序来使整部主机开始运行。

  • init 进程:系统开始的第一个工作,它是其他所有进程的父进程,一直处在运行状态,并且进程 id 号永远是第一个。作用是读取初始化脚本,完成系统相关管理任务。


运行级别

Linux 系统的运行级别由 init 启动的,可以通过 ps aux 看到 PID=1 的是 init 进程。init 是 Linux 内核启动的用户级别进程。ubuntu 的默认运行级别文件是 /etc/init/rc-sysinit.conf 。在 /etc/rc.d 目录中定义了各种运行级别的运行服务:

1
2
cd /etc
ls | grep rc

级别 功能
0 关闭系统
1 让系统进入单用户(S,恢复)模式
2/3/4/5 多用户,图形界面,运行所有预定的系统服务。于系统定制而言,运行级别2-5的作用相同。
6 重启系统
S 单用户与(恢复)模式, 文本登录界面,只运行很少几项系统服务

默认情况下,ubuntu 系统引导进入运行级别 2。查看定义为 2 级别的服务:

1
ls rc2.d

说明:

  • rc.local 可以写入任何想要开机时就进行的工作,在启动的最后阶段,系统会执行存于 rc.local 中的命令。

  • 目录里面的服务以 K 开头的是系统将终止对应的服务,以 S 开头的是系统将启动对应的服务。

  • S 或者 K 后面跟的数字是程序优先级,数值越小,优先级越高。数字后面的是服务的名称。


查看 /etc/init/rc-sysinit.conf 的内容:

1
cat /etc/init/rc-sysinit.conf

可以看到 default runlevel = 2,即默认运行级别为 2。


添加 / 移除开机启动项

1. 用 rc.local

/rc.local 脚本是 ubuntu 开机之后就会自动执行的一个脚本,位于 /etc

1
vim /etc/rc.local 

如果需要添加执行的操作,那么必须写在 exit 0 之前。


2. 自定义脚本

新建脚本,设置脚本权限:

1
2
vim new.sh
chmod +x new.sh

移动脚本到启动目录下:

1
mv new.sh /etc/init.d/new_service.sh

将自定义脚本添加至启动项中:

1
2
cd /etc/init.d/
update-rc.d new_service.sh defaults 95

(其中,数值 95 表示一个优先级,越小表示执行的越早,可以按照需要修改。) 设置某些运行级别启动,某些运行级别不启动:

1
update-rc.d mysql start 50 2 3 4 . stop 51 0 1 5 6 . 

优先级为 50 的在 2,3,4 上启动,优先级为 51 的在 0,1,5,6 上不启动。


3. 使用 sysv-rc-conf

安装:

1
apt-get install sysv-rc-conf

验证使用工具:

1
2
sudo su
sysv-rc-conf

用鼠标点击,或方向键定位;用空格键设置,X 表示开启该服务,q 退出。


4. 举例:将 mysql 设置为自启动

使用 update-rc.d

1
update-rc.d mysql defaults

用  ll 查看 mysql 运行信息

1
ll /etc/rc?.d/*mysql

移除自启动:

1
update-rc.d -f mysql remove