2011年8月16日火曜日

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のシステムでした。

Android init

BeagleBoard-xMの起動はイカのようになっています。

  1. CPUがROM内のブートコードを使って起動
  2. ROMのローダーがmicroSD内のMLOファイルを読み込みその中のX-LoaderをSoC内のRAMに展開して実行
  3. X-LoaderがmicroSD内のu-bootを起動
  4. u-boot が 最低限のデバイスを初期化後、uImageをRAMに展開、カーネルを起動
  5. カーネルが各種デバイスを初期化後、init を起動
ここまでの挙動は、BeagleBoard-xMの固有の動作であり、アーキテクチャやボードによって異なります。

Linux カーネルが最初に起動するプロセスは init という名前のプロセスですが、一般のLinuxディストリビューションで採用されている init と動作が大きく異なります。

Androidのinitプロセスの役割は、大きく分けて二つあります。
  • Boot処理部
  • Daemon処理部

Boot処理部は、必要なディレクトリの生成後、rcファイルをパースしてそこに登録された処理を実行していきます。
  • init.rc
  • init.<hardware>.rc
その後Daemon処理部に移ると、3種類のevent用fdをpollしながら電源断までイベント処理を続けます。
  • property_set_fd
  • signal_fd
  • keychord_fd
実は、このあたりの処理が、froyoまでと異なってまして、froyoまでは init が udevd 的な機能も含んでいました。init.c内には、デバイスファイルを生成するためのルールが直に実装されており、init.rcファイルで追加できるものの基本のデバイスファイルはソースコードを変更してビルドし直さないと作れない状態だったわけです。froyoまではDaemon処理部では、上記の他に、device_fdもpollしてましたが、Gingerbreadからはこれが無くなっています。

今回からは、Android.mkで init が、ueventdとしてシンボリックリンクされるようになっており、udevdとして起動されると、ueventd.rc をパースしてデバイスのリストを保持した後、device_fdをpollするように実装されています。

ueventd 自体は、init.rc にサービスとして登録されており、initプロセスとは異なるプロセスとして起動されることになります。なおこれに伴いfroyoまでinit.rc , init.<hardware>.rc で利用できたdeviceコマンドは使えなくなりました。こちらはueventd.rcファイルに記載しueventdのみが利用することにまります。

アプリ側もAPI Levelが変わるとついて行くのが大変そうなんですが、プラットフォーム側もバージョンが上がると結構追いかけるのが大変なんですよねぇ。