web-dev-qa-db-ja.com

ネイティブAndroid ARM= x86で実行されるコードはどうですか?

Motorolaは、x86ベースのAndroid電話。ARM用に作成されたネイティブアプリ/ライブラリ(netflixなど)がこの電話でどのように動作するかについて少し混乱しています。

誰かが説明できるとありがたいです。

29
Ayush

はい、ARMネイティブコードはHoudiniという名前のエミュレーション機能を使用してIntel x86で実行されます

このライブラリは、ARM命令をオンザフライで読み取り、それらを同等のx86命令に変換します。これが、多くのアプリが実際に同等のライブラリを構築しなくてもx86で動作する理由です。

enter image description here

52
Royston Pinto

実際には、異なるアーキテクチャの異なるネイティブコードを含めることができます。Netflixの実行方法はわかりませんが、apkを開くと/lib/armeabi-v7a/ので、/lib/x86/

編集:armとx86のネイティブコードがあるAmazonショッピングアプリをチェックしました。多分それは、Netflixがそれを行う方法です。

9
nandeesh

Android St​​udio 3エミュレーターはバックエンドとしてQEMUを使用します

https://en.wikipedia.org/wiki/QEMU

QEMUは間違いなく主要なオープンソースクロスアーチエミュレーターです。これはGPLソフトウェアであり、x86およびARMに加えて、さらに多くのアーキテクチャをサポートしています。

その後、AndroidはQEMUにUIマジックを少し追加し、場合によってはいくつかのパッチを追加しますが、コアは間違いなくQEMUアップストリームにあります。

QEMUはバイナリ変換と呼ばれる手法を使用して、かなり高速なエミュレーションを実現します。 https://en.wikipedia.org/wiki/Binary_translation

バイナリ変換は、基本的にARM命令を同等のx86命令に変換します。

したがって、詳細を理解するための最良の方法は次のとおりです。

  • qEMUソースコードを読む: https://github.com/qemu/qemu
  • 一般にバイナリ翻訳を勉強し、おそらく独自のおもちゃの実装を書く

理論

  • CPUは「 Turing complete 」です(メモリ制限まで)
  • CPUには、有限メモリチューリングマシンでシミュレートできる単純な決定論的な動作があります

したがって、十分なメモリがあれば、どのCPUも任意のCPUをエミュレートできることは明らかです。

難しい質問は、その方法fastです。

演習:QEMUユーザーモードシミュレーション

QEMUにはユーザーランドモードがあり、ゲストとホストが同じOSである限り、x86マシンでユーザーランドARMコードを簡単に操作して、何が起こっているかを確認できます。

このモードでは、バイナリ変換が基本的な指示を処理し、システムコールがホストシステムコールに転送されるだけです。

たとえば、Linux自立型(glibcなし)のHello Worldを使用したLinux on Linuxの場合:

main.S

.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

GitHubアップストリーム

次に、次のようにアセンブルして実行します。

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 

そして、期待される結果を出力します:

hello syscall v8

C標準ライブラリに対してコンパイルされたARMプログラムを実行して、プログラムをGDBステップデバッグすることもできます。この具体例を参照してください: シングルステップARM QEMU上のGDBでのアセンブリ?

バイナリ変換について説明しているため、ロギングを有効にして、QEMUが実行している正確な変換を確認することもできます。

qemu-aarch64 -d in_asm,out_asm main.out

ここに:

  • 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 

INセクションには、手書きのARMアセンブリコードが表示され、OUTセクションには、生成されたx86アセンブリが表示されます。

Ubuntu 16.04 AMD64、QEMU 2.5.0、binutils 2.26.1でテスト済み。

QEMUフルシステムエミュレーション

ただし、QEMUでAndroidを起動すると、もちろんユーザーランドバイナリが実行されず、実際のLinuxカーネルとシミュレーション内のすべてのデバイスが実行される完全なシステムシミュレーションが実行されます。

完全なシステムシミュレーションはより正確ですが、少し遅くなり、QEMUにカーネルとディスクイメージを提供する必要があります。

それを試すには、次のセットアップを見てください。

[〜#〜] kvm [〜#〜]

QEMUでAndroid X86を実行すると、はるかに高速であることがわかります。

その理由は、QEMUが [〜#〜] kvm [〜#〜] を使用するためです。これは、ホスト上でゲスト命令を直接実行できるLinuxカーネル機能です。

強力なARMマシンを持っている場合(2019年の時点ではまだ珍しい)、ARMでARMを使用してKVMを実行することもできます。はるかに高速。

このため、X86ホストを使用している場合は、 Android AOSPカーネルをコンパイルし、Android Emulator? (低レベルのものに実際に触れる必要がない限り)。

Trend Micro Safe Mobile Workforce には、ARMアプリでのネイティブライブラリのランタイム(Intelのhoudiniではない)Android強力なx86サーバーでARM libのみでAPKを実行することをサポートできます。

0
Sun Junwen