在 x86 安卓模拟器上运行 ARM 原生 App

2016-02-27 18:24:39 +08:00
 wuhx
安卓模拟器 2.0 以后完全到达可用级别了,各种操作非常流畅。所以想用来做一个虚拟环境跑 App ,但是很多 App (比如微信支付宝等)依赖 ARM 原生代码 library ,不能直接在 x86 的模拟器上跑。

搜了一下,英特尔的方案是:
1. 使用 X86 的 NDK 重新重新打包应用。
2. 在 X86 的安卓系统中装 ARM Binary Translation ,通过 Hook JNI 调用把 ARM 指令转成 X86 指令。

1 没指望,就从 2 入手:
1 )创建一个 AVD : Intel atom x86 image, google api level 23
2 )从 google 发布的 Nexus player (用了 atom cpu )二进制文件中,拷贝安卓 6.0 的 native bridge 驱动。 https://developers.google.com/android/nexus/drivers#fugu
3 )修改 AVD 的 system.img 和 ramdisk.img 使能 Native Bridge 。 参考 Nexus player 的配置,
ro.dalvik.vm.native.bridge=libhoudini.so
ro.dalvik.vm.isa.arm=x86
ro.enable.native.bridge.exec=1 等

启动后,运行 App 。
Native Bridge 成功加载了,但 App 运行还是失败。
02-25 15:04:11.990 1512 1620 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.tencent.mm/.ui.LauncherUI (has extras)} from uid 10007 on display 0
02-25 15:04:12.046 2586 2586 D houdini : [2586] Initialize library(version: 6.0.0_y.48180 RELEASE)... successfully.
02-25 15:04:12.048 1512 1524 I ActivityManager: Start proc 2586:com.tencent.mm/u0a55 for activity com.tencent.mm/.ui.LauncherUI
02-25 15:04:13.700 2586 2586 D houdini : [2586] Added shared library /data/app/com.tencent.mm-1/lib/arm/libstlport_shared.so for ClassLoader by Native Bridge.
02-25 15:04:13.703 2586 2586 E ActivityThread: Failed to find provider info for com.tencent.mm.coolassist.debugprovider
02-25 15:04:13.784 2586 2586 F libc : Fatal signal 11 (SIGSEGV), code 128, fault addr 0x0 in tid 2586 (com.tencent.mm)

dmsg
[ 366.571014] traps: com.tencent.mm[2586] general protection ip:b0f13dd1 sp:10011f20 error:30 in libhoudini.so[b0cfa000+3b4000]

另外,也尝试了 android-x86 和 remix os 提供的 libhoudini ,他们的 houdini 版本更旧, 5.多的。也是失败,最成功的一次看到了微信启动画面的地球小人。

使能 Native bridge 后 ARM 版本的 busy box 可以跑,确认基本功能正常。

更多 log : https://gist.github.com/wuhx/bfd814bba5f2523449f1

V2 有人了解这块吗?求教
39255 次点击
所在节点    Android
17 条回复
wbsdty331
2016-02-27 18:41:58 +08:00
我记得 intel x86 手机 好像都有个 arm 解释器
spance
2016-02-27 18:45:51 +08:00
安卓手机那么便宜, raspberry pi 则更便宜,为什么要费这个劲?
icedx
2016-02-27 18:51:31 +08:00
包含安卓模拟器 2.0 的 AndroidStudio 已经出正式版了么
wuhx
2016-02-27 19:18:52 +08:00
@wbsdty331 就是移植这个解释器

@spance 模拟器的环境更可控,并且有最新的安卓系统。

@icedx 还在 preview
crystom
2016-02-27 19:45:14 +08:00
我用 arc welder 运行微信, intel 的 chromebook ,能跑微信 5.4 版本,之后的不行
wuhx
2016-02-27 22:09:43 +08:00
@crystom 感谢提示,估计后面的版本增强了模拟器环境检测,但我测试了一下 x86 版本的 Xposed 可以正常安装在模拟器上,所以隐藏系统特征比较容易。 何况还有模拟器和整个安卓系统的源码。
wohenyingyu01
2016-02-27 22:41:45 +08:00
没怎么看懂,不过就我的理解需要用 x86 的 ndk 重新编译一下原生的库即可。具体可以参考 android ndk 文档
breeswish
2016-02-27 23:09:32 +08:00
Genymotion 直接把 ARM translation 拖进去就可以开始用了..
不过现在瞄了一眼 GM 好像没免费版了,但仍然有其他一大批类似产品
wuhx
2016-02-27 23:44:44 +08:00
@wohenyingyu01 不是编译一个用 x86 NDK 的 App ,针对没有代码的第三方 App

@breeswish 主要是希望自己编译一切,强迫症。
wuhx
2016-02-28 00:05:23 +08:00
总结一下:
1. ARM 版的 busybox 能用, App 运行失败,必然是安卓相关的一些调用引发的故障。
2. 和 Nexus player 对比差异:
Nexus palyer 的内核是 64 位的,但用户态系统是 32 位的
x86 的 AVD 内核用户态都是 32 位,
x86_64 的 AVD 内核用户态都是 64 位,
所以很可能是用户态和内核通信时数据结构异常。

所以怀疑问题是安卓的 Binder IPC 通信引起的。

搜集了一些相关资料
Android Binder IPC Fixes
https://lwn.net/Articles/555871/

Android: Add support for a 32bit Android file system in a 64bit kernel
https://lwn.net/Articles/527989/

[PATCH 2/3] staging: binder: Support concurrent 32 bit and 64 bit processes.
http://www.serverphorums.com/read.php?12,881092

走读代码, Binder 如何区分 32 位指针和 64 位指针
http://androidxref.com/kernel_3.10/xref/include/uapi/linux/android/binder.h#42

根据上面的信息 checkout 了模拟器内核代码( goldfish ),并配置内核参数 CONFIG_ANDROID_BINDER_IPC_32BIT=y ,编译了一个内核,然而这个内核并不能起来。

看来是个大坑,没有之前想的那么简单,先记录下来,睡觉~
woyaojizhu8
2017-02-10 22:23:28 +08:00
请问楼主现在实现了在 x86 安卓模拟器上运行 ARM 原生 App 吗?
woyaojizhu8
2017-09-02 23:00:20 +08:00
https://groups.google.com/forum/#!topic/android-emulator-dev/LCTh_oxhrCs
这里的帖子也是楼主发的吧。这里已经解答了问题,贴链接过来,希望可以帮到他人
wuhx
2017-09-10 13:42:18 +08:00
@woyaojizhu8 多谢,自己都快忘了,没想到 1 年后有人回复。
woyaojizhu8
2017-09-10 13:53:21 +08:00
@wuhx #13 请问你现在在这个问题上有进展吗?有进展的时候请楼主分享下经验呗。
我一直想在谷歌安卓模拟器上装 libhoudini , 折腾了很久都没成功。
wuhx
2017-09-10 16:12:55 +08:00
@woyaojizhu8 后来换了个方案,没继续研究了,有空再看看
essicaj
2018-01-19 17:21:24 +08:00
分享一下,Android 5.1 x86 虚拟机跑 arm 的方案。(下面的属性是从 genymotion 的 build.prop 提取出来的)
# Allow installation of ARM apps
ro.product.cpu.abi2=armeabi-v7a
ro.product.cpu.abilist=x86,armeabi-v7a,armeabi
ro.product.cpu.abilist32=x86,armeabi-v7a,armeabi
# Enable native bridge for ARM apps
ro.dalvik.vm.isa.arm=x86
ro.dalvik.vm.native.bridge=libhoudini.so

# Enable execution of ARM executables
ro.enable.native.bridge.exec=1

添加进虚拟机的文件是来自于
Genymotion_ARM_Translation_5.1_Lollipop.zip

我是直接编译源码的,拷贝文件可以用 PRODUCT_COPY_FILES、属性可以用 PRODUCT_PROPERTY_OVERRIDES
yaorc
2018-08-22 16:29:13 +08:00
@essicaj 请问两个问题:
1.ARM_Translation.zip 怎么添加到 AVD 里面呢?是 pull 到 sd 卡再用 flash-archive.sh 安装吗?
2.AVD 的 system.img 文件怎么修改呢?我是 Window 10 平台

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/259515

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX