JTAG ICEによる 組み込みLinuxデバッグ 京都マイクロコンピュータ株式会社 http://www.kmckk.co.jp/
Linuxデバッグ
GDBの制限(1) デバッグにはカーネル内のptrace()システムコールを利用している。デバッグデーモン(gdbserver)はユーザーアプリケーションの一つ ユーザー空間 gdbserver デバッグ対象アプリ カーネル/ローダブルモジュール ptrace ドライバ カーネル空間
GDBの制限(1) カーネルは一つのプログラムなので、ドライバがブレークするとptrace()も動作しない ユーザー空間 gdbserver デバッグ対象アプリ デバッグブレーク発生 カーネル停止 カーネル/ローダブルモジュール ptrace ドライバ カーネル空間
GDBの制限(1) ドライバでブレークしている時に、デバッグ対象アプリのメモリを見ようとしたり、ブレークを設定する事が出来ない ユーザー空間 gdbserver デバッグ対象アプリ カーネルが動かないので、 gdbserverが動作しない デバッグブレーク発生 カーネル停止 カーネル/ローダブルモジュール ptrace ドライバ カーネル空間
GDBでの問題(2) 複数のプロセスを同時にデバッグする時の問題 gdbserver kernel プロセスA プロセスB 実行停止 ブレーク要求 シグナル 実行停止 ブレーク要求 プロセスB は動作する 可能性がある シグナル 実行停止 カーネル空間 ユーザー空間
Linuxにおけるデバッグ対象と特徴 PARTNER-Jetは上記の全てに完全対応しています プログラム種別 空間 アドレス ページング ブートローダ 非MMU空間 固定番地 無し 通常の組み込みデバッグに同じ Linuxカーネル MMU上のカーネル空間 無し(※1) ローダブルモジュール リロケータブル デマンドページング リロケーションとページングへの対応が必要 共有ライブラリ MMU上の多重仮想空間 論理多重空間、リロケーション、ページングへの対応が必要 アプリケーション 論理多重空間、ページングへの対応が必要 ※1 CPUによっては、初期化セクションが「ページアウト」する PARTNER-Jetは上記の全てに完全対応しています
技術的課題 リロケータブル デマンドページング MMU上の仮想多重空間 カーネルがメモリにロードするまで、実際に動作するアドレスは分からない ブレークポイントの設定や変数を参照しようとした時に、そのメモリがページにある保証は無い MMU上の仮想多重空間 同一のアドレスでもプロセスIDが異なれば、それは別のメモリ ハードウェアブレークポイントの対応 プロセスへのトレース(ETM/AUDなど)の対応
リロケーションの解決(ローダブルモジュール) ローダブルモジュールをデバッグ用に細工 モジュール初期化の前にソフトウェアブレークを挿入 insmod時にソフトウェアブレークの実行でICEに落ちる 落ちたアドレスで .textは解決。SBPの前後に埋め込んだ情報より.data,.bssを解決 この方法は特にLinuxに依存しなかったので、他のシステムでリロケータブルオブジェクトが使われてるシステムのデバッグにも利用した #define module_init(x) \ int init_module(void) __attribute__((alias(#x))); \ static inline __init_module_func_t __init_module_inline(void) \ { return x; } int init_module(void) \ { __kmc_module_debug_start(); return x(); } \ asm(" .text"); asm(" .long 0x4c434d81"); asm("__kmc_driver_start:"); asm(" .long 0xdeeedeee"); asm(" .long 0x4c434d80"); asm(" .long __kmc_driver_name"); asm(" .long __kmc_driver_tmp");
リロケーションの解決(共有ライブラリ) PARNTERがカーネルの情報から取得 そのプロセスの task_struct file_struct mm_struct を参照して、/proc/(pid)/maps 相当の情報を取得 得られる情報から.text,.data,.bssをリロケーション
デマンドページングの解決 ICEからプログラムを送りこみ、アクセスしたいメモリでページが無い所のリードアクセスを発生させる ページ持ってくる処理はカーネルが行う これらの処理に関しては、利用者は全く意識する必要なく、PARTNER-Jetが自動的に行う PARNTER-Jetはメモリアクセスを確実に行うために、カーネル内の各種情報を解析する
日経エレクトロニクス2006年1月2日号 弊社著「Linuxやマルチコア環境のデバッグを支える仮想化技術」P121より
多重空間の解決 ICEが仮想空間を管理 必要最低限のカーネルパッチ プロセスをデバッグしている時には、そのプロセスの管理構造体(task_struct)を追いかける ブレークした時にも、その時のプロセスの状態を把握する 必要最低限のカーネルパッチ リアルタイムトレースのプロセス振り分けに必要(sched.c)。またその他少々 void __kmc_schedule(prev,next) struct task_struct *prev, *next; { int index_next; index_next=__kmc_schedules_index & (KMC_MAX_SHEDULE_LIST-1); ++__kmc_schedules_index; __kmc_schedules_list_pid[index_next]=next->pid; } ・・・・・・ #ifdef CONFIG_KMC_TRACE_EXT __kmc_schedule_call(prev,next); #endif /* * This just switches the register state and the * stack. */ switch_to(prev, next, prev); __schedule_tail(prev);
デモンストレーション
Linux向けの工夫 実行中プロセスへのアタッチ デバッグ情報の自動読み込み 関数トレースのプロセス対応 実行中、カーネル内で停止中、プロセスで停止中のどのタイミングでも可能 ICEがコンテキストとして保存してあるPCを保存し、アタッチ領域のアドレスに変更。再スケジュール時にアタッチ領域が実行されブレークする。 デバッグ情報の自動読み込み プロセスが利用している共有ライブラリのデバッグ情報を全て自動読み込み、自動リロケーション そのプロセスの管理構造体を解析する 関数トレースのプロセス対応 カーネル空間に停止している時に、指定のスレッドのバックトレースの参照が可能 ICEがコンテキストとして保存してあるPC,SP,FPとスタックを参照して再現 アプリケーションモード(次ページ以降参照) デバッグ対象プロセス以外を動かしたままデバッグ
アプリケーションモード - Virtual ICE Technology - メモリスワップなどにも完全対応 対象プロセスのみデバッグ デバッグ対象外のプロセスやカーネルなどは動作させたままデバッグ可能 ICE機能も有効活用 ハードウェアブレークポイントやトレース機能
アプリケーションモード - Virtual ICE Technology - ターゲットシステム プロセス1 プロセス2 プロセス3 デバイス ドライバ オペレーティングシステム CPU ターゲットシステム JTAG ICE PARTNER-Jet PARTNER Debug Control DLL デバッガ PARTNER/Win 仮想ICE 仮想ICE 仮想ICE デバッガ PARTNER/Win デバッガ PARTNER/Win デバッガ PARTNER/Win デバッグホスト パソコン カーネルや モジュールの デバッグ プロセス1の デバッグ プロセス2の デバッグ プロセス3の デバッグ
Linux対応プロファイル機能 JTAG ICEからプロファイルを実行 カーネルに最小限のパッチで実現 トレースデータを保持するためのターゲットメモリを使わない(メモリが限られる組み込み向け) カーネルに最小限のパッチで実現 ARM11の場合は、三つのソースで合計4カ所 ARM DCCの利用で通信の効率化 static inline unsigned int jtag_com_stat11(void) { unsigned int stat; __asm__("mrc p14,0,%0,c0,c1":"=r"(stat)); return stat; } static inline void jtag_com_put11(unsigned int data) __asm__("mcr p14,0,%0,c0,c5"::"r"(data)); return;
Linux対応プロファイル 主な機能 カーネル/プロセス両方を統合したプロファイルが可能 100usec単位のサンプリングで、ターゲットへの負荷は 1/100以下(ARM9の時) プロセスやスレッドの生成、消滅、切り替えの遷移を取得、プロセスID/プロセス名で表示 プロセス別の実行比率の取得 プロセス内/カーネル内の関数別の実行比率の取得 プロセス/カーネルの実行比率の取得 デバッガ上で参照するだけでなく、データを CSV形式に保存し、EXECLなどで自己解析も可能
オープンソースである事
組み込みLinuxデバッグの効率化 オープンソースである事を最大限活用する ICEだけでなく、ICE+カーネル改造の組み合わせでデバッグ環境はより強力になる 弊社のようなツールベンダもオープンソースであるので、Linux対応ツールは開発しやすかった PARNTER-JetはLinuxカーネルの主要データ構造(task_struct,mm_struct,file_structなど)を監視している ETM/AUDなどのトレースとソースコードの対応で、Linuxの動きを詳細に調査が可能
Linuxとツールの連携 カーネルやプロセスなどから、トレースやロギングしたいデータをJTAG使って転送する。 カーネルの特定箇所に来たときの、メモリフリーズ、トレースフリーズ、解析機能など 解析アプリケーション アプリA アプリB アプリC JTAG ICE カーネル ドライバ
お問い合わせ先 本社 東京オフィス URL:http://www.kmckk.co.jp jp-info@kmckk.co.jp 〒610-1104 京都市西京区大枝中山町2-44 TEL 075-335-1050 FAX 075-335-1051 東京オフィス 〒105-0004 東京都港区新橋2-14-4 Rビル 5F TEL 03-5157-4530 FAX 03-5157-4531 URL:http://www.kmckk.co.jp jp-info@kmckk.co.jp er-info@kmck.co.jp