BusyBox 搭建 mini rootfs 完全指南 / 第 1 章:BusyBox 概述
第 1 章:BusyBox 概述
1.1 什么是 BusyBox
BusyBox 是一个将数百个标准 Unix/Linux 工具集成到单个可执行文件中的开源项目。它由 Bruce Perens 于 1995 年发起,目标是在极小的磁盘空间内提供一个功能完整的 POSIX 环境。
“BusyBox: The Swiss Army Knife of Embedded Linux” — BusyBox 官方标语
核心特点
| 特点 | 说明 |
|---|---|
| 单一二进制 | 所有工具编译进一个可执行文件 |
| 极小体积 | 静态编译约 1-3MB,动态链接更小 |
| POSIX 兼容 | 提供标准 Unix 接口的子集 |
| 可裁剪 | 通过 menuconfig 选择需要的功能 |
| 广泛使用 | Alpine Linux、Android、OpenWrt 等均基于它 |
历史演变
1995 Bruce Perens 创建 BusyBox(单一 shell 脚本)
1999 Erik Andersen 重写为 C 语言版本
2000 版本 0.x 系列,支持更多 Applet
2005 版本 1.0 发布,功能趋于稳定
2010+ 持续维护,支持现代 Linux 特性
2024 版本 1.36+,支持更多平台
1.2 Applet 机制
Applet(小程序)是 BusyBox 的核心概念。每个 Applet 对应一个标准 Linux 命令。
Applet 工作原理
# BusyBox 通过 argv[0] 判断要执行哪个 Applet
$ ls -la /bin/busybox
-rwxr-xr-x 1 root root 1.2M Jan 1 00:00 /bin/busybox
# 创建符号链接
$ ln -s /bin/busybox /bin/ls
$ ln -s /bin/busybox /bin/cat
$ ln -s /bin/busybox /bin/grep
# 直接调用 Applet
$ busybox ls # 通过 busybox 命令调用
$ busybox cat # 通过 busybox 命令调用
# 通过符号链接调用
$ ls # 实际调用 /bin/busybox,argv[0]="ls"
$ cat # 实际调用 /bin/busybox,argv[0]="cat"
Applet 列表
BusyBox 包含 300+ 个 Applet,按功能分类:
| 类别 | 典型 Applet | 数量 |
|---|---|---|
| Shell | ash, sh, bash(受限) | ~10 |
| 文件操作 | ls, cat, cp, mv, rm, find, grep | ~50 |
| 文本处理 | sed, awk, cut, sort, uniq, tr | ~30 |
| 网络工具 | ifconfig, route, wget, ping, nc | ~40 |
| 系统管理 | mount, umount, ps, kill, df | ~60 |
| 压缩归档 | tar, gzip, bzip2, xz, zip | ~15 |
| 初始化 | init, poweroff, reboot | ~10 |
| 其他 | vi, ed, bc, diff, patch | ~100+ |
查看当前编译包含的所有 Applet:
# 列出所有可用 Applet
$ busybox --list
# 带分类的列表
$ busybox --list-full
# 示例输出
$ busybox --list | head -20
[
[[
ash
awk
base64
basename
cat
chattr
chgrp
chmod
chown
chroot
clear
cmp
cp
cpio
cut
date
...
Applet 优先级
当系统中同时存在 BusyBox Applet 和完整版命令时:
# 查看命令来源
$ which ls
/bin/ls # 可能是 GNU ls 或 BusyBox 符号链接
$ ls --version
ls (GNU coreutils) 8.32 # GNU 版本
# 或
BusyBox v1.36.1 (...) # BusyBox 版本
# BusyBox Applet 优先级:
# 1. PATH 中的完整命令(如 /usr/bin/ls)
# 2. BusyBox 符号链接(如 /bin/ls -> busybox)
# 3. busybox <applet> 显式调用
1.3 设计哲学
1.3.1 极简主义
BusyBox 的核心设计原则是**“够用就好”**:
// BusyBox 源码中的典型实现风格
// 以 cat 命令为例 (simplified)
static int cat_main(int argc, char **argv)
{
int fd;
// 简单直接的实现
if (argc == 1) {
// 读取 stdin
bb_copyfd_eof(STDIN_FILENO, STDOUT_FILENO);
} else {
while (*++argv) {
fd = open(*argv, O_RDONLY);
if (fd < 0) {
bb_perror_msg("can't open '%s'", *argv);
continue;
}
bb_copyfd_eof(fd, STDOUT_FILENO);
close(fd);
}
}
return 0;
}
1.3.2 代码复用
大量公共函数被提取为共享库:
libbb/
├── bb_cat.c # cat 实现
├── bb_copyfd.c # 文件描述符复制
├── bb_getopt.c # 参数解析
├── bb_mkpath.c # 路径创建
└── ...
1.3.3 选项兼容性
BusyBox 尽量保持与 GNU 工具兼容,但有意简化:
# BusyBox 支持的典型选项
$ busybox ls -la /tmp
# 等价于 GNU ls -la /tmp
# BusyBox 特有的选项
$ busybox ls --color=auto # 部分 Applet 支持
# BusyBox 不支持的选项(刻意简化)
$ busybox ls --author # 不支持
$ busybox ls --time-style= # 不支持
1.4 与 GNU 工具链对比
1.4.1 功能对比
| 方面 | BusyBox | GNU Coreutils |
|---|---|---|
| 二进制大小 | 1-3MB(全部) | 10-50MB(分散) |
| 功能完整性 | 子集(80% 常用功能) | 完整(100%) |
| 选项支持 | 简化版 | 完整版 |
| 性能 | 足够 | 更优 |
| 可移植性 | 极佳 | 良好 |
| 依赖 | 无(静态编译时) | glibc 等 |
| 许可证 | GPLv2 | GPLv3 |
1.4.2 详细差异示例
ls 命令对比
# GNU ls 完整输出
$ ls --format=long --time-style=full-iso /tmp
drwxrwxrwt 2 root root 4096 2024-01-01 10:00:00.000000000 +0800 .
# BusyBox ls 输出
$ busybox ls -l /tmp
drwxrwxrwt 2 root root 4096 Jan 1 10:00 .
sed 命令对比
# GNU sed 支持扩展正则
$ echo "hello" | sed -E 's/(hel)lo/\1p/'
helpp
# BusyBox sed 基本兼容,但部分高级特性缺失
$ echo "hello" | busybox sed -E 's/(hel)lo/\1p/'
helpp
# 注:BusyBox sed 对 -E 支持取决于编译选项
# GNU sed 支持的 in-place 编辑
$ sed -i 's/old/new/g' file.txt # GNU
$ sed -i 's/old/new/g' file.txt # BusyBox(兼容)
grep 命令对比
# GNU grep 完整选项
$ grep -P '\d+' file.txt # PCRE 支持
$ grep --color=auto "pattern" file # 高亮显示
# BusyBox grep(不支持 -P)
$ busybox grep -E '[0-9]+' file.txt # 使用扩展正则替代
$ busybox grep "pattern" file # 基本功能
1.4.3 选择建议
| 场景 | 推荐 | 原因 |
|---|---|---|
| 嵌入式设备 | BusyBox | 体积小,资源占用少 |
| 容器基础镜像 | BusyBox/Alpine | 快速启动,安全攻击面小 |
| 开发环境 | GNU | 功能完整,调试方便 |
| 生产服务器 | GNU | 性能和功能保障 |
| 系统恢复盘 | BusyBox | 单一二进制,易于部署 |
1.5 适用场景
1.5.1 嵌入式 Linux 系统
# 典型的嵌入式系统 rootfs
/
├── bin/
│ ├── busybox # 主二进制
│ ├── sh -> busybox # 符号链接
│ ├── ls -> busybox
│ └── ... # 其他符号链接
├── etc/
│ ├── inittab # BusyBox init 配置
│ └── init.d/
│ └── rcS # 启动脚本
├── lib/ # 动态库(静态编译时可为空)
├── proc/
├── sys/
└── dev/
1.5.2 Docker/容器基础镜像
# 基于 BusyBox 的极小镜像
FROM scratch
COPY busybox /busybox
RUN ["/busybox", "mkdir", "-p", "/bin", "/tmp", "/proc", "/sys", "/dev"]
RUN for cmd in sh ls cat echo cp mv rm mkdir; do \
["/busybox", "ln", "-s", "/busybox", "/bin/$cmd"]; \
done
CMD ["/bin/sh"]
构建后镜像大小仅约 1-3MB。
1.5.3 系统恢复/救援盘
# 创建最小恢复环境
$ mkdir -p rescue/{bin,sbin,etc,proc,sys,dev,tmp}
$ cp /bin/busybox rescue/bin/
$ cd rescue/bin
$ for cmd in sh ls cat mount umount fsck reboot; do
ln -s busybox $cmd
done
# 打包为 initramfs
$ cd ../..
$ find rescue | cpio -o -H newc | gzip > rescue.cpio.gz
1.5.4 网络设备/路由器固件
OpenWrt、DD-WRT 等路由器固件广泛使用 BusyBox:
OpenWrt 系统架构:
┌─────────────────────────────────┐
│ 用户空间 │
│ ┌───────────────────────────┐ │
│ │ BusyBox │ │
│ │ ash, ls, cat, wget... │ │
│ └───────────────────────────┘ │
│ ┌───────────────────────────┐ │
│ │ 应用程序 │ │
│ │ iptables, dnsmasq... │ │
│ └───────────────────────────┘ │
├─────────────────────────────────┤
│ Linux 内核 │
├─────────────────────────────────┤
│ 硬件平台 │
└─────────────────────────────────┘
1.6 BusyBox 版本与许可
版本历史
| 版本系列 | 发布年份 | 主要变化 |
|---|---|---|
| 0.x | 1999-2004 | C 语言重写,功能扩展 |
| 1.0 | 2005 | 首个稳定版 |
| 1.20 | 2012 | 改进 ash,新增 Applet |
| 1.30 | 2019 | 改进 musl 支持 |
| 1.36 | 2023 | 改进安全特性 |
| 1.37+ | 2024+ | 持续维护 |
许可证
BusyBox is licensed under the GNU General Public License version 2 (GPLv2).
https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
注意事项:
- 静态链接 BusyBox 的程序必须提供源码或源码获取方式
- 商用嵌入式设备需遵守 GPLv2 要求
- 动态链接不触发 GPL 传染性
1.7 安装 BusyBox 的预编译版本
大多数 Linux 发行版提供预编译的 BusyBox 包:
# Ubuntu/Debian
$ sudo apt install busybox
# CentOS/RHEL
$ sudo yum install busybox
# Arch Linux
$ sudo pacman -S busybox
# Alpine Linux(默认已安装)
$ apk add busybox
# 验证安装
$ busybox --help
BusyBox v1.36.1 (Ubuntu 1:1.36.1-1ubuntu1) multi-call binary.
...
提示:预编译版本通常包含大多数常用 Applet,但可能缺少某些可选功能。如需自定义功能,请参考第 2 章从源码编译。
1.8 本章小结
| 要点 | 说明 |
|---|---|
| Applet | 每个 Unix 命令对应一个 BusyBox Applet |
| 设计哲学 | 极简、够用、可裁剪 |
| 与 GNU 对比 | 功能子集,体积优势明显 |
| 适用场景 | 嵌入式、容器、恢复盘、网络设备 |
| 版本 | 推荐使用 1.36+ 稳定版 |
扩展阅读
下一章: 第 2 章 — 编译安装