ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
![]() |
デバイスドライバの記述 Oracle Solaris 11.1 Information Library (日本語) |
パート I Oracle Solaris プラットフォーム用デバイスドライバの設計
2. Oracle Solaris カーネルとデバイスツリー
22. ドライバのコンパイル、ロード、パッケージ化、およびテスト
23. デバイスドライバのデバッグ、テスト、およびチューニング
LDI には、デバイスの階層化と使用状態の情報を報告する、ユーザーレベルのライブラリとコマンドインタフェースが含まれています。「デバイス情報ライブラリインタフェース」では、デバイス階層化の情報を報告するための libdevinfo(3LIB) インタフェースについて説明します。「システム構成の出力コマンドインタフェース」では、カーネルデバイスの使用状態情報を報告する、prtconf(1M) インタフェースについて説明します。「デバイスユーザーコマンドインタフェース」では、デバイスコンシューマの情報を報告する、fuser(1M) インタフェースについて説明します。
LDI には、デバイス階層化情報のスナップショットを報告する libdevinfo(3LIB) インタフェースが用意されています。デバイス階層化は、システム内の 1 つのデバイスが、システム内の別のデバイスのコンシューマであるときに発生します。デバイス階層化情報が報告されるのは、コンシューマとターゲットの両方が、スナップショット内に含まれる 1 つのデバイスノードにバインドされている場合のみです。
デバイス階層化情報は、libdevinfo(3LIB) インタフェースによって有向グラフとして報告されます。i ノードは、グラフの頂点を表し、デバイスノードにバインドされた抽象概念です。libdevinfo(3LIB) インタフェースを使用すると、ノードの名前やデバイス番号などの i ノードのプロパティーにアクセスできます。
グラフのエッジはリンクによって表されます。リンクには、デバイスコンシューマを表すソース i ノードがあります。また、リンクにはターゲットデバイスを表すターゲット i ノードがあります。
次に、libdevinfo(3LIB) デバイス階層化情報のインタフェースについて説明します。
デバイス階層化情報を得られるようにするスナップショットフラグです。
2 つのエンドポイント間の有向リンクです。各エンドポイントは 1 つの di_lnode_t です。不透明な構造体です。
リンクのエンドポイントです。不透明な構造体です。di_lnode_t は di_node_t にバインドされます。
1 つのデバイスノードを表します。不透明な構造体です。di_node_t は di_lnode_t にバインドされるとは限りません。
スナップショット内のすべてのリンクを調べます。
スナップショット内のすべての i ノードを調べます。
指定された di_node_t ノードがソースとターゲットのいずれかである次のリンクへのハンドルを取得します。
指定された di_lnode_t i ノードがソースとターゲットのいずれかである次のリンクへのハンドルを取得します。
di_link_t リンクの指定されたエンドポイントに対応する i ノードを取得します。
リンクの spectype を取得します。spectype は、ターゲットデバイスがアクセスされる方法を示します。ターゲットデバイスはターゲット i ノードによって表されます。
指定の di_node_t デバイスノードに関連付けられている、次に出現する指定された di_lnode_t i ノードへのハンドルを取得します。
指定された i ノードに関連付けられている名前を取得します。
指定された i ノードに関連付けられているデバイスノードへのハンドルを取得します。
指定された i ノードに関連付けられているデバイスノードのデバイス番号を取得します。
LDI によって返されるデバイス階層化情報は非常に複雑な場合があります。そのため LDI には、デバイスツリーやデバイスの使用状態のグラフをたどる助けになるインタフェースが用意されています。これらのインタフェースによって、デバイスツリースナップショットのコンシューマはカスタムデータポインタを、スナップショット内の異なる構造に関連付けることができます。たとえば、アプリケーションは、i ノードをたどるときに、各 i ノードに関連付けられているカスタムポインタを更新し、参照済みの i ノードにマークを付けることができます。
次に、libdevinfo(3LIB) ノードおよびリンクのマーク付けインタフェースについて説明します。
指定されたデータを指定された i ノードと関連付けます。この関連付けによって、スナップショット内の i ノードをたどることができます。
di_lnode_private_set(3DEVINFO) への呼び出しを通して、i ノードに関連付けられていたデータへのポインタを取得します。
指定されたデータを指定されたリンクと関連付けます。この関連付けによって、スナップショット内のリンクをたどることができます。
di_link_private_set(3DEVINFO) への呼び出しを通して、リンクに関連付けられていたデータへのポインタを取得します。
prtconf(1M) コマンドは、カーネルデバイス使用状態の情報を表示するように拡張されています。デフォルトの prtconf( 1M) 出力は変更されていません。デバイス使用状態情報は、prtconf(1M) コマンドで詳細オプション (-v) を指定したときに表示されます。特定のデバイスに関する使用状態情報は、prtconf(1M) コマンド行で、そのデバイスへのパスを指定したときに表示されます。
デバイスマイナーノードとデバイス使用状態情報を表示します。カーネルコンシューマと、各カーネルコンシューマが現在開いているマイナーノードを表示します。
path によって指定されたデバイスのデバイス使用状態情報を表示します。
path によって指定されたデバイスのデバイス使用状態情報と、path の上位ノードであるすべてのデバイスノードを表示します。
path によって指定されたデバイスのデバイス使用状態情報と、path の子であるすべてのデバイスノードを表示します。
例 14-6 デバイス使用状態情報
特定のデバイスに関する使用状態情報が必要なときには、有効な任意のデバイスパスを path パラメータの値として指定できます。
% prtconf /dev/cfg/c0 SUNW,isptwo, instance #0
例 14-7 上位ノードの使用状態情報
特定のデバイスと、その特定デバイスの上位ノードになっているすべてのデバイスノードに関する使用状態情報を表示するには、prtconf(1M) コマンドに -a フラグを指定します。上位ノードには、デバイスツリーのルートまでのすべてのノードが含まれます。prtconf(1M) コマンドに -a フラグを指定した場合は、デバイスの path 名も指定する必要があります。
% prtconf -a /dev/cfg/c0 SUNW,Sun-Fire ssm, instance #0 pci, instance #0 pci, instance #0 SUNW,isptwo, instance #0
例 14-8 子ノードの使用状態情報
特定のデバイスと、その特定デバイスの子になっているすべてのデバイスノードに関する使用状態情報を表示するには、prtconf(1M) コマンドに -c フラグを指定します。prtconf(1M) コマンドに - c フラグを指定した場合は、デバイスの path 名も指定する必要があります。
% prtconf -c /dev/cfg/c0 SUNW,isptwo, instance #0 sd (driver not attached) st (driver not attached) sd, instance #1 sd, instance #0 sd, instance #6 st, instance #1 (driver not attached) st, instance #0 (driver not attached) st, instance #2 (driver not attached) st, instance #3 (driver not attached) st, instance #4 (driver not attached) st, instance #5 (driver not attached) st, instance #6 (driver not attached) ses, instance #0 (driver not attached) ...
例 14-9 階層化およびデバイスマイナーノードの情報 – キーボード
特定デバイスに関するデバイス階層化とデバイスマイナーノードの情報を表示するには、prtconf(1M) コマンドに -v フラグを指定します。
% prtconf -v /dev/kbd conskbd, instance #0 System properties: ... Device Layered Over: mod=kb8042 dev=(101,0) dev_path=/isa/i8042@1,60/keyboard@0 Device Minor Nodes: dev=(103,0) dev_path=/pseudo/conskbd@0:kbd spectype=chr type=minor dev_link=/dev/kbd dev=(103,1) dev_path=/pseudo/conskbd@0:conskbd spectype=chr type=internal Device Minor Layered Under: mod=wc accesstype=chr dev_path=/pseudo/wc@0
この例では、/dev/kbd デバイスがハードウェアキーボードデバイス (/isa/i8042@1,60/keyboard@0) の上に階層化されていることが示されています。また、/dev/kbd デバイスにはデバイスマイナーノードが 2 つあることが示されています。最初のマイナーノードには、ノードにアクセスするために使用できる /dev リンクがあります。2 つ目のマイナーノードは、ファイルシステムからはアクセスできない内部ノードです。2 つ目のマイナーノードは、ワークステーションコンソールである wc ドライバによって開かれています。この例の出力を、例 14-12 の出力と比較してください。
例 14-10 階層化およびデバイスマイナーノードの情報 – ネットワークデバイス
この例は、現在接続されているネットワークデバイスをどのデバイスが使用しているかを示しています。
% prtconf -v /dev/iprb0 pci1028,145, instance #0 Hardware properties: ... Interrupt Specifications: ... Device Minor Nodes: dev=(27,1) dev_path=/pci@0,0/pci8086,244e@1e/pci1028,145@c:iprb0 spectype=chr type=minor alias=/dev/iprb0 dev=(27,4098) dev_path=<clone> Device Minor Layered Under: mod=udp6 accesstype=chr dev_path=/pseudo/udp6@0 dev=(27,4097) dev_path=<clone> Device Minor Layered Under: mod=udp accesstype=chr dev_path=/pseudo/udp@0 dev=(27,4096) dev_path=<clone> Device Minor Layered Under: mod=udp accesstype=chr dev_path=/pseudo/udp@0
この例では、iprb0 デバイスが udp および udp6 の下でリンクされたことが示されています。udp と udp6 が使用しているマイナーノードへのパスは表示されていないことに注意してください。ここでパスが表示されていないのは、iprb ドライバの clone による開く操作でマイナーノードが作成され、その結果これらのノードのアクセスに使用できるファイルシステムのパスがないことが理由です。この例の出力を、例 14-11 の出力と比較してください。
fuser(1M) コマンドは、デバイス使用状態の情報を表示するように拡張されています。fuser(1M) コマンドは、path がデバイスマイナーノードを表している場合のみ、デバイス使用状態情報を表示します。-d フラグが fuser(1M) コマンドで有効なのは、デバイスマイナーノードを表す path を指定した場合だけです。
path がデバイスマイナーノードを表している場合に、アプリケーションデバイスコンシューマとカーネルデバイスコンシューマに関する情報を表示します。
path で表されたデバイスマイナーノードと関連付けられている、配下のデバイスのユーザーをすべて表示します。
カーネルデバイスコンシューマは次の 4 つの形式のいずれかで報告されます。カーネルデバイスコンシューマは常に角括弧で囲まれます ([])。
[kernel_module_name] [kernel_module_name,dev_path=path] [kernel_module_name,dev=(major,minor)] [kernel_module_name,dev=(major,minor),dev_path=path]
fuser(1M) コマンドでファイルまたはデバイスユーザーが表示されるとき、その出力は、stdout でのプロセス ID と、それに続く stderr での文字から構成されます。stderr での文字は、ファイルまたはデバイスがどのように使用されているかを説明するものです。カーネルコンシューマ情報はすべて stderr に表示されます。stdout にはカーネルコンシューマ情報は表示されません。
-d フラグを使用しない場合、fuser(1M) コマンドは path によって指定されたデバイスマイナーノードのコンシューマについてのみ報告します。-d フラグを使用する場合、fuser(1M) コマンドは、path によって指定されたマイナーノードの下にあるデバイスノードのコンシューマについて報告します。次の例は、これら 2 つの場合のレポート出力における違いを示しています。
例 14-11 配下のデバイスノードのコンシューマ
ほとんどのネットワークデバイスは、デバイスが開かれたときにマイナーノードを複製します。クローンのマイナーノードのデバイス使用状態情報を要求すると、使用状態情報に、そのデバイスを使用してるプロセスはないと表示される可能性があります。代わりに、配下のデバイスノードのデバイス使用状態情報を要求すると、使用状態情報に、1 つのプロセスがそのデバイスを使用してると表示される可能性があります。この例では、デバイスの path のみが fuser(1M) コマンドに渡された場合、報告されるデバイスコンシューマはありません。-d フラグが使用されると、出力には、udp および udp6 によってデバイスが使用されていることが表示されます。
% fuser /dev/iprb0 /dev/iprb0: % fuser -d /dev/iprb0 /dev/iprb0: [udp,dev_path=/pseudo/udp@0] [udp6,dev_path=/pseudo/udp6@0]
この例の出力を、例 14-10 の出力と比較してください。
例 14-12 キーボードデバイスのコンシューマ
この例では、カーネルコンシューマは /dev/kbd にアクセスしています。/dev/kbd デバイスにアクセスしているカーネルコンシューマは、ワークステーションコンソールドライバです。
% fuser -d /dev/kbd /dev/kbd: [genunix] [wc,dev_path=/pseudo/wc@0]
この例の出力を、例 14-9 の出力と比較してください。