カーネルドライバとカーネルモジュールの違いは何ですか?

カーネルドライバとカーネルモジュールの違いは何ですか?

lspci -k3.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_currentnouveaunvidiafb

では、カーネルドライバとカーネルモジュールの違いが何であるかを知りたいです。

答え1

カーネルモジュールは、実行時にカーネルに挿入できるコンパイル済みのコードです。insmodまたはmodprobe

ドライバは、一部のハードウェアデバイスと通信するためにカーネルで実行されるコードの一部です。ハードウェアを「駆動」します。コンピュータのほとんどのハードウェアには関連ドライバがあります。実行中のカーネルのほとんどはドライバコードです。 ²

ドライバはディスク上のカーネルファイルに静的に構築できます。ドライバは、後で動的にロードできるようにカーネルモジュールとして構築することもできます。 (その後、削除することができます。)

標準的な慣行は、ドライバをカーネルに静的に接続するのではなく、可能な限りドライバをカーネルモジュールとして構築することです。これにより、より大きな柔軟性が得られます。ただし、これを行わないには、次の理由があります。

  • 時には、システムの起動を支援するために特定のドライバが必要な場合もあります。これは思ったほど頻繁には起こりません。なぜなら初期化プログラム特徴。

  • 静的に構築されたドライバは、静的にスコープされたシステムで正確に必要なものである可能性があります。組み込みシステム。つまり、どのドライバが常に必要で変更されていないかを正確に知っている場合は、動的カーネルモジュールを使用する必要はありません。

  • カーネルを静的にビルドし、Linuxの動的モジュールロード機能を無効にすると、カーネルコードの実行時の変更を防ぐことができます。これは、柔軟性を犠牲にして追加のセキュリティと信頼性を提供します。

すべてのカーネルモジュールはドライバではありません。たとえば、Linuxカーネルの比較的新機能は次のとおりです。さまざまなプロセススケジューラのロード。別の例は、より複雑なタイプのハードウェアが、下位レベルのハードウェアドライバとユーザ空間との間に複数の共通層を有することが多いことである。USB HIDドライバ、これUSBスタックの特定の要素、基本ハードウェアとは無関係です。


ナレーター:

  1. この広範な説明の1つの例外は、「ドライバ」のないCPUチップです。それ自体。コンピューターには、ドライバーのないハードウェアが含まれている場合があります。

  2. オペレーティングシステムカーネルの残りのコードは、次の一般的なサービスを提供します。メモリ管理産業用コンピュータスケジューリング待つ。これらのサービスは主に次のサービスを提供できます。ユーザーエリア以前にリンクされている例のようなアプリケーション、またはドライバまたは他のカーネル内のインフラストラクチャで使用される内部サービスのいずれかです。

  3. いずれかが/boot開始時に次の人によって開始されました。ブートローダーすでに起動プロセス

答え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では、ハードウェアとの会話は次のように要約されます。

これらの操作は通常、以下のようにユーザースペースでは実行できません。ユーザー空間とカーネル空間の違いは何ですか?しかし、いくつかの例外があります。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。これは、モジュールをリストし、モジュールを削除することを意味します。

関連情報