デバイスドライバとは、コンピュータに接続された特定の種類のデバイスを操作または制御するソフトウェアです。[ 1 ]ドライバはハードウェアデバイスへのソフトウェアインターフェイスを提供し、他のソフトウェアがハードウェアの詳細を知らなくてもハードウェア機能にアクセスできるようにします。
ドライバは、ハードウェアが接続されているコンピュータバスまたは通信サブシステムを介してデバイスと通信します。呼び出し元のプログラムがドライバ内のルーチンを呼び出すと、ドライバはデバイスにコマンドを発行します(デバイスを駆動します)。デバイスがドライバにデータを送信すると、ドライバは元の呼び出し元プログラム内のルーチンを呼び出すことがあります。
ドライバはハードウェアに依存し、オペレーティングシステムに固有です。通常、必要な非同期時間依存ハードウェアインターフェイスに必要な割り込み処理を提供します。 [ 2 ]
デバイスドライバの主な目的は、ハードウェアデバイスとそれを使用するアプリケーションまたはオペレーティングシステムとの間の翻訳者として機能することにより、ハードウェアの抽象化を提供することです。[ 1 ]プログラマは、エンドユーザーが使用する特定のハードウェアに関係なく、より高レベルのアプリケーションコードを記述できます。
例えば、シリアルポートとやり取りするための高レベルアプリケーションは、データの送信と受信という2つの機能だけを持つ場合があります。より低レベルでは、これらの機能を実装するデバイスドライバが、ユーザーのコンピュータにインストールされている特定のシリアルポートコントローラと通信します。16550 UARTを制御するために必要なコマンドは、 USB-シリアルアダプタを制御するために必要なコマンドとは大きく異なりますが、各ハードウェア固有のデバイスドライバは、これらの詳細を同じ(または類似の)ソフトウェアインターフェイスに抽象化します。
デバイスドライバを作成するには、特定のプラットフォーム機能におけるハードウェアとソフトウェアの動作原理を深く理解する必要があります。ドライバは動作するためにハードウェア機能への低レベルアクセスを必要とするため、通常は特権の高い環境で動作し、何らかの問題が発生するとシステムの動作上の問題を引き起こす可能性があります。対照的に、最新のオペレーティングシステム上のほとんどのユーザーレベルソフトウェアの誤動作は、システムの他の部分に大きな影響を与えることなく停止できます。デバイスが誤ってプログラムされている場合、ユーザーモードで実行されるドライバでさえシステムをクラッシュさせる可能性があります。これらの要因により、問題の診断はより困難で危険になります。[ 3 ]
そのため、ドライバの作成は通常、ハードウェア開発会社に勤務するソフトウェアエンジニアやコンピュータエンジニアが担当します。これは、従業員である彼らが、外部のほとんどの人よりもハードウェアの設計について詳しい情報を持っているためです。さらに、ハードウェアメーカーにとって、顧客が自社のハードウェアを最適に使用できるようにすることは、従来から重要な利益になると考えられてきました。通常、ドライバのハードウェア抽象化部分はオペレーティングシステムベンダーが作成し、低レベルの物理デバイスアクセス部分はデバイスベンダーが実装します。しかし近年、ベンダー以外の企業が、主にフリーおよびオープンソースのオペレーティングシステムで使用するために、独自のデバイス向けに多数のデバイスドライバを作成しています。このような場合、ハードウェアメーカーがデバイスの通信方法に関する情報を提供することが重要です。この情報はリバースエンジニアリングによって取得することもできますが、ハードウェアの場合はソフトウェアの場合よりもはるかに困難です。
Windows では、ドライバとミニドライバの組み合わせが使用されています。完全なクラス/ポートドライバはオペレーティングシステムに付属しており、ミニクラス/ミニポートドライバはベンダーによって開発され、完全なドライバスタックのハードウェアまたは機能固有のサブセットを実装します。[ 4 ]ミニポートモデルは、 NDIS、 WDM、WDDM、WaveRT、StorPort、WIA、およびHIDドライバで使用されています。それぞれがデバイス固有の API を使用し、開発者がデバイス管理タスクを処理する必要があります。
マイクロソフトは、不適切なデバイスドライバによるシステム不安定性を軽減するため、Windows Driver Frameworks (WDF) と呼ばれる新しいドライバ開発フレームワークを作成しました。これには、特定の種類のドライバ(主にデバイスとの通信にメッセージベースのプロトコルを実装するドライバ)をユーザーモードドライバとして開発することを推奨するユーザーモードドライバフレームワーク (UMDF) が含まれます。このようなドライバが誤動作しても、システム不安定性を引き起こすことはありません。カーネルモードドライバフレームワーク(KMDF) モデルでは、引き続きカーネルモードデバイスドライバの開発が可能ですが、I/O 操作のキャンセル、電源管理、プラグアンドプレイデバイスのサポートなど、問題を引き起こすことが知られている機能の標準的な実装を提供することを目指しています。
Appleは、 macOS上でドライバを開発するためのオープンソースのフレームワークであるI/O Kitを提供している。
Linux 環境では、プログラマはカーネルの一部として、ロード可能なモジュールとして、または USB デバイスなどカーネル インターフェイスが存在する特定のタイプのデバイス用のユーザー モード ドライバとしてデバイス ドライバを構築できます。Makedevには、ttyS (ターミナル)、lp (パラレル ポート)、hd (ディスク)、ループ、サウンド (ミキサー、シーケンサー、DSP、オーディオを含む) など、Linux のデバイスのリストが含まれています。[ 5 ]
Microsoft Windowsの.sysファイルとLinuxの.koファイルには、ロード可能なデバイスドライバを含めることができます。ロード可能なデバイスドライバの利点は、必要なときにのみロードし、その後アンロードできるため、カーネルメモリを節約できることです。
オペレーティングシステムによっては、デバイスドライバはさまざまな異なる特権レベルで実行が許可される場合があります。ドライバがどの特権レベルにあるかは、オペレーティングシステムが使用するカーネルの種類によって大きく左右されます。Linuxカーネルなどのモノリシックカーネルを使用するオペレーティングシステムでは、通常、デバイスドライバは他のすべてのカーネルオブジェクトと同じ特権で実行されます。対照的に、Minixなどのマイクロカーネルを中心に設計されたシステムでは、ドライバはカーネルとは独立したプロセスとして実行されますが、重要な入出力機能にはドライバが使用されます。[ 6 ]ハイブリッドカーネルを使用するWindows NTシステム では、デバイスドライバはカーネルモードまたはユーザーモードのいずれかで実行されるのが一般的です。[ 7 ]
メモリをさまざまな特権レベルに分離する最も一般的なメカニズムは、保護リングを使用することです。x86やARMプロセッサを搭載したシステムなど、多くのシステムでは、リング間の切り替えによってパフォーマンスが低下するため、オペレーティングシステム開発者や組み込みソフトウェアエンジニアは、ネットワークインターフェイスカードなど、低遅延で動作することを好むデバイスのドライバを作成する際に、この要素を考慮します。ドライバをユーザーモードで実行する主な利点は、安定性の向上です。これは、記述が不十分なユーザーモードデバイスドライバがカーネルメモリを上書きしてシステムをクラッシュさせることができないためです。[ 8 ]
デバイスドライバの一般的な抽象化レベルには、以下のようなものがあります。
現代の多様性のためハードウェアやオペレーティングシステムなど、ドライバはさまざまな環境で動作します。[ 10 ]ドライバは以下とインターフェースする可能性があります。
そのため、特定のハードウェアに適したデバイスドライバを選択してインストールすることは、コンピュータシステムの構成において重要な要素となることが多い。[ 11 ]
仮想デバイスドライバは、デバイスドライバの特定のバリアントです。これらは、特に仮想化環境において、ハードウェアデバイスをエミュレートするために使用されます。たとえば、ゲストオペレーティングシステムがXenホスト上で実行される場合などです。 [ 12 ]仮想デバイスドライバは、ゲストオペレーティングシステムがハードウェアを制御できるようにする代わりに、ハードウェアをエミュレートします。これにより、仮想マシン内で実行されているゲストオペレーティングシステムとそのドライバは、実際のハードウェアにアクセスしているという錯覚を得ることができます。ゲストオペレーティングシステムによるハードウェアへのアクセス試行は、ホストオペレーティングシステム内の仮想デバイスドライバにルーティングされます。仮想デバイスドライバは、割り込みなどのハードウェア関連のシミュレートされたイベントを仮想マシンに送信することもできます。
仮想デバイスは、仮想化されていない環境でも動作可能です。例えば、仮想ネットワークアダプタは仮想プライベートネットワークで使用され、仮想ディスクデバイスはiSCSIで使用されます。仮想デバイスドライバの良い例としては、 Daemon Toolsが挙げられます。
仮想デバイスドライバには、 VxD、VLM、VDDなど、いくつかの種類があります。
Solarisで一般的に使用されるデバイスドライバの説明:
PCIバスまたはUSB上のデバイスは、それぞれ2バイトからなる2つのIDによって識別されます。ベンダーIDはデバイスのベンダーを識別し、デバイスIDはそのメーカー/ベンダーの特定のデバイスを識別します。
PCIデバイスには、デバイスのメインチップを識別するIDペアと、ベンダーを識別するサブシステムIDペアが備わっていることが多く、このサブシステムIDペアはチップメーカーのIDとは異なる場合があります。
コンピュータには、オペレーティングシステムカーネル内で動作する多様でカスタマイズされたデバイスドライバが多数存在することが多く、それらにはさまざまなバグや脆弱性が含まれていることが多く、エクスプロイトの標的となる。[ 19 ]BYOVD( Bring Your Own Vulnerable Driver)攻撃者は、カーネルに悪意のあるコードを挿入できる既知の脆弱性を持つ署名済みの古いサードパーティ製ドライバをインストールします。[ 20 ] 脆弱なドライバには、WiFi および Bluetooth 用ドライバ、[ 21 ] [ 22 ]ゲーム/グラフィックドライバ、[ 23 ]およびプリンタ用ドライバが含まれます。[ 24 ]
特に、Microsoft Windows [ 25 ]のようなクローズドソースのオペレーティングシステムでは、効果的なカーネル脆弱性検出ツールが不足しています。デバイスドライバのソースコードはほとんどが独自仕様で調査できないため[ 26 ]、ドライバは多くの場合、多くの特権を持っています[ 27 ] [ 28 ] [ 29 ] [ 30 ] 。
セキュリティ研究者グループは、分離の欠如をカーネルセキュリティを損なう主な要因の1つと考えており、[ 31 ]オペレーティングシステムカーネル、特に年間約80,000件のコミットがあるというモノリシックなLinuxカーネルを保護するための分離フレームワークを公開しました。 [ 32 ] [ 33 ]
カーネルの設計において重要な考慮事項は、障害からの保護(フォールトトレランス)と悪意のある動作からの保護(セキュリティ)に対するサポートです。これら 2 つの側面は通常明確に区別されておらず、カーネルの設計でこの区別を採用すると、保護のための階層構造が拒否されます。[ 34 ]
カーネルが提供するメカニズムやポリシーは、以下のようないくつかの基準に基づいて分類できます。
ハードウェアRAID機能を提供するHP(旧Compaq)Smart Arrayコントローラ用のドライバ。
{{cite book}}:|work=無視されました (ヘルプ)ホストデバイスとシリアル転送媒体との間で双方向データ転送を実行するための改良されたギガボーリンクモジュール(GLM)が提供される。