2011年12月21日

Android 4.0でZygoteを起動せずに最小構成で動かす

Androidのinit.rcでは複数のserviceをまとめて扱うclassを定義することができます。この機能は以前からあったのですが、使われていませんでした。

Android 4.0ではinit.rcを少し修正することで、ZygoteなどAndroidのframeworkのserviceが起動する前の、最小限の構成までで止めることができます。



最小構成で動かす

通常状態でのプロセスは以下のものが動いています。

$ ps
USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
root      1     0     332    196   ffffffff 00000000 S /init
  ... (kernel threadは省略) ...
root      41    1     328    180   ffffffff 00000000 S /sbin/ueventd
system    42    1     832    260   ffffffff 00000000 S /system/bin/servicemanager
root      43    1     4020   740   ffffffff 00000000 S /system/bin/vold
root      44    1     6312   912   ffffffff 00000000 S /system/bin/netd
root      45    1     696    272   ffffffff 00000000 S /system/bin/debuggerd
radio     46    1     4472   752   ffffffff 00000000 S /system/bin/rild
system    47    1     49244  7984  ffffffff 00000000 S /system/bin/surfaceflinger
root      48    1     103276 35308 ffffffff 00000000 S zygote
drm       49    1     12232  3812  ffffffff 00000000 S /system/bin/drmserver
media     50    1     28096  6416  ffffffff 00000000 S /system/bin/mediaserver
bluetooth 51    1     1332   596   ffffffff 00000000 S /system/bin/dbus-daemon
root      52    1     844    328   ffffffff 00000000 S /system/bin/installd
keystore  53    1     1736   544   ffffffff 00000000 S /system/bin/keystore
shell     55    1     760    324   c00597f8 4000d264 S /system/bin/sh
root      56    1     3436   172   ffffffff 00000000 S /sbin/adbd
system    94    48    184232 45844 ffffffff 00000000 S system_server
system    158   48    122116 45440 ffffffff 00000000 S com.android.systemui
app_5     173   48    113080 31436 ffffffff 00000000 S com.android.inputmethod.latin
radio     197   48    127064 36036 ffffffff 00000000 S com.android.phone
app_16    209   48    136500 54892 ffffffff 00000000 S com.android.launcher
app_2     244   48    139312 51560 ffffffff 00000000 S android.process.acore
app_29    262   48    111744 27172 ffffffff 00000000 S com.android.smspush
app_2     303   48    119600 32820 ffffffff 00000000 S com.android.contacts
app_0     338   48    113256 29828 ffffffff 00000000 S com.android.providers.calendar
app_1     353   48    117804 28816 ffffffff 00000000 S com.android.exchange
app_3     367   48    122856 33936 ffffffff 00000000 S com.android.email
app_7     380   48    115424 30420 ffffffff 00000000 S android.process.media
app_4     403   48    115096 30972 ffffffff 00000000 S com.android.mms
app_20    444   48    111804 27272 ffffffff 00000000 S com.android.voicedialer
app_33    457   48    114552 29304 ffffffff 00000000 S com.android.deskclock
system    473   48    123924 39356 ffffffff 00000000 S com.android.settings
app_26    486   48    116264 29592 ffffffff 00000000 S com.android.calendar
shell     505   55    960    340   00000000 40010438 R ps
$

init.rcを一行コメントアウトし、core classのserviceだけ動かしてmain classのものを動かさないことにします。

--- init.rc	2011-12-15 20:42:46.000000000 +0900
+++ init.rc.min	2011-12-15 20:42:39.000000000 +0900
@@ -264,7 +264,7 @@
     setprop system_init.startsurfaceflinger 0
 
     class_start core
-    class_start main
+#    class_start main
 
 on nonencrypted
     class_start late_start

これで再起動すると以下のようになります。

$ ps
USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
root      1     0     332    196   c00d1884 000086e8 S /init
  ... (kernel threadは省略) ...
root      41    1     328    180   c00d1884 000086e8 S /sbin/ueventd
system    42    1     832    260   c02431bc 40010670 S /system/bin/servicemanager
root      43    1     4020   728   ffffffff 40015c74 S /system/bin/vold
root      45    1     760    324   c00597f8 4000d264 S /system/bin/sh
root      46    1     3432   164   ffffffff 0000825c S /sbin/adbd
root      60    45    960    340   00000000 40010438 R ps
$

シリアルコンソールでshellが使えるほか、adbdが起動しているのでadb経由で通信できます。

host$ adb logcat
...

もうひとつ別のターミナルから

host$ adb shell
#

この状態で有線LANは使用可能なので、サーバー的に使用するならばこれでも十分です。

例えば、rubyをインストールして簡単にHTTPサーバを動かすことができます。

RubyをAndroid用にビルドする

ここからZygoteを起動する

以下のコマンドでmainクラスのサービスを起動することができます。

# setprop vold.decrypt trigger_restart_framework

または、デバッグや動作の理解のために以下のようにひとつづつserviceを手動で起動していくこともできます。

# start netd
# start debuggerd
# start ril-deamon
# start surfaceflinger
# start zygote
# start drm
# start media
# start dbus
# start installd

surfaceflingerをstartさせたときにブートアニメーションが起動されます。

(参考:Androidのブートアニメーション)

Android4.0でなぜcoreとmainのクラスに分かれたのか

Android2.3まではclassの定義はされていなかったので全てのserviceはdefaultクラスに属していました。

core classにvold(Volume Daemon)が含まれていることと、その後にmain classをstartさせるproperty名がvold.decryptであることから、このクラス分けはストレージの暗号化が関係しているようです。おそらく製品では、core classを起動した後に、ストレージの暗号化を行うならばそのためのセットアップを行い、その後にmain classのserviceを起動させるようにしているのではないでしょうか。

Android2.3で同様のことをするには

複数のserviceをまとめて扱うclassを定義することはAndroid2.3でも可能です。そのため、Android4.0のinit.rcと見比べて、同様の変更をすればよいと思います。



トラックバックURL

コメントする

名前
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード