2. 根文件系统(RootFS)概念:作用、典型目录结构
根文件系统(Root Filesystem,简称 RootFS)是 Linux 系统启动过程中内核挂载的第一个文件系统。它不仅是系统运行的基石,更是内核从“自举”阶段过渡到“用户态”的关键桥梁。理解 RootFS 的作用与结构,是正确配置内核挂载参数的前提。
2.1 根文件系统的作用
在 Linux 内核启动的后期阶段,内核需要加载第一个用户态进程(通常是 /sbin/init 或 /bin/busybox),并执行系统初始化脚本。这一切都依赖于一个可读写的、包含必要工具和库的文件系统。RootFS 的核心作用可归纳为以下四点:
| 作用维度 | 具体说明 | 关键依赖 |
|---|---|---|
| 进程启动 | 提供 /sbin/init 或指定 init= 参数对应的可执行文件 |
内核需找到 ELF 格式的 init 程序 |
| 库与工具 | 提供 C 运行时库(libc)、动态链接器(ld-linux)及基础命令 | init 进程依赖 /lib 下的共享库 |
| 设备与内核接口 | 通过 /dev、/proc、/sys 与内核交互 |
udev/mdev 需要挂载虚拟文件系统 |
| 配置与持久化 | 存放系统配置文件(/etc)和运行时数据 |
日志、PID 文件、临时文件需要可写空间 |
关键概念: 内核在挂载 RootFS 之前,只拥有一个临时的
rootfs(基于 tmpfs 的内存文件系统)。真正的 RootFS 挂载成功后,内核会 pivot_root 或 switch_root 将根目录切换到新的文件系统,并执行 init 进程。
2.2 典型目录结构详解
一个标准的 Linux 根文件系统遵循 FHS(Filesystem Hierarchy Standard)规范。在嵌入式系统中,虽然可以裁剪,但以下目录是绝大多数场景下必须保留的:
嵌入式裁剪提示: 如果使用静态编译的 busybox,可以省略
/lib 目录;如果使用 devtmpfs,可以省略 /dev 目录中的静态设备节点。但 /proc 和 /sys 几乎总是必需的。
2.2.1 核心目录功能对照表
| 目录 | 全称 | 作用 | 启动阶段是否必需 |
|---|---|---|---|
/bin |
User Binaries | 存放用户级基础命令(ls, cp, cat, sh) | 是 |
/sbin |
System Binaries | 存放系统管理命令(init, mount, ifconfig) | 是 |
/etc |
Configuration Files | 系统配置文件(inittab, fstab, passwd) | 是 |
/lib |
Libraries | 共享库和内核模块(libc.so, ld-linux.so) | 是(动态链接时) |
/dev |
Device Files | 设备节点(console, null, ttyS0) | 是 |
/proc |
Process Information | 虚拟文件系统,提供进程和内核信息 | 是 |
/sys |
System Information | 虚拟文件系统,提供设备和驱动信息 | 是 |
/tmp |
Temporary Files | 临时文件存储(通常挂载为 tmpfs) | 推荐 |
/var |
Variable Data | 可变数据(日志、缓存、锁文件) | 推荐 |
/usr |
Unix System Resources | 次要层次结构(可独立挂载) | 可选 |
2.2.2 目录依赖关系与挂载顺序
在系统启动过程中,目录的挂载和初始化存在严格的先后顺序。下图展示了 RootFS 中关键目录的依赖关系:
2.3 关键目录的启动阶段行为
2.3.1 /dev —— 设备节点
在系统启动初期,内核会尝试挂载 devtmpfs(如果内核配置了 CONFIG_DEVTMPFS),自动创建设备节点。如果未启用,则必须在 RootFS 中静态创建至少 /dev/console、/dev/null、/dev/ttyS0 等关键节点,否则内核无法输出启动信息。
# 手动创建设备节点示例(在构建 RootFS 时)
mknod -m 600 dev/console c 5 1
mknod -m 666 dev/null c 1 3
mknod -m 666 dev/ttyS0 c 4 64
2.3.2 /proc 与 /sys —— 内核接口
这两个目录是虚拟文件系统,不占用磁盘空间。内核在 init 进程启动后,由 init 脚本通过 mount 命令挂载:
# 在 init 脚本中挂载虚拟文件系统
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs none /tmp
常见错误: 如果 RootFS 中缺少
/proc 或 /sys 挂载点目录,mount 命令会失败。务必在构建 RootFS 时创建这些空目录:mkdir -p /proc /sys /tmp。
2.4 最小 RootFS 目录结构示例
对于嵌入式系统或 initramfs,一个可工作的最小 RootFS 通常包含以下内容:
/
├── bin/
│ ├── sh # shell(通常为 busybox 链接)
│ └── busybox # 或静态编译的 busybox 二进制
├── sbin/
│ └── init # 指向 /bin/busybox 或自定义 init
├── etc/
│ ├── inittab # init 进程配置文件
│ └── fstab # 文件系统挂载表(可选)
├── lib/
│ ├── libc.so.6 # C 运行时库
│ └── ld-linux.so.* # 动态链接器
├── dev/
│ ├── console
│ ├── null
│ └── ttyS0
├── proc/ # 空目录,用于挂载 proc
├── sys/ # 空目录,用于挂载 sysfs
└── tmp/ # 空目录,用于挂载 tmpfs
性能与安全建议: 在嵌入式系统中,建议将
/tmp 和 /var 挂载为 tmpfs,避免频繁写 flash 导致磨损。同时,/proc 和 /sys 的挂载权限应设置为只读(ro)或使用 hidepid=2 等安全挂载选项。
2.5 本章小结
- RootFS 是内核启动的终点,用户态运行的起点。 没有正确的 RootFS,内核会 panic 并停止启动。
- 目录结构遵循 FHS 标准,但嵌入式系统可裁剪。 核心目录
/bin、/sbin、/etc、/lib、/dev是启动必需的。 - 虚拟文件系统
/proc、/sys必须在 init 脚本中挂载。 它们提供了用户态与内核交互的唯一通道。 - 设备节点
/dev/console是内核输出控制台信息的必要条件。 缺少它会导致启动信息丢失。