スマートまたは仮想ハードウェアドライバー

ドライバーに関する最初の記事は絶対に紹介的なものであり、最新のデバイスのドライバーがどのように配置されているかについての話を補足することはできないと思いました。



最初に、バスマスターの定義を紹介します。バスマスターは、スレーブだけでなく、コンピューターバス上のマスターにもなることができます。 つまり、プロセッサによって開始されたI / Oトランザクションに応答するだけでなく、メモリに「移動」する独自のイニシアチブで独立して開始することもできます。



このようなデバイスの歴史はDMAの概念に根ざしています:マイクロプロセッサの先駆者である8080マイクロプロセッサ(KR5080IK80)の時代には、I / Oデバイスとメモリ間でバイトをドラッグするルーチン操作からプロセッサをアンロードするのが良いことが明らかになりました。



DMA(Direct Memory Access)コントローラーはI / Oデバイスに関して外部サブシステムであり、明示的にプログラムする必要がありました-操作の種類(メモリへの書き込み、メモリからの読み取り、メモリメモリのコピー)、メモリアドレスなどを設定します。実際、私は過去時制でこれについて完全に不公平に書いています。これらはすべて、たとえばマイクロコントローラなどに存在しています。



すでにDMAモードでは、ドライバーの操作は大きく異なります。ドライバーはI / Oを実行せず、デバイスの設定を準備し、アクティブにし、I / Oの最後で割り込みを待ち、操作の成功を確認する必要があります。 前の記事で述べられたことはすべてDMAデバイスにも当てはまりますが、言われたことに加えて、ドライバーはデバイスとDMAコントローラーの間の相互作用を理解し、時にはコントローラーを明示的に割り当てて構成する必要があります:古いデバイスでDMAコントローラーへのI / Oポートのバインドが修正された場合、多くの場合、完全なルーティングまたは2〜4オプションからのDMAチャネル選択が可能です。



それとは別に、次のI / Oトランザクションの開始は、自動(可能な限り最高速度でDMAポンド)、ペース設定で自動(バス帯域幅全体を消費しないように)、またはイベントごとに開始できることに注意する必要があります。



同時に、開発されたシステムのイベントは、割り込み、マイクロコントローラのレッグの状態の変化、または別のデバイスがイベントのソースになる可能性があります。 たとえば、タイマー。 これにより、DAC、DMAエンジン、およびタイマーを組み合わせて、次のバイトを事前に定義された(タイマー)周波数でDACに供給することができます。 デバイス集約には他のオプションがあります。たとえば、1つのDMAチャネルを別のDMAチャネルの最後に含めることです。 プロセッサの注意を引き付けることなく。



また、DMAコントローラーは、1つのチャンネルが終了し、2番目のチャンネルが起動され、割り込みが生成されたときにデータフローの連続性を確保するために、明示的に1組のチャンネルをペアリングできる場合があることも適切です。



コントローラの世界から「アダルト」マシンに戻ります。 最新のI / Oサブシステムのほとんどは、外部DMAに基づいていませんが、内部にアナログを直接持っています。



これらは、「マスターバス」モードのデバイス、バスマスターです。



組み込みの個人用で最適に設計されたDMAコントローラーを備えたデバイスと考えるのが最も簡単です。



通常、このようなデバイスはメモリ内の記述子のツリーを介して制御されます。デバイスには特別なレジスタがあり、プロセッサがコントローラのジョブを含む構造体のアドレスをメモリに配置します。 または、より頻繁に、そのようなタスクを含む構造の配列またはリスト。 コントローラーはメモリからタスクを個別に読み取り、ステップごとに実行します。 原則として、タスクは、操作の識別子、メモリ内のアドレス、データを取得する場所、および操作に必要な追加パラメーターで構成されます。 例:{ディスクへの書き込み、ディスクアドレス、メモリ内のバッファアドレス}。 これは、ディスク、USB、ネットワークインターフェイスなど、あらゆるものの最新のコントローラーの配置方法です。



このようなデバイスには、記述子構造に加えて、イベントを交換するためのツールも必要です。プロセッサは、記述子を変更または補足したことを報告できる必要があり、デバイスは部分的または完全に通信できる必要があります。 もちろん、2番目は割り込みを介して実行されます。1番目の場合、レジスタ(ドアベル)がよく使用されます。プロセッサでは、変更にデバイスの注意を引くためにプロセッサが「ノック」します。



同時に、デバイスが現在処理しているものを正確に変更する危険性があり、ドライバーの構造に追加の制限を課します。



この行には、virtioデバイスが個別にあります。 彼らは世界中のハイパーバイザーの勝利の行列の結果として現れました。 伝統的に、ハイパーバイザーは、ゲストOSに、1つまたは別の一般的な物理デバイスをコピーした仮想デバイスの特定のセットを提供していました。 既知のネットワークカードまたはディスクコントローラー。 しかし、「アイアン」デバイスのエミュレートは難しく、不便で退屈です。多くの場合、仮想世界では完全に不要なプロパティを維持する必要があり、仮想化の目的では、実際のアイアンデバイスの構造は通常最適ではありません。



これにより、著者は意図的に仮想デバイスを設計することになり、仮想デバイスはハードウェアに実装されることは決してなく(決して©007とは言わない)、ハイパーバイザーとゲストOS間の通信にのみ必要です。 これらは、多数の異機種デバイスに対して、ゲストOSのコアとハイパーバイザーの両方に共通の均一なインフラストラクチャを実装できるように設計されています。



実装を見る



本質的に、virtioドライバーは、ゲストOSとハイパーバイザー間の要求と応答を含むパケットトランスポートです。 パッケージの内容は、ドライバーのタイプとそのモードに固有です。 たとえば、ネットワークカードの場合、これはイーサネットパケットのアドレスであり、ディスクの場合、ディスク操作のタイプとディスク上のアドレスを持つスキャッターギャザーハンドルです。



virtioドライバーでは、カーネルがパッケージを満たし、汎用vitioドライバーにそれをデバイスに「渡す」ように要求します。 これで、デバイスがパケットを「送信」するまで、パケットに触れることはできません。 また、逆に、デバイスが外部のイニシアチブで入力を行うことができる場合、いくつかの空の(読み取りの準備ができた)パケットをデバイスに転送する必要があります-データが到着すると(たとえば、着信ネットワークメッセージ)、パケットはいっぱいになり、ゲストOSカーネルに返送されます。



さらに、virtio標準では、カーネルとデバイスが標準の方法で動作モードとサポートされている機能に同意する機能をサポートしています。 たとえば、virtioネットワークドライバーは、送信されたIPパケットにチェックサムを読み取って挿入できる場合とできない場合があります。



virtio規格がかなり一般的な汎用バスマスターデバイスドライバーを記述していることは簡単にわかります。メモリ内のアドレスとI / Oリクエストパラメーターを使用して「デバイス」にリクエストを送信し、残りは非同期に発生します。



前述の背景に照らして、DPCについて話すことはもはやそれほど重要ではありませんが、コメントで議論が生じたので、簡単に説明します。



一部のオペレーティングシステム(PhantomはNTでこれを「コピー」しましたが、コピー元-私は知りません)「ライト」スレッド(遅延プロシージャコール)内でコードを実行するための定期的なサポートがあります。 これにより、ドライバーが割り込みに費やす時間を短縮できます。割り込みハンドラーはイベントのみをキャプチャし、最大で1つのレジスターからデバイスからステータスを読み取ります。 残りはDPCで行われます。DPCはすぐにアクティブになり、ジョブを完了します。



率直に言って、これにはあまり意味がありません-ドライバーで独自の高優先度のスレッドを実行し、それから入出力を行う方が簡単です。 ただし、オプションが存在する場合があります。 DPC優先度グループを選択して、スレッドの優先度よりも常に高い優先度を保証できます。 超高速のスケジューリングを提供し、このDPCが要求した割り込みの終了時にプロセッサをこれらのスレッドに直接転送することにより、待ち時間を短縮できます。



それとは別に、DPCからは、割り込みでは不可能なことの多くが可能であることに注意してください。 OSに正確に依存するもの。 DPC内のファントムでは、1か月間眠りにつくことを含め、すべてを行うことができます。 罪ですが、それは可能です。 それにもかかわらず、NT、EMNIPは何らかの形でDPCの権利を制限します(つまり、これらは通常のスレッドではありません)が、詳細は覚えていません。



これに関して、私はドライバーに対する義務を果たしたと感じています。 :)



5月1日以来、遅かれ早かれあなたは。 :)



All Articles