Android AOSPの64bit化の現在の状況

2014/05/03(#yapf)横浜Android and モバイルOSプラットフォーム部第35回勉強会での@hidenorly さんの発表Investigation report on 64 bit support in Android Open Source Projectに触発されて、現在(2014/5/10)のAOSPでarm64とx86_64でビルドしてみました。

arm64

$ . build/envsetup.sh 
$ lunch

You're building on Linux

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     3. aosp_mips-eng
     4. aosp_mips64-eng
     5. aosp_x86-eng
     6. aosp_x86_64-eng
     7. vbox_x86-eng
     8. aosp_manta-userdebug
     9. mini_x86-userdebug
     10. mini_mips-userdebug
     11. mini_armv7a_neon-userdebug
     12. aosp_mako-userdebug
     13. aosp_hammerhead-userdebug
     14. aosp_tilapia-userdebug
     15. aosp_deb-userdebug
     16. aosp_flo-userdebug
     17. aosp_grouper-userdebug

Which would you like? [aosp_arm-eng] 2

lunchコマンドでいつものaosp_arm-engでなく、aosp_arm64-eng を選んでビルドしました。

$ nohup make -j4 &

ビルドは完了しましたが、arm64用のemulatorはまだ無いので実行することはできません。
できたファイルを観察してみます。

$ cd out/target/product/generic_arm64
$ file root/init
root/init: ELF 64-bit LSB executable, version 1 (SYSV), statically linked, stripped

カーネルから一番最初に起動されるプロセスであるinitは64bit ELFでした。
system/lib と system/lib64 があります。前者は32bitのダイナミックリンクライブラリ、後者が64bit用です。
ダイナミックリンクライブラリは32bitと64bitで混ぜて使うことはできません。32bitのプロセスでは32bitのライブラリのみ使用可能で、64bitのプロセスは64bitのライブラリのみです。そのため同じライブラリが32bitと64bitの二通りで用意されています。

DalvikVMの本体である libdvm.so がありません。ARTの本体のlibart.so は32bit/64bit両方あります。
やはり64bitでのAndroidの本命はDalvikでなくARTのようです。これらの実行環境を開発して品質を上げていくには相当のエンジニアリングリソースが必要になるので、両方に分散させるのでなくひとつに集中させるのは理にかなっていると思います。

system/bin のコマンドはほとんどが64bitになっています。
Zygoteの元となるapp_processのコマンドが2通りあります。無印のほうが32bitです。

$ file system/bin/app_process*
system/bin/app_process:   ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
system/bin/app_process64: ELF 64-bit LSB shared object, version 1 (SYSV), dynamically linked (uses shared libs), stripped

おや?ARTのコンパイラであるlibart-compiler.so が32bitのものしかありません。そして、framework.jarなどのシステムライブラリをARTであらかじめコンパイルした system/framework/boot.oat も32bitのものしかありません。
そうすると現時点のAOSPではJavaを含むプログラムは32bit版しか動かすことができないですね。
system/priv-apps にプリインストールされるアプリがARTでコンパイル済みのものが置かれていますが、全て32bitでした。
そういえば、@hidenorly さんの発表の中でrenderscriptもまだ32bitに固定されていると言っていました。

つまり、今のところはarm64向けのLLVMバックエンドはまだ固まっていないようです。

x86_64

次に、lunchコマンドでaosp_x86_64-eng を選んでビルドしてみます。
こちらはemulatorがあるので、ビルドできたら動かすことができます。しかしずっとブートアニメーションのままで起動しません。
logcatのログでは

F/art     (  946): art/runtime/gc/space/image_space.cc:156] Failed to load image '/system/framework/boot.art': Failed to open oat file '/system/framework/boot.oat' referenced from image /system/framework/boot.art: Expected ISA X86_64 but found X86
F/art     (  946): art/runtime/runtime.cc:257] Runtime aborting...
F/art     (  946): art/runtime/runtime.cc:257] (Aborting thread was not attached to runtime!)
F/art     (  946): art/runtime/runtime.cc:257] Dumping all threads without appropriate locks held: thread list lock mutator lock
F/art     (  946): art/runtime/runtime.cc:257] All threads:
F/art     (  946): art/runtime/runtime.cc:257] DALVIK THREADS (0):
F/art     (  946): art/runtime/runtime.cc:257] 
F/libc    (  946): Fatal signal 6 (SIGABRT), code -6 in tid 946 (zygote64)

zygote64が起動に失敗しています。/system/framework/boot.oat がX86_64用のはずがx86用のためのようです。
さきほどarm64のほうで思ったことがそのまんま実際に起こっていました。

/default.prop でro.zygote=zygote32_64 のところを ro.zygote=zygote32 に変更して、zygote64を使用しないようにしたら起動して最初のランチャーメニューの画面まで表示されるようになりました。
/はread onlyでmountされているため、いかのパッチをあててルートファイルシステムを再度作成しました。
build/target/product/core_64_bit.mk

 --- core_64_bit.mk.org	2014-05-08 17:02:56.192121328 +0900
 +++ core_64_bit.mk	2014-05-08 17:03:57.339841240 +0900
 @@ -27,7 +27,8 @@
  
  # Set the zygote property to select the 32-bit primary, 64-bit secondary script
  # This line must be parsed before the one in core_minimal.mk
 -PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32_64
 +#PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32_64
 +PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32
  
  # Temporary hack to prefer launching processes as 32 bit
  # instead of 64 bit.

このx86_64のemulatorではkernelのバージョンは3.10でした。arm版は3.4だったので、LTSのカーネルを使っていることがわかります。

まとめ

AOSPは開発途上なので、日に日に更新されていくとは思いますが、現段階では64bit向けのARTのコンパイラが(arm64, x86_64ともに)まだできていません。

現状のARTのコンパイラのバックエンドは quick と名前がつけられている独自のものですが、LLVMベースのものも準備されていて、いずれはそれが使われるようになると思います。
ARM 64bit のLLVMバックエンドに関しては先日の以下の記事が関連しています。
ARM 64bit でLLVMは見逃せない - 組み込みの人。