首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wuhx
V2EX  ›  Android

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

  •  2
     
  •   wuhx · 2016-02-27 18:24:39 +08:00 · 25635 次点击
    这是一个创建于 1422 天前的主题,其中的信息可能已经有所发展或是发生改变。
    安卓模拟器 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 :

    V2 有人了解这块吗?求教
    17 回复  |  直到 2018-08-22 16:29:13 +08:00
    wbsdty331
        1
    wbsdty331   2016-02-27 18:41:58 +08:00
    我记得 intel x86 手机 好像都有个 arm 解释器
    spance
        2
    spance   2016-02-27 18:45:51 +08:00
    安卓手机那么便宜, raspberry pi 则更便宜,为什么要费这个劲?
    icedx
        3
    icedx   2016-02-27 18:51:31 +08:00 via Android
    包含安卓模拟器 2.0 的 AndroidStudio 已经出正式版了么
    wuhx
        4
    wuhx   2016-02-27 19:18:52 +08:00
    @wbsdty331 就是移植这个解释器

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

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

    @breeswish 主要是希望自己编译一切,强迫症。
    wuhx
        10
    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
        11
    woyaojizhu8   2017-02-10 22:23:28 +08:00
    请问楼主现在实现了在 x86 安卓模拟器上运行 ARM 原生 App 吗?
    woyaojizhu8
        12
    woyaojizhu8   2017-09-02 23:00:20 +08:00
    https://groups.google.com/forum/#!topic/android-emulator-dev/LCTh_oxhrCs
    这里的帖子也是楼主发的吧。这里已经解答了问题,贴链接过来,希望可以帮到他人
    wuhx
        13
    wuhx   2017-09-10 13:42:18 +08:00
    @woyaojizhu8 多谢,自己都快忘了,没想到 1 年后有人回复。
    woyaojizhu8
        14
    woyaojizhu8   2017-09-10 13:53:21 +08:00
    @wuhx #13 请问你现在在这个问题上有进展吗?有进展的时候请楼主分享下经验呗。
    我一直想在谷歌安卓模拟器上装 libhoudini , 折腾了很久都没成功。
    wuhx
        15
    wuhx   2017-09-10 16:12:55 +08:00
    @woyaojizhu8 后来换了个方案,没继续研究了,有空再看看
    essicaj
        16
    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
        17
    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 平台
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4419 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 53ms · UTC 02:59 · PVG 10:59 · LAX 18:59 · JFK 21:59
    ♥ Do have faith in what you're doing.