Android* 開発者向けラーニングシリーズ 6: Android* OS でのデバッグ

同カテゴリーの次の記事

Android* 開発者向けラーニングシリーズ 7: NDK ベースのインテル® アーキテクチャー向け Android* アプリケーションの開発および移植

この記事は、インテル® デベロッパー・ゾーンに掲載されている「Intel for Android* Developers Learning Series #6: Debugging on Android* OS」の日本語参考訳です。


Android* OS 向けアプリケーションまたは Android* システム・ソフトウェア・スタックのランタイム問題や問題が発生する可能性のあるコードを特定する課題とアプローチは、プラットフォーム・アーキテクチャーがインテル® アーキテクチャーや最新世代のインテル® Atom™ プロセッサーをベースにしている場合でも、ARM* アーキテクチャーをベースにしている場合でも、ほぼ同じです。この記事では、インテル® アーキテクチャー上で Android* 向けソフトウェアのデバッグに利用可能なデバッグ手法を紹介します。また、Android* とインテル® アーキテクチャーを対象とするアプリケーションおよびシステム・ソフトウェア・デバッグ環境のセットアップと構成についても説明します。その過程で、ARM* アーキテクチャー上で開発する場合との相違点も示します。

1. 必要条件

ここでは、Android* OS で動作するインテル® Atom™ プロセッサー・ベースのデバイス上でリモート・アプリケーション・デバッグを行うのに必要なインテル® USB ドライバーについて説明します。

また、Android* 向けインテル® Atom™ x86 System Image エミュレーターについても説明します。物理的なデバッグターゲットが利用できない場合、Android* SDK のデバイス・エミュレーション・レイヤーの内部で仮想のインテル® Atom™ プロセッサー・ベースのデバイスをエミュレーションできます。

この 2 つと Android* SDK により、インテル® Atom™ プロセッサー・ベースのタブレットやスマートフォンのクロス開発用の環境を構築することができます。    

1.1. Android* デバイス用インテル® USB ドライバー

まず、開発ホストとインテル® Atom™ プロセッサーを搭載した Android* デバイスを接続する、インテル® Android* USB ドライバーパッケージから説明します。最初の例は、開発ホストが Windows* であることを想定しています。開発ホストが Linux* や OS X* でも基本的な手順は同じです。

  • http://www.intel.com/software/android (英語) の [Tools & downloads] タブからインストーラー・パッケージ 「Intel® USB Driver for Android* Devices」をダウンロードします。

  • ダウンロード後、インストーラーを実行します。Windows* のユーザーアカウント制御 (UAC) ダイアログが表示された場合は、続行を許可してください。

  • 次の画面が表示されます (図 1)。[Next (次へ)] をクリックして続行します。 (インストーラーがドライバーの以前のバージョンを検出した場合は、以前のバージョンをアンインストールしてください。)

図 1: USB デバイスドライバーのインストール開始画面

  • インテル® Android* USB ドライバーのエンド・ユーザー・ライセンス契約書 (EULA) が表示されます。ドライバーをインストールするには、EULA に同意する必要があります。
  • コンポーネントを選択する画面が表示されたら、[Next (次へ)] をクリックして続行します。
  • インストール先を選択して、[Install (インストール)] をクリックします。
  • Android* USB ドライバーのインストールが始まります (図2 )。

図 2: USB デバイスドライバーのインストール進捗画面

1. ドライバーのインストールが完了したら、ポップアップ画面で [OK] をクリックし、[Finish (完了)] をクリックしてインストール・プログラムを終了します。

1.2. Android* 向けインテル® Atom™ x86 System Image エミュレーターのインストール

Android* Virtual Device Manager を使用して開発ホストでデバッグする場合、最初の必要条件として適切なシステムイメージが必要です。

Android* x86 Emulator System Image アドオンを使用するには、Android* SDK がインストールされている必要があります。Android* SDK のインストール方法については、Android* 開発者 Web サイト (http://developer.android.com/sdk/installing.html) (英語) を参照してください。Android* SDK Manager から、Android* x86 Emulator System Image アドオンをダウンロードしてインストールできます。

次の操作を行います。

1. Android* SDK Manager を起動します。

2. [Packages (パッケージ)] – [Android 4.x.x (API 1x)] で、[Intel Atom x86 System Image by Intel Corporation] のチェックボックスをオンにします。

3. [Install Package (パッケージのインストール)] ボタンをクリックします (図 3)。

(注: ユーザーまたは Android* SDK Manager が選択したパッケージに応じて、複数のパッケージがインストールされる場合があります。)

図 3: Android* SDK Manager – x86 System Image の選択

1. インテル コーポレーションの使用許諾契約書を確認します。同意するには、[Accept (承諾)] を選択して [Install(インストール)] ボタンをクリックします (図 4)。

図 4: Android* SDK Manager – 使用許諾契約書

1. Android* SDK Manager によりアドオンがダウンロードされて、Android* SDK の add-ons フォルダー (<sdk>/add-ons/) にインストールされます。ダウンロードとインストールにかかる時間は接続速度などの環境によって異なります。

2. [Tools (ツール)] メニューから [Manage AVDs (AVD の管理)] を選択します (図 5)。

図 5: Android* SDK Manager – Android* 仮想デバイスの管理

1. Android*Virtual Device Manager ウィンドウが表示されます。[New (新規)] をクリックします (図 6)。

図 6: 新しい Android* 仮想デバイスの追加

1. [Name (名前)] フィールドに仮想デバイスの名前を入力します。注: 名前にスペースは使用できません。

2. [Target (ターゲット)] フィールドのドロップダウン・リストから [Intel Atomx86 System Image (Intel Corporation) – API Level 10] を選択します (図 7)。

図 7: インテル® Atom™ x86 System Image をターゲット仮想デバイスとして選択

1. [Create AVD (AVD の作成)] ボタンをクリックします。

2. 新しい仮想デバイスが Android* Virtual Device Manager に表示されます。新しいデバイスを選択して [Start (開始)] ボタンをクリックします (図 8)。

図 8: Android* 仮想デバイスの起動

1. [Launch Options (起動オプション)] ウィンドウが表示されます。システムの画面サイズと dpi を選択します。設定しない場合、エミュレーターが画面内に収まらないことがあります。[Launch (起動)] ボタンをクリックします (図 9)。

図 9: 仮想デバイスの起動オプション

1. しばらくするとエミュレーターが起動し、図 10 の画面が表示されます。

図 10: インテル® アーキテクチャー・ベースの Android* デバイスの AVD* エミュレーション

1.3.  Android* Debug Bridge を使用したアプリケーションのデバッグ

Android* Debug Bridge (ADB) は、ホスト上のデバッガー (通常は GDB または DDMS (Dalvik Debug Monitor Server) および ADT) とターゲットを実行している Android* イメージ間のデバッグ通信を制御するコマンドラインのツールです。ターゲットイメージはデバイス・エミュレーションまたは物理的な開発デバイス上で動作します。通信は USB-OTG (On-The-Go) または USB-イーサーネット・ドングル経由で行います。つまり、ADB は Android* 上でアプリケーションのデバッグを可能にするツールです。

さまざまなフォームファクターのデバイスを接続またはエミュレートすることが可能です。通常はスマートフォンまたはタブレットが対象ですが、医療用タブレットや組込みデバイス、家庭用エネルギー管理システム、入庫管理システム、その他のインテリジェント・システム・アプリケーションを対象にすることもできます。

Android* Debug Bridge をセットアップしてインテル® Atom™ プロセッサー・ベースのプラットフォームをリモートデバッグすることは、ほかのアーキテクチャーをデバッグすることとほとんど違いはありません。

1.4. ADB のセットアップ

最初に、ADB を含む Android* SDK を開発ホストにインストールする必要があります。インストール方法は、http://developer.android.com/sdk/installing.html (英語) を参照してください。

ターゲットイメージが物理デバイス上で動作している場合、最初に USB-OTG または USB-イーサネットのサポートを追加します。USB-イーサネットをサポートするには、カーネル構成の変更とリビルドが必要です。必要に応じて、OEM から情報を入手してください。

リモート・アプリケーション・デバッグの標準的な手法は、Android* デバイスの既存の USB-OTG インターフェイスを使用することです。セットアップの詳細は、Android* 開発者 Web サイト (http://developer.android.com/guide/developing/device.html) (英語) を参照してください。

主要なステップを以下に示します。

1. Android* のマニフェストでアプリケーションを「デバッグ可能」として宣言します。

2. デバイスの「USB デバッグ」を有効にします。

3. デバイスで、[Settings (設定)] – [Applications (アプリケーション)] – [Development (開発)] を選択し、[USB debugging (USB デバッグ)] を有効にします (Android* 4.x.x デバイスの場合は、[Settings (設定)] – [Developer options (デベロッパー・オプション)] で設定します)。

4. システムをセットアップしてデバイスを検出します。

  • Windows* 上で開発している場合、ADB 用の USB ドライバーをインストールする必要があります (必要条件を参照)。
  • Ubuntu* Linux 上で開発している場合、開発に使用する各デバイスの USB 構成が記述された udevルールファイルを追加する必要があります。各デバイスメーカー固有のベンダー ID を、ルールファイルの ATTR{idVendor} プロパティーに指定します。ベンダー ID のリストは、http://developer.android.com/tools/device.html#VendorIds (英語) を参照してください。
  • Ubuntu* Linux 上でデバイス検出をセットアップするには、root としてログインしてルールファイルを作成します。
    /etc/udev/rules.d/51-android.rules
  • 以下の形式でベンダーをファイルに追加します。
    SUBSYSTEM==”usb”, ATTR{idVendor}==”????”, MODE=”0666″, GROUP=”plugdev”
  • MODE で読み取り/書き込み権限を指定し、GROUP でデバイスノードを所有するグループを定義します。
  • 次のコマンドを実行します。
    chmod a+r /etc/udev/rules.d/51-android.rules
  • USB 経由で接続した場合、SDK の platform-tools/ ディレクトリーから ADB デバイスを実行して、デバイスが接続されているかどうかを確認できます。デバイスが接続されていると、デバイス名がリストされます。

CDK でブートされた Android* OS の場合、USB-OTG ケーブルを CDK のポート (USB ミニ B) と開発ホストのポート (USB A) に接続します。

次のコマンドを実行すると接続されているデバイスが表示されます。

$ adb devices

* daemon not running.starting it now *

* daemon started successfully *

List of devices attached

0123456789ABCDEF     device

注: Linux* 開発ホストの接続に割り当てられたデバイス名を確認するには、dmesg コマンドで “usb-storage: device found at <num>” メッセージの番号を調べた後、”ls -l /dev/bus/usb/*” コマンドで番号を調べます。

1.5. Windows* 上の ADB

http://www.eclipse.org/downloads/ (英語) から Eclipse* Classic をダウンロードしてインストールします。

http://developer.android.com/sdk/index.html (英語) から Windows* 用の Android* SDK パッケージ (android-sdk_r18-windows.zip または installer_r18-windows.exe) をダウンロードします。

Android* SDK をインストールすると、adb.exe が <install-dir>android-sdk\platform-tools にインストールされます。

1.6. ADB ホストとクライアントの通信

ここまで、開発ホストへの ADB のインストールについて説明しました。ADB は 3 つのコンポーネントを含むクライアント/サーバー・プログラムです。

  • クライアントは、開発マシンで実行します。ADB コマンドを使用してシェルからクライアントを起動することができます。ADT プラグインや DDMS* のようなほかの Android* ツールも、ADB クライアントを作成します。
  • 開発マシンのバックグラウンド・プロセスとして実行されるサーバーは、クライアントと (エミュレーターまたはデバイス上で実行する) ADB デーモン間の通信を管理します。
  • デーモンは、各エミュレーターまたはデバイスのインスタンスのバックグラウンド・プロセスとして実行されます。

ADB クライアントを開始すると、クライアントはまず ADB サーバープロセスがすでに起動されているかどうかを確認します。起動していない場合、サーバープロセスを開始します。サーバーが開始すると、ローカルの TCP ポート 5037 をバインドして、ADB クライアントから送られるコマンドを監視します (すべての ADB クライアントはポート 5037 で ADB サーバーと通信します)。

次に、サーバーは実行中のすべてのエミュレーター/デバイスのインスタンスとの接続をセットアップします。サーバーは、5555 から 5585 の偶数番号のポート、およびエミュレーター/デバイスで使用されるポートをスキャンして、エミュレーター/デバイスのインスタンスを調べます。ADB デーモンが見つかると、そのポートへの接続をセットアップします。各エミュレーター/デバイスのインスタンスは連続するポートのペア (コンソール接続用の偶数番号のポートと ADB 接続用の奇数番号のポート) を利用することに注意してください。次に例を示します。

 エミュレーター 1、コンソール: 5554

 エミュレーター 1、adb: 5555

 エミュレーター 2、コンソール: 5556

 エミュレーター 2、adb: 5557 …

ポート 5555 の ADB に接続されているエミュレーターのインスタンスは、コンソールがポート 5554 で監視するインスタンスと同じです。

すべてのエミュレーターのインスタンスへの接続がセットアップできれば、ADB コマンドを使用してインスタンスを制御およびアクセスできます。サーバーはエミュレーター/デバイスのインスタンスへの接続を管理して複数の ADB クライアントからのコマンドを処理するため、任意のクライアントから (またはスクリプトから) 任意のエミュレーター/デバイスのインスタンスを制御することができます。

1.7. ADB の起動

“adb shell” と入力します。接続に成功すると # プロンプトが表示されます。

$ adb shell

1.8. 主な ADB デバイスのコマンド

以下のコマンドは、コマンドラインからターゲットデバイスまたはエミュレーションにデバッグ対象のアプリケーションを転送するのに役立ちます。特に、ssh ターミナル接続が利用できないときに便利です。

  adb push <ローカル> <リモート>    – ファイル/ディレクトリーをデバイスにコピーします

  adb pull <リモート> [<ローカル>]  – デバイスからファイル/ディレクトリーをコピーします

  adb sync [ <ディレクトリー> ]     – 変更された場合のみホストからデバイスにコピーします

                                 (-l はリストのみでコピーしません)

                                 (詳細は ‘adb help all’ を参照)

  adb shell                    – リモートシェルをインタラクティブに実行します

  adb shell <コマンド>          – リモートシェルのコマンドを実行します

  adb emu <コマンド>            – エミュレーター・コンソールのコマンドを実行します

  adb logcat [ <フィルター> ] – デバイスのログを表示します

  adb forward <ローカル> <リモート> – ソケット接続をフォワードします

                                 次のいずれかを指定します。

                                   tcp:<ポート>

                                   localabstract:<unix ドメインソケット名>

                                   localreserved:<unix ドメインソケット名>

localfilesystem:<unix ドメインソケット名>

                                   dev:<デバイス名>

                                   jdwp:<プロセス pid> (リモートのみ)

  adb jdwp                     – JDWP トランスポートをホストするプロセスの pid を表示します

  adb install [-l] [-r] [-s] <ファイル> – パッケージファイルをデバイスにプッシュしてインストールします

                                 (‘-l’ はアプリケーションをフォワードロックします)

                                 (‘-r’ はアプリケーションを再インストールしてデータを保持します)

                                 (‘-s’ は内部ストレージの代わりに SD カードにインストールします)

  adb uninstall [-k] <パッケージ> – パッケージをデバイスから削除します

                                 (‘-k’ はデータとキャッシュのディレクトリーを保持します)

ADB のセットアップと使用法の詳細は、http://developer.android.com/guide/developing/tools/adb.html (英語) を参照してください。

1.9. Eclipse* 用 Android* Debug Tools プラグインの使用

インテル® アーキテクチャー・ベースのデバイスのセットアップ・プロセスは、http://developer.android.com/sdk/eclipse-adt.html#installing (英語) に記述されている内容とほとんど変わりません。

Android* Debug Tools (ADT) プラグインを使用すると、Eclipse* IDE からインテル® アーキテクチャー・ベースのエミュレーターとターゲットデバイス用のアプリケーションをデバッグできます。異なる機能セットによる 2 つの異なるデバッグ・パースペクティブを提供します。

必要に応じて機能セットを切り替えることができます。これらの機能セットは、アプリケーションのデバッグ時にそれぞれ異なるメリットがあります。

1.10. Eclipse* の Debug (デバッグ) パースペクティブ

Eclipse* の Debug (デバッグ) パースペクティブでは、以下のタブにアクセスできます。

  • Debug (デバッグ) – 以前および現在デバッグしている Android* アプリケーションと現在実行しているスレッドを表示します。
  • Variables (変数) – ブレークポイントがセットされると、コード実行中の変数値を表示します。
  • Breakpoints (ブレークポイント) – アプリケーション・コードにセットされているブレークポイントのリストを表示します。
  • LogCat – システムのログメッセージをリアルタイムに表示します。LogCat タブは DDMS パースペクティブでも利用できます。

Debug (デバッグ) パースペクティブにアクセスするには、[Window (ウィンドウ)] – [Open Perspective (パースペクティブを開く)] – [Debug (デバッグ)] をクリックします。詳細は、Eclipse* デバッガーのドキュメントを参照してください。

1.11. DDMS (Dalvik Debug Monitor Server) パースペクティブ

Eclipse* の DDMS パースペクティブでは、Eclipse* IDE から DDMS のすべての機能にアクセスできます。以下の DDMS セクションが利用できます。

Devices (デバイス)           – ADB に接続されているデバイスおよび AVD のリストを表示します。

Emulator Control (エミュレーター制御)  – デバイスの機能を実行します。

LogCat            – システムのログメッセージをリアルタイムに表示します。

Threads (スレッド)           – VM 内で現在実行しているスレッドを表示します。

Heap (ヒープ)              – VM のヒープ使用状況を表示します。

Allocation Tracker (アロケーション・トラッカー) – オブジェクトのメモリー割り当てを表示します。

File Explorer (ファイル・エクスプローラー)     – デバイスのファイルシステムの内容を表示します。

1.12. デバッグのアプリケーション・ランタイム環境

インテル® アーキテクチャー・ベースのデバイスをターゲットとする Android* アプリケーションのデバッグで異なるのは、デバッグするターゲットデバイスの指定方法です。

Android* SDK の一部である Android* Virtual Device Manager を使用してターゲットデバイスを選択し、Eclipse* IDE のプルダウンメニューで [Window (ウィンドウ)] > [AVD Manager (AVD マネージャー)] を選択します。OS イメージおよびデバイス・エミュレーションの EABI ターゲットとして “Intel Atom (x86)” を選択していることを確認します (図 11)。

図 11: Android* Virtual Device Manager でインテル® Atom™ プロセッサー・ベースのデバイスを選択する

ADB のセットアップの手順に従って物理デバイスへのデバッグブリッジを確立している場合、Eclipse* IDE でアプリケーション配置およびデバッグのターゲットとしてデバイスを選択できます。

ほかの点では、インテル® アーキテクチャーをターゲットとする Android* アプリケーションのデバッグは、ARM* アーキテクチャーをターゲットとする場合と違いはありません。

2. インテル® Hardware Accelerated Execution Manager

インテル® Hardware Accelerated Execution Manager (インテル® HAXM) はインテル® バーチャライゼーション・テクノロジー (インテル® VT) を使用するハードウェア支援による仮想エンジン (ハイパーバイザー) で、ホストマシン上で Android* アプリケーションのエミュレーションを高速化します。インテルから提供されている Android* x86 エミュレーター・イメージと公式の Android* SDK Manager の組み合わせにおいて、インテル® HAXM はインテル® VT 対応システム上でより高速に Android* のエミュレーションを行います。

x86 用の Android* 4.0.4 (Ice Cream Sandwich) エミュレーターのシステムイメージを使用して、開発マシンで Android* をエミュレーションすることができます。Android* SDK とともに使用することで、インテル® アーキテクチャーとインテル® VT の利点を活用しながら、インテル® アーキテクチャー・ベースの仮想 Android* デバイス上で Android* アプリケーションのテストが可能です。

エミュレーターのシステムイメージをインストールするには、Android* SDK Manager を使用します。

インテル® HAXM は、Android* SDK Manager からインストールできます (図 12)。インテル® HAXM を使用するには、Android* SDK (バージョン 17 以降) がインストールされていなければなりません。詳細は、Android* 開発者 Web サイト (http://developer.android.com/sdk/) (英語) を参照してください。

図 12: インテル® Hardware Accelerated Execution Manager のダウンロード

インテル® HAXM は、Linux*、Windows*、および iOS* ホストで利用できます。下記の Ubuntu* 64 ビット OS へのインストールで説明しているように、これらのホストは Google* が Android* ビルド用のプラットフォームとして検証しサポートしています。

以下に、Ubuntu* ホスト・プラットフォームに KVM をインストールして設定し、インテルのハードウェア支援による仮想化機能 (ハイパーバイザー) を使用して Android* x86 エミュレーターを開始する方法を説明します。インテル® HAXM を利用した AVD は、ハイパーバイザーを使用しない場合よりも高速かつスムーズに動作します。

2.1. KVM のインストール

1. プロセッサーがハードウェア仮想化をサポートしているかどうかを確認するには、次のコマンドを実行します。

$ egrep -c ‘(vmx|svm)’ /proc/cpuinfo

0 が出力された場合、CPU はハードウェア仮想化をサポートしていません。

2. 次に CPU チェッカーをインストールします。

$ sudo apt-get install cpu-checker

3. CPU が KVM をサポートしているかどうかを確認できます。

$kvm-ok

a. 次のメッセージが表示された場合:

“INFO: Your CPU supports KVM extensions
INFO: /dev/kvm exists
KVM acceleration can be used”

KVM エクステンションを使用して仮想マシンを高速に実行できます。

b. 次のメッセージが表示された場合:

“INFO: KVM is disabled by your BIOS
HINT: Enter your BIOS setup and enable Virtualization Technology (VT),
and then hard poweroff/poweron your system
KVM acceleration can NOT be used”

システムの BIOS セットアップでインテル® VT を有効にする必要があります。

2.2. 64 ビット・カーネルの使用

ホスト・オペレーティング・システムで 64 ビット・カーネルを実行することを推奨しますが、必須ではありません。VM で 2GB を超える RAM を利用するには、64 ビット・カーネルを使用する必要があります。32 ビット・カーネルでは、VM で利用可能な RAM が 2GB に制限されます。64 ビット・システムは、32 ビットと 64 ビット両方のゲストをホストできます。32 ビット・システムは、32 ビットのゲストのみホストできます。

1. プロセッサーが 64 ビットかどうかを確認するには、次のコマンドを実行します。

$ egrep -c ‘ lm ‘ /proc/cpuinfo

0 が出力された場合、CPU は 64 ビットではありません。1 以上の場合、CPU は 64 ビットです。注: lm は Long Mode (ロングモード)、つまり 64 ビット CPU を表します。

2. 実行中のカーネルが 64 ビットかどうかを確認するには、次のコマンドを実行します。

$ uname -m

x86_64 が出力された場合、実行中のカーネルは 64 ビットです。i386、i486、i586、i686 のいずれかが出力された場合、実行中のカーネルは 32 ビットです。

2.3. KVM のインストール

KVM をインストールするには、次の操作を行います。

1. Ubuntu* 10.04 以降の場合:

$ sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils

“No configuration” を選択すると、図 13 の Postfix Configuration を無視できます。

図 13: KVM の Postfix Configuration 設定のインストール

1. 次に、<ユーザー名> アカウントを kvm および libvirtd グループに追加します。

$ sudo adduser your_user_name kvm
$ sudo adduser your_user_name libvirtd

インストール後に再度ログインして、追加したアカウントを kvm および libvirtd ユーザーグループのアクティブなメンバーにする必要があります。このグループのメンバーは仮想マシンを実行できます。

2. 次のコマンドを使用して、インストールが成功したかどうかを確認することができます。

$ sudo virsh -c qemu:///system list

2.4. Android* Virtual Device の開始

インテル® アーキテクチャー (x86) 用の Android* エミュレーター (図 14) は、次のコマンドで開始します。

$ <SDK ディレクトリー>/tools/emulator-x86 -avd Your_AVD_Name -qemu -m 2047 -enable-kvm

Your_AVD_Name にはデバイス名、‘-qemu’ には qemu のオプション、‘-m’ にはエミュレートする Android* (つまり、ゲスト) のメモリーサイズを指定します。メモリーサイズが小さすぎると、頻繁にメモリースワップが発生するためパフォーマンスが低下します。

図 14: インテル® アーキテクチャー・エミュレーション・レイヤーで Android* を実行

2.5. Eclipse* の AVD Manager を使用した仮想デバイスの起動

Eclipse* IDE から AVD を使用してアプリケーションのデバッグを開始するには、Google* が推奨する次の操作を行います。

1. Eclipse* で Android* プロジェクト・フォルダーをクリックして、[Run (実行)] – [Run Configurations (実行構成)] を選択します。

2. [Run Configurations (実行構成)] ダイアログの左パネルで、Android* プロジェクトの実行構成を選択するか、新しい構成を作成します。

3. [Target (ターゲット)] タブをクリックします。

4. 作成したインテル® アーキテクチャー・ベースの AVD を選択します。

5. [Additional Emulator Command Line Options (追加のエミュレーター・コマンドライン・オプション)] フィールドに、次のオプションを入力します。

-qemu -m 2047 -enable-kvm

6. この実行構成を使用して Android* プロジェクトを実行します。

2.6. Oracle* VirtualBox 内での Android* の実行

Android* のネイティブコードの開発とデバッグを行う開発者は、Windows* ホストシステムの KVM と QEMU の代わりに、Oracle* VirtualBox 仮想マシン内部のデスクトップ PC 上で Android* OS イメージを実行することを推奨します。

このセクションでは、以下の項目について説明します。

  • (Android* 4.0.1 ソースツリーに含まれている) Google* x86 VirtualBox ターゲット vbox-x86-eng から x86 用の Android* 4.0.x VirtualBox インストーラーをビルドする方法。
  • インテルから提供されている Linux* 2.6 カーネルを使用して特定の機能を VirtualBox に追加する方法。
  • installer.vdi を使用して Android* ICS 4.0 を VirtualBox にインストールする方法。

インテル® Hardware Accelerated Execution Manager (インテル® HAXM) テクノロジーでサポートされている Google* の AVD エミュレーターに加えて、x86 用 Android* VirtualBox は、仮想化されたインテル® アーキテクチャー・ベースの環境を実行します。開発者とパートナーは、この高速かつハイパフォーマンスなツールを利用して、迅速にアプリケーションの開発とテストを行えます。典型的なインテル® Core™ i5 プロセッサー・ベースのホストシステムの VirtualBox では、約 20 秒で Android* 4.0.x のブートが完了します。Android* 開発者の間では、インテル® アーキテクチャー・ベースのプラットフォームをターゲットにする場合、速度、パフォーマンス、ユーザー体験を理由に VirtualBox の人気が高まっています。市場に出回っているインテル® アーキテクチャー・ベースの Android* タブレットやスマートフォンはまだ多くありませんが、USB 接続のデバッグの代わりに開発ホストシステム上の仮想環境を使用して開発できることは非常に便利です。 特に開発ホストと Android* ターゲットデバイスの両方がインテル® アーキテクチャー・ベースの場合は、有効な選択肢と言えるでしょう。

2.7. Android* 4.x 向け Google* x86 VirtualBox ビルドターゲット

Google* の Android* 4.0.x ソースリポジトリーを以前に使用した経験がある方は、Google* が x86 バージョンの VirtualBox ターゲット vbox_x86-eng を提供していることをご存知でしょう。ビルドを開始する前に lunch コマンドを使用すると、Google* が Android* 4.0.x 用に提供している 3 つのターゲットが表示されます。

$ lunch

1. full-eng
2.full_x86-eng
3.vbox_x86-eng

vbox_x86-eng (#3) ターゲットを利用して、アプリケーション開発者とシステム開発者は android_disk.vdi および installer.vdi パッケージを作成することができます。作成したパッケージは、Windows*、Linux*、OS X* プラットフォーム上のアプリケーション開発とシステム統合用に VirtualBox 内部で Android* 4.x を実行するのに使用できます。

2.7.1. ソースツリーのダウンロードとリポジトリーのインストール

リポジトリーをインストール、初期化、設定するには、次の操作を行います(詳細は、http://source.android.com/source/downloading.html (英語) を参照)。

$ mkdir ~/bin
$ PATH=~/bin:$PATH
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
$ mkdir ANDROID_TOP_PATH
$ cd ANDROID_TOP_PATH

利用可能なブランチのリストを取得するには、(Android* リポジトリーの checkout root から) 次のコマンドを実行します。

$ git –git-dir .repo/manifests/.git/ branch -a

repo init を実行して、最新の更新を含む利用可能なリポジトリー・サブブランチの現在のリストを取得します。

$ repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1

Gerrit* コードレビュー・ツールを使用するには、Google* アカウントに設定したメールアドレスが必要です。メッセージを受信できるメールアドレスを設定していることを確認してください。カーネルのバージョンとビルド番号がビルドに割り当てられ、情報が [Settings (設定)] – [About phone (電話について)] ページに表示されます。

初期化に成功すると、Repo が作業ディレクトリーで初期化されたことを知らせるメッセージが表示されます。クライアントのディレクトリーに、マニフェストなどのファイルが含まれた .repo ディレクトリーが追加されます。

デフォルトのマニフェストで指定したリポジトリーからファイルを作業ディレクトリーにプルダウンするには、次のコマンドを実行します。

$ repo sync

デフォルトでは、Android* ソースコードへのアクセスは anonymous (匿名) です。過度な使用からサーバーを保護するため、IP アドレス別に使用量が設定されます。

2.7.2. マウスサポートを含むカスタムカーネルのビルド

Android* はタッチスクリーン・デバイス用に設計されているため、マウスポインターはデフォルトではサポートされていません。また、ほとんどの Android* デバイスはネットワーク通信にワイヤレス接続のみを使用しているため、イーザーネット・サポート用のドライバーも含まれていません。これらの機能を追加するには、マウスサポート (および必要な追加機能) を含むカスタムカーネルをリビルドする必要があります。次の操作を行います。

1. Android* SDK Manager から Android* x86 Emulator System Image アドオンをダウンロードします。 

2. 新しいフォルダーを作成して kernel_sdk_x86.tar.gz を展開し、カーネルのソースツリーを含むフォルダーを作成します。

3. カーネルファイルを含むディレクトリーに移動します。

VirtualBox ホストシステムで使用するハードウェアと一致するように構成を変更してリビルドする必要があります。カーネルソースで提供される menuconfig GUI を使用します。

$ cp ANDROID_TOP_PATH/your_kernel_path/arch/x86/configs/vbox_defconfig  .config

$ make CC=gcc-4.4 CXX=g++-4.4 ARCH=x86 menuconfig

コンパイルとロードが完了するまでしばらくかかります。

完了したら、次の操作を行います。

  • [↑] / [↓] キーを使用して移動します。
  • [Enter] キーを使用して選択 (および展開) します。
  • [y] (または [スペース]) キーを使用して追加します。

マウスサポートを有効にするには、[Device Driver (デバイスドライバー)] – [Input Device Support (入力デバイスのサポート)] – [Mice (マウス)] を選択します。

注: menuconfig は、アプリケーションまたはシステム統合をサポートするのに必要な機能がすべて利用可能であることを確認および保証するために使用できるアプリケーションです。しかし、アプリケーション開発者にとって、デフォルトの Android* ビルドでアプリケーションをテストし検証することも同じく重要です。このテストおよび検証を行った後でのみ、複数の異なるデバイスメーカーの Android* デバイスとの互換性を保証できます。

カーネル構成に必要な変更を行ったため、コンパイルを行います。これにはあまり時間がかからないので、ここでは低い ‘j’ 値を指定しています。CC および CCX パラメーターを省略するとバージョン 4.6 が使用されるため、明示的なエラーを出力することなくコンパイルが途中で終了するので注意してください。

$ make CC=gcc-4.4 CXX=g++-4.4 ARCH=x86 –j8

–j パラメーターはコンパイルに利用可能なコア数です。上記の例は、インテル® ハイパースレッディング・テクノロジーが有効なクワッドコア・システムを仮定しています。

ビルドが正常に完了すると、ビルドログの最後の行は次のようになります。

Kernel: arch/x86/boot/bzImage is ready

2.7.3. パッチ済みカーネルの追加

カーネルイメージ bzImage の名前を kernel-vbox に変更して /ANDROID_TOP_PATH/prebuilt/android-x86/kernel/kernel-vbox にコピーします。

$ cp /ANDROID_TOP_PATH/kernel/arch/x86/boot/bzImage   /ANDROID_TOP_PATH/prebuilt/android-x86/kernel/kernel-vbox

2.7.4. CCACHE を使用したコンパイル時間の短縮

コンパイラー・キャッシュを使用して 2 回目以降のコンパイル時間を大幅に短縮できます。キャッシュを 50GB に設定するには、次の操作を行います。

1. CCcache プログラムをインストールして ccache 用のディレクトリーを作成します。

$ sudo apt-get install ccache
$ sudo mkdir /ANDROID_TOP_PATH/ccache
$ sudo chown $LOGNAME  /ANDROID_TOP_PATH/ccache

2. ~/.bashrc を変更して ccache をサポートするように環境変数を設定します。

$ sudo gedit ~/.bashrc

3. 次の行を追加します。

export CCACHE_DIR=/ANDROID_TOP_PATH/ccache
export USE_CCACHE=1

4. ccache のサイズを設定します。

$ ccache -F 100000
$ ccache -M 50G

2.7.5. 新しいカーネルでの Android* 4.0.x のビルド

環境を設定します。

$ /ANDROID_TOP_PATH/> source build/envsetup.sh

ICS 4.0.1 の場合、次のメッセージが表示されます。

including device/samsung/maguro/vendorsetup.sh
including device/samsung/tuna/vendorsetup.sh
including device/ti/panda/vendorsetup.sh
including sdk/bash_completion/adb.bash

ターゲットを確認するため、オプションを指定しないで lunch コマンドを実行します。

$ lunch

ターゲットを選択します。
1.full-eng
2.full_x86-eng
3.vbox_x86-eng
4.full_maguro-userdebug
5.full_tuna-userdebug
6.full_panda-eng

Which would you like? [full-eng]   

: ターゲットとして 3. vbox_x86-eng を選択します。

PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.0.1
TARGET_PRODUCT=vbox_x86
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=x86
TARGET_ARCH_VARIANT=x86
HOST_ARCH=x86 HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=ITL41D

make を実行します。

$ make -j8

2.8. VirtualBox Disk と Android* インストーラーのビルド

最後に、android_disk.vdi と installer_vdi をビルドします。

$ make android_disk_vdi  installer_vdi  -j8

ビルドに成功すると、ビルドログに次のように出力されます。

Done with VirtualBox bootable disk image -[ out/target/product/vbox_x86/android_disk.vdi ]-
Done with VirtualBox bootable installer image -[ out/target/product/vbox_x86/installer.vdi ]-

VirtualBox で [New (新規)] – [Create New Virtual Machine (新規仮想マシンの作成)] を選択し、仮想マシンのベースにする既存のディスクイメージとして (Android* 4.0.x を自動的にブートする) ビルドした android_disk.vdi を使用します。

VirtualBox の開始パラメーターの設定は単純です。[Settings (設定)] – [About phone (電話について)] を選択してビルド情報を確認します (図 15)。

図 15: Oracle* VirtualBox 内の Android* 4.0.x ビルド情報

2.9. Android* インストーラー・ディスクを使用した大きな仮想パーティションの作成

VirtualBox のファイルサイズを 550MB 程度まで拡張しても、テスト用のアプリケーションをロードするにはまだ小さすぎます。Android* をより大きなパーティション (4GB 以上) にインストールするには、Android* インストーラー・ディスクが必要です。

まず、VirtualBox メニューバーから [Machine (マシン)] – [New (新規)] を選択し、[Create New Virtual Machine Wizard (新規仮想マシン作成ウィザード)] を使用して IDE Controller (IDE コントローラー) エントリーにハードディスクを作成します。

次に、仮想マシンの [Settings (設定)] – [Storage (ストレージ)] で installer.vdi を “IDE Primary Slave” として追加します (図 16)。これで、Android* をインストールするハードディスクが作成できました。

図 16: 仮想マシンのストレージ設定

1. エミュレーターを開始します。

2. [F12] キーを押して BIOS ブートメニューを表示します。セカンダリー・ドライブからブートします。

3. grub を使用してインストール・オプション 2. Boot from Primary Slave を選択します (図 17)。

図 17: VirtualBox 内でのインストーラー・イメージのブート

“Done processing installer config” と表示されたら、”reboot” と入力します。

注: 最初にターゲット仮想ディスクにインストールした際にインストールに失敗した場合は、メッセージに従ってインストーラーを再度実行してください。次のコマンドを使用します。

$ installer

リブート後、Android* は作成したディスクから実行されます。VirtualBox の [IDE Controller (IDE コントローラー)] 設定で [Storage (ストレージ)] から installer.vdi を安全に削除できます。

2.10 シリアルポート

仮想マシンのシリアルポートのサポートは、デフォルトで有効です。ただし、COM1 シリアルポートを使用前に初期化して設定する必要があります。コマンドラインで以下のコマンドを実行して、ホーム・ディレクトリーに名前付きパイプ .vbox_pipe を作成します。

$ VBoxManage modifyvm Android –uart1 0x03f8 4

$ VBoxManage modifyvm Android –uartmode1 server /home/user/.vbox_pipe

または、VirtualBox GUI から、[Virtual Machine Settings (仮想マシンの設定)] メニューの [Serial Ports (シリアルポート)] タブで COM1 を “Host Pipe” として設定し、[Create Pipe (パイプの作成)] を選択して /home/user/.vbox_pipe を作成します。

この名前付きパイプに接続するには、次のコマンドを使用します。

$ socat unix-client:$HOME/.vbox_pipe stdout

注: VirtualBox では環境変数 ($HOME など) が使用できないため、/home/user/.vbox_pipe のようにフルパスで指定する必要があります。

2.11. イーサネット

イメージのイーサネット・ポート (eth0) は DHCP 用に有効になっています。ADB 経由でこのポートに接続するには、ポートに割り当てられている DHCP アドレスを確認する必要があります。

ブリッジ接続されたイーサネットを使用している場合は、シリアルポートまたは [Developer Tools (デベロッパー・ツール)] – [Terminal Emulator (ターミナル・エミュレーター)] のシェルプロンプトから次のコマンドでアドレスを取得します。

$ netcfg

ホストオンリー・アダプター ‘vboxnet0’ を使用している場合、アドレス 192.168.56.101 を使用してください。

2.12. 完了

これで、Google* の vbox-x86 ターゲットから作成した Android* 4.0.x イメージを VirtualBox で実行できるようになりました (図 18)。

図 18: VirtualBox 仮想マシン内でブートされた Android* OS

3. GDB (GNU プロジェクト・デバッガー) を使用したデバッグ

Android* NDK には、プログラムを開始、一時停止、検査、および変更できる GDB (GNU デバッガー) が含まれています。Android* (および組込み) デバイス上では、GDB はクライアント/サーバーモードで構成されます。プログラムはデバイス上でサーバーおよびリモートクライアントとして動作します。開発者のワークステーションは、プログラムに接続してローカル・アプリケーションと同様のデバッグコマンドを送ります。GDB はコマンドライン・ユーティリティーです。Eclipse* CDT の前に、基本的な使用方法を見てみましょう。

GDB でデバッグする場合、デバッグ通信の制御にはデバイス上で実行する gdbserver が使用されますが、gdbserver が TCP/IP 経由で開発ホストの GDB と通信する通信トランスポート・レイヤーの制御には ADB の USB-イーサーネット・ドングル・ドライバーが使用されます。

gdbclient は、デバッグ通信環境をセットアップして、デバッグ対象のデバイス上で gdbserver を起動します。

使用法: gdbclient EXECUTABLE :PORT [PROG_PATH]

EXECUTABLE  実行形式の名前 (デフォルトは app_process)

PORT        接続ポート (デフォルトは 1234)

PROG_PATH   ターゲットの実行形式のフルパス (例えば /system/bin/mediaserver)

PROG_PATH が設定されている場合、gdclient は gdbserver を起動して PROG_PATH にアタッチします。

gdbserver を明示的に起動するには、次のコマンドを使用します。

# gdbserver :1234 –attach 269

Attached; pid = 269

Listening on port 1234

以下の詳細なデバッグセッション起動手順は、デバッグに (ADT や DDMS ではなく) GDB を使用する場合でも ADT がどのようにデバッグ通信に関係するかを示しています。ポート 1234 が使用されていると仮定します。

プロセスを起動します。

gdbserver :1234 /system/bin/executable

または既存のプロセスにアタッチします。

gdbserver :1234 –attach pid

ワークステーションで、adb を使用してポート 1234 をデバイスにフォワードします。

adb forward tcp:1234 tcp:1234

ソースツリーの “prebuilt” 領域に含まれる特別なバージョンの gdb を開始します。

prebuilt/Linux/toolchain-eabi-4.x.x/bin/i686-android-linux-gdb (Linux* の場合)

prebuilt/darwin-x86/toolchain-eabi-4.x.x/bin/i686-android-linux-gdb (Darwin の場合)

上記の GDB バージョンが見つからない場合は、ソースツリーで find prebuilt –name i686-android-linux-gdbin を実行して最新バージョンを検索します。プライマリー・ディレクトリーの実行形式にはシンボル情報が含まれていないため、プライマリー・ディレクトリーではなく、シンボル・ディレクトリーの実行形式のコピーを使用していることを確認してください。

GDB で、ロードする共有ライブラリーの場所を指定します。

set solib-absolute-prefix /absolute-source-path/out/target/product/product-name/symbols

set solib-search-path /absolute-source-path/out/target/product/product-name/symbols/system/lib

ソースツリーのパスは absolute-source-path です。正しいディレクトリーを指定していることを確認してください。誤ったディレクトリーを指定しても GDB は何も表示しません。GDB コマンドを実行してデバイスに接続します。

(gdb) target remote :1234

:1234 は、ADB でデバイスにブリッジ接続されている、ローカルホストのポート 1234 に接続するように GDB に指示します。

これで、以前と同じ方法で、GDB を使用して Android* 上で実行しているネイティブ C/C++ コードのデバッグを開始できます。GDB を Eclipse* に統合している場合は、Eclipse* および統合された GDB を使用して直接ブレークポイントを追加し、プログラムを調査できます。

Eclipse* では、テキストエディターの左余白をクリックすることで、Java* や C/C++ ソースファイルにブレークポイントを容易に挿入できます。Java* ブレークポイントは、Android* Debug Bridge によりデバッグを管理する ADT プラグインでそのまま動作します。もちろん、Android* に対応していない CDT では動作しません。このため、NDK の GDB を使用してネイティブ Android* アプリケーションをデバッグするように CDT を設定しない限り、ブレークポイントを挿入しても何も起こりません。まず、次の操作を行ってアプリケーションでデバッグモードを有効にします。

1. アプリケーションのマニフェスト AndroidManifest.xml で Android* プロジェクトのデバッグフラグを有効にします。ネイティブコード用の適切な SDK バージョンを使用してください。

<?xml version=”1.0″ encoding=”utf-8″?> <manifest …> <uses-sdk android:minSdkVersion=”10″/> <application … <font color=”red”>android:debuggable=”true”></font> … <br />

2. マニフェストでデバッグフラグを有効にすると、ネイティブコードで自動的にデバッグモードになります。ただし、APP_OPTIM フラグもデバッグモードを制御します。このフラグを Android.mk に手動で設定した場合、値が (リリースではなく) デバッグに設定されていることを確認するか、フラグを削除します。

APP_OPTIM := debug

3. 次に、デバイスに接続する GDB クライアントを設定します。プロジェクトを再コンパイルして、デバイスを接続するかエミュレーターを起動します。そして、アプリケーションを実行します。アプリケーションがロードされていることを確認します。次のコマンド (Windows* の場合は cygwin) を使用してプロセスをリストし、アプリケーションの PID が利用可能であることを確認します。

$ adb shell ps |grep gl2jni

次のような 1 行の結果が返されます。

app_75 13178 1378 201108 68672 ffffffff 80118883 S com.android.gl2jni

4. ターミナルウィンドウを開いてプロジェクト・ディレクトリーに移動し、ndk-gdb コマンドを実行します (Android* NDK フォルダー。例えば android-ndk-r8 に含まれています)。

$ ndk-gdb

obj\local\x86 ディレクトリーに 3 つのファイルが作成されます (メッセージは表示されません)。

  • gdb.setup: GDB クライアント用に生成された構成ファイルです。
  • app_process: このファイルはデバイスから直接取得されます。システム実行形式ファイルで、システムのスタートアップ時に起動され、新しいアプリケーションを開始するためにフォークされます。GDB がマークを検索する場合は、この参照ファイルが必要です。この場合は、アプリケーションのバイナリー・エントリー・ポイントです。
  • libc.so: このファイルもデバイスから取得されます。GDB によって使用される Android* 標準 C ライブラリー (bionic) で、実行時に作成されるすべてのネイティブスレッドを追跡します。

5.プロジェクト・ディレクトリーで obj\local\x86\gdb.setup をコピーして名前を gdb2.setup に変更します。ファイルを開いて、次の行を削除します。

(gdb) target remote :1234

6. Eclipse* のメインメニューで [Run (実行)] – [Debug Configurations… (デバッグ構成…)] を選択して、C/C++ アプリケーション項目に新しいデバッグ構成 GL2JNIActivityDefault を作成します。この構成は、コンピューター上で GDB クライアントを開始して、デバイス上で実行している GDB サーバーと接続します。

7. [Main (メイン)] タブ (図 19) で、[Browse (参照)] ボタンを使用して [C/C++ Application (C/C++ アプリケーション)] が obj\local\ x86\app_process を指すように設定します (絶対パスまたは相対パスを使用できます)。

図 19: C/C++ アプリケーションのデバッグ構成

1. ウィンドウ下部にある [Select other… (ほかを選択…)] リンクを使用してランチャータイプを Standard Create Process Launcher (標準作成プロセスランチャー) に変更します (図 20)。

図 20: お気に入りのランチャーの選択

1. [Debugger (デバッガー)] タブに移動して、[Debugger (デバッガー)] を gdbserver に設定し、[GDB debugger (GDB デバッガー)] を android-ndk-r8\toolchains\x86-4.4.3\prebuilt\windows\bin\i686-android-linux-gdb.exe に設定します。[GDB command file (GDB コマンドファイル)] (図 21) で \obj\local\x86 の gdb2.setup ファイルを指します (絶対パスまたは相対パスを使用できます)。

図 21: デバッガー設定パネル

1. [Connection (接続)] タブに移動して (図 22)、[Type (タイプ)] を TCP に設定します。[Host name or IP address (ホスト名または IP アドレス)] および [Port number (ポート番号)] のデフォルト値 (localhost, 5039) は変更しません。

図 22: デバッガー設定パネルの接続設定

1. デバイス上の GDB サーバーを実行するように Eclipse* を構成します。android-ndk-r8\ndk-gdb をコピーしてテキストエディターで開き、次の行を探します。

$GDBCLIENT -x `native_path $GDBSETUP`

Eclipse* で GDB クライアントを実行するため、この行をコメントアウトします。

#$GDBCLIENT -x `native_path $GDBSETUP`

2. Eclipse* のメインメニューで [Run (実行)] – [External Tools (外部ツール)] – [External Tools (外部ツール)] – [Configurations… (構成…)] を選択して (図 23)、新しい構成 GL2JNIActivity_GDB を作成します。この構成は、デバイス上の GDB サーバーを起動します。

3. [Main (メイン)] タブの [Location (位置)] に、変更した android-ndk-r8 の ndk-gdb を指定します。作業ディレクトリーをアプリケーションのディレクトリーに設定します。必要に応じて、[Arguments (引数)] テキストボックスを設定します。

  • verbose: Eclipse* コンソールに詳細な情報を表示します。
  •  force: 以前のセッションを自動的に kill します。
  • start: アプリケーションにアタッチする代わりにアプリケーションを開始します。このオプションは、Java* ではなくネイティブコードをデバッグする場合に設定します。

図 23: 外部ツールの設定

1. 通常どおりにアプリケーションを起動します。

2. アプリケーションが起動したら、コンソールから直接または外部ツール構成 GL2JNIActivity_GDB を起動して、デバイス上の GDB サーバーを起動します。GDB サーバーは、リモート GDB クライアントから送られたデバッグコマンドを受け取り、アプリケーションをローカルにデバッグします。

3. jni\gl_code.cpp を開き、テキストエディターの左余白をダブルクリックして (または右クリックして [Toggle breakpoint (ブレークポイントの切り替え)] を選択して) setupGraphics にブレークポイントをセットします (図 24)。

図 24: ブレークポイントの設定

1. 最後に、デフォルトの C/C++ アプリケーション構成 GL2JNIActivity を起動して GDB クライアントを開始します。Eclipse* CDT から GDB サーバーにソケット接続でデバッグコマンドが渡されます。開発者から見ると、ローカル・アプリケーションをデバッグしているように見えます。

4. インテル® グラフィックス・パフォーマンス・アナライザー (インテル® GPA)

グラフィックスのパフォーマンスをデバッグする特殊なツールもあります。インテル® GPA システム・アナライザーは、インテル® アーキテクチャー・ベースの Android* デバイスに対応したインテル® グラフィックス・パフォーマンス・アナライザー (インテル® GPA) の 1 つで、OpenGL* ES のワークロードを最適化するアプリケーション・エンジニアとドライバー・エンジニア向けのツールです。

このセクションでは、インテル® GPA と USB 接続された Android* デバイスの構成および使用方法について説明します。Android* デバイスに接続されると、インテル® GPA システム・アナライザーは OpenGL* ES API、CPU、および GPU のパフォーマンス要件を提供します。また、OpenGL* ES アプリケーションのパフォーマンス解析を支援するため、複数のグラフィックス・パイプライン・ステートのオーバーライドも提供します。

Android* x86 ベースのデバイス上でインテル® GPA システム・アナライザーを使用するには、ドキュメントでターゲットマシンとファームウェア/バージョンを確認する必要があります。

要件の収集を開始するには、インテル® GPA システム・アナライザーをクライアント・システムにインストールしてターゲットデバイスに接続する必要があります。

  1. Windows*/Linux* クライアント・マシンにインテル® GPA 2012 をインストールします。
  2. インテル® GPA システム・アナライザーを起動します。
  3. Android* デバイスが USB ケーブルを使用してクライアント・システムに接続されていることを確認します。
  4. クライアント・システムがターゲットデバイスを検出するまで、10 秒ほど待ちます。検出したデバイスがダイアログに表示されます。ターゲットデバイスのリストは 5 ~ 6 秒ごとに更新されます。
  5. 接続するデバイスを選択して、[Connect (接続)] をクリックします (図 25)。必要なコンポーネントがターゲットデバイスにコピーされ、インストールされたアプリケーションのリストが生成されます。接続プロセスを中断するには、[Stop (停止)] をクリックします。

図 25: 接続されているデバイスの選択

1. リストからアプリケーションを選択します。アプリケーション・リスト (図 26) 画面には、Android* デバイスにインストールされているすべてのユーザー・アプリケーションとシステム・アプリケーションが表示されます。

図 26: アプリケーションのリスト

  1. アプリケーションが起動され、インテル® GPA システム・アナライザーのウィンドウにデータが表示されます。
  2. 別のアプリケーションに切り替えるには、[Back (戻る)] をクリックします。実行中のアプリケーションは強制的に閉じられることに注意してください。
  3. 別のターゲットデバイスに切り替えるには、[Back (戻る)] をクリックします。PowerVR* グラフィックス・アーキテクチャーは、3D アプリケーションのデータをレンダリングされたイメージに変換する、タイル・アクセラレーター (TA)、イメージ合成プロセッサー (ISP)、テクスチャー & シェーディング・プロセッサー (TSP) の 3 つのコアモジュールから構成されます。[GPU] グループのインテル® GPA の要件は、これらのコアモジュールの 1 つに対応します。また、リストの要件の順序は、グラフィックス・パイプラインのコアモジュールの順序に依存します (図 27)。

図 27: インテル® GPA システム・アナライザー

5. インテル® Atom™ プロセッサー上で実行している Android* OS のシステムデバッグ

これまでは、アプリケーションが Android の Java* ランタイムを単独で使用しているか、x86 インテル® アーキテクチャー・バイナリーおよび共有オブジェクトとしてネイティブに実行されているかどうかに関係なく、アプリケーションの開発とデバッグについて説明しました。

しかし、システム・インテグレーターとデバイスメーカーにとっては、デバイスドライバーやシステム・ソフトウェア・スタック上でもアプリケーションが同じように動作することが重要です。例えば、追加のプラットフォームに特定の周辺機器のサポートを実装する必要がある場合や、新しいインテル® Atom™ プロセッサー・ベースのデバイスにオペレーティング・システムを移植する場合には特に重要になります。

この後のセクションでは、IEEE 標準 1149.1 (JTAG) ベースのデバッグ・ソリューションについて説明します。また、ARM* アーキテクチャーとインテル® アーキテクチャーの違いがシステムレベルのデバッグに与える影響についても言及します。

5.1. JTAG デバッグ

 組込みインテリジェント・システムの世界では、ファームウェア、OS レベルのシステムおよびデバイスドライバーのデバッグには、JTAG インターフェイスを使用することが最も一般的です。JTAG (Joint Test Action Group) IEEE 標準 1149.1 は、「プリント回路基板のテストに使用されるテスト・アクセス・ポート用の標準テスト・アクセス・ポートおよびバウンダリースキャン・アーキテクチャー」を定義しています。この標準規格は一般に、JTAG デバッグ・インターフェイスと呼ばれています。当初から、回路基板テスト用の標準規格として、OS に依存しない OS システムレベルのプラットフォーム・デバッグ用の標準インターフェイスとなるように開発されました。

JTAG の詳細情報と最新のシステム・ソフトウェア・スタックのデバッグにおける使用法は、「JTAG 101; IEEE 1149.x and Software Debug by Randy Johnson and Stewart Christie」 (http://download.intel.com/design/intarch/papers/321095.pdf) (英語) を参照してください。

OEM およびパートナーのアプリケーション/ドライバー開発者から見た場合、システムオンチップ (SoC) 統合インテリジェント・システムやスマートフォン・フォーム・ファクター・デバイスのさまざまな部分で実行するドライバー/ソフトウェア・スタック・コンポーネント間の相互作用を理解することは、プラットフォームの安定性を向上させる上で非常に重要です。シリコンの評価者から見た場合、低レベルのソフトウェア・スタックにより、プラットフォームが実際の利用状況で露呈するさまざまなストレス要素を示すテスト環境が提供されます。つまり、最近の SoC では、個々のハードウェア・コンポーネントのユニットテストにパスするだけでなく、パッケージ全体および複雑な実際の相互作用を理解する必要があります。このレベルの洞察を得るには、JTAG の詳細なハードウェア認識機能とターゲット上で実行している Android* OS のステート情報をエクスポートする機能を組み合わせた、JTAG ベースのシステム・ソフトウェア・デバッグ・アプローチを利用します。

特にデバイスドライバーのデバッグでは、チップセットの周辺機器の正確な状態と、デバイスドライバーと OS レイヤーおよび残りのソフトウェア・スタックとの相互作用の両方を理解することが重要です。

システムデバッグの観点から Android* を見た場合、デバイスドライバーと OS カーネルは Linux* の特別なブランチにすぎません。実際、2.6.3x 以降の Linux* のように扱うことが可能です。

インテル® Atom™ プロセッサー Z2460 は、IEEE-1149.1 および IEEE-1149.7 (JTAG) のバウンダリースキャンと MPI PTI (Parallel Trace Interface) に加えて、インテルの JTAG 準拠拡張デバッグポート (XDP) により BTS (Branch Trace Storage)、LBR (Last Branch Record)、AET (Architectural Event Trace) ベースの命令トレースをサポートしています。

さまざまな JTAG ベンダーから Android* に対応したシステム・デバッグ・ソリューションが提供されています。

5.2. Android* OS のデバッグ

Android* ベースのプラットフォームのデバッグが複雑なのは、電力消費を抑えるために Android* が低電力のアイドルステートとスリープステートを積極的に利用することが原因です。このため、低電力ステートでのデバッグが課題となります。

  • 一部の低電力ステートで JTAG 機能を維持します。
  • 維持できない場合、JTAG のチップセットのパワードメインが再度有効になったとき直ちに JTAG を再アタッチします。

これらのプラットフォームにおける多くの OS レベルの問題は、消費電力モードの変更とスリープ/ウェイクアップ・シーケンスに集中する傾向があります。

エージェントベースのデバッグでも、JTAG デバイス・インターフェイスを使用する場合でも、システムデバッガーは、OS 開発の主要な目的達成を支援する便利なツールです。

デバッガーは、ブートプロセスの検証と、ランタイムエラー、セグメンテーション・フォルト、ブート中に正しく開始しないサービスなどの安定性問題の解析と修正に使用できます。

ページテーブル、ディスクリプター・テーブル、命令トレースの詳細なアクセス情報を提供することにより、OS の構成に関する問題の特定と修正にも使用できます。命令トレースとメモリー・テーブル・アクセスの組み合わせは、スタック・オーバーフロー、メモリーリーク、データアボートなどの根本的な原因を特定できる非常に強力なツールとなります。

図 28 は、物理アドレスから仮想メモリーアドレスへのページテーブルの変換を示しています。変換テーブルの深さとアドレスされるメモリーブロックの粒度を定義する際に x86 で利用可能な、高い柔軟性を備えて、容易にアクセスでき、可視性のあるメモリーレイアウトであることが、OS レベルでのシステム開発ではさらに重要になります。

図 28: 論理アドレスからリニアアドレスへの変換

論理アドレスをリニアアドレスに変換するため、プロセッサーは次の処理を行います。

  1. セグメントセレクターのオフセットを使用して、GDT または LDT のセグメントのセグメント・ディスクリプターを特定して読み込みます。(このステップは新しいセグメントセレクターがセグメントレジスターにロードされた場合にのみ必要です。)
  2. セグメントがアクセス可能であり、オフセットがセグメントの範囲内であることを保証するため、セグメント・ディスクリプターのアクセス権とセグメントの範囲を確認します。
  3. セグメント・ディスクリプターからセグメントのベースアドレスをオフセットに追加してリニアアドレスを形成します。
  4. ページングが使用されない場合、プロセッサーはリニアアドレスを物理アドレスに直接マップします (つまり、リニアアドレスがプロセッサーのアドレスバスの外に出ます)。リニアアドレス空間がページングされると、セカンドレベルのアドレス変換が使用され、リニアアドレスが物理アドレスに変換されます。

プロテクトモードで動作する場合、インテル® アーキテクチャーでは、リニアアドレス空間を大きな物理メモリー (例えば、4GB RAM) に直接、または小さな物理メモリーとディスクストレージに (ページングを使用して) 間接的にマップすることができます。リニアアドレス空間をマップする後者の手法は、仮想メモリーやデマンドページ仮想メモリーと呼ばれます。

ページングが使用されると、プロセッサーはリニアアドレス空間を物理メモリーまたはディスクストレージにマップ可能な固定サイズのページ (通常は 4KB) に分割します。プログラム (またはタスク) がメモリーの論理アドレスを参照している場合、プロセッサーはアドレスをリニアアドレスに変換してから、ページングメカニズムを使用してリニアアドレスを対応する物理アドレスに変換します。リニアアドレスを含むページが現在物理メモリー内にない場合、プロセッサーはページフォルト例外 (#PF) を生成します。ページフォルト例外の例外ハンドラーは、(プロセスで物理メモリーからディスクに異なるページを書き込んで) ディスクストレージから物理メモリーにページをロードするようにオペレーティング・システムに指示します。ページが物理メモリーにロードされると、例外ハンドラーからのリターンにより例外を生成した命令が再開されます。リニアアドレスを物理アドレス空間にマップし、(必要なときに) ページフォルト例外を生成するのにプロセッサーが使用する情報は、メモリーに格納されたページ・ディレクトリーとページテーブルに含まれています。

ページングは固定サイズのページを使用する点でセグメントとは異なります。通常、保持するコードやデータ構造と同じサイズである (つまりコードやデータの大きさで変化する) セグメントと異なり、ページのサイズは固定です。セグメンテーションが使用されるアドレス変換の唯一の形式であれば、物理メモリーのデータ構造のすべての部分がメモリーに含まれます。ページングが使用された場合、データ構造の一部がメモリーに含まれ、別の一部がディスクストレージに含まれます。

アドレス変換に必要なバスサイクルの数を最小限にするため、最も新しくアクセスされたページ・ディレクトリー・エントリーとページ・テーブル・エントリーが、プロセッサーのトランスレーション・ルックアサイド・バッファー (TLB) と呼ばれる領域にキャッシュされます。TLB は、バスサイクルを要求することなく、現在のページ・ディレクトリーとページテーブルの読み込みのほとんどを行うことができます。TLB にページ・テーブル・エントリーが含まれない場合に限り (ページが長い間アクセスされていないときに発生しやすい)、追加バスサイクルが発生します。

この点は、インテル® アーキテクチャーとほかのアーキテクチャーで Android* OS ソフトウェア・スタックを開発および構成する際の 2 つの重要な違いです。LDT (ローカル・ディスクリプター・テーブル) と GDT (グローバル・ディスクリプター・テーブル) を組み合わせた、セレクターベースのオフセット・アドレッシング・モデルは、可変のアドレスチャンクの粒度を使用して、物理メモリーから仮想メモリーにマルチレイヤーのアドレス変換を行うことができます。これは、保護され分離された複数のメモリー空間を含む分割された環境でカスタムメモリー構成を行う強力な機能ですが、正しく使用されないとメモリーアクセスの回数が増えます。このため、メモリーページ変換の優れた可視性が望まれます。

インテル® アーキテクチャーとほかのアーキテクチャーのもう 1 つの違いは、システム割り込みの制御です。例えば、ARM* では、ハードウェア割り込みの事前定義セットが 0x0 から 0x20 までの予約されたアドレス空間に含まれます。その後、これらの空間には割り込みハンドラーへのジャンプ命令が含まれます。インテル® アーキテクチャーでは、専用のハードウェア割り込みコントローラーが採用されています。ハードウェア割り込みはメモリー空間から直接アクセスされず、インテル® 8529 割り込みコントローラーによってアクセスされます。このアプローチの利点は、接続されているデバイスの I/O 割り込みの直接制御を割り込みハンドラーが考慮していることです。専用の割り込みコントローラーを使用しないアーキテクチャーでは、通常、IRQ 割り込みでより複雑な割り込みハンドラールーチンを処理します。

5.3. デバイスドライバーのデバッグ

OS レベルのデバッグ向けの優れた JTAG デバッガー・ソリューションは、カーネルでエクスポートされるほかの情報とともに、カーネルスレッドとアクティブなカーネルモジュールの可視性を提供すべきです。動的にロードされるサービスとデバイスドライバーのデバッグを可能にするには、ドライバーの初期化と破棄のメモリー位置をエクスポートするカーネルパッチまたはカーネルモジュールを使用します。

特にシステム構成とデバイスドライバーのデバッグでは、デバイス構成レジスターの内容を直接アクセスして確認できることも重要です。これらのレジスターと内容は、レジスターの 16 進数でリストされるか、図 29 に示されているようにビットフィールドとして視覚化されます。ビット単位の仮想化を行うと、関連するデバイスドライバーが対話している間、デバッグ中のデバイスステートに対する変更をより簡単にキャッチして理解できます。

図 29: デバイスレジスターのビットフィールド表示

start_kernel に到達するまでにデバッガーの実行コントロールをリリースすることで、Android* の圧縮した zImage カーネルイメージがメモリーに展開された後でコードを解析することができます。これは、カーネルシンボル情報を含む vmlinux ファイルがロードされたことを意味します。この時点で、ソフトウェア・ブレークポイントを使用できます。ブートプロセスのこの時点までは、デバッガーが初期化されていないメモリーにブレークポイント命令を書き込むことを回避するため、ブレークポイント・レジスター・ベースのハードウェア・ブレークポイントのみ使用できます。その後、アイドルループ mwait_idle に到達すると、オペレーティング・システムは正常にブートされます。

デバッグ・ソリューションで LBR (Last Branch Record) ベースの命令トレースへのアクセスが提供される場合、JTAG デバッガーの通常の実効制御機能とともにこの機能を使用して、例外での実行を停止し、実行フローを解析してランタイム問題の根本的な原因を探ることができます。

LBR は、ターゲットリセットからのコード実行をトレースするのに使用できます。コード実行の中断はこれらの MSR (Machine Status Register) に格納されるため、デバッガーは ‘To’ および ‘From’ アドレスを読み取って実行されたコードを再構築し、特定の場所のメモリーにアクセスして、コードを逆アセンブルすることができます。逆アセンブリーは、デバッガー・インターフェイスのトレース GUI に通常表示されます。割り込みにブレークポイントをセットすると、SMI (System Management Interrupt) やほかの例外の前に実行されたコードを調べるときに役立ちます。

5.4. ハードウェア・ブレークポイント

ARM* アーキテクチャーと同じように、インテル® アーキテクチャー・ベースのプロセッサーは、データやコードのソフトウェア・ブレークポイントとハードウェア・ブレークポイントのブレークポイント命令をサポートしています。ARM* アーキテクチャーでは、ブレークポイントとデータ・ブレークポイント (ウォッチポイント) に専用のレジスターが用意されています。一般的な実装では、2 つのレジスターを使用する傾向があります。これらのレジスターに値が含まれる場合、プロセッサーはプログラム・カウンター・レジスターまたはメモリー読み取り/書き込みによってセットされるメモリーアドレスに対するアクセスをチェックします。アクセスが行われると、実行が停止されます。これは、ブレークポイント命令で実行が停止されるという点でソフトウェア・ブレークポイントとは異なります。ブレークポイント命令は指定されたメモリーアドレスのアセンブリー命令を置換するため、ブレークポイント位置の命令が実行される前に実行が停止されます。

インテル® アーキテクチャーでのハードウェア・ブレークポイントの実装は ARM* での実装に非常に似ていますが、より柔軟です。

インテル® Atom™ プロセッサーのコアには、アドレスを格納する 4 つの DR レジスターがあり、メモリーフェッチの前に (場合によっては後に) メモリーバスのフェッチされたアドレスと比較されます。

これらの 4 つのレジスターをすべて使用して 、以下のデバッグ実行制御イベントのトリガーとなるアドレスを提供できます。

  • 00 – 命令実行でブレーク
  • 01 – データ書き込みでのみブレーク
  • 10 – 未定義あるいは (アーキテクチャーが許可している場合) I/O 読み取りまたは書き込みでブレーク
  • 11 – (命令フェッチでない) データ読み取りまたは書き込みでブレーク

つまり、4 つのハードウェア・ブレークポイントはすべて、ブレークポイントまたはウォッチポイントのいずれかに使用できます。ウォッチポイントは、書き込み専用または読み取り専用 (あるいは I/O) ウォッチポイントのいずれかです。

5.5. クロスデバッグ: インテル® Atom™ プロセッサーと ARM* アーキテクチャー

インテル® Atom™ プロセッサーをターゲットとする多くの開発者は、固定命令長の RISC アーキテクチャーにおける開発経験があることでしょう。MIPS と ARM* は固定長の ISA (Instruction Set Architecture) の代表的な例です。一般に、インテル® Atom™ プロセッサーと ARM* アーキテクチャー・プロセッサー間のクロスデバッグ使用モデルは非常に似ています。概念的なデバッグ手法と問題の多くは同じです。

ただし、選択する組込みオペレーティング・システムが Linux* や Windows* のような標準オペレーティング・システムの派生バージョンである場合、インテル® Atom™ プロセッサーをターゲットとするインテル® アーキテクチャー・ベースの開発ホスト上での開発には、2 つの大きな利点があります。最初の利点は、インテル® アーキテクチャー上のソフトウェア開発市場向けに提供されているパフォーマンス、省電力解析、デバッグツールなどの豊富なエコシステムを利用できることです。2 つ目の利点は、アプリケーションの機能的な正当性とマルチスレッドの動作のデバッグをローカルに行えることです。この利点については後で説明します。

インテル® Atom™ プロセッサーと ARM* プロセッサーには、開発者が知っておくべきいくつかの相違点があります。これらの相違点は、次の 2 つのサブセクションで説明します。

5.6. 可変長命令

IA-32 およびインテル® 64 命令セットには可変長命令が含まれています。デバッガーは、固定 32 ビット間隔でコードを検査できないため、これらの命令のコンテキストに基づいてアプリケーションの機械語命令を解釈して逆アセンブルしなければいけません。次の命令の位置は、前の命令の位置、サイズ、デコーディングに依存します。対照的に、ARM* アーキテクチャーでは、デバッガーは ARM* モードから Thumb モードまたは拡張 Thumb モード (または逆) に切り替えるコードシーケンスをモニターするだけでかまいません。特定のモードでは、すべての命令とメモリーアドレスのサイズは 16 ビットまたは 32 ビットのいずれかになります。特定のデバイスレジスターへの呼び出しを正確にアラインする必要がある (デバッガーのメモリーウィンドウの出力を利用する) ファームウェアやデバイスドライバーの開発者は、可変長命令の潜在的な影響を理解しておくべきでしょう。

5.7.ハードウェア割り込み

システムコードをデバッグするときに重要となるアーキテクチャー上のもう 1 つの相違点は、ハードウェア割り込みの制御方法です。

  • 0 リセット
  • 1 アボート
  • 2 データアボート
  • 3 プリフェッチ・アボート
  • 4 未定義命令
  • 5 割り込み (IRQ)
  • 6 高速割り込み (FIRQ)

ARM* アーキテクチャーでは、例外ベクトルはアドレス 0x0 からアドレス 0x20 にマップされます。このメモリー領域は保護され、通常は再マップできません。一般に、0x0 から 0x20 のベクトル位置には、実際の例外ハンドラーコードが存在するメモリーアドレスへのジャンプが含まれます。0x0 のベクトルのリセットは、ファームウェアまたはプラットフォームのブートコードの位置へのジャンプです。このアプローチは、ARM* アーキテクチャーではハードウェア割り込みと OS シグナルハンドラー実装の柔軟性が低くなりますが、より標準化されます。0x0 から 0x20 のベクトル位置にハードウェア・ブレークポイントをセットすることで、デバッガーの割り込みを簡単にトラップできます。

インテル® アーキテクチャーでは、専用のハードウェア割り込みコントローラーが採用されています。

  •  0 システムタイマー
  • 1 キーボード
  • 2 カスケード方式セカンド割り込みコントローラー
  •  3 COM2 – シリアル・インターフェイス
  •  4 COM1 – シリアル・インターフェイス
  • 5 LPT – パラレル・インターフェイス
  •  6 フロッピー・ディスク・コントローラー
  •  7 利用可能
  •  8 CMOS リアルタイム・クロック
  •  9 サウンドカード
  • 10 ネットワーク・アダプター
  • 11 利用可能
  • 12 利用可能
  • 13 数値プロセッサー
  • 14 IDE — ハードディスク・インターフェイス
  •  15 IDE — ハードディスク・インターフェイス

割り込みはプロセッサーのメモリーアドレス空間から直接アクセスできませんが、インテル® 8259 割り込みコントローラーにアクセスすることで制御できます。割り込みのリストから分かるように、コントローラーは接続されたデバイスのハードウェア I/O 割り込みの直接制御 (ARM* プラットフォームの IRQ 割り込みや高速割り込みでの制御) をすでに考慮しています。この機能により、インテル® アーキテクチャーではオペレーティング・システム・レベルでの適切な割り込み制御を簡単に実装できます (特にデバイス I/O)。データアボートやセグメンテーション・フォルトのようなソフトウェア例外のマッピングは、インテル® アーキテクチャーでも柔軟に行うことができ、割り込みディスクリプター・テーブル (IDT) でアドレスされる割り込みコントローラー・ポートに対応します。IDT からハードウェア割り込みへのマッピングはソフトウェア・スタックで定義できます。ソフトウェア・スタックに依存しないデバッグ情報からこれらの例外を簡単にトラップすることはできません。インテル® アーキテクチャーのハードウェア割り込みをトリガーするソフトウェア・イベントをトラップするには、OS レイヤーの知識が必要です。これらの例外の OS シグナルを割り込みコントローラーにマップする方法を知る必要があります。一般に、システムレベルのデバッガーでも、ハードウェア・レベルで直接例外をトラップする代わりに、オペレーティング・システムからメモリーをマップしたシグナルテーブルで例外をトラップします。

5.8. シングルステップ

ARM* アーキテクチャーには明示的なシングルステップ命令はありません。インテル® アーキテクチャーでは、アセンブリー・レベルのシングルステップは、シングルステップ命令によりデバッガーに直接実装されます。ARM* では、シングルステップ命令は “run until break (ブレークまで実行)” コマンドとして実装されます。デバッガーは、すべての可能なコードパス (特に分岐命令以降のステップ) がカバーされていることを保証するコード検査を行うために必要です。デバッガーの実装という点から見た場合、”run until break (ブレークまで実行)” コマンドを実装することで高水準言語のステップが頻繁に必要になるため、多少の (過度ではない) オーバーヘッドが発生します。ステップの動作が多少異なるため、ソフトウェア開発者はこの違いに注意すべきです。

5.9. 仮想メモリーマッピング

仮想メモリーマッピング用のディスクリプター・テーブルとページ変換の実装は、少なくとも概念的には非常に似ています。インテル® アーキテクチャーでは、グローバル・ディスクリプター・テーブル (GDT) とローカル・ディスクリプター・テーブル (LDT) による入れ子の粒度調整が可能なメモリーページが仮想アドレス空間にマップされます。図 30 は、インテル® アーキテクチャーのリニアアドレスから物理アドレスへの変換を示しています。

図 30: インテル® アーキテクチャーのページ変換

ARM* では、ファーストレベルとセカンドレベルのページテーブルはより直接的に定義され、最大でも仮想メモリーの 1 レベルまたは 2 レベル深いページになります。図 31 は、ARM* のリニアアドレスから物理アドレスへの変換を示しています。

図 31: ARM* のページ変換

インテル® アーキテクチャーは、ディスクリプター・テーブル、パージテーブル、リアルモードの 32 ビット・アドレス空間、セレクターの base:offset モデルに依存するプロテクトモードの 64 ビット・アドレッシングに、さまざまなレベルの粒度を用意しています。ARM* は、各種モードで base:offset を使用しません。インテル® アーキテクチャーでは、ページテーブル検索が暗黙でより深くなります。ARM* では、定義されるセットは 2 つのページテーブルです。インテル® アーキテクチャーでは、ディスクリプター・テーブルが実際に入れ子のテーブルをマスクするため、実行するページテーブルの実際の深さはすぐに ARM* の深さの 2 倍から 3 倍になります。

アプリケーション実行に保護されたブロックとして特定のメモリーチャンクを割り当てるために OS レイヤーに使用されるシステム・メモリー・レイアウトとメカニズムに対して、インテル® アーキテクチャーのページ変換メカニズムはより高い柔軟性を提供します。しかし、開発者には、メモリー仮想化について理解し、メモリーリークやメモリーアクセス違反 (セグメンテーション・フォルト) を回避するという課題が与えられます。多くのメモリーを備えたフル機能の OS では、この問題を考慮する必要はほとんどありません。メモリー処理の可視性に優れたリアルタイム・オペレーティング・システムでは、この問題が露呈しがちです。 

6. インテル® ハイパースレッディング・テクノロジーに関する注意事項

デバッグの観点から見た場合、物理プロセッサー・コアとインテル® ハイパースレッディング・テクノロジーで有効にされた論理プロセッサー・コアとの間に違いはありません。ハイパースレッディングの有効化は、BIOS のプラットフォーム初期化プロセスの一部として行います。このため、アプリケーションから見た場合、物理プロセッサー・コアと追加の論理プロセッサー・コアとの間で顕著な違いはありません。このテクノロジーにより複数のスレッドの並行実行が可能になるため、デバッグの課題は物理的なマルチコアをデバッグする場合と同じです。 

7. SoC とヘテロジニアス・マルチコアの 相互作用

SoC で多数のソフトウェア・コンポーネントとハードウェア・コンポーネントが相互に作用する場合、デバッグ中の問題の原因は増加します。異なるソフトウェア・コンポーネント間の相互作用は、多くの場合タイミング・センシティブです。コンポーネント間で多くの相互作用があるコードベースをデバッグする際、1 つの特定のコンポーネントをシングルステップで処理することは、現実的ではありません。デバッグそのものによりタイミング動作に影響を及ぼし、さらに悪い問題 (ハイゼンバグ) を引き起こす可能性があるため、従来の printf デバッグもこのコンテキストでは有効ではありません。

7.1. イベントトレースのデバッグ

この問題の対応を支援する、さまざまなスタティック・ソフトウェア・インストルメンテーション・ベースのデータ・イベント・トレース技術があります。共通なのは、少量の DRAM バッファーメモリーを利用してイベントデータをキャプチャーし、ロギング・メカニズムを使用してトレース結果をログファイルに書き込む点です。データ・トレース・モニタリングは、トレースロギング API を直接処理することでリアルタイムに、またはより複雑なソフトウェア・スタック・コンポーネントの相互作用を解析するトレースビューアーによりオフラインで行うことができます。 

この種の実装では、SVEN、LTTng*、F-Trace* の 3 つが最も一般的です。

次の表は、Linux* オペレーティング・システム向けの (つまり Android* でも利用可能な) 3 つの実装の比較です。

図 31: データ・イベント・トレース・ソリューションの違い

詳細は、各製品の Web サイトを参照してください。

8. まとめ

この記事では、必要なドライバーとデバッグツールの構成およびインストールについて説明しました。また、システムレイヤーに非常に近い開発を行っている開発者のデバッグに影響を与えるアーキテクチャー上の違いについても説明しました。

インテル® アーキテクチャー・ベースのシステムで動作する Android* で利用可能なデバッグ・ソリューションとデバッグ構成の説明で紹介したように、Java* アプリケーション開発者、ネイティブ C/C++ コード開発者、システム・ソフトウェア・スタック開発者のニーズをすべてカバーする、完全なデバッグ環境があります。

インテル® アーキテクチャーでのデバッグは、Google* から提供されている標準 Android* SDK および Android* NDK ツールセットでサポートされています。インテルとエコシステム・メーカーは、利用可能なデバッグツールを拡張するデバッグ・ソリューションに加えて、システム・ソフトウェア・スタックのデバッグとグラフィックス・パフォーマンスのデバッグ用のソリューションも提供しています。

ARM* アーキテクチャー上で実行する Android* のデバッグおよび開発に精通している場合は、同じデバッグ手法をインテル® アーキテクチャーにも使用できます。利用可能なデバッグツールと開発ツール基盤は Android* SDK をベースとしており、インテルと ARM* にも詳しいエコシステム・パートナーのソリューションにより拡張されています。このため、インテル® Atom™ プロセッサー・ベースの Android* デバイスと ARM* ベースのデバイスで、ソフトウェアのデバッグに大きな違いはありません。

9. 参考文献

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

関連記事