2015年10月25日日曜日

init.dの使い方(Xperia Z3で確認)

初めに

init.dスクリプトは起動時にデーモンなどを起動させるものです(UNIX系のOSを使用中ならご存知でしょうが)。
Androidの場合はユーザがprocなどでカーネルパラメータを指定した場合や追加モジュールを読込させる目的で使用している場合があるかと思います。
私の現在のメイン環境では起動時にsuperSUは動作しているためrootは普通に使えるのですが、rootkitではinit.dスクリプトサポートがないためせっかく作ったカーネルモジュールを読込出来ない状況でした。
OS周りのカスタマイズにはKernelAdiutorを使用していますが、これのinit.dサポートが/system/etc/init.dにスクリプトを置いても動作していないようなのでちょっと調べてみた結果を備忘録でまとめます。

その0(どちらの方法でも共通事項)

以下の記述+最下行に何も入れない行を1行追加して下さい。
/system/xbin/run-parts /system/etc/init.d 
/system/etc/init.dディレクトリのパーミッションは755もしくは777にし、init.dディレクトリ内部のシェルスクリプトもパーミッションを755もしくは777にします(755で十分動く筈なのですが、Xdaあたりを見ると777の記述も結構あるため)。
ちなみにこのrun-partsコマンド、busyboxのシンボリックリンクです。ということは当然busyboxがインストールされていないと動作しません。

その1(私の環境では動かない)

/system/etc/init.qcom.post_boot.shに記述を追加しました。
init.qcom.post_boot.shはブート中に動作するスクリプトのなのでこれで動きそうだと思ったのですが、何故か認識できず...

その2(SuperSUと同じ方法)

そう言えばSuperSUは現状では起動時にスクリプトを読み込ませる方法で対応していることを思い出し調べてみました。
/system/etc/install-recovery.shの最下行にその1と同じ内容を記載しました。
結果としてはこれが唯一動作した形になっています。
という訳で今回はかるーく流してみました。

おまけ(自分で作ったモジュールを起動時に全て読み込む)

/system/lib/modules配下にカーネルバージョンと同じフォルダを作り、その中に作成したカーネルモジュールを配置した場合にスクリプトで全てロードさせるスクリプトです。

#!/system/bin/sh
# script to load extra modules in /system/lib/modules
KVER=`/system/xbin/uname -r`
/system/bin/insmod /system/lib/modules/$KVER/symsearch.ko
for i in $(ls /system/lib/modules/$KVER);
do
/system/bin/insmod /system/lib/modules/$KVER/$i
done
上の例、簡単に説明しますが行頭の#はコメントを示します。また1行目の#!はこのスクリプトを動作させるためのシェルプログラムを指定します。
symsearch.koを先にinsmodしているのはこれに依存するモジュールがあるからです。
私がinit.dスクリプトを記載する際、おそらくPATHが/system/binには通っておりますが、/system/xbinも含めて実行コマンドはフルパスで記述しています(無用な動作不良を防止するため)。