Xperia mini pro 用ソースから cifs.ko のビルド

前回 Xperia PLAY 用の cifs.ko を拝借してきましたが、今回は自分でビルドしてみようかなと。

作業は Linux マシンで行います。

Xperia mini pro 用のソース

ここから適したバージョンを落とす。


今回は『4.0.A.2.368.tar.bz2』。

/home/nanasi に展開したとします。

ツール

コンパイラを準備。

Gentoo じゃない人

以下にコンパイラがあるので落としてくる。


最新のコンパイラだとコンパイルエラーが返ってきたので若干古いバージョンのほうがいいかもしれない。ちょっと試した感じ GNU/Linux All versions → Sourcery G++ Lite 2010q1-202 を使用したら通った気がする。

/opt/toolchain あたりに展開しておく。

$ sudo mkdir /opt/toolchain
$ cd /opt/toolchain
$ tar xfj /path/to/arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
Gentoo な人

dev-util/android-ndk を emerge するだけ。

$ sudo emerge -v android-ndk

今日現在 ~amd64 キーワードでマスクされているので外すこと。

以下 Gentoo な toolchain のパスに従って記述していきますので、 Gentoo じゃない人は toolchain のパスを適宜 /opt/arm-2010q1/bin/arm-none-linux-gnueabi- 等に読み替えてください。

ソースの準備

一部モジュール (slow-work.ko) でちょっと手を加える必要があるためちょっといじる。以下を参考にした。

$ cd /home/nanasi/kernel/4.0.A.2.364/kernel
$ cp kernel/slow-work.* fs/cifs/


その後パッチあて。

fs/cifs/slow-work.c の round_jiffies を呼んでいるところを変更。
--- slow-work.c.orig    2011-09-21 00:10:10.481512537 +0900
+++ slow-work.c 2011-09-20 20:28:53.747735454 +0900
@@ -670,7 +670,8 @@
 static void slow_work_schedule_cull(void)
 {
        mod_timer(&slow_work_cull_timer,
-                 round_jiffies(jiffies + SLOW_WORK_CULL_TIMEOUT));
+                 jiffies + SLOW_WORK_CULL_TIMEOUT);
+/*               round_jiffies(jiffies + SLOW_WORK_CULL_TIMEOUT)); */
 }

 /*
@@ -811,7 +812,8 @@
                if (atomic_dec_and_test(&slow_work_thread_count))
                        BUG(); /* we're running on a slow work thread... */
                mod_timer(&slow_work_oom_timer,
-                         round_jiffies(jiffies + SLOW_WORK_OOM_TIMEOUT));
+                         jiffies + SLOW_WORK_OOM_TIMEOUT);
+/*                       round_jiffies(jiffies + SLOW_WORK_OOM_TIMEOUT)); */
        } else {
                /* ratelimit the starting of new threads */
                mod_timer(&slow_work_oom_timer, jiffies + 1);
fs/cifs/Makefile の object に slow-work.o を追加
--- Makefile.orig       2011-09-21 00:13:34.995315280 +0900
+++ Makefile    2011-09-20 20:29:21.621131924 +0900
@@ -1,7 +1,8 @@
 #
 # Makefile for Linux CIFS VFS client
 #
-obj-$(CONFIG_CIFS) += cifs.o
+#obj-$(CONFIG_CIFS) += cifs.o
+obj-$(CONFIG_CIFS) += cifs.o slow-work.o

 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
          link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \

Make する

ここまでやったら make menuconfig && make 。


まず土台となる .config 作り。

$ ARCH=arm CROSS_COMPILE=/opt/android-ndk/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin/arm-eabi- make semc_mango_defconfig

mango は SK17 のことです。 ST15 なら semc_smultron_defconfig に。もしくは端末から /proc/config.gz を引っこ抜いてもいいと…思ったけどカーネルのデフォルトオプションで /proc/config.gz がサポートされていない...


そこまでやったら menuconfig

$ ARCH=arm CROSS_COMPILE=/opt/android-ndk/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin/arm-eabi- make menuconfig
  • File systems → Network File Systems → CIFS support をモジュール (M) に
  • File systems → Native language support → NLS UTF-8 をモジュール (M) に


menuconfig が終わったら make 。

全部 make してもよいですが、こうして必要なところだけコンパイルしてもいいみたい。

$ ARCH=arm CROSS_COMPILE=/opt/android-ndk/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin/arm-eabi- make prepare
$ ARCH=arm CROSS_COMPILE=/opt/android-ndk/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin/arm-eabi- make M=fs/cifs/
$ ARCH=arm CROSS_COMPILE=/opt/android-ndk/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin/arm-eabi- make M=fs/nls/


これで cifs.ko 等必要なモジュールが作成されるので、あとは端末に送ってやって先日の通りやれば動く。

おまけ

カーネルをフルでコンパイルして boot.img を作る場合のメモ。

以下を参考に…


make までは先ほどの工程で make all すればすんなり行くと思う。コンパイルエラーがでたらツールのバージョンをちょっと古めにしたりすればうまく行った。

mkbootimg

boot.img の作成に mkbootimg というツールが必要らしいのでぐぐってみた感じだと Android ソースについてるよ!って ここに 書いてあってリンクもあるんだけど kernel.org に繋がらないため頓挫。

しかしもう少し調べて以下のように非公式ミラーから引っ張って代用。

$ git clone git://codeaurora.org/platform/system/core.git core

あとは


上記を参考にさせていただいてコンパイル

$ cd core/cpio/
$ gcc -I../include -o mkbootfs mkbootfs.c
$ cd ../mkbootimg/
$ gcc -I../include mkbootimg.c -o mkboot.img ../libmincrypt/rsa.c ../libmincrypt/sha.c
ramdisk

boot.img の作成には ramdisk 云々と書いてあるんだけどそれはどれぞ? ということで調べてみると、そもそも boot.img が header+kernel+ramdisk で出来ているらしいので手持ちの端末の boot.img から作ればいいらしい。

boot.img を分割する perl スクリプトがあるらしいので先にそれを入手する。これも さっきのサイト に置いてあるはずなんだけどこれまた見つからず、ぐーぐる先生に頼って入手。


ramdisk の作り方はわかったけどじゃぁ端末の boot.img はどう取得するんだ?となるわけですが、これは SEUS で作成したバックアップの 15MB 程度のファイルに含まれているので、これから抽出。

  1. 15MB 程度の FILE_XXXXXXXX を ConvertTool を使って SeusDecrypt
  2. 出来た tgz を解凍
  3. さらに 7zip 等で解凍→kernel_なんちゃら.sin が boot.img の元
  4. kernel_なんちゃら.sin を SIN2IMG→kernel.img とでもする


最後にこれを unpack-bootimg.pl にかければ OK 。

$ ./unpack-bootimg.pl kernel.img

kernel written to kernel.img-kernel.gz
ramdisk written to kernel.img-ramdisk.cpio.gz
2789 blocks

extracted ramdisk contents to directory kernel.img-ramdisk/


作成された kernel.img-ramdisk.cpio.gz が ramdisk になる。

もしくは以下のとおり同じく作成されたディレクトリを参照して mkbootfs で作りなおす。

$ mkbootfs ./kernel.img-ramdisk | gzip -9 > new-ramdisk.gz
packing

make したカーネルイメージと ramdisk をくっつける。

$ mkbootimg --base 0x00200000 --kernel 4.0.A.2.364/kernel/arch/arm/boot/zImage --ramdisk new-ramdisk.gz -o boot_mod.img

flash

> fastboot flash boot boot_mod.img

するだけ。

>fastboot flash boot boot_mod.img
sending 'boot' (4314 KB)...
(bootloader) USB download speed was 9203kB/s
OKAY [  0.490s]
writing 'boot'...
(bootloader) Download buffer format: boot IMG
(bootloader) Flash of partition 'boot' requested
(bootloader) S1 partID 0x00000003, block 0x00000280-0x000002e3
(bootloader) Erase operation complete, 0 bad blocks encountered
(bootloader) Flashing...
(bootloader) Flash operation complete
OKAY [  1.290s]
finished. total time: 1.780s


できたらリブート

> fastboot reboot
失敗したら

さっき手に入れた kernel_なんちゃら.sin を fastboot flash すれば元に戻る。たとえ立ち上がらなくても fastboot モードで接続さえできれば書き換えられるので、とっても安心。

(何度かお世話になりましたw)