4. BusyBox入门

在嵌入式 Linux 根文件系统中,BusyBox 几乎是绕不开的基础组件。它把大量常用命令集成到一个可执行文件中,通过“一个二进制、多个命令入口”的方式,显著降低根文件系统的体积和移植复杂度。理解 BusyBox 的定位、编译配置和安装方法,是构建最小可用根文件系统的关键一步。

一、BusyBox 的定位与核心思想

BusyBox 常被称为“嵌入式 Linux 的瑞士军刀”。它并不是一个单一命令,而是一个集成了 ls、cp、mv、cat、mount、ifconfig、sh 等数百个命令的精简工具集。其核心思想是:将多个命令编译进同一个可执行文件,再通过命令名或参数决定实际执行哪个功能。

在传统桌面系统中,每个命令通常是独立二进制文件;而在嵌入式环境中,存储空间、内存和启动速度都受限。BusyBox 通过共享代码、裁剪功能和统一入口,把根文件系统中大量基础命令压缩到一个约几百 KB 到 1 MB 左右的程序中,非常适合资源受限设备。

BusyBox 的本质不是“替代所有 Linux 命令”,而是为嵌入式系统提供一套足够用、体积小、可裁剪的基础用户态工具集。

二、核心功能与典型命令

BusyBox 覆盖了根文件系统启动和日常维护所需的大部分基础能力,常见功能可以分为以下几类:

  • Shell 与脚本:sh、ash,用于启动脚本、环境初始化。
  • 文件操作:ls、cp、mv、rm、mkdir、cat、chmod。
  • 系统管理:mount、umount、ps、kill、reboot、init。
  • 网络工具:ifconfig、ping、route、udhcpc。
  • 设备与模块:mdev、insmod、rmmod、lsmod。
  • 文本处理:grep、sed、awk、cut、sort。

这些命令并非全部默认启用,而是通过配置菜单按需选择。对于根文件系统来说,最常用的是 sh、init、mount、mdev、ifconfig 和基础文件命令。

BusyBox 单二进制多命令入口结构 busybox 可执行文件 统一入口 + 命令分发 sh / ash ls / cp / mv mount / umount ifconfig / ping mdev 调用方式:命令名软链接 → busybox,或直接执行 busybox <applet> 例如:/bin/ls → /bin/busybox,执行 ls 时由 busybox 分发到 ls 功能

三、编译配置:从 defconfig 到 menuconfig

BusyBox 使用 Kconfig 配置系统,编译流程与 Linux 内核类似。典型步骤是:获取源码、选择默认配置、按需裁剪、编译、安装到目标根文件系统目录。

tar -xvf busybox-1.36.1.tar.bz2
cd busybox-1.36.1
make defconfig
make menuconfig
make -j$(nproc)
make install

其中 make defconfig 会生成一个通用默认配置,适合快速起步;make menuconfig 用于交互式裁剪。配置时重点关注以下选项:

配置项 作用 建议
Settings → Build static binary 生成静态链接的 busybox 根文件系统无动态库时选 Y
Settings → Cross compiler prefix 指定交叉编译器前缀 如 arm-linux-gnueabihf-
Coreutils → ls / cp / mv 基础文件命令 按需启用
Networking Utilities → ifconfig / ping 网络配置与测试 需要联网时启用
Linux System Utilities → mdev 热插拔设备节点管理 嵌入式常用
Shells → ash 轻量 Shell 通常必选
如果目标板没有动态库,建议先启用静态编译,避免启动时出现 “not found” 或库缺失错误。静态编译会增大体积,但能显著降低根文件系统依赖。

四、安装与基本使用

执行 make install 后,BusyBox 默认会安装到源码目录下的 _install 中,结构通常包括 bin/、sbin/、usr/bin/、usr/sbin/ 以及大量指向 busybox 的软链接。将这些目录复制到目标根文件系统即可。

make CONFIG_PREFIX=/opt/rootfs install
ls -l /opt/rootfs/bin/ls
# 输出示例:
# lrwxrwxrwx 1 root root 7 ... /opt/rootfs/bin/ls -> busybox

在目标板上,可以直接执行 busybox 查看已编译命令列表,也可以用 busybox ls 方式调用某个 applet。若软链接已建立,则直接输入 ls、mount 等命令即可。

busybox
busybox ls -l /
busybox ifconfig eth0 192.168.1.10 up
busybox mount -t proc proc /proc

在根文件系统启动脚本中,BusyBox 的 init 和 mdev 经常配合使用:init 读取 /etc/inittab 启动系统,mdev 负责根据内核 uevent 动态创建 /dev 下的设备节点。

五、常见误区与复盘

  • 误区一:只复制 busybox 二进制,不建软链接。 这样只能通过 busybox ls 调用,直接输入 ls 会提示找不到命令。
  • 误区二:忽略交叉编译器前缀。 在 x86 主机上编译出的 busybox 无法在 ARM 板运行,必须设置正确的 CROSS_COMPILE。
  • 误区三:动态链接却未带库。 若未静态编译,需把 libc、ld-linux 等库一并放入根文件系统。
  • 误区四:功能裁剪过度。 例如去掉 mount 或 sh,会导致系统无法挂载 proc、sysfs 或执行启动脚本。
裁剪 BusyBox 时应遵循“先跑通、再瘦身”的原则。先保留 sh、init、mount、mdev、基础文件命令和必要网络工具,确认系统能正常启动后,再逐步关闭不用的 applet。

总体来看,BusyBox 是嵌入式根文件系统的“基础工具箱”。掌握它的单二进制多命令机制、Kconfig 配置方法、交叉编译与安装流程,就能快速搭建出一个体积小、功能完整、可启动的根文件系统雏形。