2. 根文件系统基础
在嵌入式 Linux 系统中,内核启动完成后,必须挂载一个根文件系统(Root Filesystem),才能运行用户空间的第一个进程。根文件系统不是“可选项”,而是系统从“内核能跑”走向“应用可用”的关键桥梁。它决定了系统启动后能看到哪些目录、能执行哪些程序、能加载哪些驱动模块,以及设备节点、配置文件、库文件从哪里来。
一、根文件系统的基本概念
根文件系统是挂载在目录树根节点 / 上的文件系统。它至少需要包含 Linux 用户空间运行所必需的基本内容:
- 目录结构:如
/bin、/sbin、/etc、/dev、/proc、/sys、/lib、/usr、/tmp、/var等。 - 可执行程序:如
init、sh、busybox、mount、ifconfig等。 - 动态库与配置:如
libc.so、ld-linux.so、/etc/inittab、/etc/fstab、/etc/profile。 - 设备节点:如
/dev/console、/dev/null、/dev/ttyS0。 - 虚拟文件系统挂载点:
/proc、/sys、/dev等,用于内核与用户空间交互。
需要特别区分两个概念:根文件系统是运行时挂载在 / 上的文件系统实例;而根文件系统镜像是烧录到存储介质中的静态文件集合,例如 rootfs.ext4、rootfs.jffs2、rootfs.cpio.gz。镜像被内核挂载后,才成为运行时的根文件系统。
二、根文件系统与内核的关系
内核与根文件系统的关系可以概括为“内核提供机制,根文件系统提供内容”。内核负责进程调度、内存管理、设备驱动、文件系统驱动和网络协议栈;根文件系统则提供用户空间程序、配置和运行时数据。两者通过系统调用接口衔接:用户程序通过 open、read、write、ioctl 等系统调用进入内核,内核再通过 VFS 访问具体文件系统。
内核启动的最后阶段会尝试挂载根文件系统。如果挂载失败,内核会打印类似 VFS: Cannot open root device 或 Kernel panic - not syncing: No init found 的错误,系统无法进入用户空间。因此,根文件系统的类型、位置和内容必须与内核配置匹配。
root=、rootfstype=、init= 等启动参数。
三、启动流程中的角色
以典型 ARM 嵌入式 Linux 为例,启动流程如下:
- BootROM 加载 SPL/二级引导程序。
- U-Boot 初始化内存、存储和网络,加载内核镜像与设备树。
- 内核解压、初始化子系统,挂载根文件系统。
- 内核执行
/sbin/init或/init,进入用户空间。 - init 进程根据
/etc/inittab或 systemd 配置启动服务、登录 shell 和应用程序。
根文件系统在这一流程中承担“用户空间起点”的角色。没有它,内核只能停留在内核态,无法启动任何应用。对于 initramfs 方式,根文件系统被编译进内核镜像,内核启动时直接解压到内存中,适合快速启动和恢复模式;对于块设备方式,根文件系统位于 eMMC、NAND、SD 卡或网络存储上,适合功能完整、可持久化的系统。
四、常见根文件系统类型与选型依据
嵌入式场景中常见的根文件系统类型包括:
| 类型 | 典型介质 | 特点 | 适用场景 |
|---|---|---|---|
| ext4 | eMMC、SD、SSD | 日志型、可读写、成熟稳定 | 通用嵌入式设备、需要频繁写文件 |
| squashfs | NOR、NAND、eMMC | 只读压缩、体积小、启动快 | 固件只读、配合 overlay 可写层 |
| jffs2 | NOR、NAND | 日志型、支持擦写均衡 | 小容量 NAND、传统嵌入式 |
| ubifs | NAND | UBI 卷、擦写均衡、压缩 | 大容量 NAND、现代嵌入式 |
| initramfs | 内存 | 内核内置、解压到 RAM | 快速启动、恢复模式、无盘系统 |
| NFS | 网络 | 远程挂载、开发调试方便 | 开发阶段、网络启动 |
选型时可以从以下维度判断:
- 存储介质:NOR 适合 jffs2/squashfs,NAND 适合 ubifs/jffs2,eMMC 适合 ext4/squashfs。
- 读写需求:需要频繁写入选 ext4 或 ubifs;只读固件选 squashfs。
- 启动速度:initramfs 和 squashfs 启动较快;ext4 需要文件系统检查,可能稍慢。
- 可靠性:掉电频繁场景优先日志型或带擦写均衡的文件系统。
- 开发效率:开发阶段常用 NFS 根文件系统,避免反复烧录。
五、案例与常见误区
以一个基于 i.MX6ULL 的工控板为例:存储为 8GB eMMC,系统需要支持日志写入、远程升级和断电保护。最终选择 ext4 作为根文件系统,同时将 /var/log 和 /data 单独分区,避免日志写满根分区。内核启动参数配置为:
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootfstype=ext4 rw rootwait'
常见误区包括:
- 只烧内核不烧根文件系统:内核启动后找不到 init,直接 panic。
- 内核未编译对应文件系统驱动:例如内核没有开启 ext4 支持,却使用 ext4 根文件系统。
- 设备节点缺失:没有
/dev/console,init 无法打开控制台。 - 动态库路径错误:程序依赖
/lib/ld-linux-armhf.so.3,但根文件系统中不存在。 - 启动参数与分区不匹配:
root=指向错误分区,导致挂载失败。
VFS、init、root= 相关行,再确认存储分区、文件系统驱动和 init 程序是否存在。
理解根文件系统的基本概念、与内核的协作关系、在启动流程中的位置以及常见类型与选型依据,是后续制作 BusyBox 根文件系统、构建 initramfs、配置 NFS 根文件系统和进行系统裁剪的基础。