poor man’s JTAG	
     2012年4月1日
    第19回PF部勉強会
本日の発表内容	
★自己紹介
★お金をあまり掛けずにAndroid Kernelのデバッグ
 •PCとターゲットボードだけ
 •安価なJTAGボードを使って
自己紹介	
★東の羊

★twitter @pakuqi

★Blog 電脳羊(http://xiangcai.at.webry.info/)

→Androidが動作するボードの話題が多いです。

BeagleBoard, BeagleBoard xM, PandaBoard, Snowball

★2011年4月からAndroid関連の部署に異動して1年経ちました
今回の発表のきっかけ	
PF部の第3回勉強会、通称Init祭りで@tetsu_kobaさんによる
「自社製品デバッガーの説明」がありました。
Initで止めて処理を追っかけたり
http://www.yokohama.android-pf.org/study/20101204

いいなーと思いながら、お約束の「でも、お高いんでしょ?」

@tetsu_kobaさんも個人で買うもんじゃないので会社で
買ってもらって下さい
orz
その後	
Pandaboardに関する調べものをしてた時に、以下の動画を
偶然見つけました。
http://www.youtube.com/watch?v=8wK9q3XqnFY
Howto: BeagleBoard and PandaBoard with the TinCanTools
Flyswatter (OpenOCD) JTAG Debugger
TinCanTools Flyswatter 	
http://www.tincantools.com/
オーダー	
オーダーはTinCanToolsのサイトから行います。Registerから必要情報を入力して
登録してからクレジットカードで支払います。
実際のオーダー	
下にあるようにFlyswatter2本体(SKU600)が$89、JTAGの20ピンから14ピンへの変換
(SKU620)が$22、送料が$31.90
送料は3つから選べて2番目に早いの(PriorityMail)にしました。1週間くらいで届きました。
安いだけじゃない	


   オプションの変換コネクタとケーブル
   必要だけど最初からBeagleBoardに
   対応してる!!
OpenOCDも対応	
     OpenOCD(後で説明します)も
     BeagleBoard
     BeagleBoard-xM
     PandaBoard
     対応!!
Linaro Connect Q4.11	
Linaro Connect Q4.11でTinCan Toolsの中の人がデモしてるの発見!!
http://www.youtube.com/watch?v=FhMhH5kEcGw
Android Builders Summit
                2012	
前回のPF部でABS 2012の資料斜め読みしましたが、以下のプレゼンがありました
Using OpenOCD JTAG in Android Kernel Debugging

スライド
https://events.linuxfoundation.org/images/stories/pdf/lf_abs12_anderson.pdf
ビデオ
http://video.linux.com/videos/using-openocd-jtag-in-android-kernel-debugging

ビデオ(01:51:54)見ましたが
●前振りが長い
●途中で音声が切れてる(@tetsu_kobaさんによるとマイクのトラブルらしいです)
●デバッガーは動かしてるけど、実際にデバッグはしてなさそう
本日の発表	
—  大貧民コース(PCとターゲットボードのみ)
—  貧民コース(安価なJTAGボード:Flyswatter2を使用)
—  大富豪コース(対象外)
     PARTNER-Jet買って下さい(^^;
PCとターゲットのみ	
●ハードウエア構成
  PCとターゲートボード(PandaBoard)をシリアルケーブルで
  接続します。	




              シリアル
              ケーブル
PCとターゲットのみ	
●ソフトウエア構成(概略)
  gdbを使ってデバッグします。ターゲットボードのカーネルにStub
  (gdbの通信相手)のkgdbを組み込みます。
  gdbのFrontendとしてDDD(Data Display Debugger)を使います




  gdbの
 Frontend	
                                 Kernel
                              Stub
      DDD	
    gdb	
                              kgdb
PCとターゲットのみ	
●ソフトウエア構成(詳細)
  先ほどの図ですと、gdbがシリアルケーブルを使うのでPCから
  Consoleを使った操作や表示が出来なくなります。
  そのため、間にagent-proxyを入れると両方とも有効に出来ます
  詳細は以下のようになります	

              target remote localhost:4441	
                                               Target	

DDD	
         gdb	
                               agent-proxy	
      Kernel
                                               Stub
                                               kgdb	
  Console	
                telnet localhost 4444
環境構築の概要	
●カーネル側
kgdb:Linuxカーネル2.2.26から統合されました。
カーネルコンフィグで有効にすれば使えるようになります。(後述)

●PC側
gdb:Androidのprebuiltを使います
prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-
eabi-gdb

DDD(Data Display Debugger)Ver3.3.11
 システム→システム管理→Synapticパッケージマネージャ

agent-proxy	
 $ git clone git://git.kernel.org/pub/scm/utils/kernel/
kgdb/agent-proxy.git
kgdbの有効化	
(1)環境変数設定
export ANDROID_ROOT=$PWD
export ARCH=arm
export CROSS_COMPILE=$ANDROID_ROOT/prebuilt/linux-x86/toolchain/arm-
eabi-4.4.3/bin/arm-eabi-

(2)カーネルソース取得
$ mkdir kernel
$ cd kernel/
$ git clone https://android.googlesource.com/kernel/omap
$ cd omap
$ git checkout -b android-omap-panda-3.0 origin/android-omap-panda-3.0

(3)コンフィグファイルの作成
$ make panda_defconfig
kgdbの有効化	
(4)kgdbを有効にする
$ make menuconfig
メニュー画面が表示されるので、「Kernel hackingの中に入る」
Compile the kernel with debug infoを有効

「KGDB: kernel degugger」を有効にしてサブメニューの「KGDB: user kgdb
over the serial console (NEW)」を有効にする
kgdbの有効化	
(5)カーネルのビルド
$ make uImage modules -j8

(6)カーネルをSDカードにコピー

(7)ブートパラメータの追加

ブートローダがカーネルに渡すカーネルパラメータにkgdbocを追加します。	
kgdboc=[シリアルデバイスファイル],[ボーレート]
という形式で指定します。	
PandaBoardだと	
kgdboc=ttyO2,115200
になります。
PC側の処理	
(1)agent-proxyの起動
$ agent-proxy 4440^4441 0 /dev/ttyUSB0,115200 &
Agent Proxy 1.95 Started with: 4440^4441 0 /dev/ttyUSB0,115200
Agent Proxy running. pid: 2641

(2)コンソールの表示:TELNETでアクセスするとプロンプトが表示
$ telnet localhost 4440
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
root@android:/ #

(3)DDD起動
$ ddd --debugger arm-eabi-gdb
vmlinuxがあるディレクトリででDDDを起動します。                	
	

(4)デバッグイメージの読み込み
DDDのGDB Consoleで
(gdb) file vmlinux
PC側の処理	
(4)ターゲットボードのkgdbへ接続
DDDのGDB Consoleで
(gdb) target remote localhost:4441
※
通常は(gdb) target remote /dev/ttyUSB0とコンソールを指定して接続しますが、
agent-proxyが起動しているので上記のように接続します。
ターゲットに接続すると自動的にターゲット側がkgdbモードに切り替わります。
コンソール上にメッセージが表示されます。




(5)デバッグ例
printkにブレークポイントを張る	
(gdb) b printk
(gdb) c
でブレークポイントに止まります。     	
	
DDD上で変数の中を見たり、ステップ実行が出来ます
安価なJTAGボードFlyswatter2
        を使用	
●ハードウエア構成
  PCとターゲートボード(PandaBoard)をシリアルケーブルと
  JTAGで接続します。	

                                リボンケーブル
                                  14ピン	
    USBケーブル	



                Flyswatter2	




                シリアルケーブル
実物	

                                       Flyswatter2


                       20ピンから14ピンへ変換


JTAG接続:14ピン




              シリアル接続
安価なJTAGボード:
                  Flyswatter2を使用	
 ●ソフトウエア構成(詳細)
  先ほどの図と似ています。agent-proxyの代わりにOpenOCD
  が間に入っています。	
                                                         リボン
                target remote localhost:3333	
          ケーブル	

DDD	
         gdb	
                                          Target	

                       OpenOCD	
        Flyswatter2	
             Kernel
   telnet
   client	
                             config	
  telnet localhost 4444 	
                         シリアル
                                                   ケーブル	

   Console
                 minicom /dev/ttyUSB0
環境構築の概要	
差分のみ示します
●PC側
OpenOCD
TinCanToolsのサイトにビルド手順があります。それに従ってやれば構築出来ます。
 詳細はブログを参照ください。
 http://xiangcai.at.webry.info/201203/article_3.html

補足
OpenOCDはデーモンとして起動して特定のポートで接続を受け付けます。
3333:gdb
4444:telnet

OpenOCD自体への操作はTelnetで接続してコマンドラインで行います。
デバッガ:gdbからの操作をJTAGコマンドに変換してJTAGを通じてデバッグ操
作を可能にします。
Flyswatter2はシリアルの口を持っているので、minicomでttyUSB0などに接
続すればAndroidのコンソールでの操作や表示が見れます。
デバッグ操作	
実際のデバッグ操作です。詳細はブログに書いたのでそちらを参考にして下さい
http://xiangcai.at.webry.info/201204/article_1.html
ここでは概略を説明します。

(1)Flyswatter2とPandaboardの電源を入れます。

(2)minicomを起動してコンソールを表示させます。

(3)OpenOCDを起動します。	
$ sudo ./openocd -f interface/flyswatter2.cfg -f board/ti_pandaboard.cfg

OpenOCDを起動するにはJTAGとターゲットボードの情報記載したConfigファイルを指定
する必要がありますが、Flyswatter2, Pandaboardは標準で対応しているのでOpenOCD
のインストールディレクトリにあるものを指定します。

起動ログを次ページに示します。
最後にPolling succeeded againと表示されればOKです。
デバッグ操作	
Open On-Chip Debugger 0.5.0 (2011-11-13-22:03)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.berlios.de/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
15000 kHz
RCLK - adaptive
Using dbgbase = 0x80000000
force hard breakpoints
trst_only separate trst_push_pull
Info : max TCK change to: 30000 kHz
Info : RCLK (adaptive clock speed)
Info : JTAG tap: omap4430.jrc tap/device found: 0x3b95c02f (mfg: 0x017, part: 0xb95c,
ver: 0x3)
Info : JTAG tap: omap4430.dap enabled
Polling target failed, GDB will be halted. Polling again in 100ms
Polling target failed, GDB will be halted. Polling again in 300ms
Info : JTAG tap: omap4430.m30_dap enabled
Polling target failed, GDB will be halted. Polling again in 700ms
Info : JTAG tap: omap4430.m31_dap enabled
Info : omap4430.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : omap4430.m30: hardware has 6 breakpoints, 4 watchpoints
Info : omap4430.m31: hardware has 6 breakpoints, 4 watchpoints
Polling succeeded again
デバッグ操作	
(4)TelnetでOpenOCDに接続します。コマンドプロンプト”>”で入力出来ます。	
$ telnet localhost 4444
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
>

(5)Telnet上でコマンド「halt」を実行します。	
> halt
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x200000d3 pc: 0xc00637f0
MMU: enabled, D-Cache: enabled, I-Cache: enabled
デバッグ操作	
(6)DDDの実行	
$ ddd --debugger arm-eabi-gdb

GDB Consoleでコマンドを実行	
(gdb) file vmlinux
(gdb) target remote localhost:3333
→接続先はOpenOCDです。

(7)デバッガでのブレークポイント設定
(gdb) b sys_mkdir

DDDの画面を次ページに示します。
デバッグ操作
デバッグ操作	
(8)Telnet上でコマンド「resume」を実行します。	
> resume

(9)DDDのGDB Consoleで「c」を実行します。

(10)コンソールで$ mkdir tmpを実行します。	
	
(13)DDDのブレークポイントに止まります。	
pathnameとして“tmp”が表示されています。
→次のページ参照

変数の内容を見たり、ステップ実行などが出来ます。
デバッグ操作
まとめ	
※Kernelデバッグって大変そう
※高価な機材が必要
みたいなイメージがあるかと思いますが、比較的安価で気軽に出来ることが分
かりました。

デバッグ以外にも学習のために実際に動かしてブレークポイントを張ってス
テップ実行しながら、想定通りに動いていることが確認できるとカーネルへの
理解が深まると思います。
今後の予定	
★OpenOCD、JTAGの使い方に習熟する
今は何となく使ってる感じなので

★デバイスドライバー組み込んでデバッグ
まずはHello Worldレベルのものをカーネルに組み込んでデバッグ出来
るか
事前に調べた感じでは、ごにょごにょしないといけないらしい

★Insight、Eclipseを使ったデバッグ
今回はgdbのFrontendとしてDDDを使いました。
GUIなデバッグ環境としてInsightというものがありますが、コンパイルで
エラーになってまだ構築できていないので続きを

また、DDDもInsightも開発が止まっているっぽいので、Eclipse上で操
作が出来ると良いかなと(こっちはこれから調べます)
参考情報	
●電脳羊
http://xiangcai.at.webry.info/201203/article_1.html
http://xiangcai.at.webry.info/201203/article_2.html
http://xiangcai.at.webry.info/201203/article_3.html
http://xiangcai.at.webry.info/201203/article_4.html
http://xiangcai.at.webry.info/201204/article_1.html

●@IT MONOist
実践しながら学ぶ Android USBガジェットの仕組み(1):
http://monoist.atmarkit.co.jp/mn/articles/1107/22/news001.html

●TinCanTools
http://www.tincantools.com/wiki/Flyswatter2
http://www.tincantools.com/wiki/Flyswatter2_Pandaboard_How_To
http://www.tincantools.com/wiki/GDB_Debugger

PF部第19回資料 poor man's JTAG