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.  文字デバイスのドライバ

文字ドライバの構造の概要

文字デバイスの自動構成

デバイスアクセス (文字ドライバ)

open() エントリポイント (文字ドライバ)

close() エントリポイント (文字ドライバ)

入出力要求の処理

ユーザーアドレス

ベクトル化された入出力

同期入出力と非同期入出力の違い

データ転送方法

プログラム式入出力転送

DMA 転送 (同期)

DMA 転送 (非同期)

minphys() エントリポイント

strategy() エントリポイント

デバイスメモリーのマッピング

ファイル記述子に対する入出力の多重化

その他の入出力制御

ioctl() エントリポイント (文字ドライバ)

64 ビットに対応したデバイスドライバに対する入出力制御のサポート

copyout() のオーバーフローの処理

32 ビットと 64 ビットのデータ構造体マクロ

構造体マクロの動作のしくみ

構造体マクロを使用する場合

構造体ハンドルの宣言と初期化

構造体ハンドルに対する操作

その他の操作

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

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

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

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

20.  USB ドライバ

21.  SR-IOV ドライバ

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

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

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

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

パート IV 付録

A.  ハードウェアの概要

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

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

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

E.  pci.conf ファイル

索引

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

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

32 ビットと 64 ビットのデータ構造体マクロ

例 15-15 の方法は、多くのドライバで正常に機能します。この代わりに、<sys/model.h> で提供されているデータ構造体マクロを使用して、アプリケーションとカーネルの間でデータを移動する方法があります。これらのマクロによってコードが整理され、機能の点から見てまったく同様に動作するようになります。

例 15-16 データ構造体マクロを使用したデータの移動

int
    xxioctl(dev_t dev, int cmd, intptr_t arg, int mode,
        cred_t *cr, int *rval_p)
    {    
        STRUCT_DECL(opdata, op);

        if (cmd != OPONE)
            return (ENOTTY);

        STRUCT_INIT(op, mode);

        if (copyin((void *)arg,
            STRUCT_BUF(op), STRUCT_SIZE(op)))
                return (EFAULT);

        if (STRUCT_FGET(op, flag) != XXACTIVE ||     
            STRUCT_FGET(op, size) > XXSIZE)
                return (EINVAL);
        xxdowork(device_state, STRUCT_FGET(op, size));
        return (0);
}

構造体マクロの動作のしくみ

64 ビットのデバイスドライバでは、構造体マクロを使用すると、両方のサイズのデータ構造体でカーネルメモリーの同じ部分を使用できます。メモリーバッファーには、データ構造体のネイティブ形式 (つまり、LP64 形式と ILP32 形式) の内容が保持されます。構造体への各アクセスは、条件式によって実装されます。32 ビットのドライバとしてコンパイルされた場合は、1 つのデータモデル (ネイティブ形式) のみがサポートされます。条件式は使用されません。

64 ビットバージョンのマクロは、データ構造体のシャドウバージョンの定義に依存します。シャドウバージョンには、固定幅の型を含む 32 ビットインタフェースが記述されます。シャドウデータ構造体の名前は、ネイティブなデータ構造体の名前に「32」を追加することによって作成されます。将来の保守コストを軽減するために、便宜上、シャドウ構造体の定義はネイティブな構造体と同じファイル内に置きます。

これらのマクロは、次の引数を取ることができます。

structname

struct キーワードのあとに入力されたデータ構造体のネイティブ形式の構造体名。

umodel

ioctl(9E) のモードパラメータから抽出されたユーザーのデータモデル (FILP32 FLP64 など) を含むフラグワード。

handle

これらのマクロで操作される構造体の特定のインスタンスを参照するために使用される名前。

fieldname

構造体内のフィールドの名前。

構造体マクロを使用する場合

マクロを使用すると、あるデータ項目のフィールドのみへのインプレース参照を行うことができます。マクロでは、データモデルに基づいた別のコードパスを取るための方法は提供されません。データ構造体内のフィールドの数が多い場合は、マクロを避けるべきです。また、これらのフィールドを参照する頻度が高い場合も、マクロを避けるべきです。

マクロでは、データモデル間の違いの多くがマクロの実装内に覆い隠されます。その結果、このインタフェースを使用して記述されたコードは一般に読みやすくなります。32 ビットのドライバとしてコンパイルされた場合、結果のコードは煩わしい #ifdefs が必要ないため簡潔になりますが、データ型のチェックは引き続き保持されます。

構造体ハンドルの宣言と初期化

STRUCT_DECL(9F)STRUCT_INIT(9F) を使用すると、スタック上の ioctl をデコードするためのハンドルと領域を宣言して初期化できます。STRUCT_HANDLE(9F)STRUCT_SET_HANDLE(9F) は、スタック上の領域を割り当てることなくハンドルを宣言して初期化します。構造体が非常に大きいか、またはほかのデータ構造体に含まれている場合は、後者のマクロが役立つことがあります。


注 - STRUCT_DECL(9F) マクロと STRUCT_HANDLE(9F) マクロはデータ構造体の宣言まで拡張されるため、これらのマクロは C コードでこのような宣言を使用してグループ化されます。


構造体を宣言して初期化するためのマクロは次のとおりです。

STRUCT_DECL(structname , handle)

structname データ構造体のための、handle という名前の構造体ハンドルを宣言します。STRUCT_DECL は、スタック上のネイティブ形式のための領域を割り当てます。ネイティブ形式は、構造体の ILP32 形式より大きいか、または等しいと見なされます。

STRUCT_INIT(handle , umodel)

handle のデータモデルを umodel に初期化します。このマクロは、STRUCT_DECL(9F) を使用して宣言された構造体ハンドルへの何らかのアクセスが行われる前に呼び出す必要があります。

STRUCT_HANDLE(structname , handle)

handle という名前の構造体ハンドルを宣言します。STRUCT_DECL(9F) と対比されます。

STRUCT_SET_HANDLE(handle , umodel, addr )

handle のデータモデルを umodel に初期化し、addr を以降の操作に使用されるバッファーとして設定します。このマクロは、STRUCT_DECL(9F) を使用して宣言された構造体ハンドルへのアクセスの前に呼び出します。

構造体ハンドルに対する操作

構造体に対する操作を実行するためのマクロは次のとおりです。

size_t STRUCT_SIZE(handle )

handle によって参照される構造体のサイズを、その組み込みのデータモデルに応じて返します。

typeof fieldname STRUCT_FGET(handle, fieldname)

handle によって参照されるデータ構造体内の示されているフィールドを返します。このフィールドはポインタ以外の型です。

typeof fieldname STRUCT_FGETP(handle, fieldname)

handle によって参照されるデータ構造体内の示されているフィールドを返します。このフィールドはポインタ型です。

STRUCT_FSET(handle , fieldname, val)

handle によって参照されるデータ構造体内の示されているフィールドを値 val に設定します。val の型は、fieldname の型に一致します。このフィールドはポインタ以外の型です。

STRUCT_FSETP(handle , fieldname, val)

handle によって参照されるデータ構造体内の示されているフィールドを値 val に設定します。このフィールドはポインタ型です。

typeof fieldname *STRUCT_FADDR(handle, fieldname)

handle によって参照されるデータ構造体内の示されているフィールドのアドレスを返します。

struct structname *STRUCT_BUF( handle)

handle で記述されたネイティブな構造体へのポインタを返します。

その他の操作

その他の構造体マクロのいくつかを次に示します。

size_t SIZEOF_STRUCT(struct_name , datamodel)

指定されたデータモデルに基づいた struct_name のサイズを返します。

size_t SIZEOF_PTR(datamodel )

指定されたデータモデルに基づいたポインタのサイズを返します。