Kernel Tuning

kernel debuggingをOFFにしたときに見つけたSpeedMod SGS2のChange Logを見ながら、kernel Tuningを進めてみることに。

Build環境構築

念の為、Android 2.3.6のbuild環境とするため、Downloading the Source Treeを見ながら作業を開始。repo syncの所要時間は30分未満、kernel.orgから取得していたときと比べ、かなり早くなりました。ただし、2.3.6のブランチを使う限り、Toolchainなどに変更はないようです。

Linaro

buildしたkernelに変化がないため、ToolchainをLinaroから引っ張ってきます。
android-toolchain, 4.5-2011.10
Androidのtoolchainには、Version4.5と4.6がありますが、4.6だとmakeの途中でコケます。
makeするときにtoolchainを4.5に切り替えると、コンパイル時のワーニングが少し増え、バイナリサイズが若干小さくなります。動作については、現在実機にて検証中です。

Compiler optimization

EzkeelさんのGLaDOSのMakefileを参考に、コンパイルオプションの記述を追加

MODFLAGS	= -DMODULE -funswitch-loops -fpredictive-commoning -fgcse-after-reload -ftree-vectorize -fipa-cp-clone -fsingle-precision-constant -pipe

CFLAGS_KERNEL	= -funswitch-loops -fpredictive-commoning -fgcse-after-reload -ftree-vectorize -fipa-cp-clone -fsingle-precision-constant -pipe

KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
		   -fno-strict-aliasing -fno-common \
		   -Werror-implicit-function-declaration \
		   -Wno-format-security \
		   -fno-delete-null-pointer-checks \
		   -mfpu=neon \
		   -march=armv5te \
		   -mtune=cortex-a8

カーネルバージョン

ToolchainをVersion 4.5に切り替えたkernelで、ホーム画面から[設定]-[端末情報]-[カーネルバージョン]を確認すると、いままではBuild回数が「#3」などと表示されていた部分が、「))」になってしまいました。
調べてみるとSettingsアプリがカーネルバージョンを取得している部分のソースコードから、/proc/versionを参照していることがわかりました。
/home/norite/mydroid/packages/apps/Settings/src/com/android/settings/DeviceInfoSettings.java, Line:169

    private String getFormattedKernelVersion() {
        String procVersionStr;

        try {
            BufferedReader reader = new BufferedReader(new FileReader("/proc/version"), 256);
            try {
                procVersionStr = reader.readLine();
            } finally {
                reader.close();
            }

            final String PROC_VERSION_REGEX =
                "\\w+\\s+" + /* ignore: Linux */
                "\\w+\\s+" + /* ignore: version */
                "([^\\s]+)\\s+" + /* group 1: 2.6.22-omap1 */
                "\\(([^\\s@]+(?:@[^\\s.]+)?)[^)]*\\)\\s+" + /* group 2: (xxxxxx@xxxxx.constant) */
                "\\((?:[^(]*\\([^)]*\\))?[^)]*\\)\\s+" + /* ignore: (gcc ..) */
                "([^\\s]+)\\s+" + /* group 3: #26 */
                "(?:PREEMPT\\s+)?" + /* ignore: PREEMPT (optional) */
                "(.+)"; /* group 4: date */

端末側でversionを確認してみると、下記のように表示されます。

$ cat /proc/version
Linux version 2.6.35.7-g7c7e8ea-dirty (norite@ubuntu) (gcc version 4.5.4 20111003 (prerelease) (Linaro GCC 4.5-2011.10)) #9 PREEMPT Fri Nov 18 23:35:30 JST 2011

Build環境を再構築したときにgccのバージョンに(prerelease)が付いたため、アプリが想定している文字列とは括弧の数が変わってしまったようです。kernel側で解決するには、/proc/verionの返す値を変更するのが良さそうです。Makefile->version.c->compile.h->mkcompile_hと辿り、「(prerelease)」の括弧を取るようにScriptを変更しました。
./script/mkcompile_h, line:81

  echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1 | sed -e 's/(prerelease)/prerelease/'`\"

NS-GRK39F-VS10-VC2-BLN4-UV50mV-20111119.zip