BusyBox 中文文档 下载 App

BusyBox 二进制兼容性 glibc musl 架构匹配

三种常见报错

把 BusyBox 二进制拷到目标设备上,直接跑时报这三种错之一:

$ ./busybox
-bash: ./busybox: Permission denied

$ ./busybox
bash: ./busybox: cannot execute binary file: Exec format error

$ ./busybox
./busybox: /lib64/libc.so.6: version `GLIBC_2.28' not found

情况一:Permission denied

最简单的问题——文件没有可执行权限:

# 修复
chmod +x busybox

# 确认权限
ls -la busybox
# 应该看到:-rwxr-xr-x ... busybox

如果 chmod 后还是 Permission denied,可能是挂载选项问题:

# 检查挂载点
mount | grep "你的 busybox 所在分区"
# 如果有 noexec 选项,文件无法执行

# 修复(临时)
mount -o remount,exec /path/to/mountpoint
# 如果是 /tmp,它默认可能是 noexec:
mount -o remount,exec /tmp

情况二:Exec format error(架构不匹配)

BusyBox 是 ELF 格式二进制,CPU 架构必须匹配目标设备:

# 主机上查看 BusyBox 架构
file busybox
# busybox: ELF 64-bit LSB executable, x86-64, ...

# 目标设备查看支持的架构
uname -m
# x86_64(64 位桌面)
# armv7l(ARMv7 32 位,路由器常见)
# aarch64(ARM 64 位)
# mips(MIPS 架构,部分路由器)
# ppc(PowerPC,工业控制)

架构不匹配时的典型组合:

主机编译目标设备结果
x86_64armv7lExec format error
armv7laarch64Exec format error(32 位和 64 位不互通)
x86_64x86可以(64 位系统向下兼容 32 位)

解决方案:交叉编译目标架构的 BusyBox,或者下载官方预编译版本。

# 为 ARMv7 交叉编译
make CROSS_COMPILE=arm-linux-gnueabihf- defconfig
make CROSS_COMPILE=arm-linux-gnueabihf- -j$(nproc)

# 或者下载官方预编译二进制
# https://busybox.net/downloads/binaries/
# busybox-armv4tl(最通用 ARM)
# busybox-armv7l
# busybox-aarch64
# busybox-x86_64

情况三:GLIBC 版本不匹配

动态编译的 BusyBox 依赖目标设备上的 libc.so 版本。BusyBox 编译时使用的 glibc 版本太新,目标设备的太旧:

# 主机编译(用 glibc 2.34)
# BusyBox 依赖 GLIBC_2.28
# 目标设备只有 glibc 2.23
# → 报错 GLIC_2.28 not found

解决方案:静态编译

# BusyBox menuconfig 里开启:
# Build Options -> Build BusyBox as a static binary = Y

# 或者 musl libc 交叉编译(最干净的方案)
make defconfig
make CONFIG_STATIC=y -j$(nproc)
# 产物完全不依赖外部 libc
file busybox
# busybox: ELF ... statically linked, ...

静态编译的 BusyBox 单文件就能运行,不管目标设备的 glibc 版本是什么——这也是嵌入式开发的标准做法。

Android 上的 libc 差异

Android 用的是 Bionic libc,不是 glibc 也不是 musl。在 Android 上装 BusyBox 有三种方案:

方案说明
BusyBox Pro 等应用应用内置了用 Bionic 编译好的 BusyBox,直接可用
自己用 Android NDK 交叉编译用 NDK 自带的 toolchain 编译出 Bionic 版 BusyBox
musl 静态编译完全不依赖目标设备的 libc,通用但体积稍大

不要把用 glibc 编译的 BusyBox 拷到 Android 上跑——它会找 /lib64/libc.so.6,而 Android 的 libc 在 /system/lib64/libc.so(路径和文件名都不同)。

快速兼容性检查脚本

#!/bin/sh
# 检查 BusyBox 二进制是否能在目标设备上运行

BB="./busybox"

echo "=== 检查文件类型 ==="
file "$BB" 2>/dev/null || echo "file 命令不可用,跳过"

echo ""
echo "=== 检查可执行权限 ==="
[ -x "$BB" ] && echo "✓ 有可执行权限" || echo "✗ 没有可执行权限(chmod +x)"

echo ""
echo "=== 检查架构匹配 ==="
TARGET_ARCH=$(uname -m)
BB_ARCH=$(file "$BB" 2>/dev/null | grep -o "x86-64\|i386\|ARM\|aarch64\|MIPS\|PowerPC" | head -1)
echo "目标架构: $TARGET_ARCH"
echo "BusyBox 架构: $BB_ARCH"

echo ""
echo "=== 检查静态/动态链接 ==="
if file "$BB" 2>/dev/null | grep -q "statically linked"; then
  echo "✓ 静态链接(无 libc 依赖)"
else
  echo "⚠ 动态链接,检查 libc 兼容性"
  ldd "$BB" 2>/dev/null || echo "ldd 不可用"
fi

echo ""
echo "=== 实际运行测试 ==="
"$BB" --list > /dev/null 2>&1 && echo "✓ BusyBox 可以正常执行" || echo "✗ BusyBox 执行失败"