Linux 系统启动流程

Linux 系统启动流程

加电自检 → Bootloader 引导 → GRUB 加载内核 → 1 号进程初始化 → 服务 / 自定义程序启动 → 登录加载 Shell

📋 60秒速览(时间线总览)

text 复制代码
[硬件层]  加电自检(POST) → 固件配置 → 发现启动盘
   ↓
[引导层]  MBR/ESP → GRUB2 Stage1/1.5/2 → 加载 vmlinuz + initramfs
   ↓
[内核层]  解压内核 → initramfs临时根 → 挂载真实根分区(/) → 转交PID 1
   ↓
[初始化]  systemd/init → 运行级别/Target → 分批启动服务
   ↓
[用户层]  rc.local自定义 → 登录提示符 → Shell环境加载

一、Phase 0:硬件加电自检(POST)

触发:电源键 → 主板供电 → CPU 复位 → 执行 BIOS/UEFI 固件

步骤 核心操作 用户可干预点
属性定制 加载 CMOS/UEFI 设置(启动顺序、内存频率、硬盘模式 AHCI/RAID) Del/F2 进入 BIOS Setup
硬件检测 检测 CPU、内存、显卡、键盘("滴"声=通过,蜂鸣=故障) 听声音判断硬件健康
自举程序 按 Boot Priority 查找可引导设备(硬盘/CD/USB) F11/F12 临时选择启动项

💡 救援模式入口 :此阶段插入救援U盘/光盘,选择从 USB/CD 启动,可进入救援环境(Rescue Mode)修复系统。


二、Phase 1:引导发现(Bootloader Discovery)

固件找到硬盘后,读取引导代码的方式因模式而异:

2.1 BIOS vs UEFI 双模式对比

特性 Legacy BIOS UEFI(现代推荐)
分区表 MBR (msdos) GPT
引导位置 磁盘第 0 扇区 (前 446 字节为引导代码) EFI 系统分区 (ESP) /boot/efi/EFI/rocky/grubx64.efi
后续扇区 1~2047 扇区存 Stage 1.5 无此概念,直接加载完整 EFI 程序
Rocky 支持 兼容旧硬件 支持安全启动(Secure Boot)

2.2 MBR 三阶段详解(BIOS 模式)

text 复制代码
第 0 扇区 (512字节)
├── [0-445]  Stage 1: 446字节引导代码(定位 Stage 1.5)
├── [446-509] 分区表: 64字节(4个主分区信息)
└── [510-511] 魔数: 0xAA55(有效性标记)

第 1-2047 扇区 (~1MB)
└── Stage 1.5: 存放 ext4/xfs 驱动,用于识别 /boot 分区

/boot 分区
└── Stage 2: 完整 GRUB2 程序 + 菜单配置

2.3 GRUB2 加载内核

找到 Stage 2 后,GRUB2 显示启动菜单,执行:

bash 复制代码
# GRUB2 实际执行的加载命令(按 e 可编辑查看)
linux16 /vmlinuz-5.14.0-xxx.el9.x86_64 \
    root=UUID=xxxxx \      # 根分区标识(比 /dev/sda1 稳定)
    ro \                    # 初始只读(为 fsck 磁盘检查做准备)
    rhgb quiet              # 图形启动条 + 静默模式

initrd16 /initramfs-5.14.0-xxx.el9.x86_64.img

三、Phase 2:内核初始化(Kernel Space)

3.1 initramfs(初始内存文件系统)------ 关键桥梁

本质 :一个 gzip 压缩的 cpio 归档,启动时解压为临时根分区

为什么需要它?

  • 内核刚启动时没有磁盘驱动(NVMe/RAID/LVM驱动通常作为模块存在)
  • initramfs 包含这些驱动和挂载脚本,让内核能"认出"真正的根分区

流程

text 复制代码
1. 解压 vmlinuz 内核
2. 挂载 initramfs 作为临时 /(内存中运行)
3. 执行 /init 脚本,加载真实根分区所需驱动
4. pivot_root 切换到真实根分区(/dev/sda2 或 LVM 等)
5. 释放 initramfs,启动 /sbin/init(即 systemd)

实操命令

bash 复制代码
# 查看当前 initramfs 内容(排查看是否包含某驱动)
lsinitrd /boot/initramfs-$(uname -r).img | grep nvme

# 重新生成(修改磁盘配置后必须执行)
dracut -f -v /boot/initramfs-$(uname -r).img $(uname -r)

四、Phase 3:系统初始化(核心差异区)

4.1 第一个进程进化史

发行版 第一个进程 PID 特点
CentOS 6 及以前 init (SysV) 1 串行启动,按脚本顺序执行
CentOS 7 systemd 1 并行启动,兼容 init 脚本
Rocky 8/9/10 systemd 1 纯 systemd,无传统 rcx.d
Ubuntu 16.04+ systemd 1 纯 systemd

验证命令:

bash 复制代码
# 查看 PID 1 是什么
ps -p 1

# 查看 init 软链接指向
ls -l /sbin/init
# 输出:/sbin/init -> ../lib/systemd/systemd

4.2 运行级别 vs Target 映射表

传统运行级别(0-6)

级别 名称 场景 systemd Target
0 关机 关闭系统 poweroff.target
1 单用户 修复模式(无网络,仅 root) rescue.target
2 多用户无网络 rarely used multi-user.target
3 多用户字符 服务器主流模式 multi-user.target
4 保留 自定义 multi-user.target
5 图形界面 桌面版默认 graphical.target
6 重启 重新启动 reboot.target

systemd 管理命令

bash 复制代码
# 查看当前默认启动目标
systemctl get-default
# 输出示例:graphical.target(桌面)或 multi-user.target(服务器)

# 临时切换(立即生效,不重启用)
systemctl isolate multi-user.target    # 切到字符界面(类似 init 3)
systemctl isolate graphical.target     # 切到图形界面(类似 init 5)

# 永久设置(开机生效)
systemctl set-default multi-user.target
systemctl set-default graphical.target

4.3 发行版核心差异总结

CentOS 7(过渡版)

  • 保留 /etc/rc.d/rc3.d//etc/rc.d/rc5.d/ 等传统目录(兼容旧习惯)
  • 新增 systemd target 管理,两者并存
  • 服务启动脚本既可以用旧版 service sshd start,也可以用新版 systemctl start sshd

Rocky Linux 8/9/10(现代纯 systemd)

  • /etc/rcx.d/ 目录,完全通过 target 管理
  • 服务管理统一用 systemctl
  • 启动流程:default.target → 依赖树并行启动服务 → 达成目标状态

Ubuntu(现代纯 systemd)

  • 同 Rocky,纯 systemd 管理
  • 服务配置文件路径略有不同(/lib/systemd/system/ vs /usr/lib/systemd/system/

启动耗时分析(通用)

bash 复制代码
# 查看哪个服务启动最慢(优化开机速度必备)
systemd-analyze blame

# 查看依赖链
systemd-analyze critical-chain

# 查看本次启动日志(排查卡住问题)
journalctl -xb -p err

五、Phase 4:自定义启动(/etc/rc.local)

系统初始化完成后,执行用户自定义脚本:

发行版 rc.local 状态 使用注意
Rocky Linux ✅ 默认保留,但可能无执行权限 必须执行 chmod +x /etc/rc.d/rc.local 才能生效
CentOS 7 ✅ 保留,同样需执行权限 同上
Ubuntu 20.04+ ❌ 默认不存在,需手动创建 自建 /etc/rc.local,写入 #!/bin/bash 头,加执行权限

内容示例

bash 复制代码
#!/bin/bash
# /etc/rc.local 示例(Rocky/Ubuntu 通用格式)

# 自定义挂载
mount -o remount,noexec /tmp

# 启动自定义脚本
/usr/local/bin/my-startup.sh &

exit 0

⚠️ 注意 :systemd 时代推荐编写 .service 单元文件替代 rc.local,但rc.local 仍是最快的临时方案。


六、Phase 5:登录与 Shell 环境

text 复制代码
getty 服务(systemd 管理)
    ↓
显示登录提示符(tty1-tty6 字符终端,或图形登录管理器 gdm/sddm)
    ↓
用户输入账号密码 → PAM 认证通过
    ↓
启动用户 Shell(bash/zsh)
    ↓
加载配置文件:
    /etc/profile         ← 全局配置(所有用户)
    ~/.bash_profile      ← 个人登录配置(仅登录时执行)
    ~/.bashrc            ← 个人交互配置(每次开终端都执行)
    ↓
显示命令提示符 $/#,启动流程结束

🔧 故障排查速查表

故障现象 可能原因 紧急修复方法
grub> 提示符 GRUB 配置损坏 手动引导:set root=(hd0,1), linux /vmlinuz..., initrd /initramfs..., boot;进入系统后执行 grub2-mkconfiggrub2-install
Kernel panic 找不到根分区(UUID 变更) 启动参数改为 root=/dev/sda1(试);进入救援模式修正 /etc/fstab;重建 initramfs (dracut -f)
卡在启动进度条 某 systemd 服务卡死 Esc 看详细日志;重启进入 systemd.unit=rescue.targetsystemctl mask 屏蔽故障服务
Welcome to emergency mode /etc/fstab 配置错误 输入 root 密码进入;vim /etc/fstab 注释错误行;reboot
忘记 root 密码 需单用户模式 启动参数加 rd.breaksystemd.unit=rescue.targetchroot /sysrootpasswdtouch /.autorelabel(SELinux 环境必须)

📝 核心文件速查(建议背诵)

文件/命令 作用 发行版差异
/boot/vmlinuz-$(uname -r) 压缩的内核镜像 通用
/boot/initramfs-*.img 初始内存盘(临时根系统) 通用
/etc/default/grub GRUB2 主配置文件 通用
/boot/grub2/grub.cfg GRUB2 菜单(勿直接编辑 Rocky/CentOS (Ubuntu 在 /boot/grub/grub.cfg
/etc/rc.d/rc.local 用户自定义启动脚本 Rocky/CentOS 保留 Ubuntu 需自建
/etc/systemd/system/default.target 默认启动目标软链接 通用(纯 systemd)
systemctl set-default 设置开机默认运行级别 通用
dracut -f 重建 initramfs 通用
相关推荐
若风的雨2 小时前
ATF + ARMv8 多核启动流程图
linux·arm开发
阿钱真强道2 小时前
07 jetlinks-ubuntu20-rk3588-部署
linux·运维·服务器·网络协议·tcp/ip
Realdagongzai2 小时前
Python学习过程记录3-操作列表
linux·vscode·python·kernel
坐怀不乱杯魂2 小时前
Linux网络 - Socket编程(IPv4&IPv6)
linux·服务器·网络·c++·udp·tcp
燃于AC之乐2 小时前
【Linux系统编程】进程地址空间完全指南:页表、写时拷贝与虚拟内存管理
linux·操作系统·虚拟内存·进程地址空间
网硕互联的小客服2 小时前
站群服务器里的8C/4C/2C/1C有什么区别?选择哪个比较好?
运维·服务器·网络
_OP_CHEN2 小时前
【Linux系统编程】(二十三)从块到块组:Ext2 文件系统核心架构的初步认识
linux·操作系统·文件系统·c/c++·ext2文件系统·磁盘分区·块组
刘某的Cloud2 小时前
docker cp 传文件,使用 docker exec 结合 tar 流传输,效率更高且能保留权限
linux·运维·docker·容器·系统
m0_748244962 小时前
【Linux 系列】Linux 命令/快捷键详解
linux·运维·服务器