web-dev-qa-db-ja.com

ドライバーモジュールのコードフローを知る方法

私はLinuxデバイスドライバーを勉強していますが、私の主な焦点はwifiドライバーです。デバイスをプラグインしたときのコードの流れを知りたい。たぶん、すべての関数にprintk行を追加するようなことができます。私が持っているデバイスはath9k_htcドライバーでサポートされています。学習用にドライバーコードに変更を加えたい。

Linuxのドライバーモジュールのコードフローを理解するための正しいまたは一般的なアプローチは何ですか?

7
Akshdeep Singh

これを行いたいときは、 ftraceフレームワーク を使用します。まず、特別なファイルシステムをマウントします。

mount -t tracefs nodev /sys/kernel/tracing

(rootとして、このすべてのrootになる必要があります。とにかくすべてをrootとして実行します。Sudoを使用するよりも、ルートシェルを持つ方が簡単です)。

次に、そのディレクトリに移動します。

cd /sys/kernel/tracing

簡単な要約を提供する基本的なREADMEが含まれています。関数呼び出しを調べるには、 関数グラフトレーサーfunction_graphavailable_tracersで使用します。関心のある関数、たとえば ath9k_htc_tx を特定して設定します

echo ath9k_htc_tx > set_graph_function

他の関数を追加できます。最初の関数の後に必ず>>を使用してください。設定された機能は、

cat set_graph_function

set_graph_functionに書き込むと、実行中のカーネルに対して関数がチェックされます。関数が見つからない場合、書き込みは失敗するので、何もトレースしない場合はすぐにわかります。

関数が設定されたら、トレーサーを有効にします。

echo function_graph > current_tracer

次に、traceファイルを監視します。トレーサーを再度無効にするには、

echo nop > current_tracer

またはtracing_onを反転するには、0または1を書き込みます(0はトレースを無効にし、1は再度有効にします)。

15
Stephen Kitt

主な要点は、ドライバーが上位インターフェイスと下位インターフェイスを接続することです。の場合 ath9k_htc、下部のインターフェースはUSB、上部のインターフェースはネットワークスタックです。

制御フローは、主に状態マシンであり、同期せずに両方のインターフェースから到着するイベントに対応できます。たとえば、ネットワークインターフェースがマルチキャストグループに参加するようにドライバーに通知すると同時に、デバイスが排出されたUSBサブシステム-マルチプロセッサシステムでは、これらのイベントはさまざまなCPUで報告され、ドライバーは同時に入力されます。

ほとんどのドライバーはプロセスまたはスレッドコンテキストを持たず、純粋にイベント駆動型であり、ドライバーの外部にイベントループがあるため、通常、特定のイベントを処理する小さな関数が多数あり、それらを転送しようとし、失敗した場合はどこかにメモします。そしてすぐに戻ります。

典型的なドライバーの制御フローを視覚化する最も賢明な方法は、共有のロック可能なリソースのマップを描画し、それらにアクセスする機能です。一般的な通信の行は、リストをロックし、データを追加し、ロックを解除することです。一方の側にUSB関連の関数を描画し、もう一方のリソースにネットワーク関連の関数を描画すると、最も明確な画像が得られます。

1
Simon Richter