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

ドキュメントの情報

はじめに

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

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

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

3.  マルチスレッド

4.  プロパティー

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

6.  ドライバの自動設定

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

8.  割り込みハンドラ

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

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

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

12.  電源管理

13.  Solaris ドライバの強化

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

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

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

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

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

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

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

20.  USB ドライバ

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

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

ドライバ開発の概要

ドライバコードの配置

ヘッダーファイル

ソースファイル

設定ファイル

ドライバインストールの準備

ドライバのコンパイルとリンク

モジュールの依存関係

ハードウェア設定ファイルの記述

ドライバのインストール、更新、および削除

モジュールディレクトリへのドライバのコピー

add_drv を使用したドライバのインストール

ドライバ情報の更新

ドライバの削除

ドライバのロードとアンロード

ドライバのパッケージ化

パッケージのインストール後処理

パッケージの削除前処理

デバイステストの条件

設定のテスト

機能テスト

エラー処理

ロードとアンロードのテスト

ストレス、パフォーマンス、および相互運用性のテスト

DDI/DKI コンプライアンスのテスト

インストールとパッケージ化のテスト

特定の種類のドライバのテスト

テープドライバ

ディスクドライバ

非同期通信ドライバ

ネットワークドライバ

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

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

パート IV 付録

A.  ハードウェアの概要

B.  Solaris DDI/DKI サービスの概要

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

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

索引

デバイステストの条件

デバイスドライバが機能するようになったら、配布前にそのドライバを完全にテストする必要があります。従来の UNIX デバイスドライバに備わる機能をテストするほかに、Solaris ドライバでは、ドライバの動的なロードとアンロードなどの電源管理機能もテストする必要があります。

設定のテスト

複数のデバイス設定を扱うドライバの機能は、テストプロセスの重要な部分です。ドライバが単純な設定やデフォルトの設定で機能するようになったら、追加の設定をテストする必要があります。デバイスによっては、ジャンパーまたは DIP スイッチを変更することで設定のテストを完了できます。可能な設定の数が少ない場合は、すべての設定を試してください。数が多い場合は、可能な設定から成るさまざまなクラスを定義し、各クラスからサンプリングした設定をテストする必要があります。これらのクラスの定義は、異なる構成パラメータ間でどれだけの対話が可能かに左右されます。これらの対話はデバイスの種類と、ドライバが記述された方法との相関関係です。

デバイス設定ごとに、基本の機能をテストする必要があります。それには、デバイスをロードする、開く、読み取る、書き込む、閉じる、アンロードする機能が含まれます。設定に依存するすべての機能には特に注意を払う必要があります。たとえば、デバイスレジスタのベースメモリーアドレスを変更することは、おそらくほとんどのドライバ機能の動作には影響を与えません。ドライバが 1 つのアドレスで正常に機能する場合、そのドライバはおそらく、異なるアドレスでも機能します。一方、特別な入出力制御呼び出しでは、特定のデバイス設定に応じて効果が異なる可能性があります。

さまざまな設定でドライバをロードすることで、probe(9E) および attach(9E) のエントリポイントが異なるアドレスで確実にデバイスを見つけることができます。基本機能のテストの場合、文字デバイスについては、cat(1)dd(1M) などの通常の UNIX コマンドを使えば通常は十分です。ブロックデバイスについては、マウントやブートが必要な場合があります。

機能テスト

ドライバの設定を完全にテストしたら、ドライバのすべての機能を完全にテストする必要があります。これらのテストでは、ドライバのすべてのエントリポイントの操作を実行する必要があります。

多くのドライバには、機能をテストするためのカスタムアプリケーションが必要です。ただし、ディスク、テープ、非同期ボードなどのデバイスの基本ドライバは、標準のシステムユーティリティーを使用するとテストできます。このプロセスでは、該当する場合は devmap(9E)chpoll(9E)ioctl(9E) を含むすべてのエントリポイントをテストする必要があります。ioctl() テストは、ドライバごとに大きく異なる可能性があります。標準でないデバイスでは、通常はカスタムテストアプリケーションが必要です。

エラー処理

ドライバは理想的な環境では正常に実行されても、間違った操作や正しくないデータなどのエラーがある場合は失敗することがあります。そのため、ドライバのエラー処理のテストが、ドライバのテストの重要な一部となっています。

実際のハードウェアの誤動作に関するエラーの条件を含めて、ドライバの考えられるすべてのエラー条件を与える必要があります。一部のハードウェアエラー条件は発生させるのが困難な場合がありますが、可能であれば、そうしたエラーを強制したりシミュレートしたりするように努める必要があります。これらの条件は、実地ではすべて発生する可能性があります。ケーブルを抜いたりゆるめたり、ボードを取り外したり、エラーのあるユーザーアプリケーションコードを記述したりして、そうしたエラーパスをテストする必要があります。第 13 章Solaris ドライバの強化も参照してください。


高電圧

注意 - テスト時には電気的に適切な対策をとるようにしてください。


ロードとアンロードのテスト

ロードまたはアンロードされないドライバは予定外の停止時間の原因となるため、ロートとアンロードは完全にテストしておく必要があります。

次の例のようなスクリプトで十分です。

#!/bin/sh
cd <location_of_driver>
while [ 1 ]
do
    modunload -i 'modinfo | grep " <driver_name> " | cut -cl-3' &
    modload <driver_name> &
done

ストレス、パフォーマンス、および相互運用性のテスト

ドライバのパフォーマンスを確保する助けになるように、ドライバには厳しいストレステストを適用する必要があります。For example, running single threads through a driver does not test locking logic or conditional variables that have to wait. いくつかのスレッドで同じコードを同時に実行させるには、複数のプロセスで同時にデバイスの操作を実行する必要があります。

同時テストを実行するための手法はドライバによってさまざまです。一部のドライバでは特殊なテストアプリケーションが必要ですが、その他のドライバでは、バックグラウンドでいくつかの UNIX コマンドを開始すれば十分です。どのようなテストが適切であるかは、各ドライバでロックと条件変数が使われている場所によって異なります。マルチプロセッサマシンでドライバをテストすると、シングルプロセッサマシンでテストする場合より問題が表面化する可能性が高くなります。

ドライバ間の相互運用性もテストする必要があります。これは特に、さまざまなデバイスが割り込みレベルを共有できるためです。可能であれば、1 つのドライバをテストしているときに、別のデバイスを同じ割り込みレベルで設定します。ストレステストを行うと、ドライバが自身の割り込みを正しく要求し、予測どおりに動作するかどうかを判断できます。ストレステストは両方のデバイスで一度に実行する必要があります。デバイスが割り込みレベルを共有していない場合でも、このテストは有用です。たとえば、ネットワークドライバのテスト時に、シリアル通信デバイスでエラーが発生している場合を考えてください。同じ問題が原因で、システムの残りの部分でも割り込みの待ち時間の問題が発生することもあります。

これらのストレステストを適用したドライバのパフォーマンスは、UNIX のパフォーマンス測定ツールを使用して測定してください。この種類のテストは簡単で、time(1) コマンドを、ストレステストで使用されるコマンドとともに使用するだけで実行できます。

DDI/DKI コンプライアンスのテスト

後のリリースとの互換性と、最新リリースに対する信頼できるサポートを保証するため、すべてのドライバを DDI/DKI 準拠にする必要があります。『SunOS リファレンスマニュアル 9 : DDI/DKI カーネル関数』および『man pages section 9: DDI and DKI Driver Entry Points 』のカーネルルーチンと、『man pages section 9: DDI and DKI Properties and Data Structures 』のデータ構造体のみが使用されていることを確認します。

インストールとパッケージ化のテスト

ドライバはお客様に、パッケージで提供されます。パッケージは標準の機構を使用して、システムに対する追加または削除が可能です (『アプリケーションパッケージ開発者ガイド』を参照)。

ユーザーがシステムに対してパッケージの追加や削除を行う機能をテストする必要があります。テストでは、リリース時に使用されるすべての種類のメディアに対して、パッケージのインストールと削除の両方を行ってください。このテストには、いくつかのシステム構成を含める必要があります。パッケージが、インストール先システムのディレクトリ環境について、間違った想定をすることがあってはなりません。ただし、標準のカーネルファイルが保管されている場所については、有効な場所を想定することが可能です。また、開発環境用に変更されていない新しくインストールされたマシンで、パッケージの追加と削除をテストします。パッケージ化でよくあるエラーは、パッケージが開発でのみ使用されているツールやファイルに依存しているというものです。たとえば、ソース互換性パッケージ SUNWscpu のツールがドライバインストールプログラムで使用されていてはいけません。

ドライバのインストールは、オプションパッケージを一切追加していない最小限の Solaris システムでテストする必要があります。

特定の種類のドライバのテスト

この節では、特定の種類の標準デバイスをテストする方法について、いくつかの提案を示します。

テープドライバ

テープドライバは、保管と復元のいくつかの操作を実行してテストする必要があります。この目的のために、cpio(1) コマンドと tar(1) コマンドを使用できます。ディスクパーティション全体をテープに書き込むには、dd(1M) コマンドを使用します。次に、データを読み戻して、同じサイズの別のパーティションにデータを書き込みます。その後、2 つのコピーを比較します。mt(1) コマンドは、テープドライバ固有の入出力制御の大半を実行できます。mtio(7I) のマニュアルページを参照してください。すべてのオプションを使用してみます。次の 3 つの手法で、テープドライバのエラー処理機能をテストできます。

テープドライバは、通常、排他的アクセスの open(9E) 呼び出しを実装しています。これらの open() 呼び出しは、デバイスを開き、2 番目のプロセスで同じデバイスを開こうとすることでテストできます。

ディスクドライバ

ディスクドライバは raw モードとブロックデバイスモードの両方でテストする必要があります。ブロックデバイステストの場合、デバイス上に新しいファイルシステムを作成します。次に、新しいファイルシステムのマウントを試みます。次に、複数ファイルの操作を実行してみます。


注 - ファイルシステムはページキャッシュを使用するので、同じファイルを繰り返し読み取ってもドライバを働かせることになりません。ページキャッシュは、mmap(2) を使用してファイルをメモリーマッピングすることで、デバイスからデータを取得するように設定できます。次に msync(3C) を使用して、メモリー内のコピーを無効にします。


同じサイズの別の (マウントされていない) パーティションを raw デバイスにコピーします。次に、fsck(1m) などのコマンドを使用して、コピーが正しいことを検証します。新しいパーティションもマウントし、あとで古いパーティションとファイル単位で比較できます。

非同期通信ドライバ

非同期ドライバは、シリアルポートへの login 用の回線を設けることで、基本レベルでテストできます。ユーザーがこの回線でログインできるかどうかを確認するのが適切なテストです。ただし非同期ドライバを十分にテストするには、割り込みを多数発生させて、すべての入出力制御関数を高速でテストする必要があります。ループバックシリアルケーブルを使用し、高速なデータ転送速度でテストを行うと、ドライバの信頼性を判断する助けになります。回線上で uucp(1C) を実行すると、一部のテストを行えます。ただし、uucp は独自のエラー処理を実行するため、ドライバが uucp プロセスに報告するエラーの数が多すぎないか検証してください。

これらの種類のデバイスは、通常、STREAMS ベースのデバイスです。詳細については、『STREAMS Programming Guide 』を参照してください。

ネットワークドライバ

ネットワークドライバは標準のネットワークユーティリティーを使用するとテストできます。ネットワークのそれぞれの側でファイルを比較できるため、ftp(1) コマンドと rcp(1) コマンドが役立ちます。ドライバは高いネットワーク負荷をかけてテストする必要があるため、複数のプロセスで多様なコマンドを実行できます。

高いネットワーク負荷に該当するのは、次のような条件です。

テストの実行中にネットワークケーブルを抜き、発生したエラー状態から正常に回復することを確認する必要があります。別の重要なテストは、複数のパケットをドライバにたて続けに受信させることです。つまり、連続パケットを使用します。この場合、比較的高速なホストを負荷の少ないネットワーク上に置き、複数のパケットを間断なくテストマシンに送信します。受信側のドライバで、2 つ目以降のパケットが欠落していないことを確認します。

これらの種類のデバイスは、通常、STREAMS ベースのデバイスです。詳細については、『STREAMS Programming Guide 』を参照してください。