android - 書籍トップ 《日経bp社のit関連ストア/...

55
ソースコードから読み解く Androidの実像 2008/12/11 KyotoMicroComputer Co.,Ltd. Kunihiko Tsuji

Upload: nguyenkhanh

Post on 07-Apr-2018

224 views

Category:

Documents


4 download

TRANSCRIPT

ソースコードから読み解くAndroidの実像

2008/12/11

KyotoMicroComputer Co.,Ltd.

Kunihiko Tsuji

はじめに

• 2008年10月22日についにAndroidのソースコードが公開されました

• このソースをざっと見渡した印象についてお話します

• 印象は僕だけでなく、一緒に仕事をしている小林哲之や、また彼と共に活動している日本Androidの会の方の意見も大いに参考にさせていただいてます

京都マイクロコンピュータについて

• 設立 1985年

• CEO 山本彰一

• 所在地 本社 京都市西京区

支店 東京都港区

• 主要製品– ICE「PARTNERシリーズ」

– gccコンパイラ「exeGCCシリーズ」

– 評価ボード「KZシリーズ」

• 設立以来、一貫して組み込み向け開発環境のオリジナル商品の開発、販売を行う

• 従業員数 20人

僕のこと

• 組み込み業界で20年ぐらい仕事をしている42歳のエンジニア(??)です– たまにはソースを書くこともあるので、一応エンジニアという事で・・・・・

• 2003/4から現職(KMC)でデバッガ関連の仕事をしてます– KMCでは主に組み込みLinuxのデバッグ環境の開発に携わりました

• その前は、某A社で組み込みJava実行環境の開発と、そのマネジメントをしていました– 主なビジネスドメインは、携帯電話向けのJava実行環境です– 1997年から組み込みJavaの開発に携わり、当初は携帯電話向けだけでなく、JavaとRTOS(主にITRON)をハイブリッドさせた組み込み向けプラットフォームを開発していました

なぜ僕が、またKMCがAndroidを?

• なぜ僕が?–単純に「Java」「携帯」「Linux」というキーワードで引っかかっただけでしょう(^_^;

• なぜKMCが– Linuxなどハイエンド組み込みに強いツールベンダなので、ツールを使って何か分かるかも??• 自社製ARM11ボードでAndroidを動かす

• シミュレータのAndroidをデバッグする

• デバッガを使って、Androidの動きを見る

本日お話すること

• 全体的な特徴

• Linuxとの関係

• ソースコードとビルドの概要

• QEMUシミュレータ

• まとめ

6

Androidプラットフォームの構造

Linux Kernel

各種ミドルウェア

Java仮想マシン(Dalvik VM)

各種アプリケーション

libcWebkitSQLite

OpenGL EL・・・

ブラウザGoogleMAPメール・・・

携帯電話H/W

Androidプラットフォームの構造

Linux Kernel

各種ミドルウェア

Java仮想マシン(Dalvik VM)

各種アプリケーション

libcWebkitSQLite

OpenGL EL・・・

ブラウザGoogleMAPメール・・・

ARMCode

JavaCode

携帯電話ハードウェア

Androidプラットフォームの構造シミュレータの場合

Linux Kernel

各種ミドルウェア

Java仮想マシン(Dalvik VM)

各種アプリケーション

libcWebkitSQLite

OpenGL EL・・・

ブラウザGoogleMAPメール・・・

QEMUシミュレータ

Windows

x86Code

ARMCode

JavaCode

プラットフォームとしての特徴

• オープンソース– 殆ど全てのソースコードが開示されました

• Linuxカーネルのみを使用– libcやルートファイルシステムは、通常の組み込みLinuxで使われている物と異なる

• アプリケーションレイヤはJavaで開発– ネイティブコードで記述されたミドルウェアと、上位アプリケーションの分離

• QEMUシミュレータの採用– PC上でARM CPUのバイナリ互換を実現

プラットフォームとしての特徴

• レイヤに応じて異なる安全性を確保

– カーネルレイヤ

• 安全性に関する特別な仕掛けはない

– ミドルウェアレイヤ

• プロセスによる空間保護– 他プロセスやカーネル空間へはアクセスできない

–アプリケーションレイヤ

• Java言語による安全性確保

– プロセスの空間保護に加え、仮想マシン採用による安全性確保

LINUXカーネルのみの使用

AndroidのLinux環境

• 本当にカーネルしか使っていない!!

• 通常のLinux的な(UNIXライク)な初期化も無い– init.rcなどのスクリプトでの初期化が少ない

– /initで小さな初期化をしたら、殆どすぐアプリケション実行環境へ

– ネットワーク関係など、簡単な初期化のみ

• ルートファイルシステムも特徴的

• libcなどの標準ライブラリもLinuxでよく使われるglibcやuClibcでなく、BSD( FreeBSD, OpenBSD, NetBSDなど)のlibcを利用

広義のLinux

ツールチェイン(コンパイラなど…)各種ミドルウェア(XやGTKなど)

ルートファイルシステム(各種コマンドなど)libcなどライブラリ群

狭義のLinux

Linuxカーネル

Androidはカーネルのみ利用今までの多くの組み込みLiunux

Androidで使っているLinux

通常ならスクリプト処理するよう内容を、C言語で記述して処理の簡略化

初期化プロセスのソース(抜粋)int main(int argc, char **argv)

{

int device_fd = -1;

int property_set_fd = -1;

int signal_recv_fd = -1;

int s[2];

int fd;

struct sigaction act;

char tmp[PROP_VALUE_MAX];

struct pollfd ufds[4];

char *tmpdev;

act.sa_handler = sigchld_handler;

act.sa_flags = SA_NOCLDSTOP;

act.sa_mask = 0;

act.sa_restorer = NULL;

sigaction(SIGCHLD, &act, 0);

/* clear the umask */

umask(0);

/* Get the basic filesystem setup we need put

* together in the initramdisk on / and then we'll

* let the rc file figure out the rest.

*/

mkdir("/dev", 0755);

mkdir("/proc", 0755);

mkdir("/sys", 0755);

mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");

mkdir("/dev/pts", 0755);

mkdir("/dev/socket", 0755); 15

プロセスID=1(init)のソース

カーネルの初期化が完了して、一番最初に動作するプロセスsystem/core/init/init.c

ユーザー空間のメモリマップAndroidの場合

app_process

Javaアプリケーションやリソースデータなど*.apk,*.jar,*.ttfなど

ネイティブコードの共有ライブラリ

libcやlibwecoreなど*.soファイル

/system/bin/linker

スタック

0x00008000

0x40000000

0xB0000000

0x00000000

0xBEFFFFFF

ファイルマッピング方向

ファイルマッピング方向

実行属性のメモリは存在しない

実行属性のメモリが存在する

ユーザー空間のメモリマップ一般的なLinuxの場合

プロセス本体

ネイティブコードの共有イブラリ

libcなど各種の*.soファイル

ld.so

スタック

0x00008000

0x40000000

0x00000000

0xBEFFFFFF

ファイルマッピング方向

実行属性のメモリが存在する

prelinkの利用

• 共有ライブラリ初期化のprelink技術の活用

– 一般的には実行時に行うライブラリのアドレス解決を、ビルド時に事前に行う事で起動時間の高速化を行える技術

– Androidではメモリ利用の効率化を狙ってる???

build/core/prelink-linux-arm.map より

# 0xC0000000 - 0xFFFFFFFF Kernel

# 0xB0100000 - 0xBFFFFFFF Thread 0 Stack

# 0xB0000000 - 0xB00FFFFF Linker

# 0xA0000000 - 0xBFFFFFFF Prelinked System Libraries

# 0x90000000 - 0x9FFFFFFF Prelinked App Libraries

# 0x80000000 - 0x8FFFFFFF Non-prelinked Libraries

# 0x40000000 - 0x7FFFFFFF mmap'd stuff

# 0x10000000 - 0x3FFFFFFF Thread Stacks

# 0x00000000 - 0x0FFFFFFF .text / .data / heap

初期化までを動的分析

• KMC製ツールを使って、実行結果を分析

– ARM11ボード(KZM-ARM11-01)に移植

– JTAGエミュレータ「PARTNER-Jet」で実行、トレース取得

– トレース解析ツール「QProbe」で分析

QProbeでの分析エミュレータで実行命令の履歴を取得する。約20秒間の実行命令を保持(数十億命令)。

実行アドレス

実行アドレスを以下のように分類し集計

0xC0000000-0xFFFFFFFF KERNEL0xAD000000-0xAD9FFFFF DALVIKVM

その他 USER

Androidが動作するターゲットボード

デバッガ

QProbeで見てみましょう

ざっくり分かった事

• 以外にカーネル実行時間が長い?– 初期画面が出るまでの約70%がカーネル空間を実行している時間

– VM処理が多くなる初期化後半部分でも、50%はカーネル空間の時間

– ファイルシステムやデバイスドライバの処理が多いのか?• ただし、今回のボードはファイルシステムにNFSを使っている事は考慮する必要あり(アイドル時間もカーネルに含まれる)

• ユーザー空間は、ほとんどDalvikVM関連

– というか、それ以外のアドレスは、ほとんど実行されてない

メモリの使われ方

この数字は2007年秋にリリースされたSDKでの計測です!!PARTNER-デバッガのTOPコマンド(Linux対応機能)で調べてみました。

• 初期画面MemTotal: 94648 K, MemUsed 51488 K, MemFree: 43160 K

• ブラウザ起動(www.google.com)MemTotal: 94648 K, MemUsed 57172 K, MemFree: 37476 K

• CELFページへ移動MemTotal: 94648 K, MemUsed 63284 K, MemFree: 31364 K

• MAP起動(アメリカ大陸が表示)MemTotal: 94648 K, MemUsed 66500 K, MemFree: 28148 K

• MAPで東京にスクロール移動して拡大MemTotal: 94648 K, MemUsed 73248 K, MemFree: 21400 K

• MAPで東京をサテライト表示MemTotal: 94648 K, MemUsed 73828 K, MemFree: 20820 K

ソースコードとビルドについて

ソースのある場所

• ここ

– http://source.android.com/

• gitとそのラッパースクリプト(repo)を使用してソースをダウンロードする。

• ブラウザで閲覧するならここ

– http://git.source.android.com/

26

何が含まれている?

• Android SDKを再ビルドに必要なものが全て。

• Linux カーネル、デバイスドライバ、標準Cライブラリ、コンパイラツールチェイン、Dalvik VM、2D/3Dグラフィックライブラリ、コーデック、アプリケーションフレームワーク、webkit(WEBブラウザ)、 ....

• ただし、MAPアプリケーションは含まれていない

• HTC G1のソース? (デフォルトではダウンロードされないがリポジトリに存在する。けっこう頻繁に更新。)– kernel/msm.git

– platform/hardware/msm7k.git

– platform/vender/htc/dream.git

27

全てのソースがあるのか?

• コンパイラツールチェインと一部のライブラリはバイナリで入っている。

– $(TOP)/prebuilt 以下

• それらをリビルドするために必要なソースのありかが明記されている。

–各ディレクトリのREBUILTというファイルに

28

全部で何行?

29

$ find . ! –path ‘*/.git/*’ -type f |xargs cat | wc

22998555 81705021 996249064

$

つまり2300万行

Linuxカーネルが1000万行external(外部ライブラリ、ツール)で800万行残りが500万行。

frameworks 100万行dalvikvm 100万行

ライセンス条件は?

• 基本はApache 2.0

• 多数のオープンソースの成果を利用しているので、それはそれぞれのライセンス条件

• モジュールごとにMODULE_LICENSE_*** とい

うファイルがあり、簡単に確認できるように整備されている

• また、それぞれライセンス表示のためのNOTICEというファイルがおかれている

30

31

$ find . -name "MODULE_LICENSE_*" |sed 's,^.*/,,

' |sort |uniq -c |sort -r

117 MODULE_LICENSE_APACHE2

24 MODULE_LICENSE_BSD_LIKE

11 MODULE_LICENSE_BSD

10 MODULE_LICENSE_GPL

9 MODULE_LICENSE_EPL

7 MODULE_LICENSE_LGPL

4 MODULE_LICENSE_PUBLIC_DOMAIN

4 MODULE_LICENSE_LGPL_AND_GPL

2 MODULE_LICENSE_CPL

1 MODULE_LICENSE_W3C

1 MODULE_LICENSE_OSL1

1 MODULE_LICENSE_MIT

1 MODULE_LICENSE_HP

1 MODULE_LICENSE_AFL_AND_GPL

$ find . -name "MODULE_LICENSE_*“

./system/extras/showmap/MODULE_LICENSE_APACHE2

./system/extras/showslab/MODULE_LICENSE_APACHE2

./system/extras/librank/MODULE_LICENSE_APACHE2

./system/extras/procrank/MODULE_LICENSE_APACHE2

./system/extras/latencytop/MODULE_LICENSE_APACHE2

...

32

$ find . -name "MODULE_LICENSE_*" |grep GPL

./external/iptables/MODULE_LICENSE_GPL

./external/elfcopy/MODULE_LICENSE_GPL

./external/jdiff/MODULE_LICENSE_LGPL

./external/yaffs2/MODULE_LICENSE_GPL

./external/qemu/MODULE_LICENSE_GPL

./external/webkit/WebCore/MODULE_LICENSE_LGPL

./external/dbus/MODULE_LICENSE_AFL_AND_GPL

./external/oprofile/MODULE_LICENSE_GPL

./prebuilt/windows/sdl/MODULE_LICENSE_LGPL

./prebuilt/windows/ccache/MODULE_LICENSE_GPL

./prebuilt/darwin-x86/sdl/MODULE_LICENSE_LGPL

./prebuilt/darwin-x86/toolchain/i686-apple-darwin8-

4.0.1/MODULE_LICENSE_LGPL_AND_GPL

./prebuilt/darwin-x86/toolchain/arm-eabi-4.2.1/MODULE_LICENSE_LGPL_AND_GPL

./prebuilt/darwin-x86/ccache/MODULE_LICENSE_GPL

./prebuilt/darwin-x86/make/MODULE_LICENSE_GPL

./prebuilt/common/jfreechart/MODULE_LICENSE_LGPL

./prebuilt/common/swing-worker/MODULE_LICENSE_LGPL

./prebuilt/common/netbeans-visual/MODULE_LICENSE_GPL

./prebuilt/linux-x86/sdl/MODULE_LICENSE_LGPL

./prebuilt/linux-x86/toolchain/i686-linux-gnu-

3.4.6/MODULE_LICENSE_LGPL_AND_GPL

./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/MODULE_LICENSE_LGPL_AND_GPL

./prebuilt/linux-x86/ccache/MODULE_LICENSE_GPL

ちなみにGPLのものは

ビルドのしかた

• Linux (ubuntu), MacOS(intel)でのビルドがサポートされている– http://source.android.com/download– 他に必要なライブラリ

– sudo apt-get install zlib1g-dev libncruses5-dev unzip

• 手軽な方法– VMWare上にubuntu 8.04 i386をクリーンインストール– 無料のVMWare player利用可能– ビルド時間 40分くらい?

• 困った時はネットで検索• make sdkでSDK一式が再ビルド

33

ビルド環境も無償で構築可能

• 一般的なLinuxディストリビューション– Ubuntu8.10を使いました

• 僕はWindows上の仮想マシン(VMWare)を使ってます

– コンパイラなどツールチェインも付属• ビルド済みが付属するが、ソースコードも入手可能

– 別途JDKをインストールする必要あり• JDKも無償で手に入ります

– シミュレータQEMUもオープンソース• Windowsで動作するシミュレータもMinGW/gccでビルドできるので、こちらも無償環境でビルド可能

一般的なWindows PCが一台持あれば、誰でも直ぐに試せます

他アーキテクチャへの移植性?

• ターゲットCPUは現在はARMのみ。– armv5t (ARM926以降、Xscale)

• パス名に’arm’を含むファイルが多いもの

– bionic

– dalvik

– external/opencore

– external/sonivox

– external/qemu

– external/openssl

• これらの移植に目途がつけば、他のCPUでもいけそう。

35

KMCでのボードへの移植

• Linux2.6.25をボードで動作させる

• Linux2.6.25にAndroid関係の機能を移植する

• あとは、ビルドされたルートファイルシステムをマウントして起動するだけ

• 以外(というより、予想通りですが)あっさり初期画面まで出ました

Linux Kernel

• 2.6.25• Android特有の部分

– binder– ashmem

• ユーザー空間デバイスドライバ?– libhardware

• thumbやEABI、またARM v5対応などコンフィグレーションの設定は必要

37

binder

• プロセス間通信

• OpenBinder.org のものをベースにしていたが今は互換性はない。

• Androidのアプリケーションフレームワークの根幹をなす。

• 上位層は AIDL につながっている。

38

ashmem

• Android / Anonymous SHared MEMory subsystem

• $(TOP)/system/core/cutils/ashmem.h– int ashmem_create_region(const char *name, size_t size) → returns fd

– int ashmem_set_prot_region(int fd, int prot)

– int ashmem_pin_region(int fd, size_t offset, size_t len)

– int ashmem_unpin_region(int fd, size_t offset, size_t len)

• ‘pin’ していないメモリはカーネルが回収して再利用

• Javaの weak reference に似ている概念。キャッシュの実装に便利。

• Javaから利用するときはandroid.os.MemoryFile

39

QEMUシミュレータの利用

QEMU

• オープンソースのシミュレータ

– CPUとH/Wのシミュレーション

– 対応CPU• alpha, arm, cris, i386, m68k, mips, ppc, sh4, sparc

– JIT(Just-In-Time Compilation)による高速化• ターゲットCPU命令をx86命令に変換

– H/Wシミュレータも存在• 一般のPCハードウェア的な物

• USBサポートなどもあり

• コントローラで独立している物も(LAN SMC91C111.cなど)

http://fabrice.bellard.free.fr/qemu/

QEMU ARM CPU対応

• 最新安定版(ver0.90)– ~ARMv5をサポート– VFPサポートあり

• 最新版(20071220のCVSツリー)– ~ARMv7をサポート– neonの実装もあり– thumb2は未調査

• CP15などコプロセッサもサポート– デバッグ用などのCP14関係は不完全でした

• 当然ですがMMUもちゃんとサポートされています

• ARM用GCCで有名なCodeSourcery社のクレジットが各所にあり

AndroidでのQEMU

• 携帯電話を想定した’goldfish’仮想ハードウェア– 画面、キーなどインプットデバイス、テレフォニー、メモリカードなど

– LANなどqemuオリジナルの仮想ハードウェアも利用

• QEMUに独自のプロファイル機能を追加実装

Linux Kernel

QEMU

ARM CPUシミュレータ

goldfishH/Wシミュレータ

qemu/hw/platfom_xxxなどのソースコード

QEMUを利用するメリット

• PC上のシミュレータで、バイナリ互換で開発

–処理速度的にも、今のPCであれば問題なし

– カーネルから下を差し替えるだけで、実H/Wでも動作させる事を実現

• シミュレータならではの解析機能

–シミュレータに手を入れる事で、実CPUには存在しないパフォーマンス解析機能などを利用可能

実ハードウェアへの移植コストが小さい

Linux Kernel

各種ミドルウェア

Java仮想マシン(Dalvik VM)

各種アプリケーション

QEMUシミュレータ

Windows

x86Code

ARMCode

JavaCode

対応したカーネルに変更

実ハードウェアへの移植コストが小さい

Linux Kernel

各種ミドルウェア

Java仮想マシン(Dalvik VM)

各種アプリケーション

ARMCode

JavaCode

携帯電話ハードウェア

対応したカーネルに変更

まとめ

今のAndroid見て感じた事

• 動かすだけだったら、比較的簡単に動きそう– QEMUというシミュレータを上手く使っている– 不必要な物を一切使わず、必要なものだけのシンプルな構成

• Linuxは本当にカーネルだけだったんだ– 今までの組み込みLinuxでも、多くは残っていたUNIX的な匂いが殆どしない– GPL回避だけでなく、より組み込みシステムに適合するソフトウェアプラットフォームという事を考えたのではないか?

• 扱いやすいライセンス

• オープンソースを使い倒す– シミュレータQEMUはじめ、開発環境も全てオープンソースで手に入る

Androidに関する将来の想像

• もしかすると、PCの水平分業モデルが成立するかも– 各レイヤの分離がハッキリしている。– また他のハードウェアの移植コストが小さい

• 実際にオーストラリアのKogan Technologiesが「Kogan」ブランドで製造/販売が2009年1月から始まる予定

• 設立2年の新しい企業でも可能、またOHAにも加入していない

• 上位アプリケーションの開発コミュニティが出来る可能性がある– ミドルウェア含めて、ソフトウェアが流通する可能性もあり

• 採用したオープンソースの質が向上– QEMUふくめ使われたオープンソースがさらに進化する可能性がある

• 応用は携帯電話に限らない

オープンソースである可能性

• やはり進化にたいして有利なのでは?

–マルチコアを意識したJITを搭載するVMなど

–他CPUへの移植

–ツールの進化

– コミュ二ティの成長

• 例えば、今日のお話しもソース開示がないと出来なかった部分がありますね

開発環境へのインパクト

• エンジニアのスキルに応じて、担当分野を選択する事が出来る–正しくC言語が扱えない(メモリが見えない)エンジニアは、Javaでアプリケーションを開発

–エキスパートは、ドライバやカーネルを開発

– ミドルウェアは開発しても良いが、Androidが普及すればミドルウェアが流通する可能性もあり

• シミュレータを用いた効率的な開発環境– QEMUは比較的高速なので、ストレスなく使える

Android SDKから学べる事

• 適材適所や必要性を極める– Linuxをカーネルしか使わないという、潔い選択

• 今までの既存の組み込みLinuxにとらわれず、Linuxの必要な部分だけを採用した

– 組み込みに必要な資源に最適化• カーネルだけの採用、ライブラリやリンカーで再構築。

• 既存のLinuxから削ったのではなく、新規に必要な物を組み合わせた、という感じ

– 過去の互換性にとらわれていない• 既存の携帯電話用のJava(J2ME)を使っていない

– 携帯電話用プラットフォームと言われているが、既存のJ2MEは力不足(目的も違いますが….)と判断したのか、完全に切り捨て

Android SDKから学べる事

• カーネル、ミドルウェア、アプリケーションのレイヤ分離の重要性– 同等機能のカーネルが動作すれば、異なるH/Wでも比較的簡単に動作した

• Javaの活用– 重要な機能の実装は、ミドルウェア化する事で、汎用化と高速化の両方を実現

• シミュレータの活用– オープンソースのシミュレータでも、ここまで使える– シミュレータを改造する事で、独自の解析機能などを追加

• オープンソースの積極採用– Linux, Webkit, SQLite, QEMU ……

Androidとオープンソースでのビジネス

• アプリケーションは流通するだろう– そこはAndroid Marketもあるし

• オープンソースベースのビジネス– お金をかけたからこそ、出来たのではないか?

– オープンソースでGPLが少ないから、このプラットフォームを強化するソフトウェアでビジネスが出来るかもしれないが・・・・

– プラットフォームの成長には、ビジネスとしてお金が動く仕組みも必要かと思うが

– テクノロジをお金に・・・

Thank you

Kyoto Microcomputer Co., Ltd.

http://www.kmckk.co.jp/