1、Rootfs 概述:什么是 Rootfs、它在嵌入式系统中的作用、与内核的关系
各位好,我是老李。做嵌入式 Linux 也有十几年了,今天咱们来聊聊 Rootfs。很多刚入行的朋友总觉得 Rootfs 就是个文件系统,装点库和脚本就完事了。其实不然,Rootfs 是整个用户态的灵魂,内核只是把硬件拉起来,真正干活的全靠它。
说白了,Rootfs 就是根文件系统。它挂载在 / 目录下,包含了系统启动后所需的一切:init 程序、共享库、配置文件、设备节点、应用程序等等。没有 Rootfs,内核启动完就只能打印一句 Kernel panic - not syncing: VFS: Unable to mount root fs,然后死在那。
一句话总结:Rootfs 是用户态世界的基石,内核负责提供舞台,Rootfs 负责上演好戏。
1.1 什么是 Rootfs
Rootfs 的全称是 Root Filesystem,根文件系统。它不仅仅是一个文件系统类型,更是一个逻辑概念。你想想看,系统启动后,内核会挂载一个文件系统到根目录 /,这个被挂载的文件系统就是 Rootfs。
它可以是真实的块设备分区,比如 /dev/mmcblk0p2;也可以是内存中的 tmpfs;还可以是 initramfs,直接打包在内核镜像里。我个人习惯把 Rootfs 理解为「用户态程序的生存环境」。
这里有个容易混淆的点:Rootfs 和根文件系统类型是两码事。Rootfs 是挂载点 / 上的内容,而它底层的格式可以是 ext4、squashfs、ubifs、jffs2 等等。我在项目中遇到过有人把这两者搞混,调试了三天才发现是文件系统类型选错了。
| 概念 | 说明 | 常见形式 |
|---|---|---|
| Rootfs | 挂载在 / 下的文件系统整体 |
目录树、文件、链接 |
| 文件系统类型 | 底层存储格式 | ext4、squashfs、ubifs |
| 存储介质 | 物理存储设备 | eMMC、NAND Flash、SD 卡 |
1.2 Rootfs 在嵌入式系统中的作用
嵌入式系统不像 PC 那样有完整的硬盘和 BIOS,资源有限,启动流程也精简得多。Rootfs 在这里扮演了三个关键角色:
- 提供用户态运行环境:内核启动后,第一个用户态进程(通常是
/sbin/init或/init)就来自 Rootfs。它负责拉起所有后续服务。 - 承载应用程序和库:你的业务逻辑、第三方库、脚本、配置文件,全在 Rootfs 里。没有它,内核就是个空壳。
- 管理设备节点和运行时数据:
/dev、/proc、/sys、/tmp、/var这些目录,要么在 Rootfs 中预置,要么在启动时动态挂载。
我记得有一次做工业网关,客户要求系统启动时间必须控制在 3 秒以内。我优化了内核还不够,最后发现 Rootfs 的 init 脚本里有个 sleep 2 秒的冗余等待。去掉之后,启动时间直接降到 2.1 秒。你看,Rootfs 的细节直接影响系统表现。
小提示:嵌入式系统中,Rootfs 的大小直接影响 Flash 占用和启动速度。我建议你根据实际需求裁剪,不要一股脑把整个 buildroot 或 yocto 的默认包全塞进去。
1.3 Rootfs 与内核的关系
内核和 Rootfs 的关系,我经常用「硬件驱动 + 用户态服务」来比喻。内核负责管理硬件、调度任务、提供系统调用;Rootfs 负责提供具体的业务逻辑和用户接口。两者通过 VFS(虚拟文件系统)层交互。
具体来说,内核启动流程是这样的:
- 内核解压并初始化,挂载 Rootfs。
- 内核执行 Rootfs 中的
/init或/sbin/init。 - init 进程根据配置文件启动其他服务。
如果内核找不到 Rootfs,系统就会 panic。我曾经在调试一块新板子时,内核启动参数里 root= 写错了设备节点,结果内核打印了一堆错误后直接挂掉。排查了半天才发现是 root=/dev/mmcblk0p2 写成了 root=/dev/mmcblk1p2。
避坑指南:内核启动参数中的 root= 和 rootfstype= 必须与你的 Rootfs 实际位置和类型匹配。我曾经见过有人把 squashfs 的 Rootfs 指定为 ext4 类型,内核挂载失败后直接 panic。
下面这张图展示了内核与 Rootfs 的协作关系:
从这张图可以看得很清楚:硬件在最底层,内核在中间层,Rootfs 和用户态服务在上层。每一层都依赖下一层提供的接口。内核启动后,第一个动作就是挂载 Rootfs,然后执行里面的 init 程序。如果 Rootfs 损坏或缺失,整个系统就停摆了。
嗯,这里要注意一点:Rootfs 不一定非得是持久化存储。比如 initramfs 就是在内存中解压的,系统掉电后内容就没了。这种方案适合快速启动或只读系统。我在做安全网关时就用过 initramfs,把核心校验逻辑放在内存里,防止被篡改。
1.4 常见的 Rootfs 类型对比
不同的嵌入式场景,Rootfs 的选型也不同。我整理了一张表,方便你对比:
| 类型 | 存储位置 | 读写特性 | 典型场景 | 优点 | 缺点 |
|---|---|---|---|---|---|
| initramfs | 内存 | 读写(掉电丢失) | 快速启动、安全启动 | 启动快、无 Flash 磨损 | 容量受限、掉电丢失 |
| squashfs | Flash | 只读 | 固件升级、只读系统 | 高压缩比、防篡改 | 不可写、更新需重烧 |
| ext4 | eMMC/SD | 读写 | 通用嵌入式系统 | 成熟稳定、支持日志 | 需要较大的存储空间 |
| ubifs | NAND Flash | 读写 | 大容量 NAND 设备 | 磨损均衡、掉电安全 | 配置复杂、依赖 UBI |
| jffs2 | NOR/NAND Flash | 读写 | 老旧设备、小容量 Flash | 直接操作 Flash | 挂载慢、内存占用高 |
我个人习惯是:如果系统需要频繁更新,用 squashfs + overlayfs 组合;如果对启动速度要求极高,用 initramfs;如果存储空间充裕且需要读写,直接上 ext4。
核心要点:Rootfs 的选型直接影响系统的启动速度、存储占用、可靠性和可维护性。没有银弹,只有最适合你项目的方案。