Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JTAGでarmプロセッサをデバッグする話/KernelVM Online4

JTAGでarmプロセッサをデバッグする話/KernelVM Online4

KernelVM online 4の発表資料です。

Toshifumi NISHINAGA

November 20, 2021
Tweet

More Decks by Toshifumi NISHINAGA

Other Decks in Programming

Transcript

  1. JTAGでarmプロセッサを デバッグする話 Toshifumi NISHINAGA (CV: ついなちゃん) @tnishinaga 2021-11-20 KernelVM Online

    4 https://speakerdeck.com/tnishinaga/kernelvm-online4 https://github.com/tnishinaga/kvmonline4_jtag 1
  2. 感謝 • retrageさん • レビューしていただきありがとうございます! • 桜花ちゃん • Rustコードのアドバイスありがとうございます! •

    hikaliumさん • bingen開発ありがとうございます! • https://github.com/hikalium/bingen • なひたふさん • JTAGに関する様々な情報公開ありがとうございます! 5
  3. バウンダリスキャン • ICのピンの状態を取得したり、制 御する技術 • I/Oピンの⼿前にいるScan Cell (シフトレジスタ)の値を使って ポートの状態を読み書き制御する •

    参考 • http://www.tokudenkairo.co.jp/jta g/tech/techbas2.html 8 図はXJTAGのサイト「図1 JTAG対応デバイスの概念図」より引⽤ https://www.xjtag.com/ja/about-jtag/jtag-a-technical-overview/
  4. イメージの乖離。理解の溝。 • 以下2つがJTAGを使ってできることは知っている • ICのピンの状態の取得、制御 • CPUデバッグ • しかし両者のイメージが乖離している •

    ICの状態調べる技術でどうやってCPUデバッグするの……? • 本発表ではJTAGでCPUデバッグする⽅法を調べ、この乖離を 縮める 12
  5. 本⽇の⽬標 • JTAGの通信は何をやっているの? • JTAGインターフェースに必要な機能はなに? • どうやってCPUデバッグするの? • レジスタ値の取得はどうやるの? •

    メモリの読み書きはどうやるの? • breakpointはどうやって仕掛けるの? • step実⾏はどうやるの? 14 ※: 灰⾊部は未完
  6. CPUレジスタ取得までの概要と資料 16 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP
  7. 参考資料 • JTAG関連 • MITOUJTAGのサイト • ⽇本語で最もJTAGを詳しく解説しているサイト (⼤変お世話になりました) • http://www.tokudenkairo.co.jp/jtag/whatisjtag.html

    • http://www.tokudenkairo.co.jp/jtag/tech/index.html • Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, Version F • https://developer.arm.com/documentation/ihi0031/latest • Arm® Architecture Reference Manual Armv8, for A-profile architecture, Version G.b • https://developer.arm.com/documentation/ddi0487/gb/ 17
  8. この節で説明する部分 19 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP
  9. JTAG対応ICの概要 • 以下で構成されている • テスト信号接続⽤のポート(TAP) • TDI等 • TAP制御⽤のTAPコントローラー •

    JTAGテスト⽤レジスタ • Instruction Register等 • バウンダリスキャン⽤のセル • 各ピンの状態を取れる • (本資料では扱わない) 21 図はXJTAGのサイト「図1 JTAG対応デバイスの概念図」より引⽤ https://www.xjtag.com/ja/about-jtag/jtag-a-technical-overview/
  10. Test Access Port(TAP)の信号線 22 • TMS(Test Mode Select) • TAP

    State Machineの状態遷移 を⾏うコマンド線 • TCK(Test Clock) • 信号の基準になるクロック • ⽴ち上がりエッジ • TDI(Test Data In) • インターフェース側からデバイ スに送る信号 • TDO(Test Data Out) • デバイスからインターフェース 側に送る信号 JTAG Interface Target TMS TCK TDI TDO TMS TCK TDI TDO
  11. その他信号線(オプション) • TRST • TAPステートマシンをリセットするためのピン • (※これを使わないとリセットできないターゲットがいるらしい) • SRST •

    システムリセットを⾏うためのピン • 対応していないターゲットもある • RTCK • TCKの周波数をターゲットの動作周波数に合わせるために使うピン • ARMコア⽤の機能 • Vref • ターゲットの電源電圧を取得するためのピン。信号線ではない。 • 信号電圧を決めるために使う 23 ※ http://www.tokudenkairo.co.jp/jtag/adv2018/02.php
  12. テスト⽤レジスタとの値交換⽅法 • TDIとTDOの間にあるシフト レジスタ経由で送受信する • レジスタ⻑や中⾝はTAPコン トローラの状態やセットした 命令に依存する • TDIとTDOをつなぐと複数デ

    バイスを数珠つなぎにできる • Raspberry Pi 3B+の接続先は1 つのみ 24 TCK TDO TDI JTAG chain for programmable devices, Vindicator, CC-BY https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3 %82%A4%E3%83%AB:Jtag_chain.svg
  13. TAP State Machine 26 • 概要 • TAPコントローラーの持つス テートマシン •

    TMS(とクロック)で制御する • 状態遷移 • 命令系(IR)とデータ系(DR)に分 かれている • Shift-*でレジスタの値を交換し、 Update-*で⼊⼒を確定する • TMSを5回以上送るとどの時点 からでもResetに⾏ける 図は http://www.tokudenkairo.co.jp/jtag/tech/techmid1_4.html より引⽤
  14. Instruction Register(IR) • 命令を⼊れるレジスタ • レジスタ⻑は不定 • ARMの場合は4または8bit • 2種類の命令がある

    • パブリック命令 • IEEE1149.1で決められている命令 • 必須命令 と 実装依存のオプション命令 がある • プライベート命令 • 各社が独⾃に作った命令 • 仕様が公開されてることもされていないこともある • (CPUデバッグでは主にプライベート命令を使う。詳しくは後述) • 命令に対応するビットは設計依存 • BYPASSとEXTESTのみ固定 27
  15. パブリック命令の例 • BYPASS • 必須命令 • どのデバイスでも全ビットHでBYPASSになる • DRを1bitにしてTDIの⼊⼒をそのままTDOにバイパスする •

    ターゲット以外にはBYPASSをセットしておくと安全 • IDCODE • オプション命令 • TAP識別⽤IDをDRにセットする • TAPステートをResetにするとIRにIDCODE命令がセットされる • Reset後にDRを読み出すとIDCODEが取れる 29
  16. 例: IRに命令を書き込む • 0 : Reset -> Run • 1

    : Run -> Select DR • 1 : Select DR -> Select IR • 0 : Select IR -> Capture IR • 0 : Capture IR -> Shift IR • TMS:0のままTDIから命令ビット列 を送り込む • 最終ビットはTMS:1にしながら送 る(Shift IR -> Exit1 IR) • 1: Exit1 IR -> Update IR • 0: Update IR -> Run 30
  17. IDCODE命令のセット 1. Shift-IRステートに進める 2. TDIから0b1110を送る • LSB first • 4bit⽬はTMSをHにしながら送る

    3. Update-IRを経由してRunステートに戻る • Resetまで⾏くとセットされた命令が消えるので注意 32
  18. DRからIDCODEを読み出す 1. Shift-DRステートに進める 2. TDOから32bit読み出す • TDIはLにする • LSB firstで送られてくる

    • 32bit⽬はTMSをHにしながら読み込む 3. Update-DRを経由してRunステートに戻る 37
  19. この節のまとめ • JTAGはCPUデバッグ等に使われるIEEE1149.1標準の通称 • 信号線は7本(オプション含む) • TCK, TMS, TDI, TDO,TRST,

    SRST, RTCK, (Vref) • TAPコントローラーはステートマシンをもち、TMSで制御する • IRで命令発⾏、DRでデータをやり取りする • パブリック命令とプライベート命令がある • CPUデバッグは主にプライベート命令を使う(後述) 39
  20. この節で説明する部分 41 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP
  21. JTAG Interface例 • ARM-USB-TINY-H • お値段5000円 • FTDI FT2232H 搭載

    • https://strawberry- linux.com/catalog/items?code=15045 43 ARM-USB-TINY-H
  22. FT2232のモード • SyncBitBang • ⼀部ピンをGPIOとして使えるモード • ピン状態のWrite時に同期してReadが⾏われる • (JTAG通信を⾏うにはMPSSEと⽐較して)低速だけど制御は簡単 •

    MPSSE • SPI,JTAG等の通信を半⾃動で⾏うモード • コマンドを送ると通信を⾏い、⼊⼒を返す • (SyncBitBangと⽐較して)⾼速(max 30MHz) 45
  23. FT2232HLのピン配置 • A*BUSとB*BUSの2回路搭載 • 各BUSはモードによって機能が 変わる • SyncBitBang(Sync-BB) • *DBUSがGPIOになる

    • MPSSE • *DBUSに各通信⽤ピンが割り当てら れる • *DBUS4以降と*CBUSはGPIO 46 図はdatasheetより引⽤ http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232H.pdf
  24. この節で説明する部分 53 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP
  25. ARM Debug Interface(ADI) • Armのデバイスをデバッグするための インターフェース規格 • TAP以降から、メモリ空間にアクセス するまでの仕組みを定義 •

    以下のインターフェースのどちらかを ⽤いて制御する • JTAG • Serial Wire Debug(SWD) • JTAGよりデバッグ線の本数が少ない • なひたふさんの記事が詳しい http://www.tokudenkairo.co.jp/jtag/adv2 018/08.php 54
  26. DPとAP • Debug Port(DP) • AP選択やデータのやり取り をするポート • DPACC命令でアクセスする •

    Access Port(AP) • バス等へのアクセスポート • APACC命令でアクセスする • Debug Access Port(DAP) • DPとAPをセットにしたもの 57 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, A1-25 より引⽤
  27. (DP|AP)ACC命令 • DPまたはAPにアクセスするプライ ベート命令 • DPACC: 0b1011, APACC: 0b1010 •

    DRは35bitの共通フォーマット • 送信 • [34:3] : data • [2:1] : レジスタオフセットアドレスの[3:2]bit • [0] : Read(1) or Write(0) • 受信 • [34:3] : 前回発⾏した命令の返答データ • [2:0] : 前回発⾏した命令のACK 59 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, B3-97 より引⽤
  28. (DP|AP)ACCを⽤いたレジスタ読み書き • レジスタの読み書きは命令を2度発⾏して⾏う(※) • 1度⽬ • 書き込み: RnWを0にしてdataをDRに送る • 読み込み:

    RnWを1にしてDRに送る • 2度⽬ • 読み出すと0を返すDP RDBUFFレジスタを読み出して各返答を取得する • ACKの結果によっては再度命令を発⾏する • 書き込み: DRにACKがセットされているので読み込む • 読み込み: DRに読みだした値とACKがセットされているので読み込む 60 ※パイプライン処理もできる
  29. Debug Portレジスタたち • CTRL/STAT • 電源管理制御や転送状態確認等を⾏うレジ スタ • SELECT •

    APやAP内のバンクを選択するレジスタ • RDBUFF • 読み出すと0を返すレジスタ • *ACC命令の返答を得る際に使う 62 ※DPバージョンによってレジスタ数やアドレスが変わる 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, C2-151 より引⽤
  30. DP CTRL/STATレジスタ • *PWRUPREQ, *PWRUPACK • システムやデバッグブロックの電源をONにするビット • 状態は*PWRACKの⽅で確認 •

    *PWRUPREQを両⽅ONにしないとAPアクセスができない • その他 • 通信モードの選択や通信エラー状態等を確認する 63 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, B2-56 より引⽤
  31. DP SELECTレジスタ • APSEL • APACC命令でアクセスするAPを選択する • APBANKSEL • APACC命令でアクセスするAPのバンク(オフセットの上位4bit)を設定する

    • DPBANKSEL • DPバージョンによってはアクセス先のレジスタが変わる 64 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, B2-70より引⽤
  32. 主要なAPレジスタたち その1 • CSW(0x00) • デバッグアクセス許可や転送データサイズ等を設定する32bitレジスタ • TAR(0x04 - 0x08)

    • BDレジスタ等でアクセスするメモリアドレスを指定する32bitレジス タ • 64bitアドレス指定はloとhiに分けて⾏う • BD0-3(0x10 - 0x1C) • TAR[31:4]アドレスの中⾝を読み書きする32bit x 4つのレジスタ 65
  33. AP CSW • DbgSwEnable • デバッグアクセスを許可する • 無効時はAPレジスタ返答が変になる • DeviceEn

    • APが有効なときに1になる。Read Only 67 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, C2-180より引⽤
  34. 例: AP IDR(0xFC)を読み出す • 前提条件 • AP番号は0 • DPバージョンはDPv0 •

    ⼿順 • DP SELECTでAPを0、AP Bankを0xF(※)に設定する • AP IDRを読み出す 69 ※ APレジスタアドレスの上位4bitはSELECTのバンクで設定する
  35. 例: AP IDR(0xFC)を読み出す 70 DPACC: APSEL: 0x00, APBANKSEL: 0x0F, DPBANKSEL:

    0x00, A: SELECT(0b10), RnW: 0 debugger target Unknown Ack: OK/FAULT DPACC: A: RDBUFF(0b11), RnW: 1 DATA: 0, Ack: OK/FAULT APACC: A: IDR(0b11), RnW: 1 DATA: 0x24770002, Ack: OK/FAULT DPACC: A: RDBUFF(0b11), RnW: 1
  36. 例: MEM-APを使ったメモリアクセス • MEM-APを使ってデバッグユニットのMPIDRレジスタにアク セスしてみる • MEM-APでメモリマップされたレジスタにアクセスする⼿順の 基本は以下 • AP

    TARでアクセス先のメモリアドレスをセット • AP BDレジスタでメモリを読み書き • (上記⼿順の合間にDP SELECTでAP選択とバンク選択が⼊る) 73
  37. 例: ROMテーブルの確認 • openocd の ”dap info 0” コマンドで調べられる 77

    > dap info 0 (省略) ROMTABLE[0x0] = 0x10003 Component base address 0x80010000 Peripheral ID 0x04004bbd03 Designer is 0x23b, ARM Ltd Part is 0xd03, Cortex-A53 Debug (Debug Unit) Component class is 0x9, CoreSight component Type is 0x15, Debug Logic, Processor
  38. この節で説明する部分 80 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP
  39. Debug unit及びCTIのベースアドレス • openocd の ”dap info 0” コマンドで調べられる •

    CTIのアドレスは出てこないのでネットの情報を調べる • 各コアのベースアドレス( 4 core ) • Debug unit • [0x80010000, 0x80012000, 0x80014000, 0x80016000] • CTI • [0x80018000, 0x80019000, 0x8001a000, 0x8001b000] 83
  40. レジスタ取得までの準備 • 初期化 • OS Lockの解除 • プロセッサをHaltしてDebug modeに する

    • HDEの有効化 • CTIからのHalt発⾏ • プロセッサからレジスタの値を取得す る 84
  41. Halting Debug Modeの有効化 • CPUレジスタアクセス等を⾏うには以下の2つが必要 • プロセッサをHaltする • プロセッサをdebug stateにする

    • Halting Debug有効時、Halt命令でdebug modeに⼊る • Halting Debug有効化はEDSCRレジスタのHDEビットで制御 88
  42. EDSCRレジスタ • デバッグステート取得と制御⽤のデバッグレジスタ • 主要なフィールド • HDE: Halting debugを有効にする •

    RW: ELとExecution stateを確認する • STATUS: Debug stateを確認する 89 図は Arm® Architecture Reference Manual Armv8, for A-profile architecture, H9-7584 より引⽤
  43. プロセッサコアのHalt • CTI経由でプロセッサにHalt指⽰を送る とHaltする • Halt指⽰の送り⽅ • CTIGATE[0]を0にしてch0のイベントを CTMに流さないようにする •

    CTIOUTEN0[0]を1にしてch0イベントに対 してDebug requestトリガーがイベントを ⽣成するようにする • CTIAPPPULSE[0]を1にしてチャンネルイベ ントをch0に⽣成する • 詳細はARMv8アーキテクチャマニュアルの 「Example H5-1 Halting a single PE」参照 92 図は Arm® Architecture Reference Manual Armv8, for A-profile architecture, H5-7422 より引⽤
  44. 検証: コアをDebug stateにする • HDEを有効にする • CTIからHaltを発⾏する • EDSCRレジスタのRWフィールドを確認 •

    成功すれば0b110x(Debug state) になる • 参考 • https://developer.arm.com/documentation/ddi0595/2021-03/External- Registers/EDSCR--External-Debug-Status-and-Control-Register 93
  45. 例: CPUレジスタ値の取得 • ⽬的 • レジスタx1の値をデバッガで読み出す • ⼿順 • EDITRに

    “msr DBGDTR_EL0, x1” のopcodeを書き込む • プロセッサが命令を実⾏し、DBGDTRにx1の値を書き込む • DBGDTRから値を読み出す 100
  46. 命令実⾏と読み出し 103 • x1レジスタの値をDBGDTRに ⼊れる命令を発⾏ • msr DBGDTR_EL0, x1 •

    DBGDTRをデバッガで読み出す • 64bit値はTX,RXから32bitずつ取 り出す ※bingenは命令からopcodeを⽣成するcrate(@hikaliumさん製)
  47. CPUレジスタ取得までのまとめ 107 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP