Linux 启动流程和启动过程中的故障定位

第一步:硬件自检(POST)

在计算机的主板上有一个单独的固件芯片,在出厂时就写入了一个固件程序(BIOS/UEFI),在硬件通电时会自动运行这个固件程序,它会对 CPU、内存、硬盘、显卡等硬件设备进行自检(POST),检查硬件是否存在问题。

若自检失败可能会出现黑屏、蜂鸣报警或硬件错误提示、界面一直卡在厂商 Logo;

若自检通过就会根据 BIOS / UEFI 中配置的启动顺序(Boot Order)查找可引导设备,然后加载引导程序(Boot Loader)。

BIOS 基本输入/输出系统(Basic Input/Output System)属于早期 PC 使用的固件系统,只有简单的文本界面,而且仅支持 MBR(主引导记录)分区格式,所以也就导致了单块磁盘最大支持约 2TB,而且只有 4 个主分区。

UEFI 叫作统一可扩展固件接口(Unified Extensible Firmware Interface)早期是 因特尔 开发的一种 固件程序,因为解决了BIOS 的多项限制,后面也就成为了一个标准,可以理解为 UEFI 是 BIOS 的升级版。UEFI 支持图形界面和鼠标操作,启动速度更快,安全性更高;而且支持 GPT 分区格式,解决了 MBR 分区硬盘大小和主分区数的限制问题。

现在的计算机都是默认采用 UEFI 作为引导和自检程序,但是为了兼容一些老机器、老主板,所以传统的 BIOS 模式也存在。进入UEFI的图形界面设置一些参数的时候,除了UEFI 默认外,还有个 Legacy BIOS 模式(就是 传统 BIOS 模式 )就是使用传统 BIOS 模式。

第二步:加载 Boot Loader

Boot Loader(引导加载器)是一类程序的总称,而非一个程序。Linux 默认使用的是 GRUB(常见发行版都是使用 GRUB 的 2.x 版本), Windows 默认使用的是 Windows Boot Manager。

在 固件程序 对硬件进行自检通过后,就会根据配置的启动加载顺序依次查找可引导设备(如 U 盘、硬盘、PXE 等)。当在某个设备中找到有效的引导程序(Boot Loader,如 GRUB)后,便将其加载到内存并执行,同时终止继续查找后续设备。

所以这个也就解释了为什么使用 U 盘制作启动盘后,需要进 BIOS 里面修改启动顺序,让 BIOS 优先从 U盘里面找引导设备,这样才能加载U盘中这个简洁的操作系统。

所以 固件程序(BIOS或 UEFI)将 Boot Loader 加载到内存后,Boot Loader 会根据(Linux 使用的是 Grub2) 会根据设置的内核启动参数,将内核加载到内存后开始运行,开始进行 内核的初始化。

使用不同的引导模式,加载 Boot Loader 的方式不一样,如果是传统的 BIOS 模式( Legacy BIOS),它是从硬盘MBR (第一个扇区) 读取引导代码(Boot Loader),若是 UEFI 模式,是从设备的 ESP 分区中查找 .efi 启动文件。

第三步:系统内核初始化

Boot Loader (Linux 用的 GRUB)加载到内存后,因为在 GRUB 里面配置了内核启动参数,所以会根据这个启动参数将 内核程序加载到内存中运行。

内核加载到内存后,此时是没有根文件系统的,也就是把哪个分区挂载到根上他还不知道,所以在 GRUB 里面还会配置 临时根文件系统(initramfs),内核会先将 initramfs 挂载为临时根文件系统(/),并执行其中的 /init 脚本,用于加载必要驱动、识别磁盘设备并挂载真正的 root 分区,随后切换到真实根文件系统。

当 root 分区无法被正常识别或挂载时(如文件系统损坏、UUID 不存在、磁盘异常),系统会停留在 initramfs 的应急 Shell 中。因此,当出现文件系统损坏、磁盘异常或 UUID 不匹配等情况时(例如异常断电后),系统可能会进入 initramfs 的应急 Shell。

例如:ubuntu 2004 使用的 Boot Loader 就是默认的 2.0.4 版本。在启动的时候按住 Shift(或 Esc)可以进入 GRUB 菜单,在这个菜单可以选择使用哪个内核,还有启动参数如何设置。

e 可以进入 GRUB 内核启动参数编辑界面 ,这里展示的就是:GRUB 准备如何加载内核(vmlinuz)和 initrd,并传递哪些参数给内核。

例如 这里 linux 开头的行就是设置如何加载内核的相关参数,initrd 就是设置如何加载 initramfs

第四步:启动 PID 1 的进程

现代 Linux 发行版中,PID 为 1 的进程是 systemd,systemd 会作为所有用户态进程的父进程。然后 systemd 会启动所需的 unit。当所有必要的 unit 启动完成后,系统进入了登录界面。

所以在这一步容易出现的问题就是如果服务没初始化完,或某个服务启动失败了,也会没法进入 登录界面。就类似于 /tmp 文件太多,硬盘性能又不行导致一直在启动页面加载一样。

所以这个也就解释了遇到 root 密码忘记、系统启动不起来,就修改 grub 加载内核的配置参数。就是正常情况下内核初始化完成,也就是将 根挂载完成后,就需要启动 systemd 进程,然后完成后续的一系列初始化。

通过在 GRUB 中修改内核启动参数(如 init=/bin/bash),可以绕过 systemd,直接启动一个 shell 作为 PID 1,用于修复系统或重置密码。

posted on 2026-02-03 15:31  一直小爪子  阅读(0)  评论(0)    收藏  举报