文章目录
- [10. Linux 系统启动原理](#10. Linux 系统启动原理)
10. Linux 系统启动原理
CentOS 7 启动过程
现代计算机系统是硬件与软件的复杂组合。从断电状态开始,到拥有登录提示符的运行中系统,这需要大量的硬件和软件配合工作。
以下列表从较高层面概述了 CentOS7 启动过程。

-
计算机接通电源。系统固件(现代UEFI或更旧的BIOS)运行开机自检(POST),并开始初始化硬件。
配置: 在系统启动早期,通过按特定的组合键,例如F2,配置系统固件。
-
系统固件搜索启动设备,根据固件配置的顺序搜索启动磁盘上的主启动记录(MBR)。系统固件从磁盘读取boot loader,然后将系统控制权交给boot loader,boot loader是GRand Unified Bootloader version 2(GRUB2)。
配置: 使用 grub2-install 命令进行配置,它将安装 GRUB2 作为磁盘上的启动加载器。
-
GRUB2从/boot/grub2/grub.cfg文件加载配置并显示一个操作系统菜单,可以从中选择要启动的系统。
配置: 使用 /etc/grub.d/ 目录、/etc/default/grub 文件和 grub2-mkconfig 命令进行配置,以生成 /boot/grub2/grub.cfg 文件。
-
boot loader根据选定条目的配置,从磁盘中加载kernel和initramfs,并将它们放入内存中。initramfs是一个存档,其中包含启动时所有必要硬件的内核模块、初始化脚本等等。
boot loader将控制权交给kernel,并同时将启动项的内核参数、initramfs在内存中的位置传递给kernel。内核在initramfs中找到所有硬件驱动程序,并初始化这些硬件。
配置: 使用 /etc/dracut.conf.d/ 用录、dracut 命令和 lsinitrd 命令进行配置,以检查 initramfs 文件。
-
initramfs 执行/sbin/init,作为PID 1。在CentOS中,/sbin/init是一个指向systemd的链接。
配置: 使用内核参数
init=command
配置系统初始化程序。 -
随后,systemd会加载从内核命令行传递的target或者加载系统配置的default.target,该目标通常启动一个基于文本的登录或图形登录屏幕。
**配置:**使用systemctl设置默认target。
-
default.target依赖sysinit.target,sysinit.target用于初始化系统,例如读取/etc/fstab挂载文件系统,激活systemd-journald等。
**配置:**使用/etc/fstab配置文件系统开机自动挂载。
-
default.target还会激活开机启动的单元。
**配置:**使用systemctl设置开机启用服务。
-
default.target还会激活getty.target,该target将打开tty1终端用于用户登录。
系统 target
systemd使用类型为target的单元来分组不同单元,例如multi-user.target包涵chronyd.service、crond.service、firewalld.service等服务。
target还可以包涵其他target,例如graphical.target包涵multi-user.target,multi-user.target包涵basic.target,basic.target包涵sysinit.target。
使用以下命令查看target之间依赖关系:
bash
[root@server ~ 16:46:28]# systemctl list-dependencies graphical.target
graphical.target
● ├─display-manager.service
● ├─network.service
● ├─systemd-update-utmp-runlevel.service
● └─multi-user.target
● ├─auditd.service
● ├─crond.service
● ├─dbus.service
● ├─firewalld.service
● ├─irqbalance.service
● ├─mdmonitor.service
● ├─network.service
● ├─NetworkManager.service
● ├─nginx.service
● ├─plymouth-quit-wait.service
● ├─plymouth-quit.service
● ├─postfix.service
● ├─rhel-configure.service
# 查看反向依赖
[root@server ~ 16:53:03]# systemctl list-dependencies sshd.service --reverse
sshd.service
● └─multi-user.target
● └─graphical.target
系统启动级别
CentOS 6 之前使用启动级别控制系统开机激活哪些服务。CentOS 7 使用target控制系统开机激活哪些服务。
runlevel | target | 作用 |
---|---|---|
0 | 关机,init 0 同 poweroff 和systemctl poweroff |
|
1 | emergency.target rescue.target | 单用户模式、救援模式和紧急模式用于修复系统 |
2 | 多用户文本界面,不具备NFS功能 | |
3 | multi-user.target | 多用户文本界面 |
4 | 未使用 | |
5 | graphical.target | 多用户图形界面 |
6 | 重启,init 6 同 reboot 和systemctl reboot |
设置系统运行目标
/etc/inittab文件是CentOS 6之前版本初始化系统使用的配置文件。
bash# 部分内容如下 # 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) # # 设置运行级别为5,也就是图形化方式启动。 id:5:initdefault:
设置系统当前运行 target
bash
# 设置系统当前运行target为multi-user.target
[root@server ~ 16:55:38]# systemctl isolate multi-user.target
# 设置系统当前运行target为graphical.target
[root@server ~ 16:55:58]# systemctl isolate graphical.target
设置系统开机默认运行 target
bash
# 查看系统开机默认运行target
[root@server ~ 16:56:56]# systemctl get-default
multi-user.target
# 设置系统开机默认运行target
[root@server ~ 16:57:53]# systemctl set-default multi-user.target
# 重启验证
重置 ROOT 密码
以下几种方法可用于设置新的root密码。例如:
- 系统管理员可以使用Live CD启动系统,挂载根文件系统,然后编辑/etc/shadow:
- 删除root账户密码字段
- 使用已知密码字段替换root密码字段
- 在CentOS 7之后版本中,可以让initramfs运行的脚本在某些点暂停,以提供root身份的shell,然后在该shell中重置root密码。
方法1:rd.break
- 重新启动系统。
- 按任意键(Enter除外)中断启动加载器倒计时。
- 将光标移至第一个内核条目,按e编辑当前条目。

4.将光标移至以 linux16 开头的行,末尾附加 rd.break。利用该选项,在系统从initramfs向实际系统移交控制权前,系统将会中断。按Ctrl+x进行启动。

5.此时,系统会显示root shell,且磁盘上的实际根文件系统以只读方式挂载在/sysroot。
以读/写形式重新挂载/sysroot。
bash
switch_root:/# mount -o remount,rw /sysroot
6.切换root位置,把/sysroot做为文件系统树的根。
bash
switch_root:/# chroot /sysroot
7.设置新root密码。
bash
sh-4.2# echo password | passwd --stdin root
提示:password 是用户自定义密码。
8.如果系统开启了 SELinux 功能,则需要确保所有未标记的文件(包括此时的/etc/shadow)在启动过程中都会重新获得标记。
bash
sh-4.2# touch /.autorelabel
9.执行以下命令,系统将继续启动。如果系统开启了SELinux功能,还需要执行完整的 SELinux 重新标记,然后再次重新启动。
bash
sh-4.2# exit
switch_root:/# exit
10.登录验证。
方法2:init=/bin/bash
-
重新启动系统。
-
按任意键(Enter除外)中断启动加载器倒计时。
-
将光标移至第一个内核条目,按e编辑当前条目。
-
将光标移至以 linux16 开头的行,末尾附加
init=/bin/bash
。利用该选项,在系统从initramfs向实际系统移交控制权前,系统将会中断,请开启一个root shell。按Ctrl+x使用这些更改进行启动。 -
此时系统会显示root shell,且磁盘上的实际根文件系统以只读方式挂载在/。以读/写形式重新挂载/。
bashbash-4.2# mount -o remount,rw /
-
使用以下命令删除root密码,等进入系统后再重新设置root密码。
bashsh-4.2# passwd -d root
此时还可以使用vi编辑器直接编辑/etc/shadow文件,复制已知用户的密码记录替换root密码。
-
如果系统开启了 SELinux 功能,则需要确保所有未标记的文件(包括此时的/etc/shadow)在启动过程中都会重新获得标记。
bashsh-4.2# touch /.autorelabel
-
执行以下命令,系统将继续启动。如果系统开启了SELinux功能,还需要执行完整的 SELinux 重新标记,然后再次重新启动。
bashsh-4.2# exec /usr/lib/systemd/systemd
-
使用root登录,此时不需要密码。
/etc/fstab 引起的系统启动问题
环境准备
bash
# 设置磁盘分区管理方案
[root@server ~ 18:27:47]# parted /dev/sdb mklabel msdos
警告: The existing disk label on /dev/sdb will be destroyed and all
data on this disk will be lost. Do you want to continue?
是/Yes/否/No? y
信息: You may need to update /etc/fstab.
# 创建分区
[root@server ~ 18:38:58]# parted /dev/sdb unit MiB mkpart primary 1 10241
信息: You may need to update /etc/fstab.
# 格式化为xfs文件系统
[root@server ~ 18:39:10]# mkfs.xfs /dev/sdb1
mkfs.xfs: /dev/sdb1 appears to contain an existing filesystem (xfs).
mkfs.xfs: Use the -f option to force overwrite.
# 创建挂载点
[root@server ~ 18:40:12]# mkdir /data01
# 设置持久化挂载
[root@server ~ 18:40:35]# echo '/dev/sdb1 /data01 xfs defaults 0 0' >> /etc/fstab
# 挂载并验证
[root@server ~ 18:41:18]# mount -a
[root@server ~ 18:41:23]# df -h /data01
文件系统 容量 已用 可用 已用% 挂载点
/dev/sdb1 10G 33M 10G 1% /data01
故障1:挂载点不存在
环境准备
bash
[root@server ~ 18:41:34]# umount /data01
[root@server ~ 18:42:06]# rmdir /data01
重启系统验证
bash
# 可以正常进入系统,挂载点会被自动创建
[root@server ~ 18:43:36]# df -h /data01
文件系统 容量 已用 可用 已用% 挂载点
/dev/sdb1 10G 33M 10G 1% /data01
故障2:设备名称写错或者找不到设备
环境准备
[root@server ~ 18:45:53]# vim /etc/fstab
# 将原先的sdb1修改为sdb2
/dev/sdb2 /data01 xfs defaults 0 0
重启系统验证
-
启动过程中找不到该设备。
-
1分30秒超时后,进入emergency模式,进行修复。
修改为正确的值或者注释该条目,确保系统正常启动。
-
然后输入exit,继续启动。
故障3:破坏文件系统
环境准备
bash
[root@server ~ 18:49:30]# dd if=/dev/zero of=/dev/sdb1 bs=1M count=1
记录了1+0 的读入
记录了1+0 的写出
1048576字节(1.0 MB)已复制,0.000951483 秒,1.1 GB/秒
重启系统验证
- 系统启动过程中尝试修复文件系统,修复失败后提示进入 emergency 模式修复。

2.输入root 密码进入emergency 模式。
bash
# 执行以下命令修复
[root@server ~ 18:54:45]# xfs_repair /dev/sdb1
修复完成后,输入 exit 正常启动系统。
