2011年8月16日火曜日

system_process以降

Zygoteは、/system/bin/app_processを使って起動されるすべてのVMプロセスの親となるプロセスで、起動時にオプション --start-system-serverの引数が渡されると、起動時にsystem_processという名前の子プロセスを生成するように実装されています。

system_processは、Zygoteをコピーして生成されたAndroidの中枢を担うシステム用のVMプロセスで、Java側の各種サービススレッド群は、すべてこのsystem_processのスレッドとして生成されます。

DBMSを使ってスレッドの一覧を取得できます。

*1 59 native 69 37 main
*2 60 vmwait 21 341 HeapWorker
*3 61 vmwait 106 18 GC
*4 62 vmwait 0 0 Signal Catcher
*5 63 running 138 431 JDWP
*6 64 vmwait 76 54 Compiler
7 65 native 1 0 Binder Thread #1
8 66 native 0 0 Binder Thread #2
9 71 native 479 150 android.server.ServerThread
10 72 native 248 311 ActivityManager
11 76 timed-wait 19 21 ProcessStats
12 77 native 16 5 PackageManager
13 78 native 0 0 FileObserver
14 79 native 0 0 AccountManagerService
15 81 native 0 0 SyncHandlerThread
16 86 native 55 10 AlarmManager
17 83 native 0 1 UEventObserver
18 84 native 1 0 PowerManagerService.mScreenOffThread
19 85 native 5 0 PowerManagerService
20 87 native 16 2 WindowManager
21 88 native 706 64 WindowManagerPolicy
22 89 native 1 3 InputDispatcher
23 90 native 2 0 InputReader
24 91 native 4 4 NetdConnector
25 94 native 0 0 WifiService
26 92 native 6 0 ConnectivityThread
27 95 native 0 0 Tethering
28 96 native 0 0 MountService
29 97 native 4 0 VoldConnector
30 99 native 0 0 AudioService
31 101 native 0 0 SoundPool
32 102 native 0 0 SoundPoolThread
33 103 native 0 0 backup
34 107 timed-wait 7 17 watchdog
35 110 native 2 1 LocationManagerService
36 111 native 21 13 ThrottleService
37 122 native 0 0 GpsLocationProvider
38 160 native 0 0 Binder Thread #3
39 163 native 0 0 Binder Thread #4
40 164 native 3 0 Binder Thread #5
42 292 native 0 0 Binder Thread #9
44 231 native 0 0 Binder Thread #8
45 217 native 0 0 Binder Thread #6
46 229 native 0 0 Binder Thread #7
47 293 native 0 0 Binder Thread #10
48 295 native 0 0 Binder Thread #11

結構たくさんのスレッドが立ってますね。

ここまでの流れを簡単に述べると

  1. kernelが/initを起動する
  2. /initがinit.rcに従い /system/bin/app_process(Zygote) を --start-system-server引数付きで起動する
  3. app_processがfork後、com.android.server.SystemServer#main を実行する(system_server)
  4. com.android.server.SystemServer#main が android_server_SystemServer_init1(JNIEnv* env, jobject clazz)をJNI経由で呼び出し
  5. android_server_SystemServer_init1() が system_init()を呼び出し
  6. system_init()では Surfaceflingerのinstantiate等を行った後、SystemServer#init2をコールバック
  7. SystemServer#init2が、 amdrpod.server.ServerThreadを生成、runする。
  8. ServerThreadが各種サービス・マネージャー関連を生成、登録していく。それっぽい箇所を抜き出してみると
    • new EntropyService()
    • new PowerManagerService()
    • ActivityManagerService.main()
    • new TelephonyRegistry(context)
    • AttributeCache.init(context)
    • PackageManagerService.main()
    • ActivityManagerService.setSystemProcess()
    • context.getContentResolver()
    • new AccountManagerService(context)
    • ContentService.main()
    • ActivityManagerService.installSystemProviders()
    • new BatteryService(context)
    • new LightsService(context)
    • new VibratorService(context)
    • PowerManagerService#init()
    • new AlarmManagerService(context)
    • Watchdog.getInstance().init()
    • WindowManagerService.main()
    • ((ActivityManagerService)ServiceManager.getService("activity").setWindowManager
    • new BluetoothService(context)
    • new BluetoothA2dpService()
    • new DevicePolicyManagerService(context)
    • new StatusBarManagerService(context)
    • new ClipboardService(context)
    • new InputMethodManagerService()
    • new NetStatService()
    • NetworkManagementService.create()
    • ConnectivityService.getInstance()
    • new ThrottleService(context)
    • new AccessibilityManagerService(context)
    • new MountService(context)
    • new NotificationManagerService()
    • new DeviceStorageMonitorService(context)
    • new LocationManagerService(context)
    • new SearchManagerService(context)
    • new DropBoxManagerService()
    • new WallpaperManagerService(context)
    • new AudioService(context)
    • new HeadsetObserver(context)
    • new DockObserver()
    • new UsbObserver(context)
    • new UiModeManagerService(context)
    • new BackupManagerService(context)
    • new AppWidgetService(context)
    • new RecognitionManagerService(context)
    • new DiskStatsService(context)
    • new AdbSettingsObserver
    • VMRuntime.getRuntime().startJitCompilation()
  9. この後、生成したサービスの一部のsystemReady()メソッドを実行していく
  10. Looper.loop()

とまぁ、こんな処理が長々と一つのメソッドに・・・・長いわ!と途中で放り投げたくなるところでしたけど。余所からアクセスできるようにするものは、ServiceManager#addServiceしています。とりあえずにしておきました。なお、メソッドがstaticか否かまで確かめ切れていないので、色々記載に間違いがある気もしていますが・・・とりあえずメモ書きレベルだということでお許し下さい。

名前からもなんとなく想像がつきますが、Threadは、これらのクラス群の処理の中で生成、runされていくのではないでしょうか。近いうちにこのあたりも追いかけてみたいなと思います。

さて、このsystem_processも重要なのですが、先日psコマンドの一覧をtreeにして日記にあげた通り、他のJavaアプリケーションも、それぞれZygoteを親として生成されたVMプロセスとして動作しています。
  • jp.co.omronsoft.openwnn
  • com.android.phone
  • com.android.systemui
  • com.android.launcher
  • android.process.acore
  • com.android.mms
  • android.process.media
  • com.android.deskclock
  • com.android.email
  • com.android.protips
  • com.android.music
  • com.android.quicksearchbox
ここで気になるのが、Javaアプリを起動しているのは誰?という話です。
Zygoteが親なので、fork自体はZygoteプロセスなのでしょうが、誰がどのように起動しているものやら。

initから先の勉強

今回は、initから先のプロセス群について勉強してみたいなと思います。

まぁ、こういう場合は、まずはpsの一覧を見るべきでしょう。qemuでAndroid 2.3のエミュレータを起動して、adb shellからpsの一覧を取得してみます。

USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
root      1     0     268    180   c009b74c 0000875c S /init
root      2     0     0      0     c004e72c 00000000 S kthreadd
root      3     2     0      0     c003fdc8 00000000 S ksoftirqd/0
root      4     2     0      0     c004b2c4 00000000 S events/0
root      5     2     0      0     c004b2c4 00000000 S khelper
root      6     2     0      0     c004b2c4 00000000 S suspend
root      7     2     0      0     c004b2c4 00000000 S kblockd/0
root      8     2     0      0     c004b2c4 00000000 S cqueue
root      9     2     0      0     c018179c 00000000 S kseriod
root      10    2     0      0     c004b2c4 00000000 S kmmcd
root      11    2     0      0     c006fc74 00000000 S pdflush
root      12    2     0      0     c006fc74 00000000 S pdflush
root      13    2     0      0     c00744e4 00000000 S kswapd0
root      14    2     0      0     c004b2c4 00000000 S aio/0
root      22    2     0      0     c017ef48 00000000 S mtdblockd
root      23    2     0      0     c004b2c4 00000000 S kstriped
root      24    2     0      0     c004b2c4 00000000 S hid_compat
root      25    2     0      0     c004b2c4 00000000 S rpciod/0
root      26    2     0      0     c019d16c 00000000 S mmcqd
root      27    1     248    152   c009b74c 0000875c S /sbin/ueventd
system    28    1     804    224   c01a94a4 afd0b6fc S /system/bin/servicemanager
root      29    1     3916   436   ffffffff afd0bdac S /system/bin/vold
root      30    1     3888   396   ffffffff afd0bdac S /system/bin/netd
radio     32    1     4388   432   ffffffff afd0bdac S /system/bin/rild
root      33    1     63964  20816 c009b74c afd0b844 S zygote
media     34    1     18236  1352  ffffffff afd0b6fc S /system/bin/mediaserver
root      35    1     812    244   c02181f4 afd0b45c S /system/bin/installd
keystore  36    1     1796   284   c01b52b4 afd0c0cc S /system/bin/keystore
root      37    1     732    208   c003da38 afd0c3ac S /system/bin/sh
root      38    1     820    268   c00b8fec afd0c51c S /system/bin/qemud
shell     40    1     732    208   c0158eb0 afd0b45c S /system/bin/sh
root      41    1     3372   176   ffffffff 00008294 S /sbin/adbd
root      52    37    788    212   c02181f4 afd0b45c S /system/bin/qemu-props
system    59    33    127596 28888 ffffffff afd0b6fc S system_server
app_12    109   33    76020  18872 ffffffff afd0c51c S jp.co.omronsoft.openwnn
radio     113   33    88252  19624 ffffffff afd0c51c S com.android.phone
system    115   33    76332  20672 ffffffff afd0c51c S com.android.systemui
app_1     119   33    79084  22840 ffffffff afd0c51c S com.android.launcher
root      161   41    732    208   c003da38 afd0c3ac S /system/bin/sh
root      162   161   688    284   c009b74c afd0b844 S logcat
app_5     185   33    80392  21484 ffffffff afd0c51c S android.process.acore
app_3     201   33    85188  17904 ffffffff afd0c51c S com.android.mms
app_9     204   33    75264  18544 ffffffff afd0c51c S android.process.media
app_8     237   33    75164  17676 ffffffff afd0c51c S com.android.deskclock
app_13    247   33    75612  18976 ffffffff afd0c51c S com.android.email
app_11    262   33    72828  16468 ffffffff afd0c51c S com.android.protips
root      272   41    732    340   c003da38 afd0c3ac S /system/bin/sh
app_20    275   33    73276  16904 ffffffff afd0c51c S com.android.music
app_26    284   33    73868  17720 ffffffff afd0c51c S com.android.quicksearchbox
root      297   272   740    360   c003da38 afd0c3ac S sh
root      306   1     664    264   c01b52b4 afd0c0cc S /system/bin/debuggerd
root      355   297   892    336   00000000 afd0b45c R ps

さて、これだとちょっとわかりにくいのでTreeに並べ直してみましょうか。

  • /init
    • /sbin/ueventd
    • /system/bin/servicemanager
    • /system/bin/vold
    • /system/bin/netd
    • /system/bin/rild
    • /system/bin/
    • zygote
      • system_server
      • jp.co.omronsoft.openwnn
      • com.android.phone
      • com.android.systemui
      • com.android.launcher
      • android.process.acore
      • com.android.mms
      • android.process.media
      • com.android.deskclock
      • com.android.email
      • com.android.protips
      • com.android.music
      • com.android.quicksearchbox
    • /system/bin/mediaserver
    • /system/bin/installd
    • /system/bin/keystore
    • /system/bin/sh
      • /system/bin/qemu-props
    • /system/bin/sh
    • /sbin/adbd
      • /system/bin/sh
        • logcat
      • /system/bin/sh
        • sh
    • /system/bin/debuggerd
  • kthreadd
    • ksoftirqd/0
    • events/0
    • khelper
    • suspend
    • kblockd/0
    • cqueue
    • kseriod
    • kmmcd
    • pdflush
    • pdflush
    • aio/0
    • mtdblockd
    • kstriped
    • hid_compat
    • rpciod/0
    • mmcqd

はい。だいぶわかりやすくなりましたか。まず、第一の階層としては、initとkthreaddがあります。kthreaddは、kernel threadでカーネルの側のお話です。Android固有の何かがあるかもしれませんが、とりあえず置いておきましょう。

/initから始まるのが、Androidのシステムでした。