カーネル モジュールは、insmod
などを使用して、実行時にカーネルに挿入できるコンパイル済みコードです。 または modprobe
.
ドライバーは、ハードウェア デバイスと対話するためにカーネル内で実行されるコードです。ハードウェアを「駆動」します。コンピューターのほとんどすべてのハードウェアには、ドライバーが関連付けられています。¹ 実行中のカーネルの大部分はドライバー コードです。²
ドライバーは、ディスク上のカーネル ファイルに静的に組み込まれている可能性があります。³ ドライバーは、後で動的にロードできるように、カーネル モジュールとして構築されている場合もあります。 (そしておそらくアンロードされます。)
標準的な方法は、ドライバーをカーネルに静的にリンクするのではなく、可能であればカーネル モジュールとしてビルドすることです。これにより、柔軟性が向上します。ただし、そうしない正当な理由があります:
-
システムの起動を支援するために、特定のドライバーが絶対に必要な場合があります。 initrd 機能により、想像するほど頻繁には発生しません。
-
静的に構築されたドライバーは、組み込みシステムなど、静的にスコープが設定されたシステムでまさに必要なものである場合があります。つまり、どのドライバが常に必要であり、これが決して変わらないことが事前に正確にわかっている場合は、動的カーネル モジュールを気にしない十分な理由があります。
-
カーネルを静的に構築し、Linux の動的モジュール ローディング機能を無効にすると、カーネル コードの実行時の変更を防止できます。これにより、柔軟性は犠牲になりますが、追加のセキュリティと安定性が提供されます。
すべてのカーネル モジュールがドライバーであるとは限りません。たとえば、Linux カーネルの比較的最近の機能は、別のプロセス スケジューラをロードできることです。もう 1 つの例は、より複雑なタイプのハードウェアには、下層のハードウェアとは無関係に、USB スタックの特定の要素を実装する USB HID ドライバーなど、低レベルのハードウェア ドライバーとユーザーランドの間に位置する複数の汎用レイヤーがあることが多いことです。
余談:
<オール>この大まかな説明の 1 つの例外は CPU チップです。CPU チップには「ドライバ」自体がありません .お使いのコンピューターには、ドライバーがないハードウェアが含まれている場合もあります。
OS カーネルの残りのコードは、メモリ管理、IPC、スケジューリングなどの一般的なサービスを提供します。これらのサービスは、以前にリンクされた例のように、主にユーザーランド アプリケーションにサービスを提供する場合もあれば、ドライバーまたはその他のイントラ ドライバーによって使用される内部サービスである場合もあります。カーネル インフラストラクチャ
/boot
のもの 、ブート プロセスの早い段階でブート ローダーによってブート時に RAM にロードされます。
lspci
に関する特定の質問に答えるには 出力、「kernel driver」行は、現在カードにバインドされているドライバーを参照します。この場合、独自の nvidia
運転者。 「kernel modules」行には、既知のすべてのドライバがリストされています このカードにバインドできます。ここでは、おそらく lspci
が原因で、独自のドライバーが別の名前で表示されます。 ドライバー自体にコード化された名前とは対照的に、ドライバーとそのファイル名を見つけました。
カーネル モジュールはデバイス ドライバではない可能性があります
「カーネル ドライバー」は明確に定義された用語ではありませんが、試してみましょう。
これはハードウェアを駆動しないカーネル モジュールであるため、合理的に「デバイス ドライバー」と見なすことはできません:
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int myinit(void)
{
printk(KERN_INFO "hello init\n");
return 0;
}
static void myexit(void)
{
printk(KERN_INFO "hello exit\n");
}
module_init(myinit)
module_exit(myexit)
ビルド後、以下で使用できます:
insmod hello.ko
hello init
を出力します dmesg
まで .
ただし、デバイス ドライバーではなく、実際に役立つカーネル モジュールもあります。たとえば、カーネルのデバッグやパフォーマンス情報を公開するモジュールです。
通常、デバイス ドライバはカーネル モジュールでもあります。
「デバイス ドライバー」の例は、ハードウェアを駆動する必要があり、ハードウェアの説明が複雑になる傾向があるため、生成が少し難しくなります。
ただし、QEMU やその他のエミュレーターを使用すると、実際のハードウェアまたは簡略化されたハードウェアのソフトウェア モデルを構築できます。これは、ハードウェアと対話する方法を学ぶのに最適な方法です。最小限の PCI デバイス ドライバーの簡単な例を次に示します。
次に、x86 では、ハードウェアとの通信が次のようになることがわかります。
in
とout
指示、例:https://stackoverflow.com/questions/3215878/what-are-in-out-instructions-in-x86-used-for/33444273#33444273- ハンドラを CPU に登録して割り込みを処理する
ユーザー空間とカーネル空間の違いは何ですか?ただし、いくつかの例外があります:https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space.
次に、カーネルは、そのようなハードウェアとのやり取りをより簡単にし、移植性を高めるために、より高レベルの API を提供します:
request_irq
割り込みを処理するioreadX
および IO メモリ マッピング- PCI や USB などの一般的なプロトコル用のさらに高度なインターフェース