前几篇我们已经把 Linux 启动的核心认知拆开讲了:
• Linux 启动不是一步完成,而是一场分层接力
• 板子上电不等于系统一定能起来
• BootROM、U-Boot、Kernel、rootfs 各自负责不同的事
• 嵌入式 Linux 启动比 PC 复杂得多,因为平台差异和板级细节更多
但如果一直只讲局部,很多人脑子里仍然容易缺一张“总图”:
从芯片上电开始,到最后真正进入用户空间,中间到底是一条什么样的完整链路?
所以这一篇只做一件事:
把 Linux 启动全流程从头到尾串起来。
你可以把它理解成整个 Linux 启动专题的一张“全景地图”。
一句话先讲明白
如果只记一句话,可以先记这个:
Linux 启动全流程,本质上就是一条从“硬件上电”到“用户空间接管”的逐级接力链。
这条链大致可以拆成 6 个阶段:
1. 芯片上电,BootROM 开始工作
2. 第一阶段引导程序被拉起来
3. Bootloader 准备内核启动条件
4. Kernel 接管 CPU,建立内核世界
5. rootfs 被挂载,用户空间基础准备好
6. init 启动,系统真正进入可用状态
你只要把这 6 段想清楚,后面无论看日志、排故障、写文章,都会顺很多。
第一阶段:芯片上电,BootROM 出场
系统启动的起点不是 U-Boot,也不是 Linux 内核,而是芯片内部固化的启动代码:
BootROM
它在 SoC 出厂时就已经写在片上 ROM 里,职责很简单:
• 判断从哪里启动
• 去指定介质里找第一阶段镜像
• 把镜像搬到指定位置
• 然后跳转过去执行
所以 BootROM 负责的是:
让系统迈出第一步。
如果这一棒都没交出去,后面什么都不会发生。
这也是为什么有些板子启动失败时,连 U-Boot 日志都看不到。
你可以把这一阶段理解成:
芯片先决定从哪条路进系统。
第二阶段:第一阶段引导程序把“运行环境”搭起来
BootROM 很小,能力也有限。
它不可能直接完成 Linux 所需的所有准备工作。
所以在 BootROM 后面,通常还会有一层或多层第一阶段引导程序,比如:
• SPL
• TF-A
• 厂商私有早期加载器
这一阶段最常做的事情包括:
• 初始化 DDR
• 配置时钟
• 准备电源和复位环境
• 建立更大的运行空间
• 加载后续更完整的 Bootloader
为什么这一层很关键?
因为很多东西如果没准备好,后面根本没法谈 Linux。
最典型的就是:
DDR 没初始化好,大镜像就没地方放。
所以这一步更多是在做“开场搭台”,让后面的 bootloader 真正有条件工作。
第三阶段:U-Boot 把 Linux 启动材料准备好
等系统来到 U-Boot,才进入大家最熟悉的范围。
U-Boot 这一层的核心职责非常清楚:
决定怎么启动 Linux,并把启动 Linux 需要的内容准备好。
它通常负责:
• 选择启动介质
• 加载内核镜像
• 加载设备树 dtb
• 按需加载 initrd/initramfs
• 拼接 bootargs
• 执行 bootm / booti / bootz
• 把控制权交给内核
所以可以把 U-Boot 理解成:
Linux 启动前的总调度员。
它的工作重点不是“运行 Linux”,而是:
把 Linux 启动前需要的所有东西准备正确。
这也是为什么很多现场问题都会卡在这一层,比如:
• 镜像找不到
• 启动命令用错
• bootargs 配错
• dtb 不匹配
• 启动介质链路异常
本质上都是:
U-Boot 没把 Linux 正确送上路。
第四阶段:Kernel 接管 CPU,建立内核世界
一旦执行 bootm / booti / bootz 并成功跳转,控制权就交给了 Linux kernel。
这时候很多人会以为:
系统已经起来了。
其实还没有。
Kernel 接下来要做大量初始化工作,比如:
• 建立内存管理
• 初始化中断体系
• 初始化调度器
• 初始化定时器
• 解析设备树
• 初始化控制台
• 初始化驱动
• 识别串口、块设备、网络设备等硬件
所以 Kernel 这一阶段的本质是:
先把“内核世界”建立起来。
它让系统从“bootloader 环境”切换到真正的 Linux 内核运行环境。
但这时系统还远没有真正可用,因为用户空间还没起来。
第五阶段:挂载 rootfs,把用户空间接进来
Kernel 站稳之后,下一件非常关键的事就是:
挂载根文件系统 rootfs。
这一步为什么重要?
因为 Linux 不是只靠一个内核就能正常工作的。
真正的这些东西都在 rootfs 里:
• /sbin/init
• Shell
• 库文件
• 配置文件
• 服务程序
• 启动脚本
• 用户应用
所以如果 rootfs 挂不上,内核即使已经起来,也没法进入真正可用状态。
这时就会看到非常经典的错误:
VFS: Cannot open root deviceWaiting for root deviceKernel panic - not syncing: VFS: Unable to mount root fs
这些错误说明的不是“内核没起来”,而是:
内核已经起来了,但找不到自己的家。
所以 rootfs 这一层,负责的是:
把 Linux 从“只有内核”推进到“具备用户空间基础”。
第六阶段:init 启动,用户空间真正接管
很多人以为 rootfs 挂上就结束了,其实还差最后一棒:
启动第一个用户空间进程。
通常是:
• /sbin/init
• systemd
• busybox init
• 或定制系统里的 init 替代程序
它是整个用户空间的起点。
只有它跑起来之后,后面的服务、脚本、守护进程、shell、业务程序才会陆续启动。
所以“系统真正起来”指的是什么?
• 不是看到 U-Boot 了,
• 也不是看到内核日志了,
• 甚至不只是 rootfs 挂上了,
而是:
用户空间的第一个进程已经接棒,系统开始真正进入可用状态。
到这一步,整个启动流程才算完整闭环。
你可以把整个链路记成这一张“脑图”
如果不展开细节,整个 Linux 启动流程可以直接记成这一串:
上电 → BootROM → 第一阶段引导 →
U-Boot → Kernel → rootfs → init → 用户空间
这条线是整个启动专题最重要的一条主线。
以后无论你看哪一种问题,本质上都可以回到这条链上去判断:
• 是哪一棒没接住?
• 是哪一层没交出去?
• 是哪一段已经开始跑,但没真正跑完?
这比死记命令更重要。
现场最实用的判断方法
以后再遇到启动问题,先按这张链路去定位:
1. 看不到任何输出
重点怀疑:BootROM、启动介质、供电、时钟、第一阶段引导。
2. 能看到 U-Boot,但起不来内核
重点怀疑:镜像、dtb、bootcmd、bootargs、启动命令。
3. 能看到内核日志,但最后 panic
重点怀疑:内核早期初始化、驱动、串口参数、rootfs。
4. 报 VFS、Waiting for root
重点怀疑:root=、rootfs 介质、块设备驱动、设备树。
5. rootfs 挂上了却进不了系统
重点怀疑:init、用户空间、脚本、文件系统完整性。
一旦你按链路拆开,启动问题就不再是一团黑盒。
最后怎么一句话记住?
如果你在面试、分享、技术交流里想快速讲清 Linux 启动全流程,可以直接说:
Linux 启动是一条从硬件上电到用户空间接管的分层接力链:BootROM 找入口,Bootloader 准备内核,Kernel 建立系统底座,rootfs 和 init 把用户空间真正拉起来。
如果再压缩成一句最好记的话,就是:
芯片先醒,Bootloader 铺路,Kernel 站稳,用户空间接棒。
结尾
很多人学 Linux 启动时,最容易掉进的坑,就是只盯某一层看,却没有把整条链路串起来。
但真正做启动移植、调试、排障时,你最需要的其实不是零散知识点,而是一张完整地图。
因为 Linux 启动从来不是“某个程序启动了”,而是:
一整条链路,一棒接一棒,把系统从硬件世界带进用户空间世界。
下一篇:容易混淆的 Linux 启动 10 个关键词:bootcmd、bootargs、dtb、initrd 到底是什么?