2011年11月30日
KZM-A9-DualボードでAndroid 4.0.1(Ice Cream Sandwich)を動かす
Android 4.0.1(Ice Cream Sandwich)をソースからビルドしてKZM-A9-Dualボードで何か画面に表示されるところまで動いたのでメモを残します。
おおまかな流れ
Android 2.3の時と同様に、環境変数をいくつかセットしてビルドを行い、それをNFS用のルートファイルシステムを作って動かします。使用したスクリプトは以下の通り。
$ cat build.sh export ARCH_ARM_HAVE_TLS_REGISTER=true export TARGET_ARCH_VARIANT=armv7-a-neon export TARGET_CPU_SMP=true export USE_CCACHE=1 time make -j8 showcommands > make.log 2>&1
$ cat make_nfsroot.sh ROOT=/export/android/root-kzm-ics [ -e $ROOT ] && sudo rm -rf $ROOT mkdir -p $ROOT cd out/target/product/generic/ #cd out/target/product/kzm9d/ zcat ramdisk.img | (cd $ROOT; cpio -i) cp -a system $ROOT cp $ROOT/init.rc $ROOT/init.rc.org sed -e 's/mount rootfs/#mount rootfs/' $ROOT/init.rc.org > $ROOT/init.rc sudo chown -R root:root $ROOT
eglをソフトレンダリングのライブラリを使うように設定する。
このままで動かすと、emulator専用のegl, openglのライブラリがロードされてしまって、そこでSEGVで落ちます。
これの簡単な回避方法は、ターゲットの/system/lib/egl/egl.cfg を削除することです。
grallocを持ってくる
フレームバッファに関連するHALのモジュールを持ってきます。
$ cp $GINGERBREAD/bionic/libc/kernel/common/linux/fbcommon.h bionic/libc/kernel/common/linux/ $ cd hardware/libhardware/modules/ $ mv gralloc /tmp $ cp -a $GINGERBREAD/hardware/renesas/emxx/libgralloc gralloc
Android.mkのLOCAL_MODULEは以下のようにgralloc.defaultに書き換えます。
LOCAL_MODULE := gralloc.default #LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_TAGS := optionalの行はコメントアウトします。これをしないとビルドされた gralloc.default..soが/system/lib/hw にコピーされません。
gralloc.default.soの中でゼロ除算で落ちるところがあったので、以下のように回避します。(info.pixclockが0になっているため。とりあえずrefreshRateは正確でなくてもよい。)
hardware/libhardware/modules/gralloc/framebuffer.cpp
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) return -errno; #if 1 /*koba*/ int refreshRate = 0; #else int refreshRate = 1000000000000000LLU / ( uint64_t( info.upper_margin + info.lower_margin + info.yres ) * ( info.left_margin + info.right_margin + info.xres ) * info.pixclock ); #endif if (refreshRate == 0) { // bleagh, bad info from the driver refreshRate = 60*1000; // 60 Hz }
initlogoを表示する
試行錯誤の結果、最初にinitlogoを表示するとその後もうまく表示できることがわかりました。おそらくPowerManagementか何かが関連しているのでしょう。これを行わないと内部的には起動しているのに画面は真っ暗なままです。
今までのinitlogo.rleを持ってきてターゲットのルートディレクトリに置きます。
また、元のコードではルートディレクトリはRAMディスクを想定して表示が終わったらこのファイルを消すようになっています。それでは困るのでそこをコメントアウトします。
system/core/init/logo.c: load_565rle_image
#if 0 /*koba*/ unlink(fn); #endif return 0;
USBマウスをつなぐ
これで画面が出るようになりました。タッチパネルも反応するのですが、座標のずれが大きくてうまく操作できません。おそらくキャリブレーションのしくみが変わったのでしょう。(2011/12/06 追記。タッチパネルが使えるようになりました。 KZM-A9-DualボードのAndroid4.0でタッチパネルが使えるようにする)
Android 4.0ではマウスも標準でサポートするようになっています。カーネル側にUSBマウスのデバイスドライバが組み込まれていれば、マウスを挿して動かすだけでマウスカーソルが表示されました。USBマウスは起動後に挿しても自動認識しました。
サスペンドしてしまうとまだ復帰できないので、起動したらSettingsのアプリから以下を選択してサスペンドしないようにします。
{} Developer options > Stay awake
SMPで動作
SMPカーネルを使用しています。ターゲットのシリアルコンソールから/proc/cpuinfoを確認すると2個のコアが動いているのがわかります。
$ cat /proc/cpuinfo Processor : ARMv7 Processor rev 2 (v7l) processor : 0 BogoMIPS : 1061.68 processor : 1 BogoMIPS : 1061.68 Features : swp half thumb fastmult vfp edsp neon vfpv3 CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x1 CPU part : 0xc09 CPU revision : 2 Hardware : KZM9D Revision : ffffff20 Serial : 0000000000000000 $
関連するページ
KZM-A9-DualボードでAndroid 4.0.3(Ice Cream Sandwich)を動かす
KZM-A9-DualボードのAndroid4.0でタッチパネルが使えるようにする