JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
デバイスドライバの記述     Oracle Solaris 11.1 Information Library (日本語)
このドキュメントの評価
search filter icon
search icon

ドキュメントの情報

はじめに

パート I Oracle Solaris プラットフォーム用デバイスドライバの設計

1.  Oracle Solaris デバイスドライバの概要

2.  Oracle Solaris カーネルとデバイスツリー

3.  マルチスレッド

4.  プロパティー

5.  イベントの管理とタスクのキュー

6.  ドライバの自動構成

7.  デバイスアクセス: プログラム式入出力

8.  割り込みハンドラ

9.  ダイレクトメモリーアクセス (DMA)

10.  デバイスメモリーおよびカーネルメモリーのマッピング

11.  デバイスコンテキスト管理

12.  電源管理

13.  Oracle Solaris ドライバの強化

14.  階層化ドライバインタフェース (LDI)

パート II 特定の種類のデバイスドライバの設計

15.  文字デバイスのドライバ

16.  ブロックデバイスのドライバ

17.  SCSI ターゲットドライバ

18.  SCSI ホストバスアダプタドライバ

19.  ネットワークデバイスのドライバ

20.  USB ドライバ

21.  SR-IOV ドライバ

パート III デバイスドライバの構築

22.  ドライバのコンパイル、ロード、パッケージ化、およびテスト

23.  デバイスドライバのデバッグ、テスト、およびチューニング

ドライバのテスト

ハードハングを避けるためのデッドマン機能の有効化

シリアル接続を使用したテスト

tip 接続用にホストシステムを設定するには

SPARC プラットフォームのターゲットシステムの設定

x86 プラットフォーム上のターゲットシステムの設定

テストモジュールの設定

カーネル変数の設定

テストモジュールのロードとアンロード

kmem_flags デバッグフラグの設定

テストシステムでのデータ損失の回避

代替ブート環境の使用

代替カーネルでのブート

代替バックアップ計画の検討

システムクラッシュダンプの取得

デバイスディレクトリの復旧

デバッグツール

事後デバッグ

kmdb カーネルデバッガの使用

SPARC プラットフォームでの代替カーネルを使用した kmdb のブート

x86 プラットフォームでの代替カーネルを使用した kmdb のブート

kmdb でのブレークポイントの設定

ドライバ開発者向けの kmdb マクロ

mdb モジュラーデバッガの使用

モジュラーデバッガの使用開始

kmdbmdb を使用した便利なデバッグタスク

kmdb によるシステムレジスタの調査

カーネルメモリーリークの検出

mdb を使用したデバッガコマンドの記述

カーネルデータ構造体情報の取得

デバイスツリー情報の取得

ドライバのソフト状態情報の取得

カーネル変数の変更

ドライバのチューニング

カーネル統計

カーネル統計構造体のメンバー

カーネル統計構造体

カーネル統計関数

Oracle Solaris Ethernet ドライバのカーネル統計

動的計測を行うための DTrace

24.  推奨されるコーティング方法

パート IV 付録

A.  ハードウェアの概要

B.  Oracle Solaris DDI/DKI サービスのサマリー

C.  64 ビットデバイスドライバの準備

D.  コンソールフレームバッファードライバ

E.  pci.conf ファイル

索引

ドキュメントの品質向上のためのご意見をください
簡潔すぎた
読みづらかった、または難し過ぎた
重要な情報が欠けていた
内容が間違っていた
翻訳版が必要
その他
Your rating has been updated
貴重なご意見を有り難うございました!

あなたの貴重なご意見はより良いドキュメント作成の手助けとなります 内容の品質向上と追加コメントのためのアンケートに参加されますか?

デバッグツール

このセクションでは、デバイスドライバに適用可能な 2 つのデバッガについて説明します。両デバッガの詳細については、『Oracle Solaris Modular Debugger Guide 』を参照してください。

デバッガ kmdbmdb は基本的に同じユーザーインタフェースを共有しています。したがって、両ツールの同じコマンドでは、多くのデバッグ手法が適用可能となっています。どちらのデバッガもマクロ、dcmd、および dmod をサポートしています。dcmd (「ディーコマンド」と発音) は、現在のターゲットプログラムのすべてのプロパティーにアクセス可能なデバッガ内のルーチンです。dcmd は実行時に動的にロードできます。デバッガモジュールの短縮形である dmod は dcmd をパッケージ化したものであり、標準以外の動作を提供するためにロードできます。

mdbkmdb はどちらも、adbkadb といった旧バージョンのデバッガと下位互換性を保っています。mdb デバッガは、kmdb で使用可能なすべてのマクロを実行できるだけでなく、adb 向けの旧バージョンの任意のユーザー定義マクロも実行できます。標準マクロセットの検索場所については、『Oracle Solaris モジューラデバッガ』を参照してください。

事後デバッグ

事後解析は、ドライバ開発者にさまざまなメリットを提供します。1 つの問題を複数の開発者が並行して検査できます。単一のクラッシュダンプに対してデバッガの複数のインスタンスを同時に使用できます。解析をオフラインで実行できるため、可能な場合にはクラッシュしたシステムを稼働状態に戻すことができます。事後解析では、ユーザーが開発したデバッガ機能を dmod の形式で使用できます。kmdb などのリアルタイムデバッガではメモリー消費量が多すぎて使用できない機能でも、dmod ではバンドルできます。

kmdb がロードされた状態でシステムがパニック状態になると、その調査をただちに行えるようにデバッガに制御が渡されます。kmdb で現在の問題を解析するのが適切でないと考えられる場合、推奨される方針は、:c を使用して実行を継続し、クラッシュダンプを保存することです。システムがリブートしたら、保存したクラッシュダンプに対して mdb を使用して事後解析を実行できます。この処理は、アプリケーションのクラッシュをプロセスコアファイルに基づいてデバッグするのに似ています。


注 - 以前のバージョンの Oracle Solaris オペレーティングシステムでは、adb(1) が事後解析の推奨ツールでした。現在の Oracle Solaris オペレーティングシステムでは、mdb(1) が事後解析の推奨ツールです。mdb() の機能セットは、旧バージョンの crash(1M) ユーティリティーのコマンドセットよりも優れています。Oracle Solaris オペレーティングシステムでは crash ユーティリティーは使用できなくなりました。


kmdb カーネルデバッガの使用

kmdb デバッガは対話型のカーネルデバッガであり、次の機能を提供します。

このセクションでは、ユーザーがすでに kmdb デバッガについて精通していることを前提にしています。このセクションの重点は、デバイスドライバの設計時に役立つ kmdb 機能にあります。kmdb の使用方法について詳しく学ぶには、kmdb(1) のマニュアルページと『Oracle Solaris Modular Debugger Guide 』を参照してください。kadb に精通している場合は、kadb(1M) のマニュアルページを参照し、kadbkmdb の主な違いを確認してください。

kmdb デバッガのロードやアンロードは、任意で実行できます。kmdb のロードやアンロードの手順については、『Oracle Solaris モジューラデバッガ』を参照してください。安全性と利便性の観点から、代替カーネルでのブートを強くお勧めします。このセクションで説明するように、ブート処理は SPARC プラットフォームと x86 プラットフォームとでわずかに異なります。


注 - kmdb はデフォルトで、kmdb の実行中のプロンプトとして CPU ID を使用します。この章の例では、特に明記されていないかぎり、[0] をプロンプトとして使用しています。


SPARC プラットフォームでの代替カーネルを使用した kmdb のブート

kmdb と代替カーネルの両方を使用して SPARC システムをブートするには、次のいずれかのコマンドを使用します。

boot kmdb -D kernel.test/sparcv9/unix 
boot kernel.test/sparcv9/unix -k

x86 プラットフォームでの代替カーネルを使用した kmdb のブート

kmdb と代替カーネルの両方を使用して x86 システムをブートするには、次のいずれかのコマンドを使用します。

b kmdb -D kernel.test/unix 
b kernel.test/unix -k

kmdb でのブレークポイントの設定

ブレークポイントを設定するには、次の例に示すように bp コマンドを使用します。

例 23-5 kmdb での標準ブレークポイントの設定

[0]> myModule`myBreakpointLocation::bp
        

ターゲットモジュールがロードされていない場合、この状態を示すエラーメッセージが表示され、ブレークポイントは作成されません。この場合には遅延ブレークポイントを使用できます。遅延ブレークポイントは、指定されたモジュールがロードされた時点で自動的に有効になります。遅延ブレークポイントを設定するには、bp コマンドのあとにターゲット位置を指定します。次に遅延ブレークポイントの例を示します。

例 23-6 kmdb での遅延ブレークポイントの設定

[0]>::bp myModule`myBreakpointLocation       

ブレークポイントの使用方法の詳細については、『Oracle Solaris モジューラデバッガ』を参照してください。次の 2 つの行のいずれかを入力してもヘルプが得られます。

> ::help bp
> ::bp dcmd

ドライバ開発者向けの kmdb マクロ

kmdb(1M) デバッガでサポートされているマクロを使用すると、カーネルデータ構造体を表示できます。kmdb のマクロを表示するには $M を使用します。マクロは次の形式で使用します。

[ address ] $<macroname

注 - これらのマクロから表示される情報もその表示形式も、インタフェースの一部ではありません。したがって、その情報と形式は常に変更される可能性があります。


次の表に含まれる kmdb マクロは、デバイスドライバの開発者に特に役立ちます。便宜上、該当する場合は旧バージョンのマクロ名も示します。

表 23-1 kmdb マクロ

dcmd
旧バージョンのマクロ
説明
::devinfo
devinfo

devinfo_brief

devinfo.prop

あるデバイスノードのサマリーを出力します
::walk devinfo_parents
devinfo.parent
デバイスノードの上位ノードを調査します
::walk devinfo_sibling
devinfo.sibling
あるデバイスノードの兄弟ノードを調査します
::minornodes
devinfo.minor
指定されたデバイスノードに対応するマイナーノードを出力します
::major2name
指定されたデバイスノードにバインドされたデバイスの名前を出力します。
::devbindings
指定されたデバイスノードまたはメジャー番号にバインドされたデバイスノードを出力します。

::devinfo dcmd で表示されるノード状態は、次のいずれかの値を取ります。

DS_ATTACHED

ドライバの attach(9E) ルーチンが正常に復帰しました。

DS_BOUND

このノードはドライバにバインドされていますが、ドライバの probe(9E) ルーチンがまだ呼び出されていません。

DS_INITIALIZED

親のネクサスがドライバ用のバスアドレスを割り当てました。実装に固有の初期化が完了しています。ドライバの probe(9E) ルーチンは、現時点でまだ呼び出されていません。

DS_LINKED

このデバイスノードがカーネルのデバイスツリー内にリンクされましたが、システムはまだこのノードのドライバを検出していません。

DS_PROBED

ドライバの probe(9E) ルーチンが正常に復帰しました。

DS_READY

このデバイスは完全に構成されています。

mdb モジュラーデバッガの使用

mdb(1) モジュラーデバッガは、次のタイプのファイルに適用できます。

mdb デバッガは、カーネルの問題を解析するための高度なデバッグサポートを提供します。このセクションでは mdb 機能の概要を説明します。mdb の完全な説明については、『Oracle Solaris Modular Debugger Guide』を参照してください。

mdb を使用してライブカーネル状態を変更することも可能ですが、mdb には、kmdb で提供されているカーネル実行制御の機能がありません。このため、実行時デバッグには kmdb をお勧めします。mdb デバッガは通常、静的な状況で使用されます。


注 - mdb のプロンプトは > です。


モジュラーデバッガの使用開始

mdb デバッガにはデバッガモジュールを実装するための拡張プログラミング API が用意されているため、ドライバ開発者はカスタムのデバッグサポートを実装できます。mdb デバッガには、コマンド行編集、コマンド履歴、出力ページャー、オンラインヘルプなど、多数のユーザビリティー機能も用意されています。


注 - adb マクロは使用するべきではありません。その機能の大部分が、mdb の dcmd に置き換えられました。


mdb デバッガには一連の豊富なモジュールや dcmd が用意されています。これらのツールを使用すると、Oracle Solaris カーネル、任意の関連モジュール、およびデバイスドライバをデバッグできます。これらの機能を使用すると、次のようなタスクを実行できます。

使用を開始するには、次の例に示すように、クラッシュディレクトリに移動して mdb と入力し、システムクラッシュダンプを指定します。

例 23-7 クラッシュダンプに対する mdb の呼び出し

% cd /var/crash/testsystem
% ls
bounds     unix.0    vmcore.0
% mdb unix.0 vmcore.0
Loading modules: [ unix krtld genunix ufs_log ip usba s1394 cpc nfs ]
> ::status
debugging crash dump vmcore.0 (64-bit) from testsystem
operating system: 5.10 Generic (sun4u)
panic message: zero
dump content: kernel pages only

mdb からの応答として > プロンプトが返されたら、コマンドを実行できます。

ライブシステム上の実行中のカーネルを検査するには、次のようにシステムプロンプトから mdb を実行します。

例 23-8 実行中のカーネルに対する mdb の呼び出し

# mdb -k
Loading modules: [ unix krtld genunix ufs_log ip usba s1394 ptm cpc ipc nfs ]
> ::status
debugging live kernel (64-bit) on testsystem
operating system: 5.10 Generic (sun4u)

kmdbmdb を使用した便利なデバッグタスク

このセクションでは便利なデバッグタスクの例について説明します。このセクションに含まれるタスクは、特に明記されていないかぎり、mdbkmdb のいずれかを使用して実行できます。このセクションでは、ユーザーに kmdbmdb の使用に関する基礎知識があることを前提にしています。ここで示す情報は、使用するシステムの種類に依存します。これらの例を作成する際には、64 ビットカーネルが稼働する Sun Blade 100 ワークステーションを使用しました。


注意

注意 - カーネル構造体のデータを変更すると不可逆なデータ破壊が起こる可能性があるため、細心の注意を払うべきです。Oracle Solaris DDI の一部でない構造体に含まれるデータを変更したり、そのようなデータに依存したりしないようにしてください。Oracle Solaris DDI の一部である構造体については、Intro(9S) のマニュアルページを参照してください。


kmdb によるシステムレジスタの調査

kmdb デバッガを使用すると、マシンのレジスタを 1 つのグループとして表示することも、個々のレジスタ単位で表示することもできます。すべてのレジスタを 1 つのグループとして表示するには、次の例に示すように $r を使用します。

例 23-9 kmdb による SPARC プロセッサ上のすべてのレジスタの読み取り

[0]: $r

g0    0                                 l0      0
g1    100130a4      debug_enter         l1      edd00028
g2    10411c00      tsbmiss_area+0xe00  l2      10449c90
g3    10442000      ti_statetbl+0x1ba   l3      1b
g4    3000061a004                       l4      10474400     ecc_syndrome_tab+0x80
g5    0                                 l5      3b9aca00
g6    0                                 l6      0
g7    2a10001fd40                       l7      0
o0    0                                 i0      0
o1    c                                 i1      10449e50
o2    20                                i2      0
o3    300006b2d08                       i3      10
o4    0                                 i4      0
o5    0                                 i5      b0
sp    2a10001b451                       fp      2a10001b521
o7    1001311c      debug_enter+0x78    i7      1034bb24     zsa_xsint+0x2c4
y     0
tstate: 1604  (ccr=0x0, asi=0x0, pstate=0x16, cwp=0x4)
pstate: ag:0 ie:1 priv:1 am:0 pef:1 mm:0 tle:0 cle:0 mg:0 ig:0
winreg: cur:4 other:0 clean:7 cansave:1 canrest:5 wstate:14
tba   0x10000000
pc    edd000d8 edd000d8:        ta      %icc,%g0 + 125
npc   edd000dc edd000dc:        nop

デバッガは各レジスタの値を、そのレジスタと同じ名前を持つ変数にエクスポートします。変数を読み取ると、レジスタの現在の値が返されます。変数に書き込みを行うと、関連するマシンレジスタの値が変更されます。次の例では、x86 マシン上の %o0 レジスタの値を、0 から 1 に変更しています。

例 23-10 kmdb による x86 マシン上のレジスタの読み取りと書き込み

[0]> &<eax=K
        c1e6e0f0
[0]> 0>eax
[0]> &<eax=K
        0
[0]>  c1e6e0f0>eax

別のプロセッサのレジスタを検査する必要がある場合は、::cpuregs dcmd を使用できます。次の例に示すように、検査対象となるプロセッサの ID は、この dcmd へのアドレスとして指定することも、-c オプションの値として指定することもできます。

例 23-11 別のプロセッサのレジスタの検査

[0]> 0::cpuregs
   %cs = 0x0158            %eax = 0xc1e6e0f0 kmdbmod`kaif_dvec
   %ds = 0x0160            %ebx = 0x00000000

次の例では、SPARC マシン上でプロセッサを 0 から 3 に切り替えています。%g3 レジスタが検査されたあと、クリアされています。新しい値を確認するため、%g3 が再度読み取られています。

例 23-12 指定されたプロセッサからの、特定のレジスタ値の取得

[0]> 3::switch
[3]> <g3=K
        24
[3]> 0>g3
[3]> <g3
        0

カーネルメモリーリークの検出

::findleaks dcmd は、カーネルクラッシュダンプ内のメモリーリークを検出する強力で効率的な機能を提供します。カーネルメモリーデバッグ機能のフルセットを有効化しないと、::findleaks が有効になりません。詳細については、kmem_flags デバッグフラグの設定」を参照してください。ドライバの開発中やテスト中に ::findleaks を実行すると、メモリーリークが発生したためにカーネルリソースが浪費されているコードが検出されます。『Oracle Solaris Modular Debugger Guide』の第 9 章「Debugging With the Kernel Memory Allocator」Oracle Solaris Modular Debugger Guide を参照してください。


注 - カーネルメモリーリークが発生したコードがあると、サービス拒否攻撃に対するシステムの脆弱性が高まる可能性があります。


mdb を使用したデバッガコマンドの記述

mdb デバッガには、ドライバのデバッグ用にカスタマイズ可能なデバッガ機能を実装するための強力な API が用意されています。このプログラミング API の詳細については、『Oracle Solaris モジューラデバッガ』で説明されています。

SUNWmdbdm パッケージは、ディレクトリ /usr/demo/mdbmdb のサンプルソースコードをインストールします。mdb を使用すると、ドライバが正しく動作していることを確認するための時間のかかるデバッグ作業やデバッグ支援を自動化できます。また、mdb デバッグモジュールをドライバ製品と一緒にパッケージ化することもできます。パッケージ化すると、サービス担当者がこれらの機能を顧客サイトで使用できるようになります。

カーネルデータ構造体情報の取得

Oracle Solaris カーネルはデータ型の情報を構造体として提供しており、これらの構造体は、kmdbmdb のいずれかを使用して検査できます。


注 - kmdbmdb の dcmd は、mdb 用として設計された圧縮シンボリックデバッギング情報を含むオブジェクトでしか使用できません。現在、この情報を利用できるのは、特定の Oracle Solaris カーネルモジュールのみです。このシンボリックデバッギング情報を処理するには、SUNWzlib パッケージをインストールする必要があります。


次の例は、scsi_pkt 構造体のデータを表示する方法を示しています。

例 23-13 デバッガによるカーネルデータ構造体の表示

> 7079ceb0::print -t 'struct scsi_pkt'
{
    opaque_t pkt_ha_private = 0x7079ce20
    struct scsi_address pkt_address = {
        struct scsi_hba_tran *a_hba_tran = 0x70175e68
        ushort_t a_target = 0x6
        uchar_t a_lun = 0
        uchar_t a_sublun = 0
    }
    opaque_t pkt_private = 0x708db4d0
    int (*)() *pkt_comp = sd_intr
    uint_t pkt_flags = 0
    int pkt_time = 0x78
    uchar_t *pkt_scbp = 0x7079ce74
    uchar_t *pkt_cdbp = 0x7079ce64
    ssize_t pkt_resid = 0
    uint_t pkt_state = 0x37
    uint_t pkt_statistics = 0
    uchar_t pkt_reason = 0
}

データ構造体のサイズは、デバッグ時に役立つ可能性があります。ある構造体のサイズを取得するには、次の例に示すように ::sizeof dcmd を使用します。

例 23-14 カーネルデータ構造体のサイズの表示

> ::sizeof struct scsi_pkt
sizeof (struct scsi_pkt) = 0x58

デバッグ時には、構造体内の特定のメンバーのアドレスも役立ちます。あるメンバーのアドレスを調査する場合に使用可能な方法は、いくつか存在します。

構造体の特定のメンバーのオフセットを取得するには、次の例のように ::offsetof dcmd を使用します。

例 23-15 カーネルデータ構造体へのオフセットの表示

> ::offsetof struct scsi_pkt pkt_state
offsetof (struct pkt_state) = 0x48

構造体のすべてのメンバーのアドレスを表示するには、次の例のように ::print dcmd で -a オプションを指定します。

例 23-16 カーネルデータ構造体の相対アドレスの表示

> ::print -a struct scsi_pkt
{
    0 pkt_ha_private
    8 pkt_address {
    ...
    }
    18 pkt_private
    ...
}

::print でアドレスと -a オプションを組み合わせて指定すると、各メンバーの絶対アドレスが表示されます。

例 23-17 カーネルデータ構造体の絶対アドレスの表示

> 10000000::print -a struct scsi_pkt
{
    10000000 pkt_ha_private
    10000008 pkt_address {
    ...
    }
    10000018 pkt_private
    ...
}

::print::sizeof::offsetof の各 dcmd を使用すると、ドライバが Oracle Solaris カーネルと対話する際に発生した問題をデバッグできます。


注意

注意 - この機能を使用すると、のカーネルデータ構造体にアクセスできます。ユーザーは、構造体が DDI の一部として表示されるかどうかにかかわらず、任意の構造体を検査できます。したがって、明示的に DDI の一部になっていないデータ構造体には依存しないようにしてください。



注 - 前述の dcmd は、mdb 用として設計された圧縮シンボリックデバッギング情報を含むオブジェクトでしか使用しないようにしてください。現在、シンボリックデバッギング情報を使用できるのは、特定の Oracle Solaris カーネルモジュールのみです。シンボリックデバッギング情報を処理するには、SUNWzlib (32 ビット) または SUNWzlibx (64 ビット) 圧縮ソフトウェアをインストールする必要があります。kmdb デバッガは、SUNWzlib または SUNWzlibx パッケージの有無にかかわらず、シンボリックタイプのデータを処理できます。


デバイスツリー情報の取得

mdb デバッガには、カーネルデバイスツリーを表示するための ::prtconf dcmd が用意されています。::prtconf dcmd の出力は、prtconf(1M) コマンドの出力に似ています。

例 23-18 ::prtconf dcmd の使用

> ::prtconf
300015d3e08      SUNW,Sun-Blade-100
    300015d3c28      packages (driver not attached)
        300015d3868      SUNW,builtin-drivers (driver not attached)
        300015d3688      deblocker (driver not attached)
        300015d34a8      disk-label (driver not attached)
        300015d32c8      terminal-emulator (driver not attached)
        300015d30e8      obp-tftp (driver not attached)
        300015d2f08      dropins (driver not attached)
        300015d2d28      kbd-translator (driver not attached)
        300015d2b48      ufs-file-system (driver not attached)
    300015d3a48      chosen (driver not attached)
    300015d2968      openprom (driver not attached)

ノードを表示するには、次の例に示すように ::devinfo dcmd などのマクロを使用します。

例 23-19 特定のノードのデバイス情報の表示

> 300015d3e08::devinfo
300015d3e08      SUNW,Sun-Blade-100
        System properties at 0x300015abdc0:
            name='relative-addressing' type=int items=1
                value=00000001
            name='MMU_PAGEOFFSET' type=int items=1
                value=00001fff
            name='MMU_PAGESIZE' type=int items=1
                value=00002000
            name='PAGESIZE' type=int items=1
                value=00002000
        Driver properties at 0x300015abe00:
            name='pm-hardware-state' type=string items=1
                value='no-suspend-resume'

::prtconf を使用すると、デバイスツリー内でドライバが接続されている場所を確認したり、デバイスのプロパティーを表示したりできます。また、次のように ::prtconf に詳細 (-v) フラグを指定することで、各デバイスノードのプロパティーを表示することもできます。

例 23-20 詳細モードの ::prtconf dcmd の使用

> ::prtconf -v
DEVINFO          NAME
300015d3e08      SUNW,Sun-Blade-100
        System properties at 0x300015abdc0:
            name='relative-addressing' type=int items=1
                value=00000001
            name='MMU_PAGEOFFSET' type=int items=1
                value=00001fff
            name='MMU_PAGESIZE' type=int items=1
                value=00002000
            name='PAGESIZE' type=int items=1
                value=00002000
        Driver properties at 0x300015abe00:
            name='pm-hardware-state' type=string items=1
                value='no-suspend-resume'
        ...
        300015ce798      pci10b9,5229, instance #0
                Driver properties at 0x300015ab980:
                    name='target2-dcd-options' type=any items=4
                        value=00.00.00.a4
                    name='target1-dcd-options' type=any items=4
                        value=00.00.00.a2
                    name='target0-dcd-options' type=any items=4
                        value=00.00.00.a4

ドライバのインスタンスを特定する別の方法として、::devbindings dcmd が挙げられます。次の例に示すように、ドライバ名が指定されると、このコマンドは指定されたドライバのすべてのインスタンスの一覧を表示します。

例 23-21 ::devbindings dcmd を使用したドライバインスタンスの特定

> ::devbindings dad
300015ce3d8      ide-disk (driver not attached)
300015c9a60      dad, instance #0
        System properties at 0x300015ab400:
            name='lun' type=int items=1
                value=00000000
            name='target' type=int items=1
                value=00000000
            name='class_prop' type=string items=1
                value='ata'
            name='type' type=string items=1
                value='ata'
            name='class' type=string items=1
                value='dada'
...
300015c9880      dad, instance #1
        System properties at 0x300015ab080:
            name='lun' type=int items=1
                value=00000000
            name='target' type=int items=1
                value=00000002
            name='class_prop' type=string items=1
                value='ata'
            name='type' type=string items=1
                value='ata'
            name='class' type=string items=1
                value='dada'

ドライバのソフト状態情報の取得

ドライバをデバッグするときの一般的な問題は、ある特定のドライバインスタンスの ソフト状態を取得することです。ソフト状態は、ddi_soft_state_zalloc(9F) ルーチンで割り当てられます。ドライバからソフト状態を取得するには、ddi_get_soft_state(9F) を使用します。ソフト状態ポインタの名前が、ddi_soft_state_init(9F) の第一の引数になります。名前を使用すると、mdb::softstate dcmd を使用して特定のドライバインスタンスのソフト状態を取得できます。

> *bst_state::softstate 0x3
702b7578

この場合、::softstate を使用して bst サンプルドライバのインスタンス 3 のソフト状態を取得しています。このポインタは、ドライバがこのインスタンスの状態を追跡するために使用する bst_soft 構造体を参照しています。

カーネル変数の変更

カーネル変数などのカーネル状態を変更する場合、kmdbmdb のどちらを使用してもかまいません。mdb は変更前にカーネルを停止しないため、mdb によるカーネル状態の変更は注意して行うべきです。kmdb を使用すると一連の変更を原子的に行えますが、これは、kmdb がユーザーにアクセスを許可する前にカーネルを停止するためです。mdb デバッガでは、原子的な変更は 1 つしか行えません。

変更の実行時には、必ず適切な書式指定子を使用してください。書式は次のとおりです。

変更する変数のサイズを確認するには、::sizeof dcmd を使用します。

次の例では、moddebug の値を値 0x80000000 で上書きしています。

例 23-22 デバッガによるカーネル変数の変更

> moddebug/W 0x80000000
    moddebug:       0 = 0x80000000