Подтвердить что ты не робот

Как написанный для Android-скрипт код для ARM работает на x86?

Недавно Motorola выпустила Android-телефон на базе x86. Я немного смущен тем, как на этом телефоне могут запускаться собственные приложения/библиотеки, написанные для ARM (например, netflix).

Буду признателен, если кто-нибудь сможет объяснить.

4b9b3361

Ответ 1

Да, встроенный код ARM работает на Intel x86 с использованием функции эмуляции с именем Houdini

Что делает эта библиотека, она читает инструкции ARM "на лету" и преобразует их в эквивалентные инструкции x86. Именно по этой причине многие приложения могут работать как на x86, не имея при этом необходимости создавать эквивалентную библиотеку.

enter image description here

Ответ 2

Фактически вы можете включить другой собственный код для другой архитектуры, не знаете, как работает Netflix, но если вы открываете apk, вы можете видеть /lib/armeabi-v7a/, поэтому я предполагаю, что может быть папка, похожая на /lib/x86/

Изменить: я просто проверял приложение для покупок Amazon, у него есть собственный код для руки и x86. Так может быть, Thats, как netflix тоже это делает.

Ответ 3

Эмулятор Android Studio 3 использует QEMU в качестве бэкэнда

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

QEMU, пожалуй, ведущий эмулятор кросс-арки с открытым исходным кодом. Это программное обеспечение GPL, и в дополнение к x86 и ARM поддерживает множество других арок.

Затем Android просто добавляет немного магии пользовательского интерфейса поверх QEMU и, возможно, некоторые патчи, но ядро определенно находится в QEMU upstream.

QEMU использует технику, называемую бинарным переводом, для достижения достаточно быстрой эмуляции: https://en.wikipedia.org/wiki/Binary_translation

Двоичный перевод в основном переводит инструкции ARM в эквивалентные инструкции x86.

Поэтому, чтобы понять детали, лучше всего:

  • прочитайте исходный код QEMU: https://github.com/qemu/qemu
  • изучите бинарный перевод в целом, возможно, напишите собственную игрушечную реализацию

теория

  • Процессоры " Тьюринга завершены " (до предела памяти)
  • Процессоры имеют простое детерминированное поведение, которое можно моделировать на машинах Тьюринга с конечной памятью

Поэтому ясно, что любой процессор может эмулировать любой процессор, если ему достаточно памяти.

Сложный вопрос, как сделать это быстро.

Практика: симуляция пользовательского режима QEMU

QEMU имеет режим пользовательского пространства, который позволяет очень легко играть с пользовательским кодом ARM на вашем компьютере с архитектурой x86, чтобы увидеть, что происходит, если ваш гость и хост находятся в одной ОС.

В этом режиме происходит то, что двоичный перевод выполняет основные инструкции, а системные вызовы просто перенаправляются на системные вызовы хоста.

Например, для Linux на Linux с автономным Linux (без glibc) привет мир:

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

Вы даже можете запускать программы ARM, скомпилированные со стандартной библиотекой C, и GDB шаг отлаживает программу! Посмотрите этот конкретный пример: Как выполнить пошаговую сборку ARM в GDB на QEMU?

Поскольку мы говорим о двоичном переводе, мы также можем включить некоторую регистрацию, чтобы увидеть точный перевод, который делает 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 полная эмуляция системы

Однако, когда вы загружаете Android в QEMU, он, конечно, не запускает бинарный файл пользователя, а скорее выполняет полную симуляцию системы, где он запускает реальное ядро Linux и все устройства в симуляции.

Полная симуляция системы более точна, но немного медленнее, и вам нужно передать ядро и образ диска в QEMU.

Чтобы попробовать это, взгляните на следующие настройки:

KVM

Если вы запустите Android X86 на QEMU, вы заметите, что он намного быстрее.

Причина в том, что QEMU использует KVM, которая является функцией ядра Linux, которая может выполнять гостевые инструкции прямо на хосте!

Если у вас есть мощный компьютер ARM (но редкий по состоянию на 2019 год), вы также можете запустить ARM на ARM с KVM намного быстрее.

По этой причине я рекомендую придерживаться X86-симуляции AOSP, если вы работаете на хосте X86, как указано в разделе: Как скомпилировать ядро Android AOSP и протестировать его с помощью эмулятора Android? Если только вам действительно не нужно прикасаться к чему-то низкому уровню.

Ответ 4

В Trend Micro Safe Mobile Workforce у нас есть время выполнения ARM (не Intel houdini) для собственной библиотеки в приложениях Android. Чтобы мы могли поддерживать APK только с ARM lib на мощном сервере x86.