Android自社端末作成中


弊社では現在BeagleBoardをベースにしたAndroid端末を作成中です。
形は不恰好ですが、Androidで1台端末をきっちり作る技術の習得を目指しています。

Android 1.5ベースでBeagleBoardサウンドの鳴動まで確認できている資料を公開いたします。

Beagleboardを使用しての端末作成

              株式会社ブリリアントサービス
                   技術部 藤井 洋祐
0.始めに
 現在株式会社ブリリアントサービスは自社端末プロジェクトでAndroid搭載端末を作成中です。
 その際に得たノウハウをここに公開いたします。
 当プロジェクト参加企業および参加者は以下の通りです。


<ハード担当>
 Ex.株式会社 http://www.ex-inc.com/

<ソフト担当>
 株式会社ブリリアントサービス
  代表  杉本 礼彦
  技術部 梶谷 亮太、八木 佑馬、河原 豊、藤井 洋祐

 某IT関連企業勤務
  S氏


★部品構成
メインボードは、Beagleboard Rev.CRev.B5を使用しています。
その他の構成に関しましては以下の通りです。

分類 機能 型番
モジュール 通信モジュール RX420IN
モジュール GPS FGPMMOUDG
モジュール 液晶パネル PD035VX3
モジュール 液晶パネルタイミングコントローラー LT035V2PL0-FDR
モジュール タッチコントローラー ETP-4000UCG-02
モジュール USB カメラ CMS-V23SETSV
モジュール ACアダプタ DC12V 1A NP12-1S1210
モジュール 3軸磁気センサ MicroMag3
モジュール 3軸加速度センサ MMA7455L
IC DVIレシーバー TFP401APZP
IC RS232C ドライバ/レシーバ MAX3233ECWP
IC I2C接続 汎用IO MCP23017-E/SO
IC USB HUB TUSB2046BVF
コネクタ HDMIコネクタ MD60-19P
コネクタ ピンソケット(メス)40P(2×20) (EXPANSION)  
コネクタ ピンソケット(メス)10P(2×5) (RS232C)  
コネクタ ピンソケット(メス)14P(1×14)  (磁気・加速度用)  
コネクタ 基板対基板コネクタ (無線LAN用) DF12 (3.0)-30DP-0.5V(86)
コネクタ 6pinコネクタ (Audio・内部電源用) S6B-XH-A
コネクタ 2pinコネクタ (電池BOX用) S2B-XH-A
コネクタ W-SIM用コネクタ SCZA1A0100
コネクタ FPC31接続コネクタ IL-FRR-31S-HF-NI
コネクタ Φ3.5mm 標準ステレオジャック MJ-352W-C
コネクタ Φ2.1mm標準DCジャック MJ-179P
コネクタ USBレセプタクル (立型:I/F-カメラ・GPS接続用) 47500-0000
コネクタ USBコネクタ ミニAB (Beagle-I/F接続) 56579-0576
コネクタ 4pinコネクタ (電池BOX用) S4B-XH-A
  単4NiH電池 (1100mAh) 110AAAHC
  電池ボックス SBH-441AS
  スピーカー CPE403NT18
  マイク (ECM) WM-61A
  Φ3.5ステレオプラグ (アングルタイプ) WTN03F1100ST
  6pinハウジング XHP-6
  2pinハウジング XHP-2
  4pinハウジング XHP-4
  pinヘッダ (Beagle-I/F間接続用)  
  DCプラグ (Beagle電源供給用) MP-136L

★外観イメージ


★使用環境
 ubuntu8.10


1.準備
 1.1 Android開発環境の設定
  ・Linux環境
  下記リンクを参考にしてください。
  http://source.android.com/download
  http://d.hatena.ne.jp/bs-android/20090324/1237864332
  ※uboot-mkimageのインストールもしておきます。
  ※ubuntu8.10の場合、synapticマネージャーからインストールできます。
  ※ubuntu8.04の場合、apt-get install でインストールしました。

 1.2 使用ツール等の設定
  ・GNU C & C++ Compilersのインストール
   使用するリリースはarm-2007q3-51です。下記リンクからインストールできます。
   http://www.codesourcery.com/sgpp/lite/arm/portal/subscription3057
   ※インストールは、TARの解凍形式、インストーラー使用など、ユーザーの好みにしたがって各種用意されています。
    TARを解凍される場合は、インストール場所のパス設定を各自で行ってください。
    (~/.bashrcファイルに$PATHを記述します)


2.Beaglebord用Androidソースの取得
 2.1 repoの初期化
  まず、ベースとなるAndroidソースDownloadのための下準備を行ないます。
  ターミナルウィンドウにコマンドを入力していきます。

$ mkdir mydroid ★名前は任意です。
$ cd mydoroid
$ repo init -u git://android.git.kernel.org/platform/manifest.git

上記操作で、最新のAndroidソースをmydroidにDownloadする設定を行います。


 2.2 Omap用カーネルの取得準備
  Beagleboard上でAndroidを動かす場合、Androidのレポジトリから不要なサブプロジェクトの削除と標準プロジェクト群に含まれないプロジェクトをダウンロードする必要があります。
  そのための設定ファイルを使用します。
  mydroid/.repo/ に local_manifest.xml を作成します。
  local_manifest.xmlの内容は次の通りにします。

local_manifest.xml

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remove-project name="kernel/common"/>
  <project path="kernel" name="kernel/omap" revision="refs/heads/android-omap-2.6.29"/>
  <project path="external/alsa-lib" name="platform/external/alsa-lib"/>
  <project path="external/alsa-utils" name="platform/external/alsa-utils"/>
  <project path="hardware/alsa_sound" name="platform/hardware/alsa_sound"/>
</manifest>

2.3 ソースの取得
 2.1、2.2の準備が出来れば、Download準備完了です。
 ターミナルウィンドウに以下のコマンドを入力します。

$ repo sync

 上記、コマンド実行後、ソース取得が開始されます。
 稀に失敗する場合がありますが、その場合、再度上記コマンドを実行してください。


3. パッチの準備
 3.1 Linuxカーネル環境構築
  BeagleBoardALSA audio driverを使用しています。
  ALSA on beagleboardAndroidとの結合に関しては、色々問題が報告されていますが、ALSAを使用してサウンドを鳴動させることに成功しました。


 3.2.1 サウンドバイスのBuild定義追加
  Androidプロジェクトにあるomap kernelは、Beagleboardサウンドバイスがビルドできない様になっています。
  その為、古いカーネルから差分を抽出し、パッチを当てました。
  SND_OMAP_SOC_OMAP3_BEAGLEを設定可能なように以下の記述を追加しました。
  ※依存関係に注意してください。弊社では、”config SND_OMAP_SOC_N810“の次に追加しました。

mydroid/kernel/sound/soc/omap/Kconfig
追加部分

config SND_OMAP_SOC_OMAP3_BEAGLE
	tristate "SoC Audio support for OMAP3 Beagle"
	depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_BEAGLE
	select SND_OMAP_SOC_MCBSP
	select SND_SOC_TWL4030
	help
	  Say Y if you want to add support for SoC audio on the Beagleboard.

mydroid/kernel/sound/soc/omap/Makefile
beagleboard関連のコンパイル設定を追加。

# OMAP Machine Support
snd-soc-n810-objs := n810.o
snd-soc-omap3beagle-objs := omap3beagle.o
snd-soc-osk5912-objs := osk5912.o
snd-soc-overo-objs := overo.o
snd-soc-omap2evm-objs := omap2evm.o
snd-soc-sdp3430-objs := sdp3430.o
snd-soc-omap3pandora-objs := omap3pandora.o

obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o
obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o


 3.2.2 カーネルコンフィギュレーションの作成
  弊社で作成したAndroid、ADB、ALSA、FrameBuffer機能有効化を追加したカーネルコンフィギュレーションファイルです。
  omap3_beagle_android_defconfigをmydroid/kernel/arch/arm/configs に保存しておきます。


3.3 Android環境構築
 3.3.1 ALSAサウンドドライバ
  2.2章のlocal_manifest.xmlの設定により、ALSAサウンドライブラリなどの関連ファイルが取得できています。
  これらのライブラリをAndroidで使用可能にする為にコンフィグを追加する必要があります。

mydroid/build/target/board/generic/BoardConfig.mk

# config.mk
#
# Product-specific compile-time definitions.
#

# The generic product target doesn't have any hardware-specific pieces.
TARGET_NO_BOOTLOADER := true
TARGET_NO_KERNEL := true
TARGET_NO_RADIOIMAGE := true
HAVE_HTC_AUDIO_DRIVER := true
BOARD_USES_ALSA_AUDIO := true
BUILD_WITH_ALSA_UTILS := true
#BOARD_USES_GENERIC_AUDIO := true ※コメントアウト

  しかし、このままでは二重定義によりBuildが失敗します。これの原因も取り除きます。

mydroid/external/alsa-utils/android/aconfig.h

#define DATADIR "/system/usr/share/alsa"

#define rindex strrchr
#define open64 open

/*typedef int off64_t;*/ //この定義をコメントアウト

#undef __swab16
#define __swab16(x)  __arch__swab16((x))

#undef __swab32
#define __swab32(x)  __arch__swab32((x))

 3.3.2 Batteryパッチ
  当初、BeagleboardAndroidロゴが表示されるもrebootを繰り返すという現象が発生していました。
  調査の結果、boot時に、バッテリーパワーがゼロで返されるということが判明しました。
  そこで、/sys/class/power_supply以下の情報を無視して、バッテリーがFULLである様にAndroidに通知し、Low batteryによるpower downを防ぐようにしました。
  ※現在Beagleboard用のパワーサプライのデバイスドライバが現在存在していない為、暫定措置として常に電池が満タンの状態を返すようにしていますが、今後改善していく予定です。

mydroid/frameworks/base/services/jni/com_android_server_BatteryService.cpp
BatteryServiceがAC,USB,電池のいずれかであっても、常にtrueを返却するように変更。

static void setBooleanField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
{
    const int SIZE = 16;
    char buf[SIZE];
    
    jboolean value = true; //falseをtrueに変更
/* コメントアウト
    if (readFromFile(path, buf, SIZE) > 0) {
        if (buf[0] == '1') {
            value = true;
        }
    }
*/
    env->SetBooleanField(obj, fieldID, value);
}

Batteryの容量、電圧、温度を100%で返却するように変更。

static void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
{
    const int SIZE = 128;
    char buf[SIZE];
    
    jint value = 100; //0を100に変更
/* コメントアウト
    if (readFromFile(path, buf, SIZE) > 0) {
        value = atoi(buf);
    }
*/
    env->SetIntField(obj, fieldID, value);
}

Battery充電状態をFullで、劣化状態を常に良に設定するように変更。

static void android_server_BatteryService_update(JNIEnv* env, jobject obj)
{
    setBooleanField(env, obj, AC_ONLINE_PATH, gFieldIds.mAcOnline);
    setBooleanField(env, obj, USB_ONLINE_PATH, gFieldIds.mUsbOnline);
    setBooleanField(env, obj, BATTERY_PRESENT_PATH, gFieldIds.mBatteryPresent);
    
    setIntField(env, obj, BATTERY_CAPACITY_PATH, gFieldIds.mBatteryLevel);
    setIntField(env, obj, BATTERY_VOLTAGE_PATH, gFieldIds.mBatteryVoltage);
    setIntField(env, obj, BATTERY_TEMPERATURE_PATH, gFieldIds.mBatteryTemperature);

    env->SetIntField(obj, gFieldIds.mBatteryStatus, gConstants.statusFull); //追加
    env->SetIntField(obj, gFieldIds.mBatteryHealth, gConstants.healthGood); //追加
    env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF("1")); //追加
/* コメントアウト
    const int SIZE = 128;
    char buf[SIZE];
    
    if (readFromFile(BATTERY_STATUS_PATH, buf, SIZE) > 0)
        env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf));
    
    if (readFromFile(BATTERY_HEALTH_PATH, buf, SIZE) > 0)
        env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));

    if (readFromFile(BATTERY_TECHNOLOGY_PATH, buf, SIZE) > 0)
        env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf));
*/
}


4. Build
 4.1 カーネル環境Build
  以下のコマンドを実行してカーネルをビルドします。

 $ cd ~/mydroid/kernel
 $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- distclean
 $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- omap3_beagle_android_defconfig
 $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage
 $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- modules <-ADBを使用しない場合は不要


 4.2 Android環境Build
  以下のコマンドを実行してAndroid環境をビルドします。

$ cd ~/mydroid
$ make


5. Boot用SDカードの作成
 5.1 作成方法
  以下の情報を参考にさせていただきました。
  http://wiki.davincidsp.com/index.php?title=MMC_Boot_Format
  http://d.hatena.ne.jp/naka-3/20090128/1233125851


 5.2 init.rcの変更
  linuxandroidの初期化設定ファイルです。
  Beagleboardを使用するためファイルシステムが変更されます。そのため初期化パラメータの変更を行ないました。
  また、ADB(デバッガ)モジュール*1のロード設定、ALSAドライバの権限変更を追加しました。
  ※SDカードext3パーティション上のrootにおいてください。
  ※ADBモジュールのロード設定は以下になります。不要の場合はコメントアウトしてください。

init.rc

### Load some modules using ADB kernel module
    insmod /system/lib/modules/switch_class.ko
    insmod /system/lib/modules/switch_gpio.ko
    insmod /system/lib/modules/g_android.ko

6. ADB(デバッガ)
 ADBにてデバッグを行なうためにパッチ、変更をいくつか実施しています。
 こちらも合わせて記載させていただきます。ADBが不要であれば、読み飛ばしてください。


 6.1 カーネルモジュールのインストール
  ADB(デバッガ)を使用する場合、makeによって
  mydroid/kernel 以下に生成された*.koファイルを、
  SDカードのext3パーティション上に作成した
  /system/lib/modules 以下にコピーします。
  ※カレントディレクトリをmydroid/kernel とし以下のコマンドを入力すれば見つかります。

$ find -name "*.ko" -type f


 6.2 init.rcの変更
  5.2章にあるADB(デバッガ)モジュールのロード設定を有効にし、SDカードext3パーティションのrootディレクトリにコピーします。


 6.3 PC側のUSB設定
  HOST PC側でBeagleboardのADBを認識させる必要があります。
  そのUSB設定ファイルです。

50-android.rules

SUBSYSTEM=="usb",SYSFS{idVendor}=="18d1",MODE="0666"
SUBSYSTEM=="usb_device", SYSFS{idVendor}=="18d1",MODE="0666"

  このファイルをPC側の /etc/udev/rules.d にコピーします。その後、以下のコマンドにてchmodしてください。

$ sudo chmod a+rx /etc/udev/rules.d/50-android.rules

7. おまけ
VGA表示させたときの写真です。(さりげなく基板のロゴをアピール)

ケースに入った写真


LCD表示

作者プロフィール
 藤井 洋祐(ふじい ようすけ)
 京都市生まれ。
将来の夢 :世界平和
好きな言葉:学問に王道なし。日々が大切である(小学校の恩師の言葉)

略歴
 ジ○リ○ナ東京でお立ち台の全盛時、東京に憧れるも、大阪のソフトハウス入社。
メーカー系ソフトウェア子会社で金融系端末(現金自動支払機)の制御プログラム開発に従事。
そこで、お金を扱う仕事柄からお金の大切さを学ぶ。
上場派遣会社に転職後、上司の「1年間、我慢して」の一言から、携帯メーカーにて作業開始。
そこで杉本 礼彦氏(現、ブリリアントサービス代表)と運命的な出会いを果たすことになる。
彼の生き様に心酔し、良くも悪くも現在に至る。

今回Ex.さんにハードを作成していただいていますが、弊社側がビーグルボード+W-SIMにこだわった為に、大きく不恰好な端末になってしまっています。
2号機は今回のノウハウを活かして、スマートな端末にする予定です。

この端末に興味のある方は
bs_handset@brilliantservice.co.jp(@を半角にしてください。)
にメールをください。

*1:6章を参照してください。