将 BusyBox 直接集成到 Android 系统镜像中,需通过修改系统源码构建脚本、配置编译规则实现,以下是基于 AOSP 源码的完整集成方案:
一、准备 BusyBox 源码 / 二进制文件
1. 下载 BusyBox 源码
从BusyBox 官网下载最新稳定版源码(如busybox-1.36.1.tar.bz2),解压到 Android 源码的external/busybox/目录(若目录不存在则创建):
bash
运行
cd android-src/external/
mkdir busybox && cd busybox
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar -xvf busybox-1.36.1.tar.bz2 --strip-components=1
2. 配置 BusyBox 编译选项
进入 BusyBox 目录,生成默认配置并修改:
bash
运行
make defconfig # 生成默认配置
make menuconfig # 图形化配置(可选,按需开启命令)
关键配置项:
Settings → Installation Options → BusyBox installation prefix:设置安装路径为/system/xbin(Android 系统可执行目录);Settings → Build Options:勾选Build static binary (no shared libs)(静态编译,避免依赖系统库);- 按需勾选需要的命令(如
ls、grep、ping等)。
二、添加 Android 编译规则(Android.mk)
在external/busybox/目录下创建Android.mk文件,写入以下内容(适配 Android 编译系统):
makefile
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# BusyBox编译配置
LOCAL_MODULE := busybox
LOCAL_SRC_FILES := busybox # 若用源码编译则指定源码目录,若用二进制则指定二进制文件路径
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_OUT)/xbin # 安装到/system/xbin
# 若用源码编译,需添加编译脚本(替代LOCAL_SRC_FILES)
ifneq ($(wildcard $(LOCAL_PATH)/Makefile),)
LOCAL_SRC_FILES := $(shell find $(LOCAL_PATH) -name "*.c")
LOCAL_CFLAGS += -Os -Wall -Wextra
LOCAL_LDFLAGS += -static -s # 静态编译+去除符号表
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(BUILD_EXECUTABLE)
endif
# 安装BusyBox链接(生成ls、cp等命令符号链接)
include $(CLEAR_VARS)
LOCAL_MODULE := busybox-links
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := FAKE
LOCAL_MODULE_SUFFIX := -timestamp
# 执行BusyBox --install生成链接
busybox_install := $(TARGET_OUT)/xbin/busybox --install -s $(TARGET_OUT)/xbin
LOCAL_POST_INSTALL_CMD := $(busybox_install)
include $(BUILD_PHONY_PACKAGE)
三、修改系统构建配置
1. 将 BusyBox 加入编译目标
编辑build/target/product/core.mk(或自定义产品配置文件,如device/[厂商]/[设备]/device.mk),添加:
makefile
PRODUCT_PACKAGES += busybox busybox-links
2. 配置系统分区权限(可选)
确保/system/xbin目录有执行权限,编辑system/core/rootdir/init.rc(或设备专属 init 文件):
plaintext
# 设置/system/xbin权限
chmod 0755 /system/xbin
chown root:shell /system/xbin
四、编译 BusyBox 并打包到镜像
1. 单独编译 BusyBox
bash
运行
cd android-src
source build/envsetup.sh
lunch # 选择目标设备(如aosp_arm64-eng)
make busybox busybox-links -j$(nproc)
2. 编译完整系统镜像
bash
运行
make -j$(nproc) # 编译整个Android系统,BusyBox会被打包到system.img中
五、验证集成结果
编译完成后,通过以下方式验证:
- 烧录
system.img到设备,启动后进入终端:bash
运行
busybox --version # 查看BusyBox版本 ls -l /system/xbin/ | grep busybox # 查看生成的命令链接 - 直接调用 BusyBox 命令:
bash
运行
busybox ls -al /system # 使用BusyBox的ls命令 ping -c 3 baidu.com # 直接使用BusyBox的ping命令(已生成链接)
六、优化与注意事项
1. 静态编译
务必开启静态编译(Build static binary),避免 BusyBox 依赖 Android 系统的动态库(如libc.so),否则可能因系统版本差异导致无法运行。
2. 命令冲突处理
Android 系统自带部分命令(如ls、cp),若需优先使用 BusyBox 版本,可修改/system/etc/profile或/system/bin/sh的PATH变量,将/system/xbin放在PATH最前面:
bash
运行
export PATH=/system/xbin:$PATH
3. 精简体积
若系统镜像空间有限,可在make menuconfig中取消不必要的命令(如telnet、ftp),减少 BusyBox 体积。
4. SELinux 权限
若设备 SELinux 为 Enforcing 模式,需添加 SELinux 规则(external/sepolicy),允许 BusyBox 执行:
bash
运行
# 在external/sepolicy/untrusted_app.te中添加
allow untrusted_app busybox_exec:file execute;
总结
通过将 BusyBox 集成到 Android 源码编译流程,可直接打包到system.img中,设备启动后无需额外安装即可在终端使用 BusyBox 命令。核心是配置Android.mk编译规则、指定安装路径,并将 BusyBox 加入系统编译目标,确保编译后自动生成命令链接。
有个疑问,# 在external/sepolicy/untrusted_app.te中添加 allow untrusted_app busybox_exec:file execute;这个selinux文件中,没有提及busybox啊,只有busybox_exec
你的观察很关键!SELinux 规则中 “busybox_exec” 是BusyBox 可执行文件的类型标签,而非文件名 ——SELinux 通过 “类型标签” 管控进程对文件的访问,不是直接用文件名匹配,这就是规则中不提 “busybox”(文件名)、只提 “busybox_exec”(类型)的核心原因。
一、核心逻辑:SELinux 的 “类型标签” 机制
- 文件需要先打标签:Android 编译时,会给
/system/xbin/busybox这个可执行文件,分配一个 SELinux 类型标签(这里我们定义为busybox_exec); - 规则管控 “主体 - 类型 - 动作”:
allow untrusted_app busybox_exec:file execute;的意思是:允许 “untrusted_app” 类型的进程(普通 APP 进程),对 “busybox_exec” 类型的文件,执行 “execute”(执行)操作; - 为什么不用文件名:SELinux 的访问控制基于 “类型” 而非 “文件名”,这样可以批量管控同类文件(比如所有系统工具都标为
system_file),也避免文件名变更导致规则失效。
二、关键补充:需要给 BusyBox 文件 “打标签”(否则规则无效)
你之前的疑问本质是 “规则里的busybox_exec从哪来”—— 这个类型不会自动生成,需要手动定义标签,否则 SELinux 会把 BusyBox 默认标为system_file,你的自定义规则就不起作用了。
步骤 1:定义busybox_exec类型(新增文件)
在 external/sepolicy/file_contexts 中添加一行(给 BusyBox 文件分配类型标签):
plaintext
# 格式:文件路径 类型标签
/system/xbin/busybox u:object_r:busybox_exec:s0
- 解释:
/system/xbin/busybox是你编译后 BusyBox 的安装路径;u:object_r:busybox_exec:s0是完整标签(object_r表示文件类型,busybox_exec是自定义类型名,s0是 MLS 级别)。
步骤 2:声明busybox_exec类型(避免编译报错)
在 external/sepolicy/device.te 中添加一行(告诉 SELinux 这个类型是合法的):
plaintext
# 声明busybox_exec是“文件类型”
type busybox_exec, file_type, exec_type, vendor_file_type;
- 解释:
file_type表示这是文件类型,exec_type表示这是可执行文件类型,确保 SELinux 识别它为可执行文件。
步骤 3:添加访问规则(你之前提到的那行)
在 external/sepolicy/untrusted_app.te 中添加执行权限:
plaintext
# 允许普通APP进程执行busybox_exec类型的文件
allow untrusted_app busybox_exec:file execute;
# 可选:如果需要APP能读取/执行BusyBox的链接(如ls、ping),再添加:
allow untrusted_app busybox_exec:lnk_file read;
三、完整流程梳理(让规则生效的关键)
- 编译 BusyBox 时,文件被安装到
/system/xbin/busybox; - 通过
file_contexts给这个文件打上busybox_exec标签; - 通过
device.te声明busybox_exec类型是合法的; - 通过
untrusted_app.te允许 APP 进程执行该类型文件; - 最终 APP 在终端调用
busybox时,SELinux 会检查:APP 进程(untrusted_app)→ 访问文件(类型busybox_exec)→ 动作(execute),规则允许则放行。
四、常见误区提醒
- 若不定义
busybox_exec类型,BusyBox 会继承/system/xbin目录的默认标签(如system_file),此时需把规则改成allow untrusted_app system_file:file execute;,但不建议(会开放所有system_file类型文件的执行权限,有安全风险); - 自定义类型名(
busybox_exec)可任意改(如my_busybox),但要保证file_contexts、device.te、untrusted_app.te中一致; - 若设备是 userdebug/eng 版本,可先执行
setenforce 0(临时关闭 SELinux)验证 BusyBox 是否能正常运行,排除编译问题后再配置 SELinux 规则。
简单说:busybox_exec是你给 BusyBox 文件贴的 “SELinux 标签”,规则通过标签管控访问,所以不需要提文件名,只要标签对应上就能生效。
9772

被折叠的 条评论
为什么被折叠?



