BusyBox 在嵌入式系统中的集成方式
嵌入式系统为什么必须用 BusyBox
一个典型的嵌入式 Linux 设备(路由器、智能家居、工业控制器)的存储规格通常是:
| 设备类型 | Flash 容量 | 可用空间 |
|---|---|---|
| 家用路由器 | 8-16MB | ~4MB |
| IoT 网关 | 4-8MB | ~2MB |
| 工业控制器 | 16-32MB | ~8MB |
| 智能家电 | 2-4MB | ~512KB |
在这样的约束下,完整的 GNU 工具集(coreutils 15MB + bash 1MB + util-linux 5MB)根本装不下。而 BusyBox 默认编译约 1.1MB,裁剪后可以做到 200KB——这是唯一现实的选择。
集成方式一览
BusyBox 集成到嵌入式系统有三种主流路径:
Buildroot 方式(推荐)
Buildroot 是一个自动化构建完整根文件系统的工具链。它会:
- 自动下载 BusyBox 源码
- 使用内置的默认配置(或自定义 .config)
- 编译并安装到
output/target/ - 打包成 cpio 或 ext4 镜像直接烧录
# Buildroot 自动完成一切
make busybox-menuconfig # 进入 BusyBox 配置界面
make # 整体构建
# 产物在 output/images/ 下
OpenWrt 方式
OpenWrt 是专门针对路由器的发行版,它的构建系统(OpenWrt Buildroot)深度集成了 BusyBox。在 OpenWrt 的 make menuconfig 里可以直接打开 BusyBox 的子配置,按路由器需要裁剪:
# 在 OpenWrt 源码树中
make menuconfig
# 选择 Global build settings → Custom busybox configuration
# 或者直接 make menuconfig BUSYBOX_CONFIG
OpenWrt 还在 BusyBox 基础上增加了 UCI(Unified Configuration Interface)等路由器特有的工具,全部通过 BusyBox 的 Applet 机制挂上去。
手动方式(自定义根文件系统)
如果不用 Buildroot/OpenWrt,手动集成也不复杂:
# 1. 准备根文件系统目录
mkdir -p rootfs/{bin,sbin,etc,dev,proc,sys,tmp,var,usr/bin,usr/sbin}
# 2. 编译安装 BusyBox
make defconfig
make CONFIG_STATIC=y -j$(nproc)
make CONFIG_PREFIX=rootfs install
# 3. 添加必要的库和模块(如果用动态链接)
# 静态编译跳过这一步
# 4. 准备 /dev(或用 devtmpfs)
mknod rootfs/dev/console c 5 1
mknod rootfs/dev/null c 1 3
# 5. 准备配置文件
cp etc/inittab rootfs/etc/
cp etc/fstab rootfs/etc/
# 6. 打包成 cpio(initramfs)
cd rootfs && find . | cpio -o -H newc | gzip > ../initramfs.cpio.gz
集成时的关键配置
静态编译:make menuconfig → Build Options → Build BusyBox as a static binary = YES。嵌入式设备通常没有完整的动态链接环境,静态编译可以避免 libc 缺失的问题。
交叉编译:用 CROSS_COMPILE=arm-linux-gnueabihf- make 指定交叉编译器前缀。Buildroot 和 OpenWrt 会自动处理这个。
init 支持:BusyBox 内置 init Applet,如果你想让它作为 PID 1,需要在 menuconfig 里确保 init 相关选项开启,并准备好 /etc/inittab。
shell 选择:ash 是默认 Shell,够用且小。如果需要 bash 特性可以开 hush,或者单独安装 bash(代价是增加体积)。