V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
wuhx
V2EX  ›  Android

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

  •  2
     
  •   wuhx · Feb 27, 2016 · 43606 views
    This topic created in 3714 days ago, the information mentioned may be changed or developed.
    安卓模拟器 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 replies    2018-08-22 16:29:13 +08:00
    wbsdty331
        1
    wbsdty331  
       Feb 27, 2016
    我记得 intel x86 手机 好像都有个 arm 解释器
    spance
        2
    spance  
       Feb 27, 2016
    安卓手机那么便宜, raspberry pi 则更便宜,为什么要费这个劲?
    icedx
        3
    icedx  
       Feb 27, 2016 via Android
    包含安卓模拟器 2.0 的 AndroidStudio 已经出正式版了么
    wuhx
        4
    wuhx  
    OP
       Feb 27, 2016
    @wbsdty331 就是移植这个解释器

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

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

    @breeswish 主要是希望自己编译一切,强迫症。
    wuhx
        10
    wuhx  
    OP
       Feb 28, 2016
    总结一下:
    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  
       Feb 10, 2017
    请问楼主现在实现了在 x86 安卓模拟器上运行 ARM 原生 App 吗?
    woyaojizhu8
        12
    woyaojizhu8  
       Sep 2, 2017
    https://groups.google.com/forum/#!topic/android-emulator-dev/LCTh_oxhrCs
    这里的帖子也是楼主发的吧。这里已经解答了问题,贴链接过来,希望可以帮到他人
    wuhx
        13
    wuhx  
    OP
       Sep 10, 2017
    @woyaojizhu8 多谢,自己都快忘了,没想到 1 年后有人回复。
    woyaojizhu8
        14
    woyaojizhu8  
       Sep 10, 2017
    @wuhx #13 请问你现在在这个问题上有进展吗?有进展的时候请楼主分享下经验呗。
    我一直想在谷歌安卓模拟器上装 libhoudini , 折腾了很久都没成功。
    wuhx
        15
    wuhx  
    OP
       Sep 10, 2017
    @woyaojizhu8 后来换了个方案,没继续研究了,有空再看看
    essicaj
        16
    essicaj  
    PRO
       Jan 19, 2018   ❤️ 1
    分享一下,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  
       Aug 22, 2018   ❤️ 1
    @essicaj 请问两个问题:
    1.ARM_Translation.zip 怎么添加到 AVD 里面呢?是 pull 到 sd 卡再用 flash-archive.sh 安装吗?
    2.AVD 的 system.img 文件怎么修改呢?我是 Window 10 平台
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   907 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 50ms · UTC 21:04 · PVG 05:04 · LAX 14:04 · JFK 17:04
    ♥ Do have faith in what you're doing.