3、BusyBox源码下载与配置:从git仓库拉取BusyBox源码,使用menuconfig进行基础配置

好,到了真正动手的环节了。前面两章我们把嵌入式Linux的根文件系统构成和BusyBox的角色讲清楚了,现在咱们直接拉代码、配配置。

我个人习惯,做嵌入式项目第一步永远是锁定源码版本。你想想看,BusyBox迭代了二十多年,不同版本之间的配置项、默认行为差异其实挺大的。我早期带团队时吃过一次亏——有人从网上下了一个旧版BusyBox,编译出来的init行为跟新内核不兼容,排查了两天才发现是版本问题。从那以后,我要求所有项目必须用git管理源码版本。

3.1 从git仓库拉取BusyBox源码

BusyBox的官方仓库在git.busybox.net,不过国内访问有时不太稳定。我个人建议用GitHub上的镜像,或者提前把源码包下载到本地。

先看看怎么从官方仓库拉取:

# 克隆完整仓库(包含所有历史记录)
git clone git://git.busybox.net/busybox

# 或者指定一个稳定分支,比如1_36_stable
git clone -b 1_36_stable git://git.busybox.net/busybox

# 如果网络慢,可以用GitHub镜像
git clone https://github.com/mirror/busybox.git

拉下来之后,我习惯先看看版本信息:

cd busybox
git branch -a          # 查看所有分支
git tag | tail -10     # 查看最近的标签
git describe --tags    # 当前HEAD对应的标签
我的建议:不要用master分支做产品开发。master是开发分支,可能有不稳定的提交。选一个稳定标签,比如1_36_0或1_36_1,这样后续遇到问题也好查资料。

如果你是在没有网络的环境下开发(比如涉密项目或工厂产线),可以提前在能联网的机器上把源码打包带走:

git clone -b 1_36_stable git://git.busybox.net/busybox
tar czf busybox-1_36_stable.tar.gz busybox

嗯,这里要注意:打包前记得把.git目录删掉,否则包会很大。不过如果你后续还想用git管理自己的修改,保留.git也行。

3.2 源码目录结构速览

拉完代码别急着配,先花两分钟看看目录结构。我当年第一次打开BusyBox源码时,说实话有点懵——几千个文件,从哪下手?

目录/文件 作用 我的关注点
applets/ 每个命令的入口函数(main的封装) 调试时看这里,确认命令是否被编译
libbb/ BusyBox核心库,公共函数都在这里 修改系统调用行为时经常翻这里
networking/ 网络相关命令(ping、ifconfig等) 嵌入式网络调试必看
util-linux/ Linux工具类命令(mount、fdisk等) 文件系统相关功能在这里
Config.in Kconfig风格的配置文件 menuconfig的菜单定义
.config 编译配置(menuconfig生成) 这个文件决定了最终编译哪些命令

说白了,你不需要把每个文件都看懂。但要知道:配置系统在顶层,功能实现在子目录。我们接下来要做的menuconfig,就是修改顶层那个.config文件。

3.3 使用menuconfig进行基础配置

BusyBox的配置系统和Linux内核一样,都是基于Kconfig的。所以如果你配过内核,那这套东西你闭着眼都能操作。

先执行清理,确保没有残留的配置:

make distclean

然后启动配置界面:

make menuconfig

如果提示缺少ncurses库,装一下就好:

# Ubuntu/Debian
sudo apt-get install libncurses5-dev

# CentOS/RHEL
sudo yum install ncurses-devel

核心思路:menuconfig里几千个选项,你不可能全配一遍。我的做法是——先配一个最小可用系统,然后按需添加。这样编译快、体积小、问题也少。

进入menuconfig后,你会看到这样的界面:

BusyBox Configuration
├── Busybox Settings
│   ├── General Configuration
│   ├── Build Options
│   ├── Debugging Options
│   └── Installation Options
├── Applets
│   ├── Archival Utilities
│   ├── Coreutils
│   ├── Console Utilities
│   ├── Editors
│   ├── Finding Utilities
│   ├── Init Utilities
│   ├── Login/Password Management Utilities
│   ├── Linux Ext2 FS Progs
│   ├── Linux Module Utilities
│   ├── Linux System Utilities
│   ├── Miscellaneous Utilities
│   ├── Networking Utilities
│   ├── Process Utilities
│   ├── Shells
│   └── System Logging Utilities
└── ...

嗯,这里要注意:不要被选项数量吓到。你只需要关注几个关键区域。

3.4 必须配置的几个关键项

我根据多年经验,把必须配的选项整理成了一张表。这些是让系统能跑起来的最低配置:

配置路径 选项 推荐值 为什么重要
Settings → Build Options Build static binary (no shared libs) 选上(静态编译) 嵌入式环境库不完整,静态编译最省心
Settings → Build Options Cross Compiler prefix arm-linux-gnueabihf- 指定交叉编译工具链前缀
Settings → Installation Options Destination path for 'make install' ./_install 编译产物输出目录
Init Utilities init 选上 系统启动的第一个进程
Shells ash 选上 最轻量的shell,嵌入式标配
Coreutils cat, ls, cp, mv, rm, mkdir 选上 最基本的文件操作命令
我曾经踩过的坑:第一次做项目时,我忘了配"Build static binary",结果编译出来的BusyBox动态链接了glibc。放到目标板上运行时,系统提示"file not found"——其实文件在,只是动态链接器没找到。从那以后,嵌入式项目我全部静态编译。

具体操作步骤:

  1. 进入 Busybox Settings → Build Options
  2. 按空格选中 Build static binary (no shared libs)
  3. 在 Cross Compiler prefix 里输入你的工具链前缀,比如 arm-linux-gnueabihf-
  4. 进入 Installation Options,把安装路径设成 ./_install
  5. 回到主菜单,进入 Init Utilities,确保 init 是 [*] 状态
  6. 进入 Shells,选中 ash
  7. 进入 Coreutils,按 / 搜索 cat,然后逐个选中你需要的命令

配置完成后,按两次ESC退出,选择保存。这时你会看到当前目录下生成了一个.config文件。

3.5 验证配置是否正确

配置完别急着编译,先检查一下.config文件:

# 查看是否启用了静态编译
grep "CONFIG_STATIC" .config

# 查看交叉编译前缀
grep "CROSS_COMPILER_PREFIX" .config

# 查看启用了哪些命令(会很多,只看前10个)
grep "=y" .config | head -10

我一般还会做一件事——把.config备份一份:

cp .config config_my_minimal

这样以后想回退或者对比配置时,直接拿这个文件出来就行。

3.6 本章知识体系

下面这张图把BusyBox源码获取和配置的整个流程串起来了:

BusyBox源码获取与配置流程 第一阶段:源码获取 git clone 官方仓库 切换到稳定标签 确认版本号 第二阶段:基础配置 make distclean make menuconfig 保存 .config 第三阶段:关键配置项 静态编译 交叉编译前缀 init + ash 基础coreutils 第四阶段:验证配置 → 备份 .config

这张图把整个流程分成了四个阶段:源码获取、基础配置、关键配置项、验证备份。每个阶段都有明确的输入输出,照着走不会出错。

我的习惯:每次配置完,我都会在.config文件头部加一行注释,写上配置日期、目标平台和用途。比如:# 2024-03-15 arm926ej-s 最小系统。这样三个月后回来看,还能想起来当时为什么这么配。