Linuxのデバイスドライバは、ユーザーモードまたはカーネルモードで実行できることがわかりました。
また、ポートマッピングIOを使用するか、メモリマッピングIOを使用する2つの方法のいずれかでIOデバイスにアクセスできることにも注意してください。
ポートマッピングIOはIN
命令とを使用してIOデバイスにアクセスしますOUT
が、メモリマッピングIOではIOデバイスのレジスタがカーネル空間メモリにマッピングされます(したがって、メモリにアクセスする通常のCPU命令を使用してアクセスできますmov
)。
これで、デバイスドライバがIOデバイスに直接アクセスせず、代わりにIOデバイスが接続されたIOポートを持つデバイスドライバを介して通信する必要があります(たとえば、シリアルポートを持つデバイスドライバを介して(IOデバイスがシリアルポートに接続))。
ただし、IOデバイスがポートマッピングIOを使用している場合と命令はIN
特権OUT
命令であるため、それを使用するにはカーネルモードにする必要があります。 IOデバイスがメモリマッピングされたIOを使用している場合、IOデバイスレジスタはカーネル空間メモリにマッピングされ、カーネル空間メモリにアクセスするにはカーネルモードにする必要があります。
そのため、IOデバイスに直接アクセスするデバイスドライバはユーザーモードでは実行できないと思います。
私の言葉は正しいですか、それとも何かが抜けていますか?
答え1
Q. IN、OUT命令は特権命令であるため、これを使用するにはカーネルモードにする必要があります。
iopl()
。ポート番号が十分に低い場合は、使用することを選択できますioperm()
。
明らかに、すべてのアーキテクチャでサポートされているわけではありません。
バラよりinb、inl、inwを使用してユーザー空間からカーネル空間にアクセスする。このリンクは、メソッドとサンプルコードの更新へのリンクです。
Q. IOデバイスがメモリマップされたIOを使用している場合、IOデバイスレジスタはカーネル空間メモリにマッピングされ、カーネル空間メモリにアクセスするにはカーネルモードにする必要があります。
これはXFree86 / Xorgでグラフィックアダプタを駆動するために使用されます!
割り込みについて言及するのを忘れました。これが最も難しい部分です。幸いなことに、これは最新のPCIデバイス用に標準化されているため、デバイス固有のカーネルドライバなしで駆動できます。バラよりユーザースペースI / O HOWTO:汎用PCI UIOドライバ
PCIデバイスへのアクセスに関する具体的な詳細と制限が何であるかわかりません。
DMAはサポートされていません。 DMA用のメモリをマップできるように最小UIOドライバを作成できます。 UIO方法を参照してください。これにより、ユーザースペースドライバは、DMAする場所をデバイスに慎重に知らせることができます。エラーが発生すると、デバイスはシステム RAM の任意の場所に書き込むことができます。喜び!