2026年正点原子开发板移植方案——从0开始的Rootfs之路(2)BusyBox 编译安装:一把瑞士军刀的自制指南

发布时间:2026/5/26 23:27:06

2026年正点原子开发板移植方案——从0开始的Rootfs之路(2)BusyBox 编译安装:一把瑞士军刀的自制指南 2026年正点原子开发板移植方案——从0开始的Rootfs之路2BusyBox 编译安装一把瑞士军刀的自制指南小请假条笔者从今天开始出差今天更新完毕之后到4月1日前不会更新公众号了也就是3月29日30日和31日更新的话可能只会缓慢更新手头有的存货。相关仓库已经开源https://github.com/Awesome-Embedded-Learning-Studio/imx-forge欢迎各位大佬看看批评指正为什么要写这篇文章上一章我们介绍了 Rootfs 的概念和各种方案。这一章我们要真正动手把 BusyBox 编译出来。你可能会说编译软件有什么难的不就是./configure make make install三板斧吗问题是BusyBox 的编译有几个坑让我当初踩了好久第一BusyBox 没有标准的 autotools./configure它用的是类似 Linux 内核的 Kconfig 系统。你得先了解 defconfig、menuconfig 这些概念。第二这是交叉编译你得指定架构ARCH和交叉编译工具链CROSS_COMPILE而且 BusyBox 的 defconfig 默认开启的一些选项在 ARM 上不兼容需要手动修复。第三编译产物在哪里安装到哪里去每次我都要去翻半天文档才搞清楚CONFIG_PREFIX是什么意思。第四验证你怎么知道自己编译出来的 busybox 是对的是 ARM 架构的吗大小正常吗所以这篇文章我会带你完整走一遍 BusyBox 的编译流程解释每一步在做什么为什么这么做。当你读完这篇文章你不仅能够编译出可用的 BusyBox更重要的是你会理解嵌入式交叉编译的基本流程。BusyBox 是什么瑞士军刀的传说BusyBox 的官方定义是“The Swiss Army Knife of Embedded Linux”嵌入式 Linux 的瑞士军刀。这个比喻非常形象。想象一把瑞士军刀它只有把手那么大但折叠着刀片、剪刀、锯子、开瓶器、螺丝刀等几十种工具。你需要什么功能就展开哪个工具。BusyBox 也是这样它只有一个可执行文件busybox但这个文件里编译进了几百个常用命令的实现——ls、cat、cp、mv、grep、awk、sh、vi 等等。运行时你可以通过两种方式调用# 方式一通过符号链接ls-l# 符号链接 ls 指向 busyboxbusybox 检测 argv[0] 知道要运行 ls# 方式二通过 applet 参数busyboxls-l# 直接告诉 busybox 要运行 ls这种设计带来了巨大的优势体积小一个 1-2 MB 的文件就包含了数百个命令资源共享所有命令共享代码库比独立编译节省大量空间部署简单只需要复制一个文件创建一堆符号链接BusyBox 的历史BusyBox 最早是 Bruce Perens 在 1996 年创建的当时叫 “BusyBox” 因为它把很多工具塞进一个盒子。1998 年由 Erik Andersen 接手维护2006 年后由 Denys Vlasenko 接手成为当前维护者。当前2026 年的最新稳定版本是 1.37.0IMX-Forge 项目使用的是 1.37.0 版本。环境准备工欲善其事必先利其器在开始编译之前我们需要确保环境准备好了。这包括1. 主机依赖检查BusyBox 的编译需要一些主机工具。在 Ubuntu/Debian 上你可以这样检查# 检查 gcc$ gcc--version# 检查 make$make--version# 检查 ncurses 库menuconfig 需要$ dpkg-l|greplibncurses为什么需要 ncursesmenuconfig 使用 ncurses 库来绘制终端上的图形配置界面。如果你只打算用 defconfig理论上可以不装但强烈建议装上——因为迟早你会用到 menuconfig 来修改配置。2. 交叉编译工具链检查我们要为 ARM 编译 BusyBox所以需要 ARM 交叉编译工具链。在 IMX-Forge 项目中我们使用arm-none-linux-gnueabihf工具链。3. BusyBox 源码准备IMX-Forge 项目将 BusyBox 作为子模块管理位于third_party/busybox/# 检查源码是否存在$lsthird_party/busybox/Makefile third_party/busybox/Makefile# 查看版本$head-5third_party/busybox/Makefile VERSION1PATCHLEVEL37SUBLEVEL0如果源码目录不存在记得初始化子模块gitsubmodule update--initthird_party/busyboxBusyBox 配置系统Kconfig 的世界BusyBox 使用与 Linux 内核相同的 Kconfig 配置系统。这意味着它的配置方式和内核几乎一模一样。配置文件层级Config.in源码中的配置定义描述各个选项.config实际的配置文件由配置工具生成defconfig默认配置模板常用配置目标目标作用defconfig使用默认配置推荐新手menuconfig图形化配置界面推荐修改配置config基于文本的配置界面allnoconfig全部禁用最小配置allyesconfig全部启用最大配置第一步使用 defconfig 生成初始配置我们从一个简单的配置开始——使用 defconfig 生成默认配置。# 进入项目根目录cd/path/to/imx-forge# 使用项目提供的构建脚本./scripts/build_helper/build-busybox.sh defconfig这个命令实际上执行的是make-Cthird_party/busybox\ARCHarm\CROSS_COMPILEarm-none-linux-gnueabihf-\O$(pwd)/out/busybox\defconfig让我们分解一下这些参数参数含义-C third_party/busybox切换到 BusyBox 源码目录执行 makeARCHarm目标架构是 ARMCROSS_COMPILEarm-none-linux-gnueabihf-交叉编译工具链前缀O$(pwd)/out/busybox输出目录构建产物放在这里defconfig使用默认配置执行成功后你会看到[INFO] Starting BusyBox build for arm [INFO] Target: defconfig [INFO] Checking host dependencies... [INFO] ✓ build-essential [INFO] ✓ libncurses-dev [INFO] All host dependencies found [INFO] Checking toolchain... [INFO] Toolchain found: arm-none-linux-gnueabihf-gcc (GNU Toolchain ...) xx.x.x [INFO] Toolchain verified [INFO] Checking BusyBox source... [INFO] BusyBox source: 1.37.0 [INFO] BusyBox source verified [INFO] All checks passed # # configuration written to out/busybox/.config #[!经验] 为什么使用 O 指定输出目录将构建产物与源码分离是一个好习惯源码目录保持干净便于 git 管理可以维护多个不同的构建配置Oout1, Oout2清理构建产物更简单rm -rf out/busybox第二步ARM 兼容性修复重要这是新手最容易忽略的一步。BusyBox 的 defconfig 默认启用了某些 x86 特定的优化选项在 ARM 上会导致编译错误。好奇有没有大手子提个Issue的。。。我当时看到了都惊呆了我都ARCHarm了为啥还开着hhh具体来说是这两个选项CONFIG_SHA1_HWACCELySHA1 硬件加速x86 特定CONFIG_SHA256_HWACCELySHA256 硬件加速x86 特定IMX-Forge 的构建脚本会自动检测并修复[INFO]Checking ARM-incompatible config items...[WARN]Disabled CONFIG_SHA1_HWACCEL(x86-only, not supported on ARM)[WARN]Disabled CONFIG_SHA256_HWACCEL(x86-only, not supported on ARM)[INFO]Running oldconfig tosyncpatched dependencies...如果你是手动编译需要这样修复# 编辑 .config禁用这两个选项sed-is/^CONFIG_SHA1_HWACCELy/# CONFIG_SHA1_HWACCEL is not set/out/busybox/.configsed-is/^CONFIG_SHA256_HWACCELy/# CONFIG_SHA256_HWACCEL is not set/out/busybox/.config# 运行 oldconfig 同步依赖make-Cthird_party/busyboxARCHarmCROSS_COMPILEarm-none-linux-gnueabihf-Oout/busybox oldconfig[!踩坑] 忘记修复会怎样编译会报类似这样的错误coreutils/libcoreutils.a(libcoreutils_a-sha1.o): In function sha1_hash: sha1.c:(.text0x38): undefined reference to sha1_begin_arch这个错误非常困惑因为它只告诉你链接失败但没说为什么。记住遇到 undefined reference 且与 sha 相关首先检查是否禁用了 HWACCEL。第三步编译 BusyBox配置好之后就可以编译了./scripts/build_helper/build-busybox.sh或者手动执行make-Cthird_party/busybox\ARCHarm\CROSS_COMPILEarm-none-linux-gnueabihf-\O$(pwd)/out/busybox\-j$(nproc)-j$(nproc)表示使用所有 CPU 核心并行编译可以显著加快速度。编译过程中你会看到大量输出[INFO] Building BusyBox (8 parallel jobs)... [CMD] make -C third_party/busybox ARCHarm CROSS_COMPILEarm-none-linux-gnueabihf- Oout/busybox -j8 CC applets/applet_tables.o LD applets/applet_tables HOSTCC applets/usage GEN include/usage_compressed.h CC applets/applets.o LD applets/built-in.o CC archival/built-in.o CC archival/libarchive/built-in.o CC console-tools/built-in.o CC coreutils/built-in.o ... LD busybox_unstripped GEN busybox.links STRIP busybox COPY busybox_unstripped COPY busybox关键文件的含义busybox_unstripped未剥离符号的版本用于调试busybox剥离符号后的最终版本busybox.links符号链接列表编译完成后输出的 busybox 二进制文件在out/busybox/busybox。第四步验证编译产物编译完成后我们要验证产物是否正确# 使用构建脚本的验证功能./scripts/build_helper/build-busybox.sh --install-only# 如果已编译# 或完整流程会自动验证你会看到[INFO] Verifying build artifacts... [INFO] ✓ out/busybox/busybox: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, no section header info [INFO] Size: 1045656 bytes [INFO] ✓ out/busybox/.config: present [INFO] ✓ rootfs/nfs/bin/busybox: installed [INFO] Symlinks in bin/: 315 [INFO] Build artifacts verified successfully手动验证你也可以手动验证# 检查文件类型$fileout/busybox/busybox out/busybox/busybox: ELF32-bit LSB executable, ARM, EABI5 version1(SYSV), statically linked, no section header info# 检查大小$ls-lhout/busybox/busybox -rwxr-xr-x1user user1.0M Mar1510:30 out/busybox/busybox# 检查架构$ readelf-hout/busybox/busybox|grepMachine Machine: ARM[!经验] 1MB 算大吗BusyBox 的典型大小在 1-2MB 之间静态链接。如果你启用更多功能可能达到 2-3MB。如果超过 5MB可能需要检查是否不小心启用了某些大型功能如 full vi。第五步安装到 Rootfs最后一步将 BusyBox 安装到 Rootfs 目录# 使用项目构建脚本./scripts/build_helper/build-busybox.sh --install-only或者手动执行make-Cthird_party/busybox\ARCHarm\CROSS_COMPILEarm-none-linux-gnueabihf-\O$(pwd)/out/busybox\installCONFIG_PREFIX$(pwd)/rootfs/nfsCONFIG_PREFIX参数指定安装目标目录。执行后[INFO] Installing BusyBox to /path/to/imx-forge/rootfs/nfs... [CMD] make -C third_party/busybox ARCHarm CROSS_COMPILEarm-none-linux-gnueabihf- Oout/busybox install CONFIG_PREFIX/path/to/imx-forge/rootfs/nfs ./_install/usr/bin/ - /path/to/imx-forge/rootfs/nfs/usr/bin/ ./_install/usr/sbin/ - /path/to/imx-forge/rootfs/nfs/usr/sbin/ ./_install/bin/ - /path/to/imx-forge/rootfs/nfs/bin/ ./_install/sbin/ - /path/to/imx-forge/rootfs/nfs/sbin/ ./_install/bin/busybox - /path/to/imx-forge/rootfs/nfs/bin/busybox ...安装完成后检查 Rootfs 目录$lsrootfs/nfs/bin/[[[acpid add-shell addgroup adduser... busybox# 主二进制文件cat# 符号链接 - busyboxchmod# 符号链接 - busybox...# 验证符号链接$ls-lrootfs/nfs/bin/ls lrwxrwxrwx1root root7Mar1510:30 rootfs/nfs/bin/ls -busybox $filerootfs/nfs/bin/busybox rootfs/nfs/bin/busybox: ELF32-bit LSB executable, ARM, EABI5 version1(SYSV), statically linked, no section header info使用 menuconfig 自定义配置当你需要添加或删除某些功能时menuconfig 是最有用的工具。# 启动 menuconfig./scripts/build_helper/build-busybox.sh menuconfig你会看到一个图形化的配置界面BusyBox Configuration ──────────────────────────────────────────────────────────────────────── Arrow keys navigate the menu. Enter selects submenus ---. Highlighted letters are hotkeys. EscEsc exits. * means built in. M means module. means excluded (not built). ──────────────────────────────────────────────────────────────────────── Busybox Settings --- Coreutils --- Console Utilities --- Debian Utilities --- Editors --- Finding Utilities --- Init Utilities --- Login/Password Management Utilities --- Linux Ext2 FS Progs --- Linux Module Utilities --- Linux System Utilities --- Miscellaneous Utilities --- Networking Utilities --- Print utilities --- Mail utilities --- ... ──────────────────────────────────────────────────────────────────────── Select Exit Help Save Load ────────────────────────────────────────────────────────────────────────常用配置项Settings → Build OptionsBuild BusyBox as a static binary静态链接推荐用于 RootfsCross compiler prefix设置交叉编译器前缀Init Utilitiesinit必须启用系统启动需要Support for running an init from within an shell调试时有用Shellsash推荐功能比 sh 强比 bash 小Feature: Editing mode命令行编辑功能Networking Utilitiesifconfig网络配置ping网络测试wget下载文件telnetd远程登录调试有用[!经验] 配置修改后记得重新编译menuconfig 退出后会自动保存 .config但你需要重新运行编译命令./scripts/build_helper/build-busybox.sh --build-only ./scripts/build_helper/build-busybox.sh --install-only常见编译问题排查问题 1工具链找不到error: arm-none-linux-gnueabihf-gcc: command not found解决检查工具链是否在 PATH 中或显式设置 PATHexportPATH/path/to/toolchain/bin:$PATH问题 2ncurses 头文件找不到scripts/kconfig/lxdialog/dialog.h:32:10: fatal error: ncurses.h: No such file or directory解决安装 libncurses-devsudoaptinstalllibncurses-dev问题 3undefined reference 错误undefined reference to sha1_begin_arch解决检查是否禁用了 x86 特定的 HWACCEL 选项见第二步。问题 4配置修改不生效原因旧的 .config 残留解决使用--clean选项清理后重新编译./scripts/build_helper/build-busybox.sh--clean构建脚本完整选项说明IMX-Forge 提供的build-busybox.sh脚本支持以下选项Usage: ./scripts/build_helper/build-busybox.sh[TARGET][OPTIONS]Targets(BusyBoxmaketargets): defconfig - Default configuration(default)menuconfig - Interactive curses-based configurator(exits after config, no build)config - Text-based configurator(exits after config, no build)allnoconfig - Disable all symbols(exits after config, no build)allyesconfig - Enable all symbols(exits after config, no build)Options:--clean- Clean build directory before building--static- Build static binary --build-only - Build only, using existing .config --install-only - Install only, using existing build Examples: ./scripts/build_helper/build-busybox.sh# Full flow: config build install./scripts/build_helper/build-busybox.sh menuconfig# Interactive configuration only./scripts/build_helper/build-busybox.sh --build-only# Build only using existing .config./scripts/build_helper/build-busybox.sh --install-only# Install only using existing build./scripts/build_helper/build-busybox.sh--clean# Clean and rebuild from scratch./scripts/build_helper/build-busybox.sh defconfig--clean--static# Clean build with static binary写在最后通过这一章你应该已经能够理解 BusyBox 的瑞士军刀设计配置和交叉编译 BusyBox处理 ARM 架构的兼容性问题验证和安装编译产物现在你的 Rootfs 目录中已经有了 BusyBox 及其数百个命令的符号链接。但系统还不能启动——我们还缺少关键的配置文件特别是 inittab。下一章我们将深入 Linux 系统的第一进程——init理解它是如何工作的以及如何配置 inittab 让系统顺利启动。下一章inittab 与 init 系统

相关新闻