JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
デバイスドライバの記述     Oracle Solaris 10 1/13 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.  デバイスドライバのデバッグ、テスト、およびチューニング

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

デバッグ準備手法

一意の接頭辞を使用してカーネルシンボルの衝突を回避する

cmn_err() を使用してドライバの活動を記録する

ASSERT() を使用して無効な前提条件を見つける

mutex_owned() を使用してロック要件の検証とドキュメント化を行う

条件付きコンパイルを使用してコストの高いデバッグ機能を切り替える

変数の volatile 宣言

保守性

定期的な健全性検査

パート IV 付録

A.  ハードウェアの概要

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

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

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

E.  pci.conf ファイル

索引

変数の volatile 宣言

volatile は、デバイスレジスタを参照する変数を宣言するときに適用する必要があるキーワードです。volatile を使用しないと、コンパイル時のオプティマイザが偶然、重要なアクセスを削除することがあります。volatile を使用しないでいると、追跡するのが困難なバグが発生する可能性があります。

見つけにくいバグを防ぐには、volatile を正しく使用する必要があります。volatile キーワードはコンパイラに、宣言されているオブジェクトの正確なセマンティクスを使用するように指示します。これは特に、オブジェクトへのアクセスの削除や並び替えを行わないようにするためです。デバイスドライバで volatile 修飾子を使う必要があるのは次の 2 つの場合です。

次の例では volatile を使用しています。デバイスがビジーのときにスレッドが継続しないようにビジーフラグが使用され、フラグはロックによって保護されていません。

    while (busy) {
      /* do something else */
      }

テストスレッドは、別のスレッドが busy フラグをオフにした場合は続行されます。

    busy = 0;

busy はテストスレッドで頻繁にアクセスされるため、コンパイラは毎回のテストの前にメモリー内の busy の値を読み込まずに、busy の値をレジスタに置き、レジスタの内容をテストすることでテストを最適化できる可能性があります。テストスレッドから見ると busy が変化することはなく、ほかのスレッドのみがメモリー内の busy の値を変更することがあるため、デッドロックが発生する結果になります。busy フラグを volatile と宣言することで、各テストの前にフラグの値を強制的に読み取ります。


注 - busy フラグの代わりになる方法は、条件変数を使用することです。「スレッド同期における条件変数」を参照してください。


volatile 修飾子を使用するときには、不注意による抜けが生じないようにします。たとえば、次のコードの場合を考えます。

    struct device_reg {
     volatile uint8_t csr;
     volatile uint8_t data;
     };
     struct device_reg *regp;

これは、もう 1 つの例よりも推奨される記述方法です。

    struct device_reg {
     uint8_t csr;
     uint8_t data;
     };
     volatile struct device_reg *regp;

2 つの例は機能上は同等ですが、2 つ目の例では、コードの記述者は struct 型の device_reg のすべての宣言で volatile を使用するようにする必要があります。最初の例では、すべての宣言でデータが volatile として処理されることになるため、これが推奨される方法です。前述したように、デバイスレジスタにアクセスするために DDI データアクセス関数を使用すると、volatile としての修飾変数が不要になります。