web-dev-qa-db-ja.com

Androidカーネルのデバッグ

私はkgdbをNexus Oneで動作させるための実験を行っています。

https://Android.googlesource.com からカーネルをプルして、kgdbを含むすべてのkgdbtsを使用したmenuconfigを使用したテストを有効にしました。カーネルを正常にビルドし、デバイスにフラッシュしました(ルート化されてロック解除され、CyanogenMod 7が実行されています)

http://bootloader.wikidot.com/Android:kgdb に記載されている手順に従って、USB接続がkgdb(およびttyACM0からttyGS0への通信のテストに成功しました)。

次のフォルダは、kgdbocおよびkgdbtsがカーネルに組み込まれていることを示しています。

/sys/modules/kgdboc/parameters
/sys/modules/kgdbts/parameters

以下は、kgdbtsテストが実行されていることを示すdmesgからの出力で、テストが正常に完了したこと(私が思う)を示しています。

# dmesg | grep kgdb
<6>[   12.974060] kgdb: Registered I/O driver kgdbts.
<6>[   12.981781] kgdbts:RUN plant and detach test
<6>[   12.995178] kgdbts:RUN sw breakpoint test
<6>[   13.002441] kgdbts:RUN bad memory access test
<6>[   13.010864] kgdbts:RUN singlestep test 1000 iterations
<6>[   13.019042] kgdbts:RUN singlestep [0/1000]
<6>[   13.077850] kgdbts:RUN singlestep [100/1000]
<6>[   13.132720] kgdbts:RUN singlestep [200/1000]
<6>[   13.187500] kgdbts:RUN singlestep [300/1000]
<6>[   13.242370] kgdbts:RUN singlestep [400/1000]
<6>[   13.297149] kgdbts:RUN singlestep [500/1000]
<6>[   13.351928] kgdbts:RUN singlestep [600/1000]
<6>[   13.406829] kgdbts:RUN singlestep [700/1000]
<6>[   13.461578] kgdbts:RUN singlestep [800/1000]
<6>[   13.516540] kgdbts:RUN singlestep [900/1000]
<6>[   13.570922] kgdbts:RUN do_fork for 100 breakpoints
<6>[   21.117645] kgdb: Unregistered I/O driver kgdbts, debugger disabled.

私が直面している問題は、カーネルにkgdbをトリガーさせることだと思います。

# echo -n g > /proc/sysrq-trigger

その結果、コマンドプロンプトに戻ってしまいます。電話には実際のポートがないため、すべてをフリーズし、疑似シリアルポートとして使用されているUSBを介してプロンプトを送信するとします。

私の研究から収集したものから、プロンプトは発行を可能にするトリガーであると想定されています

(gdb) target remote /dev/ttyACM0

カーネルを使用してデバッグセッションに接続します。

私はbcを使用して/proc/sysrq-triggerもテストしました。sysrqにいくつかのコマンドを渡すことができることを確認してください。

したがって、できる限り多くの情報を提供しようという長い間試みられてきた私の質問は、なぜgがデバッガーをトリガーしないのですか?

これは、あらゆるシステムでカーネルデバッグを行う最初の試みであり、Googleで検索をフレーズする方法が不足しているため、私はあなたに目を向けます。ありがとう!

(Androidカーネル)ではまだサポートされていないと思われるため、カーネルコマンドラインにkdgbwaitを入れてもうまくいきませんでした。

62

[SO]では、Androidカーネルに関する質問はほとんどありません。この問題に関する調査結果を提供したので、他の誰も答えていません。残念ながら、これをテストするためのネクサスはありません。そのため、この回答は、問題の段階的な解決を意図したものではありませんが、どこを見ればよいかを示す必要があります。

この問題について私が見つけた唯一の有用なリソースは Dongdong DengによるLKMLパッチ にあります。そのため、これらは通常豊富で広く公開されているため、構成の問題になる可能性はほとんどありません。

これは、カーネルのビルドに問題があることを示しています。 CMの最新バージョンからもう一度やり直して、問題が解消されるかどうかを確認したくなります。

それが失敗する場合は、これをシアンチームに報告して、これが既知の問題であるか、簡単な回避策があるかどうかを確認してください。

最後の手段として、バージョンに互換性がある場合はパッチを試すことができます。唯一の代替策は、袖をまくり上げて、パッチを組み込むためにCMカーネルをハッキングし始めることです。

幸運を。

6
Merlin

Androidハードウェアの経験はありませんが、VirtualBoxクライアントとして実行されているkgdbでコンパイルされたカーネルを実行し、ホストから仮想シリアルポートを介してゲストに接続し、gdb(標準「target remote」コマンド)仮想ゲストカーネルのブートアップ全体をステップ実行できます-kgdbwaitの助けを借りて、これがなければ、「int 13」と呼ばれるインラインアセンブリを実装する以外に何もしないカーネルモジュールを作成できます。これは0xccです。読み込まれると、シリアル接続のホスト側にブレークポイントが表示され、ブレークポイントを設定してカーネルの実行を続行できます。これは、kgdbが例外 "int 13"を処理するため機能します。 "* p = 0"のような他の種類の例外、およびpがNULLを指している場合、uは引き続きブレークポイントを取得しますが、uが実行を続行できるかどうかは疑問です。

2
Peter Teoh

関連する投稿 からこの投稿を見つけ、興味がある場合は、Nexus 6でこれを機能させるために行ったいくつかの作業を公開したことを伝えたい:

http://www.contextis.com/resources/blog/kgdb-Android-debugging-kernel-boss/

興味深いことに、sysrqに関するOPの問題は、私が遭遇した問題でもありました。この動作の理由は、KGDBが正しく初期化されなかったため、「g」(kgdb)トリガーのハンドラーをインストールできないためです。これが、他のすべてのsysrqコマンドが引き続き機能する理由です。

より長い説明(@Robertに感謝):

これを機能させるには、UARTに基づいたデバッグケーブル このAccuvantブログ を作成する必要がありました。これは、FTDI 3.3vの基本的なブレークアウト(執筆時にSparkFunから入手可能)、および4つの抵抗(2 x 1Kオーム、1 x 1.2Kオームおよび1 x 100オーム)、および4素子のチップリングリングスリーブ(TRRS)ヘッドフォンジャック。抵抗は本質的に分圧器を提供し、3.3vを電話に少し安全なものに下げます。回路基板に接続されたもう一方の端でオーディオジャックを挿入することにより、オーディオサブシステムは電圧(〜2.8V)を認識しますピンの1つで、UARTケーブルを介してインターフェイスを提供することがわかっています。FTDIブレークアウトはUSBを介してPCにプラグインし、ここからminicomなどのターミナルエミュレータを介してコンソールメッセージにアクセスできます。ただし、これで同じメカニズムによるシリアルインターフェイスが作成され、KGDB接続に使用できるようになります。

したがって、この時点で、KGDB(具体的には、アトミック文字I/O操作を実行する機能)をサポートするには、Nexus 6のシリアルドライバー(msm_serial_hs_lite.c)に比較的小さな変更が必要です。これらの変更をLinuxカーネルのメインラインコードから移植したのは、Stephen Boydと呼ばれるchapが完全なMSM(Qualcomm)シリアルドライバーmsm_serial.cにハードワークを行ったためです。彼の変更は ここにあります か、Googleで「msm_serial:add support for poll_」を検索するだけです。移植は難しくなく、私のコードは githubにあります です。

それとは別に、グーグルが提供するN6用のカスタムカーネルを構築できるようにする必要があります たくさんの情報 。次に、githubリポジトリにKGDBの変更を含むブートイメージを作成する必要があります。私は https://developers.google.com/Android/nexus/images からストックカーネルを取り出し、それを抽出し(abootimg -xを使用)、次のコマンドを使用してカスタムカーネルで再パックしました(zImage-dtb)とKGDBが確実に読み込まれ、次のように私のシリアルポートを指すようにする追加のコマンドラインパラメーター:

abootimg -u boot.img -k zImage-dtb -c 'cmdline=console=ttyHSL0,115200,n8 kgdboc=ttyHSL0,115200 kgdbretry=4'

Boot.imgを作成したら、fastboot boot boot.imgコマンドを使用して起動し、adbシェルを開いて、Androidカーネルで次のコマンドを使用してブレークポイントをトリガーします。

echo -n g > /proc/sysrq-trigger

/ proc/sysrq-triggerにアクセスするにはスーパーユーザー権限が必要なため、rootが必要であることを完全に言及する価値があります。

電話が停止し、デバッグケーブルが接続された状態で、ホストPC上で非圧縮カーネルを引数として、ARM用のバージョンのGDBを起動します(たとえば、arm-eabi-gdb ./vmlinux)。注:私はUbuntu 14.04を実行しており、AOSPソースリポジトリの「prebuilts」ディレクトリからarm-eabi-gdbを使用しています。最後に、次のコマンドを入力します。

set remoteflow off
set remotebaud 115200
target remote /dev/ttyUSB0

すべてが順調に進んでいると、すぐにkgdbブレークポイント(/ proc/sysrq-triggerへの書き込みによって生成されたもの)に侵入し、デバッグを開始できます。

2
Andy Monaghan