組み込みAndroid開発 事始め

組み込みAndroid開発 事始め

手早く始める環境構築 VMware Player+Ubuntu 12.04(LTS)

「この手順を最初から知っていれば、ビルト環境の構築にたいへんな思いをしなくてもよかったのに…」。
そんな後悔を未然に防ぐことができるように書いてみました。

by Dairaku 2014/02/12

組み込みAndroid開発 事始め

携帯電話/スマートフォン向けに提供されていたAndroidを、さまざまな組込み機器のプラットフォームとしても活用しようという動きが、急速に進んでいます。
組み込み機器開発では、ドライバの高速化やカスタムデバイスを追加したり、Androidプラットフォーム自体のカスタマイズが必要となるシーンがたびたびあります。これらを実現するには、当然ながらKernelやAndroidをビルドする必要が出てきます。ビルド環境を構築する方法は、すでにネット上にもいろいろな情報がアップされていますが、開発環境に合わせてパッチを当てたり、英語の文献を読んだりと、始めるまでには何かと手間がかかります。
そこで今回は、なるべく手早くビルド環境を構築するための実践的な手順を、まとめてみました。

組み込みOSとしてのAndroid

最近のモバイル機器や家電製品は年々進化&多機能化しており、タッチパネルやメディアプレーヤー、GPS、無線LAN機能などが搭載されているものが多くなっています。
このような組み込み機器のOSは、2014年1月現在、Linuxが主流です。現在の組み込み機器の多くは、スタンドアロンで使用するものが多く、コスト削減のためにCPU性能やメモリ、消費電力の削減要求が強く、機能自体もコンパクトだからです。このため、多機能で規模の大きいAndroidプラットフォームから機能を削るよりも、コンパクトなLinuxに機能を追加した方が、開発効率がよいという側面があるからです。
しかし近年、多くの人が日常生活でスマートフォン/タブレットを活用するようになり、スマートデバイスを核にしてさまざまな機器と連携させて利用できるサービスが、次々と発表されています。こうした背景から、今後はネットワーク接続やタッチパネルでの操作など、Linuxだけで開発を行うよりも、LinuxをベースとしたAndroidプラットフォームを利用した方が、組み込み機器の開発効率が向上するという局面が、ますます増えてくるのではないでしょうか。
・・・というわけで、カスタムデバイスが追加された組み込み機器を前提とした、Android開発のための環境を、実際に構築していきます。

Androidのアーキテクチャ

まず、Androidプラットフォームを図解化してみます(図1)。簡単に言うとAndroidプラットフォーム用にカスタマイズされたLinuxをベースに、Android仮想マシン(Dalvik VM)上でフレームワークやアプリケーションを動かしています。

組み込み開発とは

上の図のとおり、組み込みボードにカスタムデバイスを追加すると、Kernelドライバが必要となる場合があります。そして、これらをAndroidアプリケーションから利用するためには、以下のように各レイヤーの機能を開発・カスタマイズすることになります。

  • Android(ターゲット)アプリケーション
  • アプリケーションフレームワークのカスタマイズ
  • AndroidプラットフォームがLinux上のデバイス使用するためのHardware Abstraction Layerライブラリ
  • LinuxカーネルがHardwareを使用するためのデバイスドライバ
  • 組み込み機器からLinuxカーネルを呼び出すためのブートローダー

開発環境

これらを開発するにあたって、具体的には以下が必要となります。

  1. アプリケーション開発環境
    Androidターゲットアプリケーションを開発する必要があります。
    アプリケーション開発環境については、Linux、Windows、Mac上での開発が可能です。
    ネット上には、各OSに対してまとまった情報があるので、ここでは割愛します。
  2. Androidプラットフォームビルド環境
    組み込み機器に合わせてカスタマイズする必要がある場合があります。
  3. Linuxカーネルのビルド環境
    ドライバを組み込んだり、固有の機能をカスタマイズする必要があります。
  4. ブートローダー(MLO,u-boot)ビルド開発環境
    組み込み機器のメモリデバイスなどに則してカスタマイズが必要な場合があります。

これらのうち1~3は、組み込みボードメーカーが開発キットとして提供していることが多いので、これが利用できれば手間が省けます。

ここでは、定番のテキサスインスツルメンツ社AM335x評価ボード用に構築してみることにします。
1~3のビルドには、LinuxOS、もしくは、MacOSが必要となります。開発用PCはコンパイルに時間がかかるため、可能であれば専用にPCを調達することをお勧めします。新たに調達するのが難しい場合も多いので、まずは手軽にWindows7上にVMware(R) Playerを使った仮想マシン上で構築します。
採用OSとしては、Ubuntu(64bit版)が推奨されていることもあり、長期サポートされているUbuntu12.04(Long Time Support)を採用します。

構築手順の概要

以下の手順で、開発環境を構築していきます。

1. Windows上への環境構築
1.1. 必要ファイルの入手1.2. VMware(R) Playerのインストール1.3. 仮想マシン(Ubuntu 12.04 LTS 64bit版)の作成
2. Ubuntuの設定
2.1. ネットワーク設定2.2. 日付設定2.3. Ubuntuアップデート2.4. 日本語化
3. 開発ツールのインストール
3.1. JDKインストール 3.2. Androidビルド用Ubuntuパッケージインストール
4. 組み込みボード用Developer Kitのインストール
4.1. DevKitダウンロード 4.2. DevKit展開
5. ビルド
5.1. u-bootビルド5.2. Linuxカーネルビルド5.3. Android関連ファイルをビルド
6. ブートイメージデータの作成
6.1. Android関連ファイルのアーカイブ作成6.2. ブートメディア用データの集約6.3. ブートスクリプトファイルの作成
7. ブートメディアの作成
7.1. 書き込みツールの準備7.2. Ubuntu上のSDカードデバイス名の確認7.3. SDカードへのデータコピー
8. 起動
8.1. SDカードの挿入8.2. 評価用ボードとPCのシリアルケーブル接続8.3. Ubuntuへのターミナルソフトインストール8.4. ターミナルソフト起動8.5. ターミナルソフトへのシリアルポート設定 8.6. シリアル通信の開始 8.7. 評価用ボード起動

構築手順

1. Windows上への環境構築

WindowsOS上にVMware(R) Playerを使って、Ubuntu12.04(64bit)仮想マシン環境を構築します。

1.1. 必要ファイルの入手

以下のサイトからファイルをダウンロードします。
・VMware(R) Player
https://my.vmware.com/jp/web/vmware/downloads
VMware Player and VMware Player Plus for Windows
・Ubuntu12.04(64bit版)
http://www.ubuntu.com/download
Ubuntu Desktop→64bitを選択→Ubuntu12.04 LTSをクリック

1.2. VMware(R) Playerのインストール

ダウンロードしたexeファイルはインストーラーになっていますので、指示に従ってインストールします。

1.3. 仮想マシン(Ubuntu 12.04 LTS 64bit版)の作成

  1. VMware(R) Playerを起動し、「新規マシンの作成」を選びます。
  2. インストーラディスクイメージファイルを選択し、先ほどダウンロードしたUbuntuOSのディスクイメージを選択します。
  3. 簡易インストール用の情報を入力します。(アカウント情報)
  4. 仮想マシン名、データ格納場所を指定します。
  5. ディスク容量を指定します。
    ビルドおよびブートメディア(SDカード等)用に、25GByte程度必要となります。
    一度 設定するとUbuntu内でパーティションを切り直すためにツールをダウンロードしたり、注意深く作業する必要があるなど、何かと手間がかかるので、なるべく大きめに確保しておくことをお勧めします。
  6. メモリ、プロセッサ数をカスタマイズします。
    「ハードウェアをカスタマイズ」ボタンを押して、使用するPCに合わせてプロセッサ数、メモリをカスタマイズします。プロセッサ数はPCのコア数を設定して、不具合があるようでしたら一つ減らすとよいという情報もあります。
    メモリはWMWareと同時に利用するアプリケーションにもよりますが、WindowsOSがスワップを始めると非常に速度が低下するため、物理メモリの半分程度を設定しておくとよいようです。
    完了するとUbuntuのインストールが始まります。インストールが終わるとUbuntuが起動します。
    ※次回起動する時には、VMware Player起動画面より作成した仮想マシンを選択し、「仮想マシンの再生」ボタンを押します。

2. Ubuntuの設定

以下、必要な設定を行います。

2.1. ネットワーク設定

利用環境に合わせて設定を行います。Ubuntuのアップデートが必要になりますので、インターネットに繋がる環境を設定してください。

2.2. 日付設定

デフォルトでは、NTP参照、ロケーションは「Los Angeles」になっています。必要に合わせて変更します。

2.3. Ubuntuアップデート

右上の電源アイコンから「Software Up to Date」を選択し、アップデートマネージャーを起動します。アップデートが完了したら、再起動します。
プロクシーを設定している場合、アップデートに失敗する場合があります。再起動して、コンソールからロックファイルの削除とキャッシュクリーン、アップデートを行います。

> sudo rm /var/lib/apt/lists/lock
> sudo apt-get autoclean
> sudo apt-get clean
> sudo apt-get update

2.4. 日本語化

必要であれば、日本語化を行います。

  1. 「System Settings」→「Language Support」-→「Install/Remove Language」から「Japanese」を選び、インストールします。
  2. 「Language Support」画面で、日本語をいちばん上にドラッグ&ドロップします。

3. 開発ツールのインストール

3.1. JDKインストール

1. OracleJDKダウンロード
 以下のサイトから、Java SE Development Kit6uXXをダウンロードします。
サイト:
http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase6-419409.html#jdk-6u45-oth-JPR

2. JDKの展開と配置
ダウンロードしたファイルを展開・配置します。

> cd (ダウンロードディレクトリ)
> chmod u+x jdk-6u45-linux-x64.bin
> ./jdk-6u45-linux-x64.bin
> sudo mkdir /usr/lib/jvm
> sudo cp -a ./jdk1.6.0_45 /usr/lib/jvm/
> sudo chown -R root:root /usr/lib/jvm/

3. Javaモジュールのパス設定
alternatives に登録します。

> sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_45/bin/java 1
> sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_45/bin/javac 1
> sudo update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/jdk1.6.0_45/bin/javaws 1
> sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/jdk1.6.0_45/bin/jar 1
> sudo update-alternatives --install /usr/bin/javadoc javadoc /usr/lib/jvm/jdk1.6.0_45/bin/javadoc 1
> sudo update-alternatives --install /usr/bin/javap javap /usr/lib/jvm/jdk1.6.0_45/bin/javap 1
> sudo update-alternatives --install /usr/bin/javah javah /usr/lib/jvm/jdk1.6.0_45/bin/javah 1
> sudo update-alternatives --install /usr/bin/jdb jdb /usr/lib/jvm/jdk1.6.0_45/bin/jdb 1

3.2. Androidビルド用Ubuntuパッケージインストール

コンソール画面からapt-getを実行します。

>sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl libc6-dev x11proto-core-dev g++-multilib mingw32 tofrodos python-markdown libxml2-utils python-software-properties xsltproc libx11-dev:i386 gcc-4.5 g++-4.5 gcc-4.5-multilib g++-4.5-multilib zlib1g-dev:i386 libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev lib32ncurses5-dev lib32readline-gplv2-dev lib32z-dev ia32-libs

4. 組み込みボード用Developer Kitのインストール

u-boot,linux kernel,Androidプラットフォームのビルド環境を、テキサスインスツルメンツ社のDeveloperKitを使用して構築します。

4.1. DevKitダウンロード

http://software-dl.ti.com/dsps/dsps_public_sw/sdo_tii/TI_Android_DevKit/TI_Android_ICS_4_0_3_DevKit_3_0_1/index_FDS.html
から、TI Android ICS 4.0.3 DevKitV3.0.1 AM335x Sourcesをダウンロードします。

4.2. DevKit展開

ビルド手順はDevelopersGuideに詳しく記載されています。
しかし、この手順の中には間違っている部分があるので、以下に、成功した手順とコマンドを記載します。

1. HOMEディレクトリに展開します。
ダウンロードしたファイル(TI-Android-ICS-4.0.3_AM335x_3.0.1.bin)をHOMEディレクトリに置き、以下を実施します。

> cd ~
> chmod a+x TI-Android-ICS-4.0.3_AM335x_3.0.1.bin
> ./ TI-Android-ICS-4.0.3_AM335x_3.0.1.bin

ライセンスを読み、最後に 「I ACCEPT」を入力します。

2. ソフトリンクを貼ります。

> ln -s TI-Android-ICS-4.0.3_AM335x_3.0.1 rowboat-android

3. ToolChainを設定します。

> export PATH=$HOME/rowboat-android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH

4. mkimageをインストール

>sudo apt-get install uboot-mkimage

5. ビルド

u-boot,kernel,android関連ファイルをビルドします。

5.1. u-bootビルド

1. u-bootビルドディレクトリに移動します。

> cd ~/rowboat-android/u-boot

2. Configを設定します。

> make CROSS_COMPILE=arm-eabi- distclean
> make CROSS_COMPILE=arm-eabi- am335x_evm_config

3. ビルドします。

> make CROSS_COMPILE=arm-eabi-

5.2. Linuxカーネルビルド

1. Linuxカーネルビルドディレクトリに移動します。

> cd ~/rowboat-android/kernel

2. Configを設定します。

> make ARCH=arm CROSS_COMPILE=arm-eabi- distclean
> make ARCH=arm CROSS_COMPILE=arm-eabi- am335x_evm_android_defconfig

3. ビルドします。

> make ARCH=arm CROSS_COMPILE=arm-eabi- uImage

5.3. Android関連ファイルをビルド

1. ビルドエラー対策の修正

ファイル:rowboat-android/build/core/combo/HOST_linux-x86.mk
56行目を修正

> HOST_GLOBAL_CFLAGS += -D_FORTIFY_SOURCE=0 --- > HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0

ファイル:rowboat-android/external/gtest/include/gtest/internal/gtest-param-util.h
39行目に追加

> #include

ファイル:rowboat-android/external/llvm/llvm-host-build.mk
46行目に追加

< mutable counts_t &amp; counts; --- > counts_t &amp; counts;

ファイル:rowboat-android/frameworks/compile/slang/Android.mk
22行目を修正

< local_cflags_for_slang := -Wno-sign-promo -Wall -Wno-unused-parameter -Werror --- > local_cflags_for_slang := -Wno-sign-promo -Wall -Wno-unused-parameter

2. Androidビルドディレクトリに移動します。

> cd ~/rowboat-android/

3. ビルドします。

> make TARGET_PRODUCT=am335xevm OMAPES=4.x -j 4

6. ブートイメージデータの作成

ブートメディアにコピーするブートイメージデータを生成し、集約します。

6.1. Android関連ファイルのアーカイブ作成

> cd ~/rowboat-android/
> make TARGET_PRODUCT=am335xevm fs_tarball

6.2. ブートメディア用データの集約

起動用メディアに、コピーするファイルを集約します。

> cd ~
> mkdir image_folder
> cp -p rowboat-android/u-boot/u-boot.img image_folder/
> cp -p rowboat-android/u-boot/MLO image_folder/
> cp -p rowboat-android/kernel/arch/arm/boot/uImage image_folder/
> cp -p rowboat-android/out/target/product/am335xevm/rootfs.tar.bz2 image_folder/

6.3. ブートスクリプトファイルの作成

起動用メディアに、コピーするファイルを集約します。
Linuxカーネル起動のための設定を記述したファイルを作成します。
ファイル名:~/image_folder/uEnv.txt

ファイル内容:

bootargs=console=ttyO0,115200n8 androidboot.console=ttyO0 mem=256M root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait init=/init ip=off
bootcmd=mmc rescan ; fatload mmc 0 81000000 uImage ; bootm 81000000
uenvcmd=boot

7. ブートメディアの作成

今回、使用する評価ボードは、SDカードスロットを持つため、ブートメディアとしてはSDカードを使用します。

7.1. 書き込みツールの準備

1. フォーマット用ツールダウンロード

 http://software-dl.ti.com/dsps/dsps_public_sw/sdo_tii/TI_Android_DevKit/TI_Android_ICS_4_0_3_DevKit_3_0_1/index_FDS.html からTI Android Utilitiesをダウンロードします。

2. フォーマット用ツールを展開します。

> cd (ダウンロードディレクトリ)
> gzip -dc TI_Android_Utilities.tar.gz | tar xvf –

3. 展開したツールをMMCカード用データディレクトリにコピーします。

> cp –p TI_Android_Utilities/mk-mmc/mkmmc-android.sh ~/image_folder/
> chmod u+x ~/image_folder/ mkmmc-android.sh

7.2. Ubuntu上のSDカードデバイス名の確認

    1. メディアリーダーなどに、SDカードを挿入します。
      WindowsOS上のExplorerにマウントされる場合は、VMware Playerの「Player」メニュー→「取り外し可能デバイス」からデバイスを選択、「接続(ホストから切断)」をクリックします。
    2. Ubuntu上でディスクユーティリティを起動します。
    3. メディアリーダデバイスを選択します。
    4. 右上にデバイス名が「デバイス:」として表示されます。

    7.3. SDカードへのデータコピー

    集約したデータをコピーします。(下記は、SDカードデバイスとして「/dev/sdb」として認識した例です。)

    > cd ~/image_folder
    > export LANG=C
    > sudo ./mkmmc-android.sh /dev/sdb MLO u-boot.img uImage uEnv.txt rootfs.tar.bz2

    これで、評価ボードを起動することができるSDカードが準備できました。

    8. 起動

    カスタムドライバを追加した場合には、kernelのブートシーケンスを確認する必要があります。このためにシリアルケーブル(RS-232C)でPCと接続し、ターミナルソフトを起動します。

    8.1. SDカードの挿入

    評価用ボードのSDカードスロットにブートイメージをコピーしたSDカードを挿入します。

    8.2. 評価用ボードとPCのシリアルケーブル接続

    最近のPCには、シリアル端子が付いていないことが多いので、シリアルUSB変換ケーブルを利用するとよいでしょう。

    8.3. Ubuntuへのターミナルソフトインストール

    ここでは、簡単にインストール可能なminicomを使用します。

    > sudo apt-get install minicom

    8.4. ターミナルソフト起動

    > export LANG=C
    > sudo minicom –s

    8.5. ターミナルソフトへのシリアルポート設定

    「Serial port setup」を選択し、「A」キーを押し、シリアルポートデバイスを設定します。
    最後に「Enter」キーを押して、「Configuration」画面に戻ります。
    シリアルUSB変換ケーブルを使った場合は、「/dev/ttyUSB0」のようなデバイスとして認識されます。

    8.6. シリアル通信の開始

    「Exit」を選択すると、シリアル通信を開始します。

    8.7. 評価用ボード起動

    評価用ボードの電源ボタンを押します。ターミナル上にブートシーケンスのログが表示されます。

    おわりに

    以上で、組み込み用のAndroidプラットフォームビルド環境が、ようやくできました。
    しかし実際の開発においては、ようやくスタートラインに立ったところです。ここからは—–

    • カスタマイズ機器用のLinuxドライバ開発
    • Linuxデバイスを利用するためのAndroid HAL部分の開発
    • 性能が要求されたり、既存のデバイスとして扱えなければ、ライブラリの追加
    • 常駐サービスとして利用したり、フレームワークレベルでの動きをカスタマイズ場合は、アプリケーションフレームワークの開発・修正
    • そして最後に、Androidアプリケーションの開発

    —–という、長い道のりが待っています。


    組み込みソフトウェアがカバーする領域はどんどん広がり、しかも、製品リリースのサイクルは短縮化する一方。ソフトウェアの品質確保や生産性の向上が、開発現場で大きな課題となる中、今回のような技術情報が、とりわけビルト環境構築の部分で、SE/プログラマーの皆様のお役に立つことができれば幸いです。