0%

linux启动过程

Linux 启动过程详解:从开机到用户登录的完整流程

Linux 系统的启动是一个从硬件初始化到用户空间就绪的复杂过程,涉及固件、内核、初始化系统等多个层面。理解启动流程不仅有助于系统故障排查,还能深入掌握 Linux 的底层运行机制。本文将以传统 SysVinit 系统为例,详细解析启动的五个核心阶段,并补充现代 systemd 系统的差异。

内核引导(Boot Loader 阶段)

这是启动的第一个阶段,负责从硬件到内核的交接,分为 BIOS/UEFI 自检引导程序加载 两步。

BIOS/UEFI 自检(硬件初始化)

  • BIOS(基本输入输出系统):传统固件接口,开机后首先运行,负责检测 CPU、内存、硬盘等硬件是否正常(即 “POST 自检”)。
  • UEFI(统一可扩展固件接口):现代固件接口,功能与 BIOS 类似,但支持更大的硬盘、更快的启动速度和图形化界面。
  • 核心任务:确定启动设备(如硬盘、U 盘、光驱),并读取设备的第一个扇区(MBR 主引导记录,传统 BIOS)或 EFI 系统分区(UEFI)。

引导程序(Boot Loader)加载内核

引导程序是位于启动设备第一个扇区的小程序,负责加载 Linux 内核。常见的引导程序有 GRUB(Grand Unified Bootloader)和 LILO(Linux Loader),其中 GRUB 因支持多系统引导而被广泛使用。

GRUB 的工作流程:
  1. 阶段 1:从 MBR 加载 GRUB 核心代码(占 512 字节,仅够启动下一步)。
  2. 阶段 1.5:加载位于 MBR 之后的驱动,使 GRUB 能识别内核所在的文件系统(如 ext4、xfs)。
  3. 阶段 2:读取 /boot/grub/grub.cfg 配置文件,显示启动菜单(如选择不同内核版本或操作系统)。
  4. 加载内核:用户选择后,GRUB 将 Linux 内核(/boot/vmlinuz-<version>)和初始 RAM 磁盘(/boot/initramfs-<version>.img)加载到内存。
    • 内核(vmlinuz):Linux 核心程序,负责硬件管理和进程调度。
    • 初始 RAM 磁盘(initramfs):临时根文件系统,包含启动阶段必需的驱动(如硬盘驱动),帮助内核挂载实际根分区。

内核初始化(Kernel 阶段)

内核被加载到内存后,接管系统控制权,完成从硬件到用户空间的过渡。

内核自检与硬件初始化

  • 内核解压后,首先初始化 CPU、内存管理单元(MMU)、中断控制器等核心硬件。
  • 加载 initramfs 中的驱动模块,识别并初始化硬盘、网卡等外设。

挂载根文件系统

  • 内核通过 initramfs 中的脚本找到并挂载实际根分区(如 /dev/sda1),挂载方式由 /etc/fstab 或内核参数(如 root=/dev/sda1)指定。
  • 卸载 initramfs,切换到根文件系统。

启动第一个用户态进程

内核完成初始化后,启动 init 进程(传统系统)或 systemd 进程(现代系统),并将进程号(PID)设为 1,作为所有用户态进程的父进程。

  • 传统 SysVinit 系统:执行 /sbin/init
  • systemd 系统:执行 /usr/lib/systemd/systemd

初始化系统(Init 阶段)

初始化系统是用户态的第一个进程(PID=1),负责启动后续所有服务和进程。

传统 SysVinit 系统(基于 /etc/inittab

  • 读取运行级别:init进程首先解析/etc/inittab文件,确定系统运行级别(Runlevel):
    • 0:关机
    • 1:单用户模式(用于修复系统)
    • 2:多用户模式(无网络)
    • 3:完全多用户模式(命令行,服务器默认)
    • 4:预留
    • 5:图形化模式(带桌面环境)
    • 6:重启
  • 执行系统初始化脚本:根据运行级别,首先执行/etc/rc.d/rc.sysinit(系统初始化核心脚本),完成以下任务:
    • 激活交换分区(swap)。
    • 检查磁盘完整性(fsck)。
    • 设置系统时钟、主机名。
    • 加载内核模块(/etc/modules.conf)。
    • 挂载 /etc/fstab 中定义的文件系统(如 /home/tmp)。

现代 systemd 系统(基于目标单元)

systemd 用 “目标(target)” 替代传统运行级别,通过配置文件和依赖关系管理服务启动:

  • 核心目标:
    • multi-user.target:对应运行级别 3(命令行多用户)。
    • graphical.target:对应运行级别 5(图形化)。
    • rescue.target:单用户模式。
  • 启动流程:
    • 内核启动 systemd 后,systemd 读取 /etc/systemd/system/default.target 确定默认目标。
    • 按依赖关系启动目标所需的服务(.service)、挂载点(.mount)等单元(unit)。
    • 替代 rc.sysinit 的功能由多个基础服务(如 systemd-fscksystemd-sysctl)共同完成。

启动系统服务与建立终端

初始化系统完成基础配置后,开始启动用户态服务并建立终端,为用户登录做准备。

启动后台服务

  • SysVinit 系统:根据运行级别,执行/etc/rc.d/rc<N>.d目录下的脚本(N为运行级别):
    • 脚本命名格式:Sxx<service>(启动服务,xx 为优先级)或 Kxx<service>(停止服务)。
    • 常见服务:sshd(SSH 服务)、crond(定时任务)、network(网络服务)。
  • systemd 系统:通过目标单元的依赖关系自动启动服务(如 sshd.service),可通过 systemctl list-dependencies 查看依赖链。

建立终端(TTY)

  • 系统启动多个虚拟终端(TTY),供用户登录:
    • 传统系统:init 进程启动 /sbin/mingetty/sbin/getty 程序,创建 TTY 设备(通常 6 个,Ctrl+Alt+F1F6 切换)。
    • systemd 系统:由 getty@.service 管理,默认启动 tty1tty6
  • 图形化模式下,还会启动显示管理器(如 GDM、LightDM),提供图形登录界面。

用户登录系统

终端就绪后,用户可通过命令行或图形界面登录,完成启动的最后一步。

命令行登录(TTY 或 SSH)

  • 用户输入用户名和密码后,login 程序验证身份(通过 /etc/passwd/etc/shadow)。
  • 验证成功后,加载用户环境(~/.bash_profile~/.bashrc),启动 shell(默认 bash)。

图形化登录

  • 显示管理器(如 GDM)验证用户身份后,启动桌面环境(如 GNOME、KDE),加载用户配置。

登录后的进程树

登录成功后,用户进程以 init/systemd(PID=1)为根,形成完整的进程树:

1
systemd(1) → login(1000) → bash(1001) → user commands...

欢迎关注我的其它发布渠道