Linuxでは、ユーザープログラムは常にオペレーティングシステムカーネルへのシステムコールを使用してデバイスドライバに間接的にアクセスしますか?
ドライバがロード可能およびアンロード可能モジュールとして実装されている場合、ユーザープログラムはカーネルへのシステムコールなしでドライバに直接アクセスできますか?
答え1
ユーザーはシステム呼び出しを囲むライブラリ関数を呼び出します(通常のプログラマーにとっては、生のシステム呼び出しは非常にまれです)。モジュールコードはとにかくカーネルモードで実行されるため、ある時点でユーザー空間からカーネル空間へのコンテキスト切り替えが必要です。理想的には、ほとんどのモジュールは標準化されたインタフェース(デバイスノード、netlinkソケット、またはinetソケット)を使用しているため、ユーザー側の対話は主にシステムコールを介して行われread()
ますwrite()
(ioctl
標準のシステムコールではなく「追加」設定を扱うため、一般的です) )。バッファはコールの数を減らしますが、最終的にはシステムコールが含まれます。
答え2
カーネルモジュールはカーネル空間に存在するため、定義に従ってユーザー空間からアクセスできるシステムコールが必要です。はいそれらについて。
ただし、最終的に実行するにはシステムコールを行う必要がありますが、カーネルドライバの一部に構築されたユーザースペースドライバを作成することは可能です。これはI2Cデバイスで可能です。ユーザー空間ドライバは、カーネルのSMBus API(すべてのシステムコール)を使用します。この場合、一部のアプリケーションはシステムを介さずに技術的にドライバの一部の機能を使用できますが、ドライバが実際にハードウェアと対話する必要がある場合は、これはシステムコールです。
システムメモリ(参考資料を参照)mmap()
のonで(システムコール)を使用することもできます。これにはカーネルスペース全体が含まれているため、ハードウェアへのアクセスが公開されます。そしてこの地図を操作してみてください/dev/mem
man mem
確かに追加のシステムコールが必要です。私はこれが異常なものだと思います。部分的には望ましくない方法でカーネル自体を回避し、部分的にはあるアーキテクチャから別のアーキテクチャへの移植に関連する冗長性によるものです。本番システムにドライバを配布するよりも、ハッキングや実験に適しています。
read()
カーネルドライバは、使用および操作が可能なユーザ空間にデバイスノードベースのインタフェースを公開できます。write()
これがまさにシステムコールです。
1. 汎用カーネルドライバを作成する場合、またはカーネルユーザエリア API を使用する場合、移植性の問題はカーネル自体で解決され、1 つのコードバージョンを使用できます。メモリマッピングアプローチを使用する場合は、各アーキテクチャに異なるバージョンのコードが必要です(カーネルにすでに存在するため、「冗長」です)。