Ayu*_*ush 30 android arm native android-ndk android-x86
摩托罗拉刚刚发布了基于x86的Android手机.关于为ARM编写的本机应用程序/库(例如netflix)如何在这款手机上运行,我有点困惑.
如果有人能解释,我将不胜感激.
Roy*_*nto 53
是的,ARM本机代码使用名为Houdini的仿真功能在Intel x86上运行
这个库的作用是动态读取ARM指令并将它们转换为等效的x86指令.这就是为什么许多应用程序可以在x86上运行而不必实际构建等效库的原因.

实际上你可以为不同的架构包含不同的本机代码,不确定Netflix是如何运行的,但是如果你打开apk就可以看到/lib/armeabi-v7a/,所以我假设可以有类似的文件夹/lib/x86/
编辑:我刚检查了亚马逊购物应用程序,它有arm和x86的本机代码.所以也许这就是netflix如何做到的.
Android Studio 3模拟器使用QEMU作为后端
https://zh.wikipedia.org/wiki/QEMU
QEMU可以说是领先的开源交叉拱形模拟器。它是GPL软件,除了x86和ARM外,还支持许多其他的arch。
然后,Android只会在QEMU之上添加一些UI魔术,并可能添加一些补丁,但是核心肯定在QEMU上游。
QEMU使用一种称为二进制翻译的技术来实现合理的快速仿真:https : //en.wikipedia.org/wiki/Binary_translation
二进制转换基本上将ARM指令转换为等效的x86指令。
因此,要了解详细信息,最好的方法是:
理论
因此,很明显,只要有足够的内存,任何CPU都可以模拟任何CPU。
困难的问题是如何快速地做到这一点。
练习:QEMU用户模式模拟
QEMU具有用户态模式,只要您的客户机和主机是同一操作系统,就可以非常轻松地在x86机器上使用用户态ARM代码来查看正在发生的情况。
在这种模式下,发生的事情是二进制翻译会处理基本指令,而系统调用只会转发到主机系统调用。
例如,对于具有Linux独立式(无glibc)的Linux上的Linux的问候世界:
电源
.text
.global _start
_start:
asm_main_after_prologue:
/* write */
mov x0, 1
adr x1, msg
ldr x2, =len
mov x8, 64
svc 0
/* exit */
mov x0, 0
mov x8, 93
svc 0
msg:
.ascii "hello syscall v8\n"
len = . - msg
Run Code Online (Sandbox Code Playgroud)
然后组装并运行为:
sudo apt-get install qemu-user gcc-aarch64-linux-gnu
aarch64-linux-gnu-as -o main.o main.S
aarch64-linux-gnu-ld -o main.out main.o
qemu-aarch64 main.out
Run Code Online (Sandbox Code Playgroud)
并输出预期结果:
hello syscall v8
Run Code Online (Sandbox Code Playgroud)
您甚至可以运行针对C标准库编译的ARM程序,然后GDB逐步调试该程序!请参见以下具体示例:如何在QEMU的GDB中单步执行ARM组装?
由于我们正在谈论二进制转换,因此我们还可以启用一些日志记录以查看QEMU正在执行的确切转换:
qemu-aarch64 -d in_asm,out_asm main.out
Run Code Online (Sandbox Code Playgroud)
这里:
in_asm 指ARM来宾输入程序集out_asm 指的是X86主机生成的可运行的程序集输出包含:
----------------
IN:
0x0000000000400078: d2800020 mov x0, #0x1
0x000000000040007c: 100000e1 adr x1, #+0x1c (addr 0x400098)
0x0000000000400080: 58000182 ldr x2, pc+48 (addr 0x4000b0)
0x0000000000400084: d2800808 mov x8, #0x40
0x0000000000400088: d4000001 svc #0x0
OUT: [size=105]
0x5578d016b428: mov -0x8(%r14),%ebp
0x5578d016b42c: test %ebp,%ebp
0x5578d016b42e: jne 0x5578d016b482
0x5578d016b434: mov $0x1,%ebp
0x5578d016b439: mov %rbp,0x40(%r14)
0x5578d016b43d: mov $0x400098,%ebp
0x5578d016b442: mov %rbp,0x48(%r14)
0x5578d016b446: mov $0x4000b0,%ebp
0x5578d016b44b: mov 0x0(%rbp),%rbp
0x5578d016b44f: mov %rbp,0x50(%r14)
0x5578d016b453: mov $0x40,%ebp
0x5578d016b458: mov %rbp,0x80(%r14)
0x5578d016b45f: mov $0x40008c,%ebp
0x5578d016b464: mov %rbp,0x140(%r14)
0x5578d016b46b: mov %r14,%rdi
0x5578d016b46e: mov $0x2,%esi
0x5578d016b473: mov $0x56000000,%edx
0x5578d016b478: mov $0x1,%ecx
0x5578d016b47d: callq 0x5578cfdfe130
0x5578d016b482: mov $0x7f8af0565013,%rax
0x5578d016b48c: jmpq 0x5578d016b416
Run Code Online (Sandbox Code Playgroud)
因此,在本IN节中,我们看到了手写的ARM汇编代码,在本OUT节中,我们看到了生成的x86汇编。
在Ubuntu 16.04 amd64,QEMU 2.5.0,binutils 2.26.1中进行了测试。
QEMU完整系统仿真
但是,当您在QEMU中启动Android时,它当然不是在运行用户级二进制文件,而是在进行完整的系统仿真,在其中运行实际的Linux内核和仿真中的所有设备。
完整的系统仿真更准确,但速度稍慢,您需要为QEMU提供内核和磁盘映像。
要尝试该方法,请查看以下设置:
虚拟机
如果您在QEMU上运行Android X86,您会注意到它的速度要快得多。
原因是QEMU使用KVM,这是一种Linux内核功能,可以直接在主机上运行来宾指令!
如果您碰巧拥有一台功能强大的ARM机器(截至2019年很少见),则还可以更快地在具有KVM的ARM上运行ARM。
因此,如果您位于X86主机上,我建议您坚持使用AOSP的X86模拟,如以下所述:如何编译Android AOSP内核并使用Android Emulator对其进行测试?,除非您确实需要低水平接触。
| 归档时间: |
|
| 查看次数: |
30489 次 |
| 最近记录: |