Go to main content
Oracle® Solaris 11.3 デバイスドライバの記述

印刷ビューの終了

更新: 2016 年 11 月
 
 

テストモジュールの設定

/etc ディレクトリ内の system(4) ファイルを使用すると、ブート時にカーネル変数の値を設定できます。カーネル変数を使用すると、ドライバの複数の動作を切り替えたり、カーネルが提供するデバッグ機能を活用したりできます。デバッグ時に非常に役立つ可能性のあるカーネル変数 moddebug と kmem_flags については、このセクションで後述します。デッドマン機能の使用も参照してください。

/etc/system はカーネルのブート時に一度読み取られるだけであるため、ブート後のカーネル変数の変更は信頼できません。このファイルを変更したあと、その変更を有効にするには、システムをリブートする必要があります。ファイルの変更後にシステムが機能しなくなった場合は、ask (-a) オプションを指定してブートします。その後、/dev/null をシステムファイルとして指定します。


注 - 将来のリリースでもカーネル変数が存在すると仮定することはできません。

カーネル変数の設定

set コマンドは、モジュール変数またはカーネル変数の値を変更します。モジュール変数を設定するには、次のようにモジュール名と変数を指定します。

set module_name:variable=value

たとえば、myTest という名前のドライバの変数 test_debug を設定するには、set を次のように使用します。

% set myTest:test_debug=1

カーネル自体によってエクスポートされた変数を設定する場合は、モジュール名を省略します。

値の設定には、ビット単位の論理和演算を使用することもできます。次に例を示します。

% set moddebug | 0x80000000

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

コマンド modload(1M)modunload(1M)、および modinfo(1M) を使用するとテストモジュールを追加できます (これはドライバのデバッグや負荷テストを行うための便利な手法です)。一般に、これらのコマンドは通常運用時には必要ありません。必要なモジュールのロードや未使用モジュールのアンロードは、カーネルが自動的に行うからです。情報の提供と制御の設定を行うため、moddebug カーネル変数はこれらのコマンドと連携して動作します。

modload() 関数の使用

あるモジュールを強制的にメモリー内にロードするには、modload(1M) を使用します。modload コマンドは、ドライバのロード時にそのドライバに未解決の参照が含まれていないことを確認します。ドライバのロードは必ずしも、そのドライバが接続可能であることを意味するわけではありません。ドライバのロードが成功すると、ドライバの _info(9E) エントリポイントが呼び出されます。attach() エントリポイントは、必ずしも呼び出されるわけではありません。

modinfo() 関数の使用

ドライバがロードされたことを確認するには、modinfo(1M) を使用します。

使用例 126  modinfo によるロード済みドライバの確認
$ modinfo
 Id Loadaddr   Size Info Rev Module Name
  6 101b6000    732   -   1  obpsym (OBP symbol callbacks)
  7 101b65bd  1acd0 226   1  rpcmod (RPC syscall)
  7 101b65bd  1acd0 226   1  rpcmod (32-bit RPC syscall)
  7 101b65bd  1acd0   1   1  rpcmod (rpc interface str mod)
  8 101ce8dd  74600   0   1  ip (IP STREAMS module)
  8 101ce8dd  74600   3   1  ip (IP STREAMS device)
...
$ modinfo | grep mydriver
169 781a8d78   13fb   0   1  mydriver (Test Driver 1.5)

info フィールドの番号は、そのドライバ用に選択されたメジャー番号です。モジュール ID を指定すれば、modunload(1M) コマンドを使用してモジュールをアンロードできます。モジュール ID は、modinfo 出力の左側の列に表示されます。

modunload の発行後に予期したとおりにドライバがアンロードされない場合がありますが、これはドライバがビジー状態であると判定されたためです。この状況が発生するのは、ドライバが実際にビジー状態であるか、または detach エントリポイントの実装が間違っているために、ドライバが detach(9E) に失敗した場合です。

modunload() の使用

現時点で使用されていないすべてのモジュールをメモリーから削除するには、モジュール ID に 0 を指定して modunload(1M) を実行します。

# modunload -i 0
moddebug カーネル変数の設定

moddebug カーネル変数は、モジュールのロード処理を制御します。moddebug の使用可能な値は次のとおりです。

0x80000000

モジュールのロードまたはアンロード時にコンソールにメッセージを出力します。

0x40000000

より詳しいエラーメッセージを提供します。

0x20000000

ロードまたはアンロード時に、アドレスやサイズを含めるなど、より詳しい情報を出力します。

0x00001000

ドライバの自動アンロードを行いません。システムリソースが少なくなっても、システムがデバイスドライバのアンロードを試みません。

0x00000080

ストリームの自動アンロードを行いません。システムリソースが少なくなっても、システムが STREAMS モジュールのアンロードを試みません。

0x00000010

すべてのタイプのカーネルモジュールの自動アンロードを行いません。

0x00000001

kmdb を使用して実行する場合、各モジュールの _init() ルーチンが呼び出される前に、moddebug によってブレークポイントが実行され、kmdb への復帰がただちに発生します。また、この設定ではモジュールの _info() および _fini() ルーチンの実行時に追加のデバッグメッセージが生成されます。

kmem_flags デバッグフラグの設定

kmem_flags カーネル変数は、カーネルのメモリーアロケータのデバッグ機能を有効化します。アロケータのデバッグ機能を有効化するには、kmem_flags0xf に設定します。これらの機能には、次のコード条件を検出するための実行時チェックが含まれます。

  • バッファー解放後のバッファーへの書き込み

  • メモリー初期化前のメモリーの使用

  • バッファーの限度を超える書き込み

カーネルメモリーアロケータを使用してそのような問題を解析する方法については、Oracle Solaris Modular Debugger Guideを参照してください。


注 - kmem_flags0xf に設定した状態でテストや開発を行うと、潜在的なメモリー破壊バグの検出が容易になる可能性があります。kmem_flags0xf に設定するとカーネルメモリーアロケータの内部動作が変化するため、kmem_flags を使用しない状態でも完全なテストを実施するべきです。