lspci -k
3.2.0-29 通常のカーネルを使用して Kubuntu で実行すると、次の内容が表示されます。
01:00.0 VGA compatible controller: NVIDIA Corporation G86 [Quadro NVS 290] (rev a1)
Subsystem: NVIDIA Corporation Device 0492
Kernel driver in use: nvidia
Kernel modules: nvidia_current, nouveau, nvidiafb
nvidia
カーネルドライバとカーネルモジュールがありますnvidia_current
。nouveau
nvidiafb
では、カーネルドライバとカーネルモジュールの違いが何であるかを知りたいです。
答え1
カーネルモジュールは、実行時にカーネルに挿入できるコンパイル済みのコードです。insmod
またはmodprobe
。
ドライバは、一部のハードウェアデバイスと通信するためにカーネルで実行されるコードの一部です。ハードウェアを「駆動」します。コンピュータのほとんどのハードウェアには関連ドライバがあります。実行中のカーネルのほとんどはドライバコードです。 ²
ドライバはディスク上のカーネルファイルに静的に構築できます。ドライバは、後で動的にロードできるようにカーネルモジュールとして構築することもできます。 (その後、削除することができます。)
標準的な慣行は、ドライバをカーネルに静的に接続するのではなく、可能な限りドライバをカーネルモジュールとして構築することです。これにより、より大きな柔軟性が得られます。ただし、これを行わないには、次の理由があります。
時には、システムの起動を支援するために特定のドライバが必要な場合もあります。これは思ったほど頻繁には起こりません。なぜなら初期化プログラム特徴。
静的に構築されたドライバは、静的にスコープされたシステムで正確に必要なものである可能性があります。組み込みシステム。つまり、どのドライバが常に必要で変更されていないかを正確に知っている場合は、動的カーネルモジュールを使用する必要はありません。
カーネルを静的にビルドし、Linuxの動的モジュールロード機能を無効にすると、カーネルコードの実行時の変更を防ぐことができます。これは、柔軟性を犠牲にして追加のセキュリティと信頼性を提供します。
すべてのカーネルモジュールはドライバではありません。たとえば、Linuxカーネルの比較的新機能は次のとおりです。さまざまなプロセススケジューラのロード。別の例は、より複雑なタイプのハードウェアが、下位レベルのハードウェアドライバとユーザ空間との間に複数の共通層を有することが多いことである。USB HIDドライバ、これUSBスタックの特定の要素、基本ハードウェアとは無関係です。
ナレーター:
答え2
出力に関する特定の質問に答えるために、lspci
「カーネルドライバ」行は現在のカードにバインドされているドライバ(この場合は排他nvidia
ドライバ)を表します。 「カーネルモジュール」行には、すべてのドライバが一覧表示されます。知られているこのカードをバインドできます。ここで、排他ドライバーは異なる名前で表示されます。それはおそらく、lspci
ドライバとそのファイル名をドライバ自体でエンコードされた名前と比較して照会する方法です。
答え3
カーネルモジュールはデバイスドライバではないかもしれません。
「カーネルドライバ」は明確に定義された用語ではありませんが、一度試してみましょう。
これはハードウェアを駆動しないカーネルモジュールなので、「デバイスドライバ」と合理的に考えることはできません。
#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デバイスドライバの簡単な例です。https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/pci.c
その後、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などの広く使用されているプロトコルのための高水準インターフェース
答え4
私の答えはJimの答えと同じです。カーネルドライバは、ハードウェアを駆動するように設計されたプログラム(カーネルモジュール)です。 lspci出力は、nvidiaがデバイスloaded
用のモジュールであるため、カーネルドライバであることを示します。また、他のカーネルモジュールも使用できます。
ドライバを一覧表示および削除するLinuxコマンドはそれぞれlsmod
およびですrmmod
。これは、モジュールをリストし、モジュールを削除することを意味します。