web-dev-qa-db-ja.com

I / Oレジスタに直接アクセスできる場合のデバイスドライバーの利点は何ですか?

現代のCベースのLinuxデバイスドライバー開発がどのように見えるかに興味があったので、 この優れた記事 をじっくり見てみました。

私はすべての行を読んだわけではありませんが、その大部分を熟読しました。私の感想は次のとおりです:Linux用のデバイスドライバーを作成することは、非常に苦痛なプロセスのようです。今はそれが私の意見であり、多くのLinux/Cの教祖たちが反対することは間違いないと思いますが、ここで頭を包むことができないことが1つあります。

すべてのCPU/MCUは、チップ上のすべてのピンにアクセスする(読み取りと書き込みの両方)ためのI/Oレジスタ、ポートなどを定義するCライブラリを公開します。たとえば、AVRコントローラーでは、<avr/io.h>。 ARMチップの場合 [〜#〜] cmsis [〜#〜] があります。

だから私の質問はこれです:

その記事のガイドラインに従い、Linuxで適切なデバイスドライバーを構築するすべての「トラブル」(より多くの作業)に行く理由は何ですか?これらのプロセッサーが提供するI/Oレジストリアクセサー(ここでも、avr/io.h、CMSISなど)を使用して、チップ上のすべてのピンにアクセスします(作業量が少ないようです)?

理由があると私は確信しています:私はそれを見ていません。適切なデバイスドライバーを使用して何が得られますか? 1つを使用せず、これらのライブラリの1つを直接使用するだけで失われるものは何ですか?

3
smeeb

Linuxのようなオペレーティングシステムがデバイスドライバーを必要とするときに、AVRファミリーのようなマイクロコントローラーがピンを直接いじることができる理由を尋ねると、リンゴとサスペンションブリッジの比較になります。

マイクロコントローラは、通常、スーパーバイザ(OS)を持たないシングルスレッドのフリーフォーオールであり、すべてのコードは、メモリ、I/O、およびチップが提供する他のあらゆるものに完全にアクセスできます。これは、アプリケーションの一部がGPIOピン3をハイに設定し、それがその状態を維持することを確認する必要がある場合、コードの他の一部が再びローに設定するのを妨げるものは何もないことを意味します。開発者は、これらの種類のインターロックを設定する責任があります。また、デバイスの概念はありません。MCUには、チップのすべてのコピーで同じであるI/Oを制御する一連のレジスタがあります。 I/Oが異なる同じファミリーの別のチップでプログラムを実行する場合は、その一部を書き直すか、少なくとも、チップ固有のヘッダーまたはライブラリを使用して再コンパイルする必要があります。

デスクトップPCのような汎用プロセッサには、I/O機能が組み込まれておらず、代わりに、レジスタがメモリ内のどこかにマップされている外部周辺機器と通信することを選択しています。モデルは同じです。 I/Oマッピングがわかっているボードにx86 CPUを配置すると、独自のI/Oを実行するAVRスタイルのプログラムを作成することは完全に可能ですが、ベアメタルでそれを実行することはありません。オペレーティングシステムが提供する機能。

多くのソフトウェアがこの方法で作成されましたが、歴史のある時点で、モデルがスケーリングされないことが明らかになりました。人々は、周辺機器の組み合わせごとに個別のバージョンを構築することに煩わされることなく、特定のプロセッサーで実行するプログラムを作成したいと考えていました。この生成されたオペレーティングシステムは、標準のソフトウェアインターフェイスを使用して、プログラムに「シリアルポート2で文字Cを送信する」などのことを伝えます。その標準インターフェイスの背後にあるコードは、そのシステムの特定のハードウェアセット用に構築されており、シリアルポート2がブランドX UARTアドレス1234にマッピングされている)であることを知っていました。マイクロコンピューティングでは、この種のこと1970年代に CP/M オペレーティングシステムが登場したことで最も明白になりました。コンピュータを販売するベンダーは、特定のハードウェア用のカスタムドライバを備えたOSのバージョンを提供することになります。汎用バージョンに手動でパッチを適用して、既存のバージョンで動作するようになりました。その結果、すべてのソフトウェアを変更せずに既製のバージョンのソフトウェアを実行できるシステムになりました。

最近のオペレーティングシステムはほとんど同じことを行いますが、より高度なレベルで行われます。システム(PCスタイルおよび多くの組み込みシステム)は、列挙可能で動的なI/Oアーキテクチャを中心に構築されています。つまり、ソフトウェアは現在の内容を把握し、メモリマッピングを割り当て、適切な関数を使用して通信することができます。これに加えて、ハードウェア開発者が毎回再発明する必要なく、ドライバーAがドライバーBが行っていることと競合するリスクなしに、すべての高度な機能を活用できるドライバーインフラストラクチャが提供されます。

Linuxのような本格的なオペレーティングシステムでpoke-the-device-directlyルートを試すことにした場合、最初に尋ねる質問は、ユーザーランドプロセスがデバイスのレジスターがマップされているメモリ領域にどのようにアクセスするかです。答え(「できない」)が、他の理由をもたらします。マルチユーザー、マルチタスクのオペレーティングシステムは、ユーザープログラムが適切に動作することを信頼していません。それらは、システムを害から保護し、システム上で実行されているプログラムを互いに保護するように設計されています。これを実現すると、インターロックとアクセス許可の複雑なモデルがもたらされます。これらはすべて、プログラムがデバイスドライバーに代わって何かを行うように要求できるかどうかに影響します。カーネルに入れられたデバイスドライバーコードは、おそらくそれを書いた人が慎重に行ったため、はるかに大きな信頼が与えられます。

Unixのほとんどの種類のデバイスドライバーに追加する関数は、本質的なもの(ロード、アンロード、オープン、クローズ、読み取り、書き込み、ioctl)であり、非常に長い意思決定チェーンの最後に呼び出されます。プロセスがシリアルポートに書き込みたい場合、OSがそのデバイス用のドライバーが存在し、機能していることをOSが確認し、プロセスがデバイスを使用する権限を持ち、ポートがそのポートによって開かれていることが確認されるまで、ドライバーコードは呼び出されません。処理する。

これがようやく、デバイスドライバーを作成する理由です。デバイスドライバー用に開発する必要のあるコードの量は、OSの他の部分がそれを提供するために提供する高度な量に比べてごくわずかです。

本当に痛くないです。なじみのないものです。カップルができたら、なぜそんなに大騒ぎしていたのか不思議に思うでしょう。 (そして、私を信じてください、それは今では25年前よりもずっと少ない仕事です。)

10
Blrfl

主な答えは統一性です。デバイスがWebカメラの場合、Cライブラリを公開して、すべてのアプリケーションに、カムから画像を受信するように指示すると、カスタムAPIに簡単に書き込むことができます。あなたが書いたもの以外のアプリケーションでウェブカメラが機能しないことを保証します!

これが通常、デバイスドライバーの背後にあるハードウェアを抽象化する理由です。自分で言うと、io.hを介してAVRチップにアクセスでき、CMSISを介してARMです。AVRで動作するアプリケーションを作成する場合、とにかく大きなswitchステートメントと抽象化コードがない限り、ARMに対しては機能しません。また、誰かが別のCPUでアプリケーションを使用している場合は、まったく機能しません。

3
gbjbaanb