ドライバーとは
ドライバーという用語を一言で正確に定義するのは難しいことです。最も基本的な定義では、ドライバーとはオペレーティング システムとデバイスの間で相互のやり取りを可能にするソフトウェア コンポーネントのことです。たとえば、あるアプリケーションでデバイスからデータを読み取る必要がある場合を考えてみます。アプリケーションはオペレーティング システムで実装された関数を呼び出し、オペレーティング システムはドライバーで実装された関数を呼び出します。デバイスの設計と製造をした会社が作ったドライバーであれば、デバイス ハードウェアとやり取りする方法を認識してデータを取得します。ドライバーがデバイスからデータを取得した後、データはオペレーティング システムに返され、さらにアプリケーションへと返されます。
定義の拡大
ここまでの説明は、次のような点でかなり簡略化されています。
すべてのドライバーが、必ずしもデバイスを設計した会社によって作られているわけではない。多くの場合、デバイスは、公開されたハードウェア標準に基づいて設計されています。つまり、ドライバーは Microsoft で作成できるため、デバイスの設計会社はドライバーを提供しなくても済むということです。
すべてのドライバーがデバイスと直接やり取りできるとは限らない。ある I/O 要求 (たとえばデバイスからのデータ読み取り) があった場合、この要求に関連するいくつかのドライバーが 1 つのスタック上に重なって置かれることがよくあります。スタックの状態を視覚的に捉えるために、以下の図のように、最初の関連ドライバーが最上位に、最後の関連ドライバーが最下段にそれぞれ置かれているイメージにたとえる方法がよく用いられます。スタック中のドライバーには、要求の形式を別の形式に変換することにより、やり取りに関与するものもあります。これらのドライバーは、デバイスとは直接のやり取りを行いません。単に要求を操作して、スタックで下段に位置するドライバーにその要求を渡すだけです。
スタック中でデバイスと直接やり取りを行うドライバーを関数ドライバーと呼びます。また補助的な処理を実行するドライバーをフィルター ドライバーと呼びます。
フィルター ドライバーには、I/O 要求に関する情報の監視や記録を行うが積極的には関与しないものもある。たとえば、検証ツールとして動作し、スタック中の別のドライバーが I/O 要求を適切に処理しているかどうかを確認するフィルター ドライバーがあります。
したがって、ドライバーとは、オペレーティング システムとデバイス間のやり取りの監視や、これに関与するあらゆるソフトウェア コンポーネントであると定義することにより、その意味を拡大解釈することができます。
ソフトウェア ドライバー
拡大解釈した定義はかなり正確ですが、ドライバーによってはハードウェア デバイスにまったく関与しないものあるという意味で、まだ完全ではありません。 たとえば、カーネル モードでコードを実行しない限りアクセスできないオペレーティング システムのコア データ構造にアクセスするツールを作る例を考えてみます。これは、ツールを 2 つのコンポーネントに分割することで可能になります。1 つ目のコンポーネントは、ユーザー モードで実行され、ユーザー インターフェイスを提供します。2 つ目のコンポーネントはカーネル モードで実行され、オペレーティング システムのコア データにアクセスします。ユーザー モードで実行されるコンポーネントをアプリケーション、またカーネル モードで実行されるコンポーネントをソフトウェア ドライバーと呼びます。ソフトウェア ドライバーはハードウェア デバイスに関連付けられません。プロセッサ モードについて詳しくは、「ユーザー モードとカーネル モード」をご覧ください。
次の図は、ユーザー モード アプリケーションとカーネル モード ソフトウェア ドライバーのやり取りを示したものです。
追加説明
ソフトウェア ドライバーは常にカーネル モードで実行されます。ソフトウェア ドライバーを作る主な理由は、カーネル モードでのみ利用可能な保護データへのアクセスを取得することです。とはいえ、デバイス ドライバーがカーネル モードのデータやリソースへのアクセスを常に必要とするわけではありません。そのため、一部のデバイス ドライバーはユーザー モードで実行されます。
この段階でまだ触れていない種類のドライバーがあります。バス ドライバーです。バス ドライバーについて理解するには、まずデバイス ノードとデバイス ツリーの概念を理解しておく必要があります。デバイス ツリー、デバイス ノード、バス ドライバーについて詳しくは、「デバイス ノードとデバイス スタック」をご覧ください。
ここまでの説明は、関数ドライバーの定義を簡略化したものです。既に、デバイスの関数ドライバーは、デバイスと直接やり取りを行う、スタック中のドライバーであることを説明しました。このことは、Peripheral Component Interconnect (PCI) バスに直接接続されたデバイスにも当てはまります。PCI デバイスの関数ドライバーは、デバイスのポートとメモリ リソースにマッピングされたアドレスを取得します。関数ドライバーは、これらのアドレスに書き込むことにより、デバイスと直接やり取りします。ただし、デバイスが PCI バスに直接接続されることはあまりありません。デバイスは、通常、PCI バスに接続されたホスト バス アダプターに接続されます。たとえば、USB トースターは、PCI バスに接続されたホスト バス アダプター (USB ホスト コントローラーと呼ばれる) に接続します。USB トースターには関数ドライバーがあり、USB ホスト コントローラーにも同様に関数ドライバーがあります。トースターの関数ドライバーは、USB ホスト コントローラーの関数ドライバーに要求を送ることにより、トースターと間接的にやり取りします。それから、USB ホスト コントローラーの関数ドライバーはトースターとやり取りする USB ホスト コントローラーのハードウェアと直接やり取りします。