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のカーネルを使っていることがわかります。