1. 课程导入

在嵌入式Linux系统中,内核启动完成后,第一件必须完成的事情就是挂载根文件系统(rootfs)。没有可用的rootfs,内核即使成功启动,也无法进入用户空间,更无法运行应用程序。因此,文件系统是嵌入式Linux产品从“能启动”走向“能工作”的关键一环。本课程以BusyBox为起点,逐步构建一个可启动、可裁剪、可量产的嵌入式Linux根文件系统,帮助学习者建立从工具链到镜像烧录的完整能力。

一、学习目标:从“会编译”到“能交付”

本课程不是单纯讲解某个命令或某个目录,而是围绕一个真实可运行的rootfs展开。学习完成后,应达到以下目标:

  • 理解Linux文件系统的层次结构、挂载机制与VFS抽象模型;
  • 掌握BusyBox的编译、安装与符号链接机制,能独立生成基础用户空间;
  • 能够编写和调试/etc/inittab、/etc/fstab、/etc/init.d/rcS等启动脚本;
  • 掌握根文件系统镜像的制作方法,包括ext4、UBIFS、SquashFS、initramfs等常见格式;
  • 能够根据产品需求裁剪系统体积、配置设备节点、设置用户权限与只读保护;
  • 具备定位“内核已启动但无法进入控制台”“挂载失败”“init进程异常”等问题的排障能力。

核心判断标准:当串口终端出现Please press Enter to activate this console,并且能够执行ls、mount、ifconfig等命令时,说明一个最小可用rootfs已经构建成功。

二、核心概念:rootfs、VFS与挂载

嵌入式Linux文件系统涉及几个必须厘清的概念。首先是rootfs,即根文件系统,它是内核挂载的第一个文件系统,承载/bin、/sbin、/etc、/dev、/proc、/sys等关键目录。其次是VFS(Virtual File System,虚拟文件系统),它为上层应用提供统一的文件操作接口,屏蔽了ext4、YAFFS2、UBIFS、NFS等具体文件系统的差异。最后是挂载,Linux通过mount将存储设备、内存文件系统或网络文件系统关联到目录树中的某个挂载点。

理解这三者关系,才能明白为什么内核启动参数中的root=、rootfstype=、init=如此重要。它们分别告诉内核:根文件系统在哪里、是什么类型、第一个用户空间进程是谁。

嵌入式Linux文件系统:知识框架与实战路线 从内核启动到用户空间,从BusyBox到可量产rootfs镜像 ① 内核启动 VFS初始化 / 挂载rootfs 启动init进程 ② BusyBox构建 交叉编译 / 配置 / 安装 生成/bin /sbin /usr ③ 目录与配置 /etc /dev /proc /sys inittab / fstab / rcS ④ 镜像制作 ext4 / UBIFS SquashFS / initramfs 核心机制层 VFS虚拟文件系统 统一file_operations接口 挂载与根切换 mount / pivot_root / switch_root init进程与运行级 sysvinit / BusyBox init 设备节点与热插拔 mdev / udev / devtmpfs 实战排障与验证层 启动失败定位 Kernel panic / No init found 挂载问题排查 root= / rootfstype= / fstab 体积与权限优化 strip / 只读 / 用户组 量产镜像验证 烧录 / 启动 / 压力测试

三、整体知识框架:四层递进

本课程的知识框架可以概括为四层递进关系。第一层是内核与VFS,理解内核如何识别文件系统类型、如何完成根挂载。第二层是BusyBox与用户空间,掌握如何用一个小型二进制提供上百个常用命令。第三层是目录布局与启动配置,包括/etc下的初始化脚本、设备节点创建、环境变量设置。第四层是镜像制作与量产,将目录树打包为可烧录的镜像文件,并考虑只读、压缩、掉电保护等产品化需求。

阶段 核心任务 关键产物 常见工具
内核启动 挂载rootfs,启动init 内核日志、启动参数 bootargs、printk
BusyBox构建 交叉编译、安装符号链接 busybox二进制、/bin目录 make menuconfig、make install
目录与配置 编写inittab、fstab、rcS 可启动的rootfs目录树 vi、chmod、mknod
镜像制作 打包为ext4/UBIFS/SquashFS rootfs.img、rootfs.ubifs mkfs.ext4、mkfs.ubifs、mksquashfs
调试与量产 启动验证、体积裁剪、只读保护 稳定可量产的固件 串口终端、df、du、mount

四、实战路线图:从零到可启动系统

建议按照以下顺序推进实践,每一步都应有明确的验证点:

  1. 准备交叉工具链:确认arm-linux-gnueabihf-gcc或对应架构编译器可用,并设置CROSS_COMPILE与ARCH。
  2. 编译BusyBox:下载源码,执行make menuconfig,选择静态编译或动态编译,安装到_install目录。
  3. 搭建目录骨架:创建bin sbin etc dev proc sys tmp var lib等目录,复制BusyBox产物。
  4. 编写启动脚本:配置/etc/inittab,在/etc/init.d/rcS中挂载proc、sysfs、devtmpfs,设置网络与主机名。
  5. 制作镜像并烧录:使用mkfs.ext4或mksquashfs生成镜像,通过TF卡、NFS或烧录工具部署到目标板。
  6. 启动验证与排障:观察串口输出,确认init进程启动、控制台可用、关键服务正常。
# 典型BusyBox安装与rootfs骨架命令
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make -j4
make install

mkdir -p rootfs/{bin,sbin,etc/init.d,dev,proc,sys,tmp,var,lib,usr}
cp -a _install/* rootfs/
mknod rootfs/dev/console c 5 1
mknod rootfs/dev/null c 1 3

学习建议:不要一开始就追求功能完整。先做出一个能进入控制台的最小系统,再逐步添加网络、存储、图形界面等组件。每增加一个功能,都要回到串口终端验证,避免问题堆积。

五、常见误区与复盘

初学者最容易陷入的误区有三个。第一,把文件系统等同于目录树,忽略了挂载点和VFS的抽象作用,导致遇到“目录存在但内容为空”时无法判断是挂载失败还是文件缺失。第二,忽略动态库依赖,BusyBox动态编译后未将libc.so等库复制到/lib,启动时出现not found。第三,设备节点缺失,没有创建/dev/console和/dev/null,导致init无法打开控制台。

排障口诀:先看内核日志,再看挂载点,最后查init脚本。内核日志告诉你rootfs是否挂载成功;mount命令告诉你当前挂载状态;init脚本决定用户空间能否正常启动。

本课程后续将围绕上述路线图逐层展开,每一节都对应一个可操作的实践环节。只要跟随课程完成每个验证点,最终就能独立构建一个体积可控、启动稳定、可量产的嵌入式Linux根文件系统。