Windowsドライバ開発WDM(3)-デバイスメモリ読み書き方式

2129 ワード

駆動によって作成されるデバイスには、一般に、バッファ方式、ダイレクト方式、その他の方式(DO_BUFFERED_IO、DO_DIRECT_IO、および0に対応)の3つの方式がある.
例:
fdo->Flags |= DO_BUFFERED_IO

DO_BUFFERED_IO現在のデバイスがバッファ方式で動作することを指定します.通常、ユーザモードとカーネルモードが相互作用すると、ユーザモードからbufferが送信されます.このbufferはユーザモードの仮想アドレスであることに注意してください.ドライバは、ユーザモードの仮想アドレスにアクセスできますが、ここでは、プロセスが切り替わると、同じユーザモードの仮想アドレスが異なる物理アドレスに対応し、このアドレスを読み出す駆動時にエラーが発生するという問題があります.これは、災害性のエラーです.したがって,カーネルモードの駆動は一般的にユーザモードの仮想アドレスを直接使用しない(特に必要であれば使用することもできるが,高い技術的要件が必要であり,注意が必要である).
 
バッファ方式(DO_BUFFERED_IO)
I/O
マネージャは、まず、ユーザー・モードのデータ・バッファ・サイズと等しいシステム・バッファを作成します.ドライバはこのシステムバッファを使用して動作します.
I/O
マネージャは、システム・バッファとユーザー・モード・バッファの間でデータをコピーします.
システムバッファのアドレスはIrp->AssociatedIrp.SystemBufferレコード、バッファの長さをIO_に記録STACK_LOCATIONでは、例えばWriteFileのシステムバッファの長さがIO_に記録されていますSTACK_LOCATIONのParameters.Write.Lengthの中.
バッファ方式で動作するデバイスでは、読み書きにかかわらず、ユーザモードアドレスとカーネルモードアドレスのデータコピーが発生します.このプロセスはオペレーティングシステムが担当し、カーネルモードアドレスの空間の割り当てと回収はオペレーティングシステムが担当し、ドライバは関心を持つ必要はありません.
バッファ方式は、ユーザモードアドレスの転送駆動の問題を比較的簡単に解決するとともに、明らかな欠点は、
ユーザー・モード・アドレスとカーネル・モード・アドレスのデータ・レプリケーションは、パフォーマンスに影響します.
適用:少量のメモリ操作.
 
ダイレクトモード(DO_DIRECT_IO)
I/O
マネージャは、ユーザー・モード・バッファを含む物理メモリ・ページをロックし、
MDL(
メモリ記述子テーブル
)
を参照してください.ドライバが使用する
MDL
仕事をする.
Irp
->
MdlAddressはMDLを指します.DDKの3つのマクロ:MmGetMdlByteCount,MmGetMdlVirtualAddress,MmGetMdlByteOffsetによりロックバッファ長,ロックバッファ開始アドレス(すなわちユーザモードプログラムのbufferの開始仮想アドレス)およびオフセット量を得ることができる.
MDLの長さ(MmGetMdlByteCountで得られる)はIO_STACK_LOCATIONの中のParameters.Read.Length(ReadFileと仮定)が等しい場合、エラーが発生します.
MmGetSystemAddressForMdlSafeを呼び出すと、ユーザモードの仮想アドレスをカーネルモードのアドレスにマッピングすることができ、ドライバはこのカーネルモードの仮想アドレスを使用することができます.
すなわち、ユーザモードアドレスとカーネルモードアドレスは、直接的に同じ物理メモリを指す.プロセスがどのように切り替えられても、カーネルモードアドレスは変更されず、正しい物理メモリが見つかります.
バッファ方式に比べて直接方式の操作はやや複雑であるが,ユーザモードアドレスとカーネルモードアドレスのデータレプリケーションを省き,性能を向上させた.
 
その他の方法(0)
I/O
マネージャは、ユーザモードの仮想アドレスのみをドライバに渡します.ユーザー・モード・アドレスを使用するドライバは、十分注意してください.
一般的にはあまり使われていませんが、上級者だけです.
 
 
全体的にバッファ方式を優先し、メモリが大きい場合は直接方式を考慮し、他の方式は特殊な場合に使用する(制御しにくいため、できるだけ少なく使用する).