私はLinuxドライバの開発が初めてで、他の初心者がカーネルの開発を始めるのに役立つと思う概念的な質問があります。
私は「Linux Device Drivers」という本を読んでいて、第1章を終えました。第3巻。これまで、私はフォルダ内のファイルにopen
、close
およびその他のコマンドを実行して、/dev
ユーザースペースがカーネル機能にアクセスできることを確認しました。
制御を共有するもう1つの方法はファイルを介することです/sys
。ここでファイルの読み書きはsys
ドライバに渡すことができます。
各アプローチのユースケースが何であるかを知りたいです。同じことを行う2つの方法ですか?他に関連して一つに制限はありますか?誰かが他のものよりも役に立つかもしれないいくつかの実際のケースを共有できますか?
私はここで別の質問を読んで説明dev
しますsys
。これは役に立ちますが、2つの違いと用途をより深く理解したいと思います。
答え1
おおよその:
/dev
初期のUnixシステムでカーネルと対話する唯一の方法であったデバイスノードを含みます。その種類は二つありますが、詰まった機器と特徴機器。これらのAPIは、ブロックベースのI / O(一種のディスク)または文字ベースのI / O(シリアルポートなど)を許可するのに適しています。
/sys
(および/proc
)は後で追加され、おそらく次の影響を受けた可能性があります。計画9オペレーティングシステム読み込み時にカーネルモジュールの内部状態を記述または書き込むときに内部状態を設定するテキストは、ファイルエントリに含まれる完全なディレクトリサブツリーを提供します。
したがって、一般的なアプリケーションは次のようになります。
特定のストレージデバイス用のカーネルドライバを作成しますか?ノードを使用して/dev
デバイス自体にアクセスする方法、またはアイテムを使用して/sys
ストレージ/proc
にアクセスする方法を微調整します。
答え2
/sys
これについては、第14章「Linuxデバイスモデル」で説明します。使用できるより多くのサンプルコードを提供します。しかし、私はこの本がもう少しコード中心のアプローチであると考えており、デザインの原則が何であるかを尋ねるのが便利だと思います。
ユーザー空間カーネル通信に/ devと/sysはいつ使用されますか?
最初の答えは、自分では選択できないということです。特定の種類のデバイス用のドライバを作成するとき、カーネルにはすでに同じ種類のデバイスの多くの例があります。既存のデバイスと同じコードパターンを使用できます。 (最も最新の文書はコード自体です。多くのカーネルインターフェースには完全な文書や最新の文書はありません。申し訳ありません!)
これがデバイスドライバを作成する主な理由です。各デバイスに異なる詳細を記述することなく、プログラムで使用できる一貫したインターフェイスを提供します。
これは一般的なアドバイスよりも優先されます。 Linux のサブシステム (デバイスクラスなど) は、見かけ上「間違った」方法を使用しますが、一貫して使用する場合は、そのサブシステムのドライバを作成するときにも一貫して「間違った」間違いでなければなりません。
/開発者
/ dev /はデータパスとして使用する必要があります。ネットワーク機器は例外であり、この本のさまざまな部分でカバーされています。
/dev/ 特殊ファイルは、UNIX 操作を標準化するために使用する必要がread()
あります。これらのいくつかのシステムコール(およびいくつかの派生バリアント)は、ほとんどすべての状況で使用されます。彼らに慣れ始める:). 以下は、ドライバーがさまざまな追加アクションを定義するために使用できるエスケープポートです。write()
poll()
select()
mmap()
ioctl()
ioctl()
/システム
sysfs書き込みは、構成パラメーターの数が少ない場合に使用する必要があります。プレーンテキスト形式でなければならず、単一の値のみを含める必要があります。 [*] 異なる sysfs ファイルがあまりにも必要ない。あなたはすぐに彼らの限界を見るでしょう。
また、sysfsファイルはデフォルトで変数(書き込み可能かどうか)を読み取る必要があると言うことができます。私はそれを読むことがハードウェアの動作を引き起こすべきではないと思います。私はあなたがすでにこの文脈で考えていると思います。
sysfsファイルの利点の1つは、実験に非常に便利です。シェルコマンドを使用すると、簡単にリスト、読み書きできます。これは危険です。実験的な状態にあるsysfsファイルを公開しないように注意してください。他の人がsysfsファイルに依存し始めた場合、ユーザースクリプトを破損するようにファイルを変更したい場合、カーネル管理者は非常に不満を感じるでしょう。
sysfs(ディレクトリ階層とシンボリックリンク)を参照することも、デバイスがどのように構成されているかを確認するのに役立ちます。
さらに、概念的にsysfsの変更を監視することは、プログラムが新しいデバイス(接続時など)を検出できる方法です。技術的には、これらのイベントはファイルシステム自体を通過しませんが、各イベントは特定のsysfsディレクトリを指します。
udevデーモンはこれらのイベントを受け取ります。一般的なプログラムは、必要に応じてudev / libudevに依存する傾向があります。たとえば、udevルールは、新しく検出されたデバイスの設定変更などのイベントが受信されたときにsysfsディレクトリの一部のファイルを読み書きできます。
例を見る
既存のケースを見るのはとても良い考えです。 1つの例だけを見て、他の場所でも同じように動作すると仮定してはいけませんが:-)。
Dirktが述べたように、ブロックストレージデバイスへのアクセスは、公開された最大物理IOサイズなどのいくつかのパラメータ/dev/sda
です。サブディレクトリを見てください。/dev
/sys/class/block/sda/
queue
多くのsysfsファイルがカーネルツリーに書き込まれますDocumentation/ABI/*/sysfs-*
。たとえば、https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block
「文字デバイス」はあまり具体的ではありません。デフォルトでは、ブロックデバイスもネットワークデバイスでもなく、すべてのデバイスに使用されます。 :-).まったく新しいタイプのデバイスを実装する必要がある場合は、まったく新しいタイプの文字デバイスを定義し、いくつかの新しいワークioctl()
セットを定義するのが難しい作業を実行する必要があります。
/sys/class/
自分のシステムで定義されている他の種類のデバイスを見始めることもできます。
/sys/
デバイスのリストも含まれていますが、/dev/
名前ではなくデバイス番号で一覧表示されます。ls -l /sys/dev/char/
とを参照してくださいls -l /sys/dev/block/
。これはudev
管理方法を説明するのに役立ちます/dev
。表示されるすべてのデバイスは。 [**]/dev
にオブジェクトとして一覧表示されます。/sys
[*] sysfsuevent
ファイルには複数の値が含まれており、実際にはコア機能です。ただし、ueventファイルを使用して内部値を変更することはできません。だからこれは次のように言います。それを見ないで、uevent
私の提案が間違っているとは思わないでください。そのようなファイルを直接定義しないでください。デバイスドライバはuevent
ファイルに行を追加できます。考える良い例は、udev
ルールでテストしたい非常に便利な識別属性がある場合です。
[**]除外などは、別々のファイルシステム「devpts」によって実際に実装されるため、リスト/dev/pts/0
に含まれていません。これは非常に特別なケースなので無視してください。私は答えがあるという結論に達しましたが、それが私が言ったことに何も追加しないと思います。ここにいる:/sys
/dev/pts/0
/dev/pts/0
端末を開くときは常にTTYを使用しますか?。