2. BusyBox源码获取与编译环境搭建
好,咱们正式开始动手了。这一章的目标很明确:拿到BusyBox源码,把交叉编译环境搭好,然后验证工具链能不能正常工作。说白了,就是给后续的裁剪工作铺好路。
我个人习惯先把环境搞利索了再动手。你想想看,如果编译环境有问题,后面折腾半天都是白费功夫。我在项目中遇到过好几次,同事花了一周裁剪出来的BusyBox,结果拿到板子上跑不起来,最后发现是工具链版本不匹配。嗯,这种坑咱们得避开。
2.1 下载BusyBox源码
BusyBox的源码托管在GitHub上,官方地址是:https://github.com/mirror/busybox。当然,你也可以从官网 https://busybox.net 下载稳定版。
我个人建议用git clone的方式,这样方便后续切换版本或者查看历史提交。比如你发现某个版本有bug,可以快速回退。
# 克隆最新源码
git clone https://github.com/mirror/busybox.git
# 或者下载指定版本(推荐稳定版)
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar -xjf busybox-1.36.1.tar.bz2
cd busybox-1.36.1/
2.2 配置交叉编译工具链
交叉编译,说白了就是在你的PC上编译出能在ARM(或其他架构)板子上运行的二进制文件。这里的关键是工具链的选择。
常见的工具链有几种:
- Linaro GCC:ARM官方推荐,支持ARMv7、ARMv8等架构
- Buildroot生成的工具链:定制化强,适合深度裁剪
- 芯片厂商提供的工具链:比如NXP、TI、Rockchip等厂家提供的SDK
我以Linaro工具链为例,演示配置过程:
# 下载Linaro GCC(ARM 32位为例)
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
# 解压到指定目录
tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
sudo mv gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf /opt/
# 配置环境变量(建议写入~/.bashrc)
export PATH=/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin:$PATH
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
source ~/.bashrc 或者重新打开终端。我曾经见过有人配完环境变量忘了source,结果编译报错找了半天原因。
2.3 搭建最小编译环境
最小编译环境需要哪些东西?其实就三样:
- 交叉编译器:上面已经配好了
- 必要的系统库:比如libc、libm等
- 内核头文件:用于编译时引用系统调用接口
对于BusyBox来说,它本身依赖很少。你甚至不需要完整的rootfs就能编译。但为了后续验证,我建议准备一个最小化的sysroot。
这里有个小技巧:用Buildroot生成一个最简工具链和sysroot,大概只需要几分钟:
# 下载Buildroot
git clone https://github.com/buildroot/buildroot.git
cd buildroot/
# 配置最小目标(ARM为例)
make qemu_arm_versatile_defconfig
# 修改配置,只生成工具链和内核头文件
make menuconfig
# 进入 Toolchain 选项,确保 Enable C++ support 关闭(节省时间)
# 进入 Filesystem images 选项,取消所有文件系统镜像生成
# 开始编译
make -j$(nproc)
编译完成后,工具链在 output/host/bin/ 目录下,sysroot在 output/host/arm-buildroot-linux-uclibcgnueabi/sysroot/。
核心要点:最小编译环境的核心是 CROSS_COMPILE 和 ARCH 两个环境变量。只要这两个对了,编译基本不会出大问题。
2.4 验证编译工具链
工具链配好了,怎么知道它能不能用?写个简单的C程序测试一下:
// test.c
#include <stdio.h>
int main() {
printf("Hello from BusyBox!\n");
return 0;
}
然后交叉编译:
arm-linux-gnueabihf-gcc -o test test.c
file test
如果输出类似下面这样,说明工具链工作正常:
test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, not stripped
接下来验证BusyBox能否正常配置和编译:
cd busybox-1.36.1/
make defconfig # 使用默认配置
make -j$(nproc) # 开始编译
编译完成后,会在当前目录生成 busybox 可执行文件。用 file busybox 查看,确认是ARM架构的ELF文件。
undefined reference to `__sync_synchronize' 错误。这是因为工具链的原子操作支持有问题。解决办法是加编译选项 -march=armv7-a 或者升级工具链版本。
最后,用QEMU模拟运行一下,验证编译出来的BusyBox能否正常工作:
# 安装QEMU用户态模拟器
sudo apt install qemu-user-static
# 运行BusyBox
qemu-arm-static ./busybox ls
如果能看到BusyBox内置的ls命令输出,恭喜你,整个编译环境搭建成功了!
本章核心知识体系:
好了,到这一步,你的编译环境已经搭建完毕。下一章我们会深入BusyBox的配置菜单,看看怎么裁剪出最适合你项目的版本。记住,环境搭好了,后面的事情就顺了。