目录
Please enable Javascript to view the contents

Linux基础-启动流程

 ·  ☕ 4 分钟
核心结论说明
Linux 启动不是从内核开始,而是从固件开始UEFI/BIOS 完成硬件初始化后,才进入 Bootloader
内核启动后第一个用户态进程是 PID 1现代发行版通常是 systemd,旧系统可能是 SysV init
systemd 用 target 取代传统运行级别multi-user.target 类似 runlevel 3,graphical.target 类似 runlevel 5
用户登录后才进入 Shell 初始化阶段/etc/profile~/.bash_profile~/.bashrc 属于登录后的 Shell 行为

1.简介

Linux 启动流程经常被简化成:

1
BIOS -> GRUB -> Kernel -> init -> login

这个说法方向没错,但不够完整。现代 Linux 需要区分三条线:

  1. 硬件 / 固件启动线:BIOS 或 UEFI 做硬件初始化;
  2. 内核启动线:Bootloader 加载内核,内核挂载根文件系统;
  3. 用户态初始化线:PID 1 启动服务,最终提供登录环境。

2.说明

2.1 总体流程

Power On
  ↓
BIOS / UEFI
  ↓
Bootloader(GRUB)
  ↓
Linux Kernel + initramfs
  ↓
挂载 rootfs
  ↓
PID 1(systemd / init)
  ↓
启动系统服务
  ↓
getty / display manager / sshd
  ↓
用户登录
  ↓
Shell 初始化

2.2 BIOS / UEFI

固件负责最早期的硬件初始化。

项目BIOSUEFI
启动方式读取 MBR 引导代码读取 EFI System Partition 中的 .efi 文件
分区表常见 MBR常见 GPT
启动文件磁盘前 446 字节引导代码EFI/BOOT/*.efi 或发行版自己的 EFI 文件
现代系统逐步淘汰主流方式

UEFI 场景下常见文件路径:

1
2
3
/boot/efi/EFI/ubuntu/grubx64.efi
/boot/efi/EFI/centos/grubx64.efi
/boot/efi/EFI/BOOT/BOOTX64.EFI

2.3 Bootloader:GRUB

Bootloader 的主要职责:

  1. 展示启动菜单;
  2. 加载 Linux 内核文件;
  3. 加载 initramfs;
  4. 向内核传递启动参数。

常见文件:

文件说明
/boot/vmlinuz-*压缩后的 Linux 内核镜像
/boot/initrd.img-*/boot/initramfs-*初始内存文件系统
/boot/grub/grub.cfgGRUB 主配置文件
/etc/default/grubGRUB 默认参数配置

查看当前内核启动参数:

1
cat /proc/cmdline

示例:

1
BOOT_IMAGE=/boot/vmlinuz-5.15.0 root=UUID=xxx ro quiet splash

2.4 Kernel 与 initramfs

内核被加载后,会完成以下动作:

  1. 初始化 CPU、内存、调度器;
  2. 初始化驱动;
  3. 挂载 initramfs;
  4. 根据启动参数找到真正的根文件系统;
  5. 挂载 rootfs;
  6. 启动第一个用户态进程。

initramfs 的作用:在真正的根文件系统挂载前,提供必要工具和驱动。

典型场景:

  • 根分区在 LVM 上;
  • 根分区加密;
  • 根分区在 RAID 上;
  • 需要提前加载存储驱动。

如果 initramfs 缺少必要驱动,可能出现无法挂载根文件系统:

1
Kernel panic - not syncing: VFS: Unable to mount root fs

2.5 PID 1:systemd / init

内核启动的第一个用户态进程固定是 PID 1。

查看当前系统 PID 1:

1
ps -p 1 -o pid,comm,args

常见结果:

1
2
PID COMMAND         COMMAND
  1 systemd         /sbin/init

现代主流发行版中,/sbin/init 通常是指向 systemd 的软链接。

1
ls -l /sbin/init

2.6 systemd target 与 SysV runlevel

旧 SysV init 使用 runlevel:

Runlevel含义
0关机
1单用户模式
2多用户模式,不同发行版含义略有差异
3多用户命令行模式
4保留
5图形界面模式
6重启

systemd 使用 target:

systemd target类似 runlevel说明
poweroff.target0关机
rescue.target1救援模式
multi-user.target3多用户命令行模式
graphical.target5图形界面模式
reboot.target6重启

查看默认 target:

1
systemctl get-default

设置默认 target:

1
2
systemctl set-default multi-user.target
systemctl set-default graphical.target

2.7 服务启动

systemd 根据 unit 文件启动服务。

常见 unit 类型:

类型说明示例
.service系统服务sshd.servicedocker.service
.socketSocket 激活systemd-journald.socket
.target一组 unit 的集合multi-user.target
.mount挂载点home.mount
.timer定时任务logrotate.timer

常见目录:

1
2
3
/usr/lib/systemd/system/
/lib/systemd/system/
/etc/systemd/system/

优先级通常是:/etc/systemd/system/ 覆盖系统默认 unit。

查看服务启动耗时:

1
2
3
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain

查看某个服务状态:

1
2
systemctl status sshd
journalctl -u sshd -b

2.8 用户登录与 Shell 初始化

系统服务启动完成后,用户可以通过不同方式登录:

登录方式关键组件
本地命令行getty + login
SSHsshd
图形界面display manager,例如 gdmsddmlightdm

Bash 启动文件需要区分登录 Shell 和非登录 Shell。

场景读取文件
登录 Shell/etc/profile,然后读取 ~/.bash_profile / ~/.bash_login / ~/.profile 中第一个存在的文件
非登录交互 Shell~/.bashrc
非交互 Shell通常不读取上述文件,除非通过环境变量或参数指定

常见建议:

  • 环境变量、PATH 等需要登录继承的内容放 ~/.profile~/.bash_profile
  • alias、prompt、补全等交互配置放 ~/.bashrc
  • ~/.bash_profile 中通常显式加载 ~/.bashrc

示例:

1
2
3
if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi

2.9 常见排查命令

目标命令
查看内核参数cat /proc/cmdline
查看当前内核uname -r
查看 PID 1ps -p 1 -o pid,comm,args
查看默认 targetsystemctl get-default
查看本次启动日志journalctl -b
查看上次启动日志journalctl -b -1
查看启动耗时systemd-analyze blame
查看失败服务systemctl --failed
查看服务依赖链systemctl list-dependencies multi-user.target

3.总结

  1. Linux 启动流程可以分为:固件初始化、Bootloader、Kernel、initramfs、rootfs、PID 1、服务启动、用户登录;
  2. BIOS / UEFI 负责找到 Bootloader,GRUB 负责加载内核和 initramfs;
  3. 内核启动后会挂载根文件系统,并启动第一个用户态进程 PID 1;
  4. 现代 Linux 大多使用 systemd,target 取代传统 runlevel;
  5. Shell 初始化发生在用户登录之后,不属于内核或 systemd 启动阶段。

4.参考

分享

Hex
作者
Hex
CloudNative Developer