当前位置: 首页 > news >正文

在 Android ARM64 上运行 x86_64 程序

在 Android ARM64 上运行 x86_64 程序

概述

本文档介绍如何在 Android ARM64 系统上通过 QEMU 用户模式模拟和 binfmt_misc 机制,实现"无感"运行 x86_64 二进制程序。配置完成后,可以直接执行 x86_64 程序,系统会自动调用 QEMU 进行模拟执行。

需要的组件

1. QEMU 二进制文件

需要 qemu-x86_64-static 的 ARM64 版本,用于在 ARM64 架构上模拟执行 x86_64 指令。

获取方式:

  • 从 Debian/Ubuntu 的 qemu-user-static 包中提取
  • 路径:/usr/bin/qemu-x86_64-static
  • 确保是静态链接版本(-static),更适合嵌入式环境

2. binfmt_misc 配置

需要在内核中注册 x86_64 二进制格式,让系统自动识别并调用 QEMU。

系统要求:

  • 内核支持 CONFIG_BINFMT_MISC
  • 已挂载 binfmt_misc 文件系统
  • Root 权限(配置 binfmt_misc 需要 root)

配置步骤

步骤 1:挂载 binfmt_misc(如果未挂载)

# 检查是否已挂载
ls /proc/sys/fs/binfmt_misc/# 如果不存在 register 和 status 文件,需要挂载
mount -t binfmt_misc none /proc/sys/fs/binfmt_misc

步骤 2:安装 QEMU 二进制文件

qemu-x86_64-static 复制到 Android 系统的合适位置,例如:

# 复制到系统目录(需要 root)
cp qemu-x86_64-static /system/bin/qemu-x86_64-static
chmod 755 /system/bin/qemu-x86_64-static# 或者复制到数据目录
cp qemu-x86_64-static /data/local/tmp/qemu-x86_64-static
chmod 755 /data/local/tmp/qemu-x86_64-static

步骤 3:注册 binfmt_misc 配置

使用以下命令注册 x86_64 二进制格式:

# 方式 1:直接使用 qemu-x86_64-static 作为解释器
echo ':qemu-x86_64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/system/bin/qemu-x86_64-static:OPF' > /proc/sys/fs/binfmt_misc/register# 方式 2:如果使用 /data/local/tmp 路径
echo ':qemu-x86_64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/data/local/tmp/qemu-x86_64-static:OPF' > /proc/sys/fs/binfmt_misc/register

配置参数说明:

  • name: qemu-x86_64 - 标识符名称
  • type: M - 使用魔数(magic)匹配
  • magic: \x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00
    • \x7f\x45\x4c\x46 = ELF 文件头(\x7fELF
    • \x02 = 64位 ELF
    • \x01 = 小端序
    • \x3e = EM_X86_64(x86_64 架构代码,十进制 62)
    • \x02 = 可执行文件类型(ET_EXEC)
  • mask: \xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff - 掩码,用于匹配时忽略某些位
  • interpreter: /system/bin/qemu-x86_64-static - QEMU 解释器路径
  • flags: OPF
    • O = 打开二进制文件
    • P = 保留(preserve)
    • F = 修复二进制文件(fix binary)

步骤 4:验证配置

# 查看注册的格式
ls /proc/sys/fs/binfmt_misc/# 查看 x86_64 配置详情
cat /proc/sys/fs/binfmt_misc/qemu-x86_64

预期输出:

enabled
interpreter /system/bin/qemu-x86_64-static
flags: OPF
offset 0
magic 7f454c4602010100000000000000000002003e00
mask fffffffffffffefe00fefffffffffffffeffffff

步骤 5:测试运行

# 测试运行 x86_64 程序
./your_x86_64_program

静态链接 vs 动态链接

静态链接程序

可以直接运行! 配置完成后,静态链接的 x86_64 程序可以直接执行:

# 编译静态链接程序(在 x86_64 系统上)
gcc -static -o program program.c# 在 Android ARM64 上直接运行
./program

动态链接程序

动态链接的程序需要额外的 x86_64 动态库支持。有两种解决方案:

方案 A:使用包装脚本

创建一个包装脚本,自动添加 -L 参数指定库路径:

#!/system/bin/sh
# wrapper script: /system/bin/qemu-x86_64-wrapper
exec /system/bin/qemu-x86_64-static -L /path/to/x86_64-libs "$@"

然后在 binfmt_misc 中注册包装脚本:

echo ':qemu-x86_64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/system/bin/qemu-x86_64-wrapper:OPF' > /proc/sys/fs/binfmt_misc/register
方案 B:手动指定库路径

如果不想使用包装脚本,可以手动运行:

qemu-x86_64-static -L /path/to/x86_64-libs ./dynamic_program

注意: 需要准备完整的 x86_64 动态库环境(libc.so、ld-linux-x86-64.so.2 等)。

持久化配置

如果需要在系统启动时自动配置,可以创建一个 init 脚本。参考 android_binfmt_misc.md 中的方法,在系统启动脚本中添加配置命令。

示例(添加到 init.rc 或类似的启动脚本):

# 在系统启动时挂载 binfmt_misc
mount binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc# 注册 x86_64 格式
write /proc/sys/fs/binfmt_misc/register ":qemu-x86_64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/system/bin/qemu-x86_64-static:OPF"

参考配置

qemu-user-static deb 包中提取的标准配置:

Systemd 风格配置 (/usr/lib/binfmt.d/qemu-x86_64.conf):

:qemu-x86_64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/libexec/qemu-binfmt/x86_64-binfmt-P:OPF

传统风格配置 (/usr/share/binfmts/qemu-x86_64):

package qemu-user-static
interpreter /usr/libexec/qemu-binfmt/x86_64-binfmt-P
magic \x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00
offset 0
mask \xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff
credentials no
fix_binary yes
preserve yes

注意事项

  1. 性能影响:QEMU 用户模式模拟会有性能损失,不适合 CPU 密集型任务
  2. Root 权限:配置 binfmt_misc 需要 root 权限
  3. 动态库依赖:动态链接程序需要完整的 x86_64 库环境
  4. 系统调用兼容性:某些系统调用可能无法完全模拟,特别是 Android 特有的系统调用
  5. 文件路径:确保 QEMU 二进制文件的路径正确,且具有执行权限

故障排查

问题 1:无法识别 x86_64 程序

# 检查 binfmt_misc 是否已挂载
ls /proc/sys/fs/binfmt_misc/# 检查配置是否存在
cat /proc/sys/fs/binfmt_misc/qemu-x86_64# 检查配置是否启用
echo 1 > /proc/sys/fs/binfmt_misc/qemu-x86_64  # 启用

问题 2:QEMU 无法找到

# 检查 QEMU 文件是否存在
ls -l /system/bin/qemu-x86_64-static# 检查执行权限
chmod 755 /system/bin/qemu-x86_64-static# 手动测试 QEMU
/system/bin/qemu-x86_64-static --version

问题 3:动态链接程序无法运行

# 检查程序依赖
file your_program
readelf -d your_program | grep NEEDED# 手动指定库路径运行
qemu-x86_64-static -L /path/to/x86_64-libs ./your_program

问题 4:Root 用户无法写入 register 文件

即使有 root 权限,也可能无法写入 /proc/sys/fs/binfmt_misc/register。可能的原因和解决方案:

检查 1:确认 binfmt_misc 已挂载
# 检查是否已挂载
ls /proc/sys/fs/binfmt_misc/# 如果 register 文件不存在,需要先挂载
mount -t binfmt_misc none /proc/sys/fs/binfmt_misc# 验证挂载
mount | grep binfmt_misc
检查 2:确认内核支持 binfmt_misc
# 检查内核配置(如果可访问)
grep CONFIG_BINFMT_MISC /proc/config.gz
# 或者
zcat /proc/config.gz | grep CONFIG_BINFMT_MISC# 应该显示:CONFIG_BINFMT_MISC=y 或 CONFIG_BINFMT_MISC=m
检查 3:SELinux 限制(Android 常见问题)
# 检查 SELinux 状态
getenforce# 如果是 Enforcing,可能需要临时关闭或设置 SELinux 策略
setenforce 0  # 临时关闭(仅用于测试)# 或者设置 SELinux 上下文
chcon u:object_r:binfmt_misc_exec:s0 /proc/sys/fs/binfmt_misc/register
检查 4:使用不同的写入方法
# 方法 1:使用 echo(标准方法)
echo ':qemu-x86_64:...' > /proc/sys/fs/binfmt_misc/register# 方法 2:使用 printf(避免 shell 转义问题)
printf ':qemu-x86_64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/system/bin/qemu-x86_64-static:OPF' > /proc/sys/fs/binfmt_misc/register# 方法 3:使用 sh -c(绕过某些限制)
sh -c 'echo ":qemu-x86_64:..." > /proc/sys/fs/binfmt_misc/register'
检查 5:文件系统只读问题
# 检查 /proc 文件系统是否只读
mount | grep proc# 如果只读,可能需要重新挂载为可写(通常不需要,/proc 默认是可写的)

问题 5:是否需要写入固件?

答案:取决于你的使用场景

场景 A:临时测试(不需要写入固件)

如果只是临时测试,可以:

  1. 每次系统启动后手动配置
  2. 或者通过脚本在应用启动时配置(如果应用有 root 权限)
场景 B:生产环境(需要写入固件)

如果需要系统级支持,让所有用户都能使用,必须写入固件

方法 1:修改 init.rc(推荐)

在系统镜像的 init.rcinit.${ro.hardware}.rc 中添加:

# 在 on early-init 或 on init 阶段添加
on early-init# 挂载 binfmt_miscmount binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc# 注册 x86_64 格式write /proc/sys/fs/binfmt_misc/register ":qemu-x86_64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/system/bin/qemu-x86_64-static:OPF"

方法 2:创建 init 脚本

创建 /system/etc/init/qemu-binfmt.rc

on early-initmount binfmt_misc binfmt_misc /proc/sys/fs/binfmt_miscwrite /proc/sys/fs/binfmt_misc/register ":qemu-x86_64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/system/bin/qemu-x86_64-static:OPF"

方法 3:使用 shell 脚本(类似 Houdini)

创建 /system/bin/init.qemu-binfmt.sh,在系统启动脚本中调用:

#!/system/bin/sh
# 在 init.rc 中调用:exec /system/bin/init.qemu-binfmt.shbinfmt_misc_dir=/proc/sys/fs/binfmt_misc# 挂载 binfmt_misc
if [ ! -e $binfmt_misc_dir/register ]; thenmount -t binfmt_misc none $binfmt_misc_dir
fi# 注册 x86_64 格式
if [ -e $binfmt_misc_dir/register ]; thenecho ':qemu-x86_64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/system/bin/qemu-x86_64-static:OPF' > $binfmt_misc_dir/register
fi

固件修改步骤:

  1. 解包系统镜像(system.img)
  2. 添加 QEMU 二进制文件到 /system/bin/
  3. 修改 init.rc 或创建 init 脚本
  4. 重新打包系统镜像
  5. 刷入设备

注意: 修改固件需要:

  • 系统镜像的源代码或解包工具
  • 重新签名(如果系统有验证)
  • 可能需要解锁 bootloader
http://www.dtcms.com/a/604845.html

相关文章:

  • 幽冥大陆(二十)屏幕录像特效增加节目效果——东方仙盟炼气期
  • 类加载机制、生命周期、类加载器层次、JVM的类加载方式
  • 数据智能开发五 技术架构
  • 免费的app软件下载网站个人网站备案 法律说明
  • MFC Check Box控件完全指南:属性设置、样式定制与高级应用
  • 广州 网站 建设支付网站建设费入什么科目
  • 西宁做网站需要多少钱wordpress怎么安装模板
  • 网站标题优化工具外贸公司电话
  • 北京北排建设公司招标网站wordpress登陆过程
  • 怎么免费做个人网站建设银行网站怎么打印明细
  • 在线设计图片网站总结郑州app拉新项目
  • 网站建设春节放假番禺免费核酸检测
  • preec网站电子商务seo实训总结
  • 优化网站浏览量怎么看网站建设方案评标原则
  • 网站设计职业工作室打开网站搜索
  • 网站建设方案书 doc织梦修改网站背景颜色
  • 网上商城建站服务商wordpress 抄袭查询
  • 网站建设设计猫和老鼠wordpress加备案号
  • 做电影网站 需要进那些群wordpress头像不同步
  • flash网站制作教程网站开发和网站运营的区别
  • 什么做直播网站sqlite开发网站
  • 沧州兼职网站建设集美区建设局网站
  • 如何把自己做的网站挂网上取公司名称大全简单大气
  • 大理市城乡建设局网站网站设计排行榜前十
  • 泉州网站建设公司首选公司哪家好东营免费网站制作
  • 制作简历哪个网站好电子书网站用dz还是wordpress
  • 毕业设计网站开发选题依据推荐几个用vue做的网站
  • 沧州网站设计公司价格logo设计报价明细表
  • 网赌网站怎么建设免费html5播放器
  • 宜昌做网站哪家最便宜南京玄武区建设局网站