1. 启动前的准备:BIOS/UEFI固件初始化、硬件自检(POST)、引导设备选择

说实话,很多人觉得内核启动是从 start_kernel() 开始的。但我不这么看。

在我眼里,真正的启动,从你按下电源键的那一刻就开始了。那会儿内核还没影儿呢,CPU 还在实模式里摸黑走路。谁在管这些事?固件——也就是 BIOS 或者 UEFI。

1.1 固件是什么?为什么它说了算?

固件,说白了就是焊死在主板上的那一段程序。它比操作系统更底层,比内核更早运行。我经常跟团队里的新人说:固件是硬件的管家,内核是系统的管家。管家还没上岗,你让管家去管硬件?不现实。

BIOS 和 UEFI 是两种主流的固件标准。我早年做嵌入式的时候,跟 BIOS 打交道比较多。后来做服务器和 x86 平台,UEFI 就成了家常便饭。它们俩的区别,我列个表给你看:

特性 BIOS(传统) UEFI(现代)
运行模式 16位实模式 32/64位保护模式
寻址能力 1MB 限制 可寻址全部内存
启动速度 较慢(逐项检测) 较快(并行初始化)
用户界面 文本菜单 图形界面 + Shell
引导方式 MBR(主引导记录) GPT + EFI 系统分区
扩展性 差(靠中断向量) 好(驱动模型 + 协议)

我个人习惯把 UEFI 看作一个微型操作系统。它有自己的驱动、文件系统、甚至网络协议栈。你想想看,这玩意儿比早期的 Linux 内核还复杂。

1.2 硬件自检(POST)—— 不是走形式

POST,全称 Power-On Self-Test。很多人觉得它就是个开机画面,转两圈就过去了。其实不是。

POST 是固件对硬件的一次全面体检。我遇到过最离谱的一次,是一台服务器开机黑屏,蜂鸣器一直响。查了半天,是内存条没插紧。POST 阶段就卡住了,内核根本见不到。

POST 主要检查这几样东西:

  • CPU:检测核心数、缓存、微码版本。如果微码不对,后面跑起来会出诡异的问题。
  • 内存:逐地址读写校验。我见过某些廉价主板,POST 阶段内存检测只扫前 64MB,后面全靠运气。
  • 芯片组:南北桥或 SoC 内部总线初始化。这一步出问题,外设全挂。
  • 基本 I/O:键盘、鼠标、显示控制器。至少得让你能看到报错信息。
  • 存储控制器:SATA、NVMe、AHCI 等。引导设备就靠它认出来。

核心要点:POST 不通过,内核连启动的机会都没有。所以排查启动问题,第一步永远是看 POST 阶段有没有报错。别一上来就追内核代码,那是舍近求远。

1.3 引导设备选择 —— 一场有顺序的博弈

POST 过了,固件就要决定:从哪个设备加载操作系统?

这个顺序是配置好的。我习惯在固件设置里把顺序排成:USB → SSD → 网络启动 → 其他。为什么?因为调试的时候经常要用 U 盘装系统,排第一位省事。

引导设备选择的逻辑其实很简单:

  1. 固件读取启动顺序列表(Boot Order)。
  2. 逐个尝试每个设备,看它是不是“可引导”的。
  3. 对于 BIOS,检查 MBR 的最后两个字节是不是 0x55AA
  4. 对于 UEFI,查找 EFI 系统分区下的 .efi 文件(比如 grubx64.efi)。
  5. 找到第一个可引导设备,就把控制权交给它。

这里有个坑。我曾经遇到过一台机器,UEFI 模式下死活不认我的 U 盘。后来发现是 U 盘格式化成 MBR 了,而固件设置里只允许 GPT。你想想看,这种问题查起来多折腾人。

注意:BIOS 和 UEFI 对引导设备的判断标准完全不同。BIOS 看 MBR 签名,UEFI 看 FAT 分区里的 EFI 文件。混用会导致无法引导。我建议统一用 UEFI + GPT,省心。

1.4 从固件到引导程序 —— 交接的那一瞬间

固件选定了引导设备,接下来就是交接。这个交接过程,我画了一张图帮你理解:

固件 → 引导程序 交接流程 固件初始化 BIOS/UEFI 启动 POST 通过 硬件枚举 CPU/内存/外设 设备就绪 引导设备选择 MBR / EFI 分区 找到引导项 加载引导程序 GRUB / bootloader 控制权移交 内核启动 start_kernel() 系统初始化 init 进程启动

从这张图你能看出来,固件做完自己的事,就把控制权交给了引导程序。引导程序再加载内核。内核再启动 init。一层一层往下传。

这里有个细节:固件交权之后,它并没有完全退出。UEFI 的运行时服务(Runtime Services)会一直存活,内核可以通过特定的接口调用它。比如设置启动项、读取固件变量。我调试过一个问题,就是 UEFI 的时钟服务跟内核的时钟中断冲突了,折腾了两天才找到根因。

经验之谈:如果你在调试启动问题,建议在固件设置里开启“详细 POST 日志”。很多主板支持把 POST 信息输出到串口或者保存到内存中。这些日志比内核的 early printk 还要早,是排查硬件问题的第一手资料。

1.5 小结

启动前的准备,说白了就是三件事:固件把自己跑起来 → 检查硬件是否正常 → 找到能启动的设备

这三件事做完了,内核才有机会登场。很多人一遇到启动问题就追内核代码,其实大部分问题都出在这三步里。我建议你下次遇到机器起不来,先别急着看 dmesg,先看看 POST 阶段有没有报错,引导设备有没有被正确识别。

嗯,这一步走稳了,后面的路就好走了。


专注资料整理