4. Busybox 源码获取与配置:从 git 仓库拉取源码、make menuconfig 图形化配置、保存与加载配置

这一章我们正式动手。源码获取和配置,是整个嵌入式系统构建的起点。说白了,你得先把 Busybox 请到你的开发机上,然后告诉它:你要编译哪些命令、用哪种 C 库、目标架构是什么。

我见过不少新手,直接从网上下载一个压缩包就开始编译。结果呢?编译出来的东西要么跑不起来,要么缺这缺那。嗯,这里面的坑,我当年都踩过。

4.1 从 Git 仓库拉取源码

我个人习惯用 Git 管理所有嵌入式项目的源码。Busybox 的官方仓库在 git.busybox.net,当然你也可以用 GitHub 上的镜像。

先看看怎么拉取稳定版本:

# 拉取最新稳定分支(推荐)
git clone git://git.busybox.net/busybox
cd busybox
git checkout 1_36_stable

# 或者拉取特定版本标签
git clone https://github.com/mirror/busybox.git
cd busybox
git checkout 1_36_1

为什么要用稳定分支?我在项目中遇到过,用 master 分支编译出来的 Busybox,在某个老款 ARM 板子上跑着跑着就 segfault 了。后来查了半天,发现是 master 分支里一个实验性的补丁没合好。从那以后,我坚持用 _stable 分支或打了 tag 的版本。

我的建议: 如果你做产品,用 1_36_stable 或 1_35_stable。如果你只是学习,1_36_1 就够了。别追新,稳定第一。

拉取完成后,看看目录结构:

busybox/
├── applets/       # 各个命令的入口
├── archival/      # 压缩/解压工具(tar、gzip 等)
├── coreutils/     # 核心工具(cat、cp、mv 等)
├── libbb/         # Busybox 自己的基础库
├── networking/    # 网络工具(ping、ifconfig 等)
├── shell/         # shell 实现(ash、hush)
├── util-linux/    # Linux 工具(mount、fdisk 等)
├── Config.in      # 顶层配置菜单
├── Makefile       # 主 Makefile
└── .config        # 配置文件(编译后生成)

你想想看,这么多目录,每个目录下又有几十个源文件。如果不用配置工具,手动去改 Makefile 来开关功能,那得累死。所以,我们需要图形化配置。

4.2 make menuconfig 图形化配置

在源码根目录下,直接执行:

make menuconfig

前提是你的系统装了 ncurses-dev 或 libncurses5-dev。没装的话,Debian/Ubuntu 上跑:

sudo apt install libncurses5-dev

然后你会看到一个蓝底白字的菜单界面。这个界面和 Linux 内核的 menuconfig 长得一模一样。为什么?因为它们用的是同一套配置框架——Kconfig。

核心概念: Busybox 的配置系统基于 Kconfig。每个功能模块都有一个 Config.in 文件,里面定义了该模块的配置选项。menuconfig 读取这些文件,生成一个树形菜单。你选中的选项,最终会写入 .config 文件。

进入 menuconfig 后,你会看到类似这样的结构:

Busybox Configuration
├── General Configuration        # 通用配置(路径、调试等)
├── Archival Utilities           # 归档工具
├── Coreutils                    # 核心工具
├── Console Utilities            # 控制台工具
├── Debian Utilities             # Debian 兼容工具
├── Editors                      # 编辑器(vi、sed 等)
├── Finding Utilities            # 查找工具(grep、find 等)
├── Init Utilities               # 初始化工具(init、halt 等)
├── Login/Password Management    # 登录管理
├── Linux Module Utilities       # 模块工具
├── Linux System Utilities       # 系统工具
├── Miscellaneous Utilities      # 杂项工具
├── Networking Utilities         # 网络工具
├── Print Utilities              # 打印工具
├── Mail Utilities               # 邮件工具
├── Process Utilities            # 进程工具
├── Shells                       # Shell 选择
├── System Logging Utilities     # 日志工具
└── ...

操作方式很简单:

  • 方向键:上下移动光标
  • Enter:进入子菜单
  • Y:选中(编译进 Busybox)
  • N:不选
  • M:编译为模块(Busybox 里很少用)
  • ?:查看帮助
  • 空格:循环切换 Y/N/M
  • Esc + Esc:返回上一级

我记得第一次用 menuconfig 时,觉得这界面太古老了。但用久了你会发现,它其实非常高效。尤其是做嵌入式,你需要在几十个选项里快速定位某个工具。按 / 键可以搜索,输入 ping 就能直接跳到 ping 的配置项。

注意: 不要把所有选项都选上。我曾经为了省事,直接 make allnoconfig 然后手动选了几个,结果编译出来的 Busybox 有 2MB 多,在只有 4MB Flash 的板子上根本放不下。嵌入式系统,寸土寸金,只选你需要的。

4.3 保存与加载配置

配置完成后,按 Esc + Esc 退出,menuconfig 会问你是否保存。选 Yes,配置就写入了 .config 文件。

但这里有个问题:.config 是编译产物,一般不会提交到 Git 仓库。那你怎么在不同项目之间复用配置?

Busybox 提供了几个命令来管理配置:

命令 作用 我常用的场景
make defconfig 生成默认配置(大部分功能开启) 快速开始,然后手动裁剪
make allnoconfig 生成最小配置(所有功能关闭) 从零开始,只选需要的
make allyesconfig 生成全功能配置 测试编译环境是否正常
make savedefconfig 将当前配置精简为最小差异文件 保存到 Git,方便版本管理
make oldconfig 基于现有 .config 更新配置 升级 Busybox 版本后使用

我个人最推荐的做法是:

# 1. 先做最小配置
make allnoconfig

# 2. 用 menuconfig 手动选你需要的工具
make menuconfig

# 3. 保存精简配置
make savedefconfig

# 4. 把 defconfig 文件提交到 Git
cp defconfig configs/my_project_defconfig
git add configs/my_project_defconfig
git commit -m "add my project defconfig"

为什么要用 savedefconfig?因为 .config 文件很大,里面有很多默认值。而 defconfig 只保存你修改过的选项,文件小、易读、易维护。你想想看,一个 2000 行的 .config 和一个 50 行的 defconfig,哪个更适合放在 Git 里?

加载配置也很简单:

# 加载你保存的精简配置
make my_project_defconfig

# 或者直接复制
cp configs/my_project_defconfig .config
make oldconfig

这里有个细节:make my_project_defconfig 会自动把 configs/my_project_defconfig 展开为完整的 .config。而 make oldconfig 会检查当前 .config 是否有缺失的选项(比如你升级了 Busybox 版本,新增了一些配置项),并提示你选择。

避坑指南: 我曾经在升级 Busybox 版本后,直接用了旧的 .config 编译,结果新版本里某个工具改了依赖关系,编译报错。后来我养成了习惯:每次升级版本后,先 make oldconfig,把新增的选项确认一遍。

4.4 知识体系总览

这一章的内容,说白了就是三个步骤:拉源码、配选项、存配置。但背后的逻辑,我画了一张图帮你理清:

Busybox 源码获取与配置流程 步骤1:获取源码 git clone + checkout 稳定分支 步骤2:配置选项 make menuconfig 图形化配置 步骤3:保存 .config make defconfig make allnoconfig make allyesconfig make menuconfig 手动微调(只选需要的工具) make savedefconfig → defconfig 直接保存 .config 最终产物:.config 或 configs/xxx_defconfig 三种基础配置模板,选一个作为起点,再用 menuconfig 手动裁剪

这张图把整个流程串起来了。你从左边开始,拉取源码,然后选择一种基础配置模板(defconfig / allnoconfig / allyesconfig),再用 menuconfig 手动微调,最后保存为 .config 或精简的 defconfig。

我个人强烈建议走 allnoconfig + 手动选择 这条路。虽然一开始多花点时间,但你对最终镜像里包含了什么、没包含什么,心里一清二楚。做嵌入式,控制力就是生产力。