SCIENCE PARK

デバドラ講座

【 デバドラ講座用語集 】

デバイスドライバでよく使用される用語をまとめたものです。

用語 説明
!analyze -v WindowsのリモートデバッグツールであるWinDbgで使用するコマンド。BSOD発生後のメモリダンプ解析によく使用される。BSODの要因・スタック表示・要因コードの表示等、解析に必要な情報をまとめて表示できるため、解析の最初に入力するコマンドである。
BSOD Blue Screen of Deathの略。Windows上で致命的なエラーが発生し処理続行不能と判断した際に表示される画面。メモリダンプとイベントログの生成を行う。デフォルトの設定ではOSが再起動するだけだが、"システムのプロパティ"から"システムエラー"の設定を変更することでBSODとなる。
buildユーティリティ WDKでドライバ等をビルドするために用いられるユーティリティ。コマンドラインで用いられる、Cコンパイラが.makファイルを元にビルドを行うのに対して、本ユーティリティはSOURCESファイルを元(.makファイルは変更しない)にしてビルドを行う。
Driver Verifier 仮想的にパソコン内の環境を変化させ、ドライバの検証を行うことができるツール。Windowsにプリインストールされている。カーネルモードドライバを動的に解析し、不正な処理を検出するとBSODを発生させる。
DriverEntry

カーネルモードドライバがロードされた時に最初に一度だけ呼び出される関数。ユーザーモードアプリケーションのmain関数と同等。

一つのカーネルモードドライバで複数のデバイスをサポートする場合でも、一度しか呼び出されない。ディスパッチルーチンの登録やレジストリの読み込みを行う。カーネルモードドライバがアンロードされると、次回ロード時に再度呼び出される。

I/O Manager カーネルモードドライバと直接IRPを介した通信を行うWindowsにおけるI/O制御の核となるモジュール。 カーネルモードドライバはこのI/O Managerの一部として動作する。
I/OControl

ユーザモードプログラムからカーネルモードドライバ、カーネルモードドライバからカーネルモードドライバに要求を発行する手段の一つ。

Read/Writeが単方向のデータ転送なのに対して、双方向へのデータ転送を提供し、且つI/Oコントロールコードというリクエスト種別値を任意に設定することができる。

デバイス独自の処理を追加する場合は、独自のI/Oコントロールコードを追加する。それにより、ユーザモードプログラムからDeviceIoControlに追加した独自のI/Oコントロールコードを呼び出すことができ、ユーザモードプログラムとカーネルモードドライバ間の通信を行うことができる。

IRP I/O Request Packetの略。ユーザモードプログラムとカーネルモードドライバ、カーネルモードドライバとカーネルモードドライバ間で用いられる、要求パケット。ほぼ全ての種別のカーネルモードドライバの共通形式として用いられる。構造体・共用体で構成され、固定長のヘッダ部分と、可変長のスタック部分に分けられる。
IRQL

Interrupt Request Levelの略。プロセス・スレッドの実行レベルとは別に、カーネルモード専用の実行レベルが定義される。 代表的なものとして以下がある。

PASSIVE LEVEL
最も低いレベル。通常のユーザモードプログラムと同等の優先度で動作する。
DISPATCH LEVEL
スレッド切り替え(ディスパッチ)と同等の優先度で動作する。このレベルで処理を専有するとスレッド切り替えが行われるが、他のカーネルモードドライバ・ユーザモードプログラムの動作を止めてしまうため、長時間処理をおこなうことは推奨されない。
割り込みレベル
ハードウェア割り込みと同等レベル。 基本的にCPUの割り込み線は1本しか存在せず、このレベルでの処理中は他の割り込みを止めてしまうことになるため、長時間処理をおこなうことは推奨されない。
ISR Interrupt Service Routineの略。PCI等のデバイスで割り込みが発生した際にOSから呼び出される関数。デバイスドライバの初期化時にOSに対して登録を行う。本関数実行時はIRQLが高いため、最低限の処理のみ実行し、残りはDPCで行う。
KMDF Kernel Mode Driver Frameworkの略。Windows Vista発売後WDK Ver.6000にて追加された、カーネルモードドライバの開発を容易にするためのフレームワーク。PnPや電源管理の煩雑な処理をフレームワークに任せることができるためより少ないコード量でカーネルモードドライバを開発することができる。
MDL

Memory Descriptor List の略。ページ単位(通常4KB)での仮想メモリと物理メモリの対応付けを格納するリスト。

ユーザモードプログラムとカーネルモードドライバ、カーネルモードドライバとカーネルモードドライバにメモリ情報を渡す際に使用される。

メモリ内の参照が必要ないときは、メモリマッピングの処理を省略できるため、時として仮想メモリポインタを渡すよりも処理が高速になる場合がある。

NDIS

Network Driver Interface Specificationの略。

Windows3.1より存在し、WindowsNT系とWindows9x系のネットワークドライバのバイナリ互換を目的としたインタフェース仕様。

NDISライブラリとして、カーネルモードドライバが使用するためのAPI群を提供する。NDISドライバはこのライブラリとのやり取りを行う。Windows 7がサポートするNDISのバージョンは6.2であり、Windows8では6.3のサポートが予定されている。

NonPaged

デバイスドライバが使用する仮想メモリ空間で、常に物理メモリ上に存在する。そのため、ページングファイルへの書き出し(ページ アウト)は行われない。DISPATCH_LEVEL以上の場合、ページイン、ページアウトを実施できないため、DISPATCH_LEVEL以上でアクセスする領域についてはNonPagedに確保する。

NonPagedで確保できる領域はPagedと比較して少ないので、Pagedで確保できる場合はPagedで確保する。

NTSTATUS

カーネルモードドライバで用いられる、ステータスコード。

カーネルモードドライバへの要求発行元がユーザモードプログラムであった場合、カーネルモードドライバが返却したエラーコードは、Win32サブシステムによって、ユーザモードプログラムが解釈可能なWin32エラーコードに変換される。

Win32サブシステムは、Win32エラーコードに変換してアプリへ返す。32ビットの整数で表され、0x0xxxxxxxは成功に属するもの、0x8xxxxxxxは警告、0xCxxxxxxxはエラーの種別である。OS内部で定義された値であり、WDKのNTSTATUS.Hで定義されている。

Paged

デバイスドライバが使用する仮想メモリ空間で、物理メモリ上もしくは仮想メモリ上に存在する。そのため、ページングファイルへの書き出し(ページ アウト)が行われる。PASSIVE_LEVEL、APC_LEVELの場合、ページイン、ページアウトを実施できるため、APC_LEVEL以下でアクセスする領域についてはPagedに確保する。

NonPagedで確保できる領域はPagedと比較して少ないので、Pagedで確保できる場合はPagedで確保する。

PREfast for Drivers デバイスドライバのコンパイル時に静的にシステムコールの使い方に関するエラーを検知/通知するツール。WDKのWindows 7ビルド環境以降に含む。
UMDF User Mode Driver Frameworkの略。UMDFドライバは、ユーザモードドライバを作成するためのフレームワークが含まれている。カーネルモードドライバ(KMDF)に比べ、セキュリティと安定性が向上する。 ユーザモードドライバは署名なく、64bitOSにインストール可能。プログラムはC++で記述する。代表的なものにポータブルデバイス(音楽プレーヤー、デジタルカメラ、携帯電話)やセンサー&ロケーションがある。
WDF Windows Driver Foundationの略。WDFは、WDMの後継として登場したデバイスドライバ開発のためのデバイスドライバモデル。WDFの主な構成として、Kernel Mode Driver Framework (KMDF)、User Mode Driver Framework (UMDF) に分けらる。一般的に、ユーザモードおよびカーネルモードの両方のデバイスドライバをサポートするフレームワークモデルを指す。
カーネルモード PCのすべてのハードウェアに対して直接アクセスができる権限を持っているモードのこと 。例えば、x86 CPUの場合はRING0(VTを使用する場合はRING-1)のモードで動作をすることと等価になる。ユーザーモードアプリケーションと分離することでユーザーモードアプリケーションの異常動作によるBSODを回避する。
コールバック 特定のイベントが発生した際に対応する処理を行うため、事前に呼び出し先(コールバック先)を登録する。特定のイベントが発生すると、コールバック先を呼び出す。ディスパッチルーチンはすべてコールバックで実現されている。例えば、ファイルを開くと、オープン要求を処理するコールバック関数が呼び出される。このコールバック関数は、DriverEntryで設定する場合が多い。
シリアライズ

データアクセスのシリアライズでは、複数のスレッドからあるデータ(メモリやリソースなど)にアクセスするとき、同時にアクセスするとデータの整合性を保てなくなる場合がある。データの整合性を保つためには各スレッドからのアクセスを制限し、1スレッドずつ処理することでデータの整合性を保つことをシリアライズと呼ぶ。

デバイスドライバ開発では、一般的にはスピンロックを多用する。そのほかにミューテックスやセマフォなどの同期オブジェクトがある。ユーザモードプログラム開発における一般的な「シリアライズ」(データをバイナリストリームへ変換する)とは異なる。

スタック

デバイスドライバではスタックメモリ、もしくはコールスタックのことを指す場合が多い。スタックメモリとは、ローカル変数(もしくは引数)の確保や関数の呼び出しのために用意されたメモリ領域のこと。

コールスタックとは、関数の呼び出し履歴のこと。関数呼び出しをすると引数や関数終了後に戻るアドレスなどがスタックメモリ上に書かれていく(スタックされていく)。これをコールスタックと呼び、関数の呼び出し履歴を読み取ることができる。

スタックオーバーフロー

スタックメモリに格納するデータの量が上限を超えてしまうこと。主に大きすぎるローカル変数(もしくは引数)の確保や再帰呼び出しによって発生する。カーネルモードで実行されるプログラムがスタックオーバーフローを起こすと、BSODが発生する。

スタックオーバーフローはユーザモードプログラムにおいても発生するが、特にカーネルモードドライバにおいては発生しやすい。これは、カーネルモードで使用できるスタックメモリ上限がユーザモードと比べて低いことと、カーネルモードドライバでは他のモジュールとのやりとりが1つのスタック上の関数呼び出しとして取り扱われるためである。

ユーザモードプログラムではリンカによりスタックサイズを指定できるが、デバイスドライバではスタックサイズを指定出来ず、OSにより決まっている。Windowsのカーネルスタック(1スレッドあたりのサイズ)は、x86ベースのプラットフォーム(XP/Vista/Win7の32bit版)で12KB、x64ベースのプラットフォーム(Vista/Win7の64bit版や2008R2)で24KB、Itaniumベースで32KBである。

スタックサイズ

スレッドに割り当てられるスタックメモリのサイズ。スタックメモリはスレッドの初期化時に指定されたサイズ分が予約され、その予約されたスタックメモリを関数の引数や関数内のローカル変数で使用する。 関数が再帰的に呼び出されるなどして、呼び出し階層が深くなると指定したスタックサイズが足りなくなり、スタックオーバーフローが発生する。ユーザモードスレッドを作成すると既定では1MBが予約される。CreateThreadの呼び出し時の引数でスタックサイズを変更することが可能である。カーネルモードスレッドでは、OSごとに上限値が決まっており、スレッドの作成時に指定することはできない。

類語:
デバイススタック、IRPスタック
スピンロック

並列処理におけるデータ保護方式のひとつ。主に複数のスレッドが同時に1つのデータにアクセスすることを防ぐために使う。

並列処理において共用されるデータがある場合は、複数の処理が同時に1つのデータにアクセスすることがないようにデータを保護する必要がある。スピンロックはデータ保護方式のひとつで、データの所有権(ロック)を確保できるまで定期的にループしてロック状態をチェックする(スピン)という方式。短時間のロックのためには効率的な方式であるため、カーネルモードドライバで多用される。

スレッド

CPUが処理を行う最小単位。一度に1つだけしかスレッドが動作しないものをシングルスレッド、複数の処理が動作するものをマルチスレッドと呼ぶ。デバイスドライバは複数スレッドから同時に要求を受付けるため、マルチスレッドを前提に作成する必要がある。

1つのプロセスにおけるアドレス空間において、複数の処理をすることができ、メインメモリの量にもよるが、スレッドの制限はWindowsの場合、32bitシステムで最大2048スレッド。64bitシステムの場合 、最大4096スレッドである。

参考:
http://technet.microsoft.com/ja-jp/windows/ee424288
メモリダンプ

BSODが発生した際、原因を解析するために必要なファイル。メモリの内容を出力(ダンプ)したファイル。デバイスドライバの用語としては、カーネルメモリの内容をダンプしたファイルを指すことが多い。ダンプファイルはWinDbgで解析する。

ダンプファイルは以下の3種が取得できる。

完全メモリ ダンプ
BSODが発生した際のメモリ上のデータを全て記録したファイル。ブート ボリュームに ページ・ファイルのサイズを物理メモリ+1 MB以上に設定しておく必要がある。
カーネル メモリ ダンプ
BSODが発生した際のカーネルモードドライバとその他カーネルモードプログラムに割り当てられたメモリのみ記録したファイル。未割り当てメモリ、ユーザモードプログラムに関する情報は含まれない。ブート ボリュームに ページ・ファイルのサイズを物理メモリ以上に設定しておく必要がある。
最小メモリダンプ
BSODが発生した際の最小限の情報を記録したファイル。BSODが発生時、直接の原因となったスレッドのエラーがこのファイルの分析によって発見できない場合がある。ブート ボリュームに 2 MB 以上のページング ファイルが必要
ディスパッチルーチン

WDMにおいて、ドライバが要求を受け付けるためのルーチン。処理の実行権を受け取るルーチンなので、ディスパッチルーチンと呼ばれる。デバイスドライバの処理は全てディスパッチルーチンから駆動される。

デバイスドライバはイベントドリブンで動作する構造になっており、これはWin32アプリケーションがウインドウメッセージを受け取って動作するのと同じ考え方。例として、デバイスが抜かれた場合はIRP_MJ_PNPというメジャーコードとIRP_MN_REMOVE_DEVICEというマイナーコードを受け取る。

デバイスエクステンション WDMにおいて、デバイスオブジェクトごとに確保できる拡張領域。それぞれのデバイスドライバでサイズを自由に定義することができる。デバイスオブジェクトを作成する際、デバイスエクステンションのサイズを決め、デバイスエクステンション上にデバイスドライバで利用するデータ構造体を定義し、デバイスに関する情報を管理するために利用する。
デバイスオブジェクト デバイスドライバがデバイスに対するI/Oを管理するためのオブジェクト。デバイスオブジェクトはいずれかのデバイスクラスに所属している。一般的には、上位のデバイスクラスのデバイスオブジェクトから下位のデバイスクラスのデバイスオブジェクトに対してIoCallDriverを呼び出すことで階層的に処理を行う。
デバイスクラス 同様の機能を持つデバイスをクラス分けし、そのクラスごとに処理やI/Fを共通したものである。たとえば、接続方式の異なるUSBメモリやSATAハードディスクなどはDiskクラスを使用することで、各デバイスに対して同一のファイルシステムドライバを階層的に配置することが可能となる。
デバイススタック WDMにおいて、デバイスオブジェクトのつながりによって構成される階層モデル。デバイスが接続されたときに、下位のデバイスドライバから順にデバイスオブジェクトを作成して接続(アタッチ)していくことでデバイススタックを形成する。
ドライバオブジェクト デバイスドライバ自体を表すオブジェクト。デバイスドライバのロード時に作成され、ディスパッチルーチンのアドレスなどデバイスドライバ全体の情報を保持する。デバイスオブジェクトと異なり、複数のデバイスが存在していてもドライバオブジェクトはデバイスドライバごとに1つだけ存在する。
ドライバスタック

デバイスドライバの呼び出し順序を示すスタック構造。基本的には最下位のバスドライバの上にファンクションドライバやフィルタドライバが並ぶ構造になっている。デバイスドライバはこの順に従ってロードされる。

デバイススタック、ドライバスタックの違いについては以下を参照。

参考:
http://blogs.msdn.com/b/jpwdkblog/archive/2010/10/01/device-object-device-stack.aspx
ハードウェアインターフェース デバイスドライバとハードウェアのインターフェース。デバイスドライバを実装するにあたり、必要なハードウェアの仕様。デバイスドライバを開発する際、ハードウェアインタフェースを理解しておくことは重要
パススルー デバイスドライバの場合は、上位から受け取った要求を処理せずに、下位のデバイスドライバにそのまま渡すこと。
バスドライバ バスとは、PCを構成するハードウェアと通信するための共通の伝送路(PCIやUSBなど)バスドライバはこの伝送路を制御するカーネルドライバであり、ハードウェアと上位デバイスドライバ間の伝送を仲介する。ドライバスタックの最下層に位置する
ファンクションドライバ カメラ、プリンタ、マスストレージ、マウス、キーボード等、各種ハードウェアを制御するためのインターフェースを提供するデバイスドライバ。ハードウェアとの通信や電源状態を管理する。
フィルタドライバ デバイスドライバの一種で、フィルタリング機能を持つもの。ファンクションドライバの上位、または下位に挿入される。ここでいうフィルタリングとは、ファンクションドライバへI./Oの変更や拡張を指す。これにより、既存のデバイスドライバに拡張機能を持たせることが可能となる。
プロセス 実行中のプログラム。メモリが割り当てられる単位。ユーザモードで実行されるプログラムは、各々が1つのプロセスとみなされる。カーネルモードで実行されるプログラムは、1つのシステムプロセスとして動作する。
ペンディング 要求がソフトウェア内で実行中(未完了)であることを示すステータス。カーネルモードドライバが使用するステータス値、STATUS_PENDINGを指す。非同期I/Oにおいて、I/O処理中に並行して別の処理を実行できるよう、カーネルモードドライバはSTATUS_PENDINGを返す。
ユーザーバッファ IRPのUserBufferを指す。Buffered I/Oにおいて、Read要求の場合、ユーザバッファにはプログラムが指定したメモリ領域のアドレスが格納される。カーネルモードドライバは、I/Oマネージャが割り当てたシステムバッファにReadデータを格納する。IRP完了後、I/Oマネージャはシステムバッファのデータをユーザバッファにコピーする。Write要求の場合、プログラムが指定したメモリ領域のアドレスは、システムバッファにコピーされ、カーネルモードドライバはシステムバッファを操作する。
ユーザーモード

ハードウェアに直接アクセス可能なカーネルモードに対し、ユーザモードでは、CPUの動作に制限が加えられ、主に以下の動作が実行できない

  • -周辺機器の管理(デバイスドライバの実行)
  • -メモリの管理
  • -ファイル・システムの管理

カーネルモードと分離することで、ユーザモードプログラムの異常動作によるBSODを回避する。

ワークアイテム デバイスドライバ内で実行するスレッド。PASSIVE_LEVELで起動される。マルチスレッドで処理をさせたい場合や、システムコールの要件によりPASSIVE_LEVELで実行しなければならない場合などに使用する。
割り込み

CPUがソフトウェア、またはハードウェアから受け取る要求の一種。前者をソフトウェア割込み、後者をハードウェア割込みという。通常、ハードウェア割込みが起きた場合、CPUがデバイスドライバの割込み処理ルーチンを呼び出し、対応するデバイスドライバの割込み処理を行う必要がある。

類語:ISR

page up