Beagleboard-xmでAndroid動かしたときのメモ

購入品
記念撮影

詳細な購入品リスト(背景が灰色のものは検討したものの購入していないものです)。
最終的な金額は液晶も含めて4万2千円程度でした。

参考にさせて頂いた書籍
そもそも組み込みのAndroidに興味を持ったのは「組み込みAndroid」という書籍を読んだからです。beagleboard-xmへのAndroidポーティングに関しては若干内容が古いですが、大変参考になります。

基礎から学ぶ 組み込みAndroid

基礎から学ぶ 組み込みAndroid

参考にさせて頂いたサイト
TI-Android-GingerBread-2.3.4-DevKit-2.1 DeveloperGuide
BeagleBoard-xM に Android Gingerbread をポーティング

なお、上の写真に移っているタッチパネルディスプレイ(HM-TL7T)でタッチパネル機能を使えるようにするためにはLinuxカーネルソースに含まれるファイルを若干修正する必要がありました。
これには「LinuxでHM-TL10Tのタッチパネルを認識させる」を参考にさせていただきました。
デバイスドライバのことなどまったく分からないのでこのようなサイトがあって大変助かりました。

事前の準備
GingerBreadをコンパイルするには64bitのUbuntu Linuxが必要です。私は手元のMacBookProにUbuntu用のパーティションを作ってダブルブート環境にしました。
Macで使えるUbuntu Linux 64bit版はこちらにあります。
Ubuntu 11.10 (Oneiric Ocelot)

既にMacをインストールしている場合もディスクユーティリティで新たにUbuntu用のパーティションを作成可能です。ただしその場合、BootCampでWindowsデュアルブートする環境にしていたらWindowsが起動できなくなる可能性が高いですので必ずバックアップは取っておいてください。私は起動しなくなりましたw

MacBookProにUbuntuをインストールする手順については以下のサイトを参考にさせていただきました。
defiantの日記

Ubuntuをインストールできたら端末から必要なパッケージをインストールします。

$ sudo aptitude install git-core gnupg flex bison gperf build-essential zip curl sun-java6-jdk zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev uboot-mkimage

gcc関連をインストール

$ sudo apt-get install gcc-4.5
$ sudo apt-get install gcc-4.5-multilib
$ sudo apt-get install g++-4.5
$ sudo apt-get install g++-4.5-multilib
$ export CC=gcc-4.5
$ export CXX=g++-4.5

ソースコードその他をダウンロードする
必要なソースコードその他はTexus Instruments のダウンロードサイトにおいてあります。

Texus InstrumentsのサイトにはGingerBreadに関して2.3と2.3.4の2種類がありますが、最新の [beagleboard-xm RevC] 上でGingerBreadを動かす場合は必ず2.3.4の方を使用してください。2.3ではマウスやネットワークデバイスの認識に関してRevCには対応していないらしく、そのままではマウスもネットワークも認識しません。

なお、ここでのこれ以降の作業は"~/src/beagle-android/GingerBread_2_3_4"というディレクトリを作って、そこにソースと開発キットをダウンロードして行うことを前提としています。

$ mkdir -p ~/src/beagle-android/GingerBread_2_3_4
$ cd ~/src/beagle-android/GingerBread_2_3_4
$ wget http://software-dl.ti.com/dsps/dsps_public_sw/sdo_tii/TI_Android_DevKit/TI_Android_GingerBread_2_3_4_DevKit_2_1/exports/TI_Android_GingerBread_2_3_4Sources.tar.gz

同じくTexus Instrumentのサイトから開発キットをダウンロードする。

$ wget http://software-dl.ti.com/dsps/dsps_public_sw/sdo_tii/TI_Android_DevKit/TI_Android_GingerBread_2_3_4_DevKit_2_1/exports/TI_Android_GingerBread_2_3_4_DevKit_2_1.tar.gz

あとはbeagleboard-xm向けのビルド済みパッケージも落としておくといいと思います。私の環境では自前でコンパイルしたMLOとu-boot.binが動作しなかったので、ビルド済みパッケージに含まれていたものを使わせてもらいました。
↑ビルドできました

$ wget http://software-dl.ti.com/dsps/dsps_public_sw/sdo_tii/TI_Android_DevKit/TI_Android_GingerBread_2_3_4_DevKit_2_1/exports/beagleboard-xm.tar.gz

ダウンロードには数時間かかります。寝る前に上記2つを別の端末で実行しておいて寝て待つのがいいと思われます。

ビルドの準備
ダウンロードが終わったらTI-Android-GingerBread-2.3-4DevKit-2.1 DeveloperGuideに従ってAndroidをビルドします。

まずは解凍

$ tar xvzf TI_Android_GingerBread_2_3_4Sources.tar.gz
$ tar xvzf TI_Android_GingerBread_2_3_4_DevKit_2_1.tar.gz 

ソースディレクトリに移動してレポジトリをセットアップします。repoについては正直よく分かってないところがあるのですが、内部でgitを操作しているらしく、下記を実行するとディレクトリにソースコードが配置されます。

$ cd TI_Android_GingerBread_2_3_4Sources/
$ ./.repo/repo/repo sync --local-only

ツールのあるディレクトリにパスを通しておきます。

export PATH=~/src/beagle-android/GingerBread_2_3_4/TI_Android_GingerBread_2_3_4Sources/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH

Beagleboard-XMにおけるAndroidの起動プロセス
予備知識として、beagleboard-xm上でのブートプロセスは以下のようになるようです。
(起動時の出力を見ての憶測に基づいたものであり、ソースを見たわけではありません)

  1. beagleboard-xm電源投入
  2. (beagleboard-xm内のブートローダ起動?)
  3. microSDカードのbootパーティションの最初にあるブートローダ"MLO"を起動
  4. microSDカードのbootパーティションにある"u-boot.bin"を起動
  5. microSDカードのbootパーティションにある"boot.scr"を実行
  6. microSDカードのbootパーティションにある"uImage"を起動
  7. Linuxカーネルが展開されて起動プロセスに入る
  8. Android起動

ここからの過程では上記のMLO, u-boot.bin, boot.scr, uImage、そしてAndroidをビルドしていきます。

ブートローダ(MLO)のビルド
MLOのビルドはソースディレクトリ内のx-loaderディレクトリに移動して行います。

$ cd x-loader
$ make CROSS_COMPILE=arm-eabi- distclean
$ make CROSS_COMPILE=arm-eabi- omapbeagle_config
$ make CROSS_COMPILE=arm-eabi-

できあがったx-load.binからデベロッパーキットに含まれるsignGPを使ってMLOを作ります。

$ ../../TI_Android_GingerBread_2_3_4_DevKit_1_0/Tools/signGP/signGP ./x-load.bin

x-load.bin.iftというファイルが作られるので、これをMLOにリネームして、実行権を付加しておきます。

$ mv x-load.bin.ift MLO
$ chmod 755 MLO

u-boot.binのビルド
u-boot.binはソースディレクトリ以下のu-bootディレクトリで行います。

$ cd u-boot
$ make CROSS_COMPILE=arm-eabi- distclean
$ make CROSS_COMPILE=arm-eabi- omap3_beagle_config
$ make CROSS_COMPILE=arm-eabi-

これでu-boot.binが作られます。
ここでカレントディレクトリにあるtoolsディレクトリ内にmkimageというファイルが作られています。この後の工程で使用しますので"/usr/bin"または"/usr/local/bin"、"~/bin"など、パスの通っているディレクトリにコピーしておいてください。
私の環境では~/binにパスが通ってますのでそこにコピーしておきました。

$ cp tools/mkimage ~/bin/

boot.scrの作成
boot.scrの作成はデベロッパーキットに移動して行います。

$ cd ~/src/beagle-android/GingerBread_2_3_4/TI_Android_GingerBread_2_3_4_DevKit_2_1/Tools/mk-bootscr/
$ ./mkbootscr

これで一旦boot.scrが作られますが、内容をカスタマイズしたいのでboot.scriptというファイルを以下の内容で、同じディレクトリ内に作ります。

mmc init
fatload mmc 1 80200000 uImage
setenv bootargs 'console=ttyO2,115200n8 androidboot.console=ttyO2 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootdelay=1 init=/init ip=dhcp omap_vout.vid1_static_vrfb_alloc=y vram=12M omapfb.vram=0:8M,1:4M,2:4M omapfb.mode=dvi:800x600@60 omapdss.def_disp=dvi'
bootm 0x80200000

そしてこれを元に以下のコマンドでboot.scrを作成します。

$ sudo ./mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "BeagleBoard" -d boot.script boot.scr

Linuxカーネルのビルド
Linuxカーネルコンパイルを行います。Linuxカーネルは上で落としたAndroidソースコードのkernelディレクトリ内にあります。

$ cd kernel
$ export CC=gcc-4.5
$ export CXX=g++-4.5
$ make ARCH=arm CROSS_COMPILE=arm-eabi- distclean
$ make ARCH=arm CROSS_COMPILE=arm-eabi- omap3_beagle_android_defconfig
$ make ARCH=arm CROSS_COMPILE=arm-eabi- uImage

Androidのビルド
つづいてAndroidコンパイルします。
私の環境ではmakeを実行した際にエラーが発生しましたので実際のコンパイルに入る前にMakefileを修正しておきます。

$ vim build/core/combo/HOST_linux-x86.mk

このファイル中の"HOST_GLOBAL_CFLAGS..." から始まる行をコメントアウトします。

HOST_GLOBAL_CFLAGS += -D_FORTIFY_SOURCE=0
  ↑
# HOST_GLOBAL_CFLAGS += -D_FORTIFY_SOURCE=0

それからAndroidコンパイルにはJava6が必要ですが、64bit版Ubuntuのaptで入る64bit版Javaではコンパイル途中でエラーが発生します。

そこで、Sunのホームページから32bit版のJava6を落として、update-alternativesコマンドで32bit版Javaを使うように設定した上でコンパイルを開始します。
Sunのホームページから32bit版Javajdk-6u30-linux-i586.bin)をダウンロードします。
/usr/localにコピーして解凍し、システムがそちらのJavaを使うように設定します。

$ sudo cp jdk-6u30-linux-i586.bin /usr/local/
$ cd /usr/local
$ sudo ./jdk-6u30-linux-i586.bin
$ sudo update-alternatives --install "/usr/bin/java" "java" "/usr/local/jdk1.6.0_30/bin/java" 1
$ sudo update-alternatives --config java

ここで表示された設定画面で/usr/local/jdk1.6.0_30/bin/java の番号を選択する。

alternative java (/usr/bin/java を提供) には 4 個の選択肢があります。

  選択肢    パス                                    優先度  状態
------------------------------------------------------------
 * 0            /usr/lib/jvm/java-6-openjdk/jre/bin/java   1061      自動モード
  1            /usr/lib/jvm/java-1.5.0-sun/jre/bin/java   53        手動モード
  2            /usr/lib/jvm/java-6-openjdk/jre/bin/java   1061      手動モード
  3            /usr/lib/jvm/java-6-sun/jre/bin/java       63        手動モード
  4            /usr/local/jdk1.6.0_30/bin/java            1         手動モード

現在の選択 [*] を保持するには Enter、さもなければ選択肢の番号のキーを押してください:4

設定したら再度上記コマンドを実行して32bit版Javaが選択されていることを確認してください。

ここまでできたら、いよいよAndroidコンパイルします。
ここで-jオプションで並列実行数を指定します。-j5の場合は5つのビルドプロセスが同時に実行されます。
「組み込みAndoid」によると通常は(コア数+1)を指定するとのことなのでMacBookPro 2コア(ハイパースレッディングで4コア)では-j5を指定します。

$ export CC=gcc-4.5
$ export CXX=g++-4.5
$ make TARGET_PRODUCT=beagleboard OMAPES=5.x -j5

MacBookPro 2コア(ハイパースレッディングで4コア)では35分程度で完了しました。

microSDカードへのポーティング
microSDカードへインストールします。
まずはホームディレクトリ以下に”images”ディレクトリを作って必要なものを全てそこに集めます。

$ mkdir ~/images
$ cd ~/images

uImageを持ってきます。

$ cp ~/src/beagle-android/GingerBread_2_3_4/TI_Android_GingerBread_2_3_4Sources/kernel/arch/arm/boot/uImage ~/images/

Androidディレクトリツリーを作って~/images以下にコピーします。

$ cd ~/src/beagle-android/GingerBread_2_3_4/TI_Android_GingerBread_2_3_4Sources/out/target/product/beagleboard/
$ mkdir android_rootfs
$ cp -r root/* android_rootfs/
$ cp -r system android_rootfs/
$ sudo ../../../../build/tools/mktarball.sh ../../../host/linux-x86/bin/fs_get_stats android_rootfs . rootfs rootfs.tar.bz2
$ cp rootfs.tar.bz2 ~/images/

MLOとu-boot.bin、そしてboot.scrをコピーします。

$ cd ~/images
$ cp ~/src/beagle-android/GingerBread_2_3_4/TI_Android_GingerBread_2_3_4Sources/x-loader/MLO ./
$ cp ~/src/beagle-android/GingerBread_2_3_4/TI_Android_GingerBread_2_3_4Sources/u-boot/u-boot.bin ./
$ cp ~/src/beagle-android/GingerBread_2_3_4/TI_Android_GingerBread_2_3_4_DevKit_2_1/Tools/mk-bootscr/boot.scr ./

また、プレビルドパッケージからmkmmc-android.shとMedia_Clipsを持ってきます。

$ cp ~/src/android-prebuild/android-gingerbread/beagleboard-xm/mkmmc-android.sh ./
$ cp -r  ../TI_Android_GingerBread_2_3_DevKit_1_0/Prebuilt_Images/beagleboard-xm/Media_Clips ~/images/

この時点で~/imagesディレクトリ以下には以下のファイルがあることを確認してください。

  • MLO
  • boot.scr
  • rootfs.tar.bz2
  • uImage
  • Media_Clips
  • mkmmc-android.sh
  • u-boot.bin

microSDカードにインストールします。ここで使うmkmmc-android.shは日本語環境では正常に動作しないのでLANG=Cをセットしておきます。
また、コマンド中の/dev/sdcは環境によって異なります。syslogやdfコマンドでデバイスを確認してください。

$ export LANG=C
$ sudo ./mkmmc-android.sh /dev/sdc MLO u-boot.bin uImage boot.scr rootfs.tar.bz2 Media_Clips

ここではmkmmc-android.shを使ってmicroSDカードにファイルを配置しますが、中でやっている事は

  1. microSDカードにboot, rootfs, dataの3つのパーティションを切る。
  2. パーティションをフォーマット
  3. MLO, u-boot.bin boot.scr uImageをbootパーティションに配置
  4. rootfs.tar.bz2をrootfsパーティションに展開
  5. MediaClipsをdataパーティションにコピー

となります。これを手動で行う事ももちろん可能ですが、その場合はbootパーティションフォーマット後のファイルのコピー順が重要となるそうです。最初は必ずMLO、続いてu-boot.binをコピーしないと正常に起動しません。それはbeagleboard-xmがbootパーティションの最初のセクタからMLOを探すかららしいです。
また、後からファイルを更新する時は必ず上書きコピーするように「組み込みAndroid」に書いてありました。一旦削除してから保存し直すとうまく起動出来ないようです。


Android起動

あとはこれをbeagleboard-xmに差して電源を入れますが、起動ログを確認するためにRS232C-USB変換ケーブルでbeagleboard-xmとパソコンをつなぎます。
そしてscreenコマンドを入れて起動ログを見られるようにします。

$ sudo apt-get install screen
$ screen /dev/ttyUSB0 115200

上記を実行すると端末上にbeagleboardのログが流れる準備が整いました(beagleboardを起動するまでは何も表示されません)

あとはbeagleboard-xmを起動します。初回起動時はかなり待たされます(10〜15分)ので、ドキドキしながら気長に待ちましょうw

キタ━━━ヽ(∀゚ )人(゚∀゚)人( ゚∀)ノ━━━!!

「LinuxでHM-TL10Tのタッチパネルを認識させる」に従ってデバイスドライバの修正とカーネルビルドの設定を行ったところ、無事タッチパネルも使用できました。

↑嬉々としてタッチするの図。ただしこのタッチパネルスクリーンは爪の先でタッチしないと反応が悪いですw
起動後暫くは内部でロードを行っているらしく動きがトロいのですが、それが落ちつくとわりとサクサクと操作できます。