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

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

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

 Basile Starynkevitch22 окт. 2012 г., 07:18
Возможно, собственный код ARM не может быть запущен на x86 или, по крайней мере, ему нужен эмулятор.

Ответы на вопрос(4)

Решение Вопроса

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

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

 Yamcha20 июн. 2013 г., 23:26
Не было бы возможно сделать это наоборот? Так х86 в ARM? чтобы Windows RT работала с приложениями x86? И производительность огромная?
 zezba900020 сент. 2014 г., 01:28
У меня есть новый четырехъядерный планшет ASUS x86, и он выполняет код ARM так же быстро, как мой Samsung Galaxy Tab 4 с тестами, которые я запускал с C # Mono. Если вы скомпилируете свой код для x86, он из моего теста будет работать в 3 раза быстрее, чем эквивалент ARM в ГГц.
 zezba900020 сент. 2014 г., 01:29
Я также установил проект Linux-x86 linux на свой старый нетбук Intel Atom 1005HA, и эта штука работает вдвое быстрее с Android по сравнению с Windows7 или GNU Linux.
 marko23 окт. 2012 г., 00:27
Я полагаю, что тип приложения, в котором разработчики сознательно использовали NDK, требует большого объема вычислений и, возможно, в режиме реального времени. Я не думаю, что перевод кода будет хорошей новостью.
 Royston Pinto24 июн. 2013 г., 13:24
Это только на Android. Я не знаю, как windows портирует свои приложения на обе арки. Хит производительности довольно минимален. Я не слышал о жалобах на приложения, борющиеся на x86.

Эмулятор 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) hello world:

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 upstream.

Затем соберите и запустите как:

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 относится к сборке гостевого ввода ARMout_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.

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

собрать AOSP из исходного кода и запустить его на QEMU:Как скомпилировать ядро Android AOSP и протестировать его с помощью эмулятора Android?соберите минимальную красивую систему Linux с помощью Buildroot и запустите ее с помощью QEMU:Как загрузить мастер ядра Torvalds Linux, (пере) скомпилировать его и загрузить с QEMU?соберите и запустите голый код на QEMU:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/79b35fb395f9f7f7621609186931408fe2f79881#baremetal-setup-getting-started

KVM

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

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

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

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

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

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

 Blackbelt04 июн. 2014 г., 10:47
Я думаю, что корень каталогаlibs неlibеще хороший ответ

Trend Micro Безопасная мобильная рабочая силау нас есть среда выполнения ARM (не houdini от Intel) для нативной библиотеки в приложениях Android. Так что мы можем поддерживать запуск APK только с ARM lib на мощном сервере x86.

Ваш ответ на вопрос