1. rootfs挂载失败概述
什么是rootfs
rootfs,全称 root filesystem,中文叫根文件系统。说白了,它就是 Linux 系统启动后挂载的第一个文件系统。内核启动完成后,必须找到一个根文件系统来加载 init 进程、读取配置文件、加载驱动模块——没有它,系统就是个空壳。
我个人习惯把 rootfs 理解为「系统的家」。内核是大脑,rootfs 就是身体。大脑再聪明,没有身体也动不了。rootfs 里装着 /bin、/sbin、/etc、/lib 这些目录,所有用户空间的程序都靠它提供。
核心要点: rootfs 不是某个特定的文件系统类型,而是一个逻辑概念。它可以是 ext4、squashfs、NFS,甚至是 initramfs 中的 cpio 归档。关键不在于格式,而在于它承载了系统启动所需的全部用户空间资源。
挂载失败的现象
rootfs 挂载失败,系统会直接卡在启动阶段。我见过太多工程师对着串口日志发呆的场景。常见的失败现象有这么几种:
- 内核 panic —— 最典型的现象。控制台打印 "VFS: Unable to mount root fs on unknown-block" 然后挂死。
- 进入 initramfs shell —— 内核找到了 initramfs,但无法挂载真正的 rootfs,把你丢到一个简陋的 shell 里。
- 启动卡住不动 —— 没有 panic,没有 shell,就是一直打印 "Waiting for root device...",直到超时。
- 挂载成功但启动失败 —— 这个比较隐蔽。rootfs 挂上了,但 /sbin/init 找不到,或者关键库缺失,系统启动到一半就崩了。
嗯,这里要注意:最后一种情况很多人会误判成 rootfs 挂载成功,其实根文件系统本身就有问题。我在项目中遇到过好几次,同事说「rootfs 挂上了啊」,结果一看 /lib 目录是空的——那叫挂上了吗?那叫挂了个空壳。
挂载失败的影响
影响不用多说,系统起不来。但具体到不同场景,后果差别很大:
| 场景 | 影响程度 | 典型后果 |
|---|---|---|
| 开发阶段 | 中等 | 调试进度受阻,反复烧写/重启 |
| 产线烧录 | 严重 | 大批量设备无法通过测试,产线停线 |
| OTA 升级 | 致命 | 设备变砖,需要人工干预恢复 |
| 现场运维 | 灾难性 | 远程设备失联,必须派人去现场处理 |
你想想看,一个产线几百台设备同时刷机,结果 rootfs 挂载失败,那场面……我曾经在客户现场遇到过,产线停了两小时,就为了查一个分区表偏移量写错的问题。
排查思路总览
排查 rootfs 挂载失败,不能瞎猜。我总结了一套思路,按优先级排列:
- 确认内核启动参数 —— 检查 bootargs 中的 root= 参数是否正确。这是最常见的翻车点。
- 确认存储设备 —— 内核是否识别了你的存储介质?MMC、NAND、SATA?驱动加载了吗?
- 确认分区表 —— 分区偏移量、大小对不对?uboot 传的 partition 和内核期望的是否一致?
- 确认文件系统格式 —— 内核是否编译了对应的文件系统驱动?ext4、squashfs、btrfs?
- 确认 rootfs 镜像本身 —— 镜像是否损坏?打包时有没有遗漏关键目录?
- 确认 init 进程 —— 挂载成功后,/sbin/init 是否存在?权限对不对?
我的习惯: 拿到一个 rootfs 挂载失败的案例,我第一件事不是看代码,而是看串口日志。从 "Starting kernel ..." 开始,一行一行往下读。很多时候,日志里已经把原因写得明明白白了,只是你没仔细看。
为了让你更直观地理解整个排查流程,我画了一张图:
曾经踩过的坑: 有一次我排查一个 rootfs 挂载失败,折腾了两天。最后发现是 uboot 传的 root= 参数里,设备名写的是 /dev/mmcblk0p2,但内核实际用的是设备号,而设备号映射关系在某个内核版本里变了。从那以后,我养成了一个习惯——每次换内核版本,都重新确认一遍 bootargs 里的 root 参数。
好了,这一章我们先把 rootfs 挂载失败的全貌看清楚。后面的章节,我会带着你一步步深入每个排查环节,从内核启动参数到文件系统格式,从分区表到 init 进程,把每个坑都填平。