3、构建最小根文件系统:选择Target包、配置Busybox、配置glibc/uclibc、首次编译与烧录验证

好,到了真正动手的环节了。前面我们把Buildroot环境搭好,也理解了它的目录结构。现在我们要做的,就是亲手构建一个最小根文件系统。

什么叫最小?说白了,就是能启动、能跑shell、能执行基本命令。没有图形界面,没有桌面环境,甚至连网络服务都可以先不装。我刚开始做嵌入式的时候,总觉得东西越多越安全,结果编译一次半小时,调试起来还互相冲突。后来学乖了——从最小系统开始,逐步往上加,这才是靠谱的做法。

核心原则: 最小根文件系统 = Bootloader + Kernel + 根文件系统(Busybox + C库 + 必要的设备节点)。其他一切,按需添加。

3.1 选择Target包:从零开始

进入Buildroot配置界面:

make menuconfig

你会看到一个层级菜单。别慌,我们一步步来。

3.1.1 Target options

这里选你的目标架构。我以常见的ARM Cortex-A7为例:

配置项 推荐值 说明
Target Architecture ARM (little endian) 小端模式,大部分ARM芯片都用这个
Target Architecture Variant cortex-a7 根据你的CPU型号选,别选错
Target ABI EABIhf 硬浮点,性能更好。如果你的CPU不支持,选EABI
Floating point strategy VFPv4-D16 跟CPU的FPU匹配

我曾经踩过的坑: 有一次我选了cortex-a7,但实际芯片是cortex-a5。编译出来的内核能启动,但一跑浮点运算就崩。查了两天才发现是Target Architecture Variant选错了。所以,一定要确认你的芯片手册,别想当然。

3.1.2 Build options

这里我建议保持默认。唯一要注意的是:

  • Download dir:默认是 dl/,如果你有代理或离线包,可以改
  • Number of jobs:填你CPU核心数的1.5倍左右,比如4核填6,编译会快很多

3.1.3 Toolchain

这是关键。Buildroot支持两种方式:

  • Buildroot toolchain:自己编译整个工具链,灵活但慢
  • External toolchain:用现成的,比如Linaro、ARM官方工具链

我个人习惯用Buildroot自带的,因为版本匹配,省心。但如果你项目急,用外部工具链也行。

Toolchain type: Buildroot toolchain
C library: glibc  (或者 uclibc,后面会讲)
Kernel Headers: 和你的内核版本一致

3.2 配置Busybox:麻雀虽小,五脏俱全

Busybox是根文件系统的灵魂。它把几百个Linux命令打包成一个二进制文件,通过符号链接来区分不同命令。

进入Busybox配置:

make busybox-menuconfig

这里我只说几个必须注意的点:

3.2.1 核心配置

配置项 建议 原因
Busybox Settings → Build static binary (no shared libs) 不选 动态链接可以减小体积,而且方便后续加库
Busybox Settings → vi-style line editing commands 选上 命令行编辑方便很多
Coreutils → cat, ls, cp, mv, rm, mkdir 全选 这些是基础中的基础
Shells → ash 选上 默认shell,够用
Init utilities → init 选上 系统启动的第一个进程

小技巧: 第一次编译,我建议把 Linux System Utilities → mount 和 Linux System Utilities → umount 选上。没有它们,你连文件系统都挂载不了,系统启动到一半就卡住了。

3.2.2 我个人的必选清单

除了上面那些,我还会加这几个:

  • find:调试时找文件用
  • grep:看日志必备
  • sed:脚本里改配置用
  • ifconfig:网络调试用
  • ping:网络通不通,一ping便知

嗯,其实这些都可以后续再加。但第一次编译,我建议你宁多勿少,省得后面缺命令还要重新编译。

3.3 配置C库:glibc vs uclibc

C库是根文件系统的基石。Buildroot支持多种C库,最常用的是glibc和uclibc。

特性 glibc uclibc
体积 大(约1.5MB) 小(约300KB)
兼容性 最好,几乎支持所有POSIX标准 大部分兼容,但有些高级功能缺失
性能 优化好,但启动稍慢 轻量,启动快
调试 支持完善,gdb等工具友好 调试支持较弱
适用场景 功能复杂、需要完整POSIX支持的系统 资源受限、对体积敏感的嵌入式设备

怎么选?我的经验是:

  • 如果你用的是Cortex-A系列,内存128MB以上:用glibc,省心
  • 如果是Cortex-M或者内存只有32MB:用uclibc,能省不少空间
  • 如果你不确定:先用glibc,后面再换也来得及

我个人的建议: 第一次做项目,用glibc。等你把整个流程跑通了,再考虑换成uclibc来优化体积。别一开始就给自己找麻烦。

3.4 首次编译:耐心等待

配置都做好了,开始编译:

make

第一次编译会下载源码包,然后编译工具链、内核、Busybox、C库……整个过程大概20分钟到1小时,取决于你的网络和机器性能。

编译过程中,你可以去喝杯咖啡。但别忘了盯着终端,万一报错呢?

常见错误:

  • 下载失败:检查网络,或者手动把源码包放到 dl/ 目录下
  • 缺少依赖:比如没装 flex、bison,用apt或yum装上就行
  • 磁盘空间不足:Buildroot编译会占用不少空间,确保有5GB以上空闲

编译成功后,你会看到:

output/images/
├── rootfs.tar
├── rootfs.cpio
├── zImage
└── ...

rootfs.tar 就是我们的根文件系统。把它解压到目标板的分区上,就能用了。

3.5 烧录与验证:第一次启动

烧录方式取决于你的硬件。我以SD卡启动为例:

# 假设SD卡是 /dev/sdb
sudo dd if=output/images/zImage of=/dev/sdb1
sudo tar xf output/images/rootfs.tar -C /mnt/sd_card
sync

插卡,上电,看串口输出:

U-Boot 2023.01
...
Starting kernel ...
...
VFS: Mounted root (ext4 filesystem) on device 179:2.
Freeing unused kernel memory: 1024K
Run /sbin/init as init process
init started: BusyBox v1.36.0
/ # _

看到这个 / # 提示符了吗?恭喜,你的最小根文件系统跑起来了!

验证清单:

  • 输入 ls,看看有没有基本命令
  • 输入 cat /proc/cpuinfo,确认CPU信息
  • 输入 free,看看内存
  • 输入 mount,看看文件系统挂载情况

如果一切正常,恭喜你,你已经掌握了嵌入式Linux最核心的一步。后面的事情,都是在这个基础上做加法。

最小根文件系统构建流程 配置Target包 架构/工具链/内核头文件 配置Busybox 选择命令/Shell/Init 配置C库 glibc / uclibc 选择 执行 make 编译 下载源码 → 编译工具链 → 编译内核 → 编译Busybox → 打包根文件系统 输出产物 zImage + rootfs.tar / rootfs.cpio 烧录验证 dd + tar → 上电 → 看串口输出 💡 核心原则:从最小系统开始,逐步往上加 先跑起来,再考虑功能扩展