1. 嵌入式Linux根文件系统概述
各位同学,咱们今天开始聊根文件系统。说实话,我刚入行那会儿,对「根文件系统」这个概念也是一头雾水。当时我师傅丢给我一句:「没有根文件系统,你的Linux内核就是个光杆司令。」嗯,这句话我一直记到现在。
什么是根文件系统
根文件系统,英文叫 Root Filesystem,简称 rootfs。说白了,它就是Linux系统启动后挂载的第一个文件系统。这个文件系统里装着系统运行所需的一切:可执行程序、库文件、配置文件、设备节点,还有挂载点目录。
你想想看,内核启动完成后,总得有个地方去读取 init 程序吧?总得知道 /lib 下的动态链接库在哪吧?这些信息,全都存在根文件系统里。
根文件系统的核心特征:
- 挂载点为
/(根目录) - 包含完整的目录结构(/bin、/sbin、/etc、/lib、/usr 等)
- 提供系统启动所需的第一个用户态程序(通常是 /sbin/init)
- 是其他所有文件系统的挂载基础
根文件系统的作用
根文件系统到底干了哪些活?我归纳了三点:
- 提供用户态运行环境——内核启动后,需要根文件系统来加载 init 进程、shell、各种工具程序。没有它,内核就只能停在 kernel panic 界面,啥也干不了。
- 管理设备与资源——/dev 目录下的设备节点、/proc 和 /sys 下的虚拟文件系统接口,都依赖根文件系统来组织。
- 承载系统配置——/etc 目录下的配置文件、/var 下的运行时数据,全在根文件系统里。我在项目中遇到过一台设备,因为 /etc/inittab 写错了,导致系统启动后直接进入单用户模式,折腾了半天才找到原因。
一个小经验:嵌入式系统里,根文件系统通常很小。我见过最小的根文件系统只有 2MB,只放了 busybox、几个库文件和必要的配置文件。够用就行,别贪大。
根文件系统与内核的关系
这个问题很多初学者搞混。我直接说结论:内核和根文件系统是两回事。
内核负责硬件初始化、进程调度、内存管理、文件系统驱动这些底层活。而根文件系统提供的是用户态的程序和数据。两者通过 VFS(虚拟文件系统)层对接。
启动流程是这样的:
- Bootloader 加载内核到内存
- 内核解压并初始化硬件
- 内核挂载根文件系统(通过内核命令行参数 root= 指定)
- 内核执行根文件系统里的 /sbin/init
- init 进程启动其他服务
我曾经犯过一个低级错误:编译内核时忘了把根文件系统所在的存储设备驱动编进去,结果内核启动后找不到根文件系统,直接 panic。嗯,那次加班到凌晨两点。
注意:内核命令行参数 root= 指定的是根文件系统的设备路径,比如 root=/dev/mmcblk0p2。如果这个参数写错了,或者设备驱动没加载,系统就起不来。这是嵌入式开发中最常见的坑之一。
常见的根文件系统类型
嵌入式Linux里,根文件系统的存放形式有好几种。我按使用场景给大家列个表:
| 类型 | 存储介质 | 特点 | 典型场景 |
|---|---|---|---|
| initramfs | 内存(与内核镜像打包) | 启动快、无持久化、体积小 | 系统安装盘、临时启动、调试 |
| initrd | 内存(独立镜像) | 老式方案、需要驱动支持 | 兼容旧内核、过渡启动 |
| 闪存文件系统(JFFS2/UBIFS) | NAND/NOR Flash | 支持磨损均衡、掉电保护 | 嵌入式设备主存储 |
| 块设备文件系统(ext4/F2FS) | eMMC/SD卡/SATA | 性能好、工具成熟 | 高性能嵌入式、开发板 |
| 网络文件系统(NFS) | 网络远程挂载 | 开发调试方便、无本地存储 | 开发阶段、快速原型 |
| 只读文件系统(squashfs) | 闪存/块设备 | 压缩率高、防篡改 | 量产固件、安全要求高 |
我个人习惯,开发阶段用 NFS 根文件系统,改完代码直接重启就能看到效果,不用反复烧写。量产的时候换成 squashfs 或者 UBIFS,稳定可靠。
根文件系统的目录结构
Linux 根文件系统的目录结构是有标准的,叫 FHS(Filesystem Hierarchy Standard)。嵌入式系统虽然可以裁剪,但基本骨架不能少:
/
├── bin/ # 用户命令(ls、cp、mv 等)
├── sbin/ # 系统管理命令(init、mount、ifconfig 等)
├── etc/ # 配置文件
├── lib/ # 动态链接库、内核模块
├── usr/ # 用户程序和数据(可独立挂载)
├── var/ # 可变数据(日志、缓存)
├── tmp/ # 临时文件
├── dev/ # 设备节点
├── proc/ # 进程信息虚拟文件系统
├── sys/ # 内核对象虚拟文件系统
├── mnt/ # 临时挂载点
└── root/ # root 用户家目录
我记得第一次自己动手做根文件系统时,漏掉了 /dev 目录下的 console 设备节点,结果系统启动后控制台没有任何输出。嗯,这种细节问题,遇到了就记住了。
根文件系统的构建方式
构建根文件系统,主流方法有三种:
- 手动构建——用 BusyBox + 交叉编译工具链,一个一个目录创建,一个一个程序拷贝。适合学习,能让你彻底理解根文件系统的每个部件。
- 使用 Buildroot——自动化构建工具,配置菜单选一选,一键生成根文件系统镜像。适合产品开发,效率高。
- 使用 Yocto/OpenEmbedded——企业级构建系统,功能强大但学习曲线陡。适合大型项目、需要定制化程度高的场景。
咱们这门课,会从手动构建开始,让你把根文件系统的每个零件都摸清楚。然后再用 Buildroot 提速。我个人建议,哪怕你以后只用 Yocto,也至少手动做一次根文件系统——那种「我亲手搭起来」的感觉,对理解系统帮助很大。
这张图把咱们这一章的核心知识点串起来了。根文件系统不是孤立的概念,它和内核、存储介质、目录标准、构建工具都紧密相关。后面的章节,咱们会一个一个深入展开。