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

步骤 1:开机自检(BIOS/UEFI)
核心作用
完成硬件初始化与自检,确认 CPU、内存、硬盘、主板等关键硬件是否正常,然后选择启动设备(硬盘 / U 盘 / 网卡)。
底层原理
- 主板上的 BIOS/UEFI 固件会按顺序读取硬件信息,执行 POST(Power-On Self-Test)自检。
- 自检通过后,会读取启动设备的引导扇区,将控制权交给下一步的引导程序。
补充 & 排障
- 排障场景:开机无显示、主板报错灯亮、提示 “no boot device found”,多为硬件故障或启动顺序设置错误。
- 常用操作:按
Del/F2进入 BIOS 设置,调整启动顺序;物理机可通过主板蜂鸣器代码判断硬件故障。
步骤 2:MBR 引导(Master Boot Record)
核心作用
读取硬盘前 512 字节的主引导记录,找到并加载 GRUB 引导程序。
底层原理
- MBR 包含三部分:引导代码(446 字节)、分区表(64 字节)、结束标志(2 字节)。
- BIOS 执行完后,会把控制权交给 MBR 里的引导代码,由它加载 GRUB 的核心文件。
补充 & 排障
-
UEFI 模式区别:UEFI 启动时,会读取硬盘上的 ESP 分区(FAT32 格式),加载
grubx64.efi文件,而非传统 MBR。 -
修复命令
:MBR 损坏无法启动时,可通过安装盘进入救援模式,执行:
grub2-install /dev/sda
步骤 3:GRUB 菜单(GRand Unified Bootloader)
核心作用
提供内核选择、修改启动参数,加载内核与 initramfs 镜像。
底层原理
- GRUB 是多阶段引导程序:第一阶段由 MBR 加载,第二阶段读取
/boot/grub2/grub.cfg配置文件,显示菜单。 - 破解 root 密码、修改
LANG环境变量等操作,都是在这一步按e修改内核参数。
补充 & 排障
-
常用内核参数
:
rd.break:打断启动进入救援模式systemd.unit=rescue.target:直接进入救援模式nomodeset:解决显卡驱动导致的启动黑屏
-
修复命令
:GRUB 损坏时,可通过安装盘挂载系统分区,重新生成配置文件:
grub2-mkconfig -o /boot/grub2/grub.cfg
步骤 4:加载内核(kernel)
核心作用
解压内核镜像,加载必要的驱动,挂载临时根文件系统(initramfs)。
底层原理
- 内核被 GRUB 加载到内存后,会解压并初始化硬件,此时还无法直接挂载真实根分区(缺少磁盘 / 文件系统驱动)。
- 内核会加载
initramfs(包含驱动和工具的临时文件系统),识别硬盘、加载 LVM/RAID 驱动,找到真实根分区。
补充 & 排障
-
initramfs 损坏
:启动卡在
dracut:提示符,重建命令:
dracut -f /boot/initramfs-$(uname -r).img $(uname -r) -
关键区别:CentOS7 的 initramfs 由
dracut工具生成,CentOS6 及更早版本使用mkinitrd。
步骤 5:运行 systemd 进程(PID=1)
核心作用
内核切换到真实根分区后,执行的第一个用户进程,接管整个系统的初始化与服务管理。
底层原理
systemd是 CentOS7 的默认 init 程序,替代了旧版的SysVinit。- 它以并行方式启动服务,大幅缩短开机时间;同时通过
target管理不同的运行级别。
补充 & 排障
-
验证命令
ps -ef | head -2可看到 PID=1 的进程是
/usr/lib/systemd/systemd。
-
关键特性:
systemd支持服务依赖管理、日志统一管理(journalctl)、资源控制(cgroup)。
步骤 6:根据 target 模式选择启动级别(/etc/systemd/system/default.target)
核心作用
确定系统默认的运行级别,决定启动哪些服务。
底层原理
default.target是一个软链接,指向实际的 target 文件(如multi-user.target或graphical.target)。- 它对应旧版的运行级别(0-6),但更灵活,支持自定义 target。
补充 & 命令
-
查看当前默认级别:
systemctl get-default -
修改默认级别:
# 切换为命令行模式 systemctl set-default multi-user.target # 切换为图形模式 systemctl set-default graphical.target -
查看软链接指向:
ls -l /etc/systemd/system/default.target
步骤 7:执行sysinit.target(系统初始化脚本)
核心作用
完成系统基础初始化,是所有 target 的基础依赖。
底层原理
sysinit.target包含挂载文件系统、启用 swap、加载内核模块、设置系统时钟等关键任务。- 只有
sysinit.target完全启动后,才会继续启动其他 target(如multi-user.target)。
补充 & 依赖关系
-
依赖链示例:
multi-user.target → basic.target → sysinit.target → local-fs.target/swap.target -
查看依赖关系:
systemctl list-dependencies sysinit.target
步骤 8:/etc/systemd/system 定义开机启动服务
核心作用
根据当前 target,启动所有关联的.service服务单元。
底层原理
- 每个服务单元文件通过
[Install]段的WantedBy=配置,关联到对应的 target。 - 执行
systemctl enable xxx.service时,systemd会在/etc/systemd/system/<target>.wants/目录下创建软链接,target 启动时会自动加载这些服务。
补充 & 命令
-
查看某个 target 下的所有服务:
systemctl list-dependencies multi-user.target -
查看服务的 target 关联:
systemctl show sshd | grep WantedBy -
手动关联服务到 target:
ln -s /usr/lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/
步骤 9:启动 mingetty 进程
核心作用
在终端提供登录界面,等待用户输入账号密码,完成系统启动流程。
底层原理
mingetty是终端登录管理器,会在每个虚拟终端(tty1-tty6)上显示login:提示符。- 用户登录后,会启动对应的 shell(如
bash),即可操作系统。
补充 & 排障
-
查看终端进程:
ps aux | grep mingetty -
若无法登录,可进入救援模式检查:
-
/etc/passwd//etc/shadow文件是否损坏 -
mingetty服务状态:
systemctl status getty.target
-
补充:Linux 启动级别(target)详解
| target 名称 | 对应旧运行级别 | 作用 |
|---|---|---|
poweroff.target | 0 | 关机 |
rescue.target | 1 | 单用户救援模式(仅 root 登录,修复系统) |
multi-user.target | 3 | 多用户命令行模式(服务器常用) |
graphical.target | 5 | 多用户图形模式(带桌面环境) |
reboot.target | 6 | 重启 |
系统 target
普通文件和目录之间关系:
- 普通文件:用来存储数据,例如MP3、mp4、fstab、passwd
- 目录:用来组织文件系统分层结构,白话用来分组文件。
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之间依赖关系:
[root@sever ~ 10:53:52]# systemctl list-dependencies graphical.target
graphical.target
● ├─display-manager.service
● ├─network.service
● ├─systemd-update-utmp-runlevel.service
● └─multi-user.target
● ├─auditd.service
● ├─chronyd.service
● ├─crond.service
● ├─dbus.service
● ├─irqbalance.service
● ├─network.service
● ├─NetworkManager.service
● ├─plymouth-quit-wait.service
● ├─plymouth-quit.service
# 查看反向依赖
[root@sever ~ 13:32:11]# systemctl list-dependencies sshd.service --reverse
sshd.service
● └─multi-user.target
● └─graphical.target
系统启动级别
传统的 SysVinit 系统定义了 7 个运行级别(0-6),每个级别有特定的作用,具体如下:
| 运行级别 | target | 作用描述 |
|---|---|---|
| 0 | 关机(halt):系统终止所有进程并关闭电源,对应命令 shutdown -h now。 | |
| 1 | emergency.target rescue.target | 单用户模式(single user mode):仅 root 用户可登录,无网络服务,用于系统修复(如密码找回)。 |
| 2 | 多用户模式(无 NFS):支持多用户登录,但不启动网络文件系统(NFS),部分发行版(如 Debian)默认此级别功能与级别 3 相同。 | |
| 3 | multi-user.target | 完全多用户模式(文本界面):启动所有网络服务,用户通过命令行登录,无图形界面。 |
| 4 | 预留级别:默认未使用,可由用户自定义用途。 | |
| 5 | graphical.target | 图形化多用户模式:在级别 3 的基础上启动图形界面(如 GNOME、KDE),用户通过图形登录界面访问系统。 |
| 6 | 重启(reboot):系统终止所有进程并重启,对应命令 shutdown -r now。 |
设置系统当前运行 target
# 设置系统当前运行target为multi-user.target
[root@client ~ 14:58:00]# systemctl isolate multi-user.target
# 等效于
[root@client ~ 15:00:56]# init 3
# 设置系统当前运行target为graphical.target
[root@client ~ 15:01:24]# systemctl isolate graphical.target
# 等效于
[root@client ~ 15:01:47]# init 5
设置系统开机默认运行 target
# 查看系统开机默认运行target
[root@client ~ 15:02:28]# systemctl get-default
multi-user.target
# 设置系统开机默认运行target
[root@client ~ 15:02:30]# systemctl set-default graphical.target
# 重启验证
在系统启动时选择其它目标
要在启动时选择其他目标,将 systemd.unit=target.target 参数附加到内核命令行。该配置是临时生效的,经常用于系统启动过程中故障排除。
要使用这种选择其他目标的方法,请执行以下步骤:
- 启动或重新启动系统。
- 按任意键中断启动加载器菜单倒计时(Enter除外,它用于执行正常启动)。
- 将光标移至第一个内核条目,按e编辑当前条目。
重置 ROOT 密码
以下几种方法可用于设置新的root密码。例如:
- 系统管理员可以使用Live CD启动系统,挂载根文件系统,然后编辑/etc/shadow:
- 删除root账户密码字段
- 使用已知密码字段替换root密码字段
- 在CentOS 7之后版本中,可以让initramfs运行的脚本在某些点暂停,以提供root身份的shell,然后在该shell中重置root密码。
方法1:rd.break
-
重新启动系统。
-
按任意键(Enter除外)中断启动加载器倒计时。
-
将光标移至第一个内核条目,按e编辑当前条目。
-
将光标移至以 linux16 开头的行,末尾附加 rd.break。利用该选项,在系统从initramfs向实际系统移交控制权前,系统将会中断。按Ctrl+x进行启动。
-
此时,系统会显示root shell,且磁盘上的实际根文件系统以只读方式挂载在/sysroot。
以读/写形式重新挂载/sysroot。
switch_root:/# mount -o remount,rw /sysroot
- 切换root位置,把/sysroot做为文件系统树的根。
switch_root:/# chroot /sysroot
- 设置新root密码。
sh-4.2# echo password | passwd --stdin root
提示:password 是用户自定义密码。
- 如果系统开启了 SELinux 功能,则需要确保所有未标记的文件(包括此时的/etc/shadow)在启动过程中都会重新获得标记。
sh-4.2# touch /.autorelabel
- 执行以下命令,系统将继续启动。如果系统开启了SELinux功能,还需要执行完整的 SELinux 重新标记,然后再次重新启动。
sh-4.2# exit
switch_root:/# exit
- 登录验证。
方法2:init=/bin/bash
- 重新启动系统。
- 按任意键(Enter除外)中断启动加载器倒计时。
- 将光标移至第一个内核条目,按e编辑当前条目。
- 将光标移至以 linux16 开头的行,末尾附加
init=/bin/bash。利用该选项,在系统从initramfs向实际系统移交控制权前,系统将会中断,请开启一个root shell。按Ctrl+x使用这些更改进行启动。 - 此时系统会显示root shell,且磁盘上的实际根文件系统以只读方式挂载在/。以读/写形式重新挂载/。
bash bash-4.2# mount -o remount,rw /
- 使用以下命令删除root密码,等进入系统后再重新设置root密码。
bash sh-4.2# passwd -d root
此时还可以使用vi编辑器直接编辑/etc/shadow文件,复制已知用户的密码记录替换root密码。
- 如果系统开启了 SELinux 功能,则需要确保所有未标记的文件(包括此时的/etc/shadow)在启动过程中都会重新获得标记。
bash sh-4.2# touch /.autorelabel
- 执行以下命令,系统将继续启动。如果系统开启了SELinux功能,还需要执行完整的 SELinux 重新标记,然后再次重新启动。
bash sh-4.2# exec /usr/lib/systemd/systemd
- 使用root登录,此时不需要密码。
/etc/fstab 引起的系统启动问题
环境准备
# 设置磁盘分区管理方案
[root@sever ~ 16:00:37]# parted /dev/sdb mklabel msdos
信息: You may need to update /etc/fstab.
# 创建分区
[root@sever ~ 16:00:51]# parted /dev/sdb unit MiB mkpart primary 1 2049
信息: You may need to update /etc/fstab.
# 格式化为xfs文件系统
[root@sever ~ 16:01:16]# 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@sever ~ 16:01:24]# mkdir /data01
mkdir: 无法创建目录"/data01": 文件已存在
[root@sever ~ 16:01:30]# echo '/dev/sdb1 /data01 xfs defaults 0 0' >> /etc/fstab
[root@sever ~ 16:02:35]# vim /etc/fstab
[root@sever ~ 16:02:52]# mount -a
[root@sever ~ 16:02:56]# df -h /data01
文件系统 容量 已用 可用 已用% 挂载点
/dev/sdb1 2.0G 33M 2.0G 2% /data01
故障1:挂载点不存在
环境准备
[root@sever ~ 16:09:26]# clear
[root@sever ~ 16:09:49]# umount /data01
[root@sever ~ 16:09:54]# rmdir /data01
重启系统验证
[root@sever ~ 16:09:59]# reboot
# 可以正常进入系统,挂载点会被自动创建
[root@sever ~ 16:10:23]# df -h /data01
文件系统 容量 已用 可用 已用% 挂载点
/dev/sdb1 2.0G 33M 2.0G 2% /data01
故障2:设备名称写错或者找不到设备
环境准备
[root@sever ~ 16:10:31]# vim /etc/fstab
# 将原先的sdb1修改为sdb2
/dev/sdb2 /data01 xfs defaults 0 0
重启系统验证
- 启动过程中找不到该设备。
- 1分30秒超时后,进入emergency模式,进行修复。
修改为正确的值或者注释该条目,确保系统正常启动。
- 然后输入exit,继续启动。
故障3:破坏文件系统
环境准备
[root@sever ~ 16:12:20]# dd if=/dev/zero of=/dev/sdb1 bs=1M count=1
重启系统验证
-
系统启动过程中尝试修复文件系统,修复失败后提示进入 emergency 模式修复。
-
输入root 密码进入emergency 模式。
bash # 执行以下命令修复 [root@centos7 ~]# xfs_repair /dev/sdb1
修复完成后,输入 exit 正常启动系统。
grub2 配置
grub2 配置文件
grub2 的主要配置文件如下:
- /boot/grub2,grub2的主要配置文件所在目录,例如grub.cfg、grubenv、user.cfg。
- /etc/grub2.cfg
- /etc/grub2.cfg 是指向 /boot/grub2/grub.cfg的软连接。
- 不要直接修改/etc/grub2.cfg文件,该文件由系统自动生成。如果需要自定义这个文件,可以通过修改/etc/grub.d/中脚本和/etc/default/grub文件,然后通过grub2-mkconfig命令生成。
使用efi启动方式的grub2配置文件是/etc/grub2-efi.cfg。
- /etc/grub.d/,该目录下存放多个数字开头的脚本,按照从小到大的顺序执行。例如00_header会调用/etc/default/grub配置文件来实现最基本的开机界面配置。
- /etc/default/grub,定义grub启动部分变量信息,例如grub启动菜单选择条目的超时时间,内核参数等。
- /boot/grub2/grubenv,设定默认启动条目。
[root@sever ~ 16:13:12]# vim /etc/default/grub
# 修改GRUB_TIMEOUT为10
GRUB_TIMEOUT=10
#生效grub2.cfg配置文件
[root@sever ~ 16:13:44]# grub2-mkconfig -o /etc/grub2.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-1160.71.1.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1160.71.1.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-1726b4f4386a4708b5dfcc73730c6f94
Found initrd image: /boot/initramfs-0-rescue-1726b4f4386a4708b5dfcc73730c6f94.img
done
#重启
[root@sever ~ 16:14:19]# reboot
kernel 启动参数
[root@sever ~ 16:15:30]# vim /etc/default/grub
# 修改GRUB_CMDLINE_LINUX,例如在最后添加参数console=ttyS0,导致不显示启动过程
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet console=ttyS0"
# console=ttyS0: 启动过程信息显示到 ttyS0 终端,导致启动过程是tty1上不显示启动消息。
# rhgb:启用图形化启动界面(Red Hat Graphical Boot)。
# quiet:减少启动过程中的日志输出(只显示重要信息), debug 开启调试模式(显示详细启动日志)
[root@sever ~ 16:15:41]# grub2-mkconfig -o /etc/grub2.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-1160.71.1.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1160.71.1.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-1726b4f4386a4708b5dfcc73730c6f94
Found initrd image: /boot/initramfs-0-rescue-1726b4f4386a4708b5dfcc73730c6f94.img
done
[root@sever ~ 16:15:46]# reboot
grub 菜单加密
# 查看/etc/grub.d/01_users脚本
[root@sever ~ 16:17:34] cat /etc/grub.d/01_users
#!/bin/sh -e
cat << EOF
if [ -f \${prefix}/user.cfg ]; then
source \${prefix}/user.cfg
if [ -n "\${GRUB2_PASSWORD}" ]; then
set superusers="bgy"
export superusers
password_pbkdf2 bgy \${GRUB2_PASSWORD}
fi
fi
EOF
# 生成grub2密码
[root@sever ~ 16:17:37]# grub2-mkpasswd-pbkdf2
输入口令:
Reenter password:
# 创建文件
[root@sever ~ 16:18:38]# vim /boot/grub2/user.cfg
# 生成grub2.cfg配置文件,重启验证
[root@sever ~ 16:18:53]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-1160.71.1.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1160.71.1.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-1726b4f4386a4708b5dfcc73730c6f94
Found initrd image: /boot/initramfs-0-rescue-1726b4f4386a4708b5dfcc73730c6f94.img
done
[root@sever ~ 16:19:14]# reboot
#效果
启动菜单界面,按e编辑。
输入自己设置的用户名密码。
进入编辑页面
思考
1. 如何避免别人获得磁盘后,读取磁盘中数据?
1. LUKS 磁盘加密(Linux 通用)
1.全盘加密
新装系统直接把分区做成 LUKS 加密卷,无密钥无法挂载读取。
# 创建加密分区
cryptsetup luksFormat /dev/sdb1
# 临时解密挂载
cryptsetup open /dev/sdb1 cryptsdb
# 格式化后正常使用
mkfs.xfs /dev/mapper/cryptsdb
开机需输入解密密码,拆盘挂载无密码直接无法读取数据。
2. 系统根分区加密
装机时勾选加密磁盘,整个系统盘底层加密,物理拿走磁盘无效。
二、文件级加密
- gpg 加密单个文件
gpg -c test.txt # 设置密码加密
gpg -d test.txt.gpg # 解密
-
ecryptfs 个人目录加密
用户家目录自动加密,注销后文件密文存储。
三、硬件层面防护
-
BIOS/UEFI 设密码
禁止 U 盘启动、禁止修改启动项,防止外接启动盘破解磁盘。
-
禁用磁盘热插拔
BIOS 关闭 SATA/NVMe 热插拔,减少拆盘读取机会。
-
TPM 芯片绑定加密密钥
密钥存硬件芯片,脱离本机硬件无法解密。
四、权限与安全加固
- 关闭 SELinux 宽容模式,保持
Enforcing最小权限管控 - 禁止普通用户查看磁盘设备
chmod 600 /dev/sd*
- 禁用 root 远程直接登录,降低提权读盘风险
五、废弃磁盘彻底销毁数据
普通删除可恢复,彻底抹除:
# 全盘随机覆写,数据无法恢复
dd if=/dev/urandom of=/dev/sdb bs=4M status=progress
六、辅助防窃取
- GRUB 菜单加密,阻止单用户篡改挂载
- 重要数据定期异地加密备份
- 虚拟机磁盘文件单独加密存放
2. 为什么将vmlinuz(kernel)和initramfs(user)分开?
- 内核体积小、只带基础驱动
vmlinuz 纯内核代码,只包含 CPU、内存、基础总线驱动,体积小启动快。
- initramfs 存放海量外设驱动
磁盘、LVM、XFS、RAID、网卡、加密分区等驱动,全都打包在这里。
- 硬件五花八门,内核不可能全塞进本体
虚拟机、物理机、不同硬盘格式、阵列卡,驱动差异极大,分开存放灵活适配。
3. Linux为什么不直接使用真正的根启动?
核心原因:开机初期没有对应文件系统 / 磁盘驱动
- 刚上电只加载内核,不认 XFS/ext4/LVM/RAID
- 直接挂真实根盘会报错、挂不上、启动卡死
启动真实流程
- GRUB 加载 vmlinuz 内核
- 加载 initramfs 虚拟内存小系统
- 临时系统加载磁盘、文件系统驱动
- 识别真实
/dev/mapper/xxx根分区 - 切换挂载真正根目录,丢弃临时盘
更多推荐




所有评论(0)