カーネル モジュールは、要求に応じてカーネルにロードおよびアンロードできるコードの一部です。これらは、システムを再起動することなく、カーネルの機能を拡張します。カスタム コードは 2 つの方法で Linux カーネルに追加できます。 - 基本的な方法は、コードをカーネル ソース ツリーに追加し、カーネルを再コンパイルすることです。
  - これを行うより効率的な方法は、実行中にカーネルにコードを追加することです。このプロセスはモジュールのロードと呼ばれます。モジュールとは、カーネルに追加するコードを指します。
  
これらのコードは実行時にロードされ、公式の Linux カーネルの一部ではないため、基本カーネルとは異なるローダブル カーネル モジュール (LKM) と呼ばれます。ベース カーネルは /boot ディレクトリにあり、マシンの起動時に常にロードされますが、LKM はベース カーネルがすでにロードされた後にロードされます。それにもかかわらず、これらの LKM はカーネルの一部であり、基本カーネルと通信して機能を完了します。 LKM はさまざまなタスクを実行できますが、基本的には 3 つの主要なカテゴリに分類されます。 - デバイスドライバー
  - ファイルシステムドライバーと
  - システムコール。
  
   では、LKM にはどのような利点があるのでしょうか? 大きな利点の 1 つは、新しいデバイスを追加するたび、または古いデバイスをアップグレードする場合に、カーネルを再構築し続ける必要がないことです。これは時間を節約し、ベースのカーネル エラーを防ぐのにも役立ちます。有用な経験則は、一度動作するベース カーネルを作成したら、ベース カーネルを変更すべきではないということです。また、システムの問題の診断にも役立ちます。たとえば、ベース カーネルにモジュールを追加し (つまり、ベース カーネルを再コンパイルして変更した)、そのモジュールにバグがあるとします。これによりシステムの起動時にエラーが発生し、カーネルのどの部分が問題を引き起こしているのかわかりません。一方、実行時にモジュールをロードして問題が発生した場合は、問題がすぐにわかり、修正するまでモジュールをアンロードできます。 LKM は、1 行のコマンドでロードおよびアンロードできるという意味で非常に柔軟です。これは、必要な場合にのみ LKM をロードするため、メモリの節約に役立ちます。さらに、それらのいずれかを呼び出すことは単にメモリの別の部分からコードをロードするだけであるため、基本カーネルよりも遅くはありません。 **警告: LKM はユーザー空間プログラムではありません。これらはカーネルの一部です。彼らはシステムを自由に実行しており、簡単にクラッシュさせることができます。   So now that we have established the use loadable kernel modules we are going to write a hello world kernel module. That will print a message when we load the module and an exit message when we unload the module. Code: CPP /**  * @file hello.c  * @author Akshat Sinha  * @date 10 Sept 2016  * @version 0.1  * @brief An introductory 'Hello World!' loadable kernel  * module (LKM) that can display a message in the /var/log/kern.log  * file when the module is loaded and removed. The module can accept  * an argument when it is loaded -- the name which appears in the  * kernel log files. */ #include  /* Needed by all modules */ #include  /* Needed for KERN_INFO */ #include  /* Needed for the macros */ ///< The license type -- this affects runtime behavior MODULE_LICENSE('GPL'); ///< The author -- visible when you use modinfo MODULE_AUTHOR('Akshat Sinha'); ///< The description -- see modinfo MODULE_DESCRIPTION('A simple Hello world LKM!'); ///< The version of the module MODULE_VERSION('0.1'); static int __init hello_start(void) {  printk(KERN_INFO 'Loading hello module...n');  printk(KERN_INFO 'Hello worldn');  return 0; } static void __exit hello_end(void) {  printk(KERN_INFO 'Goodbye Mr.n'); } module_init(hello_start); module_exit(hello_end); 
   上記のコードの説明: カーネル モジュールには少なくとも 2 つの関数が必要です。1 つはモジュールがカーネルにインモード化されるときに呼び出される init_module() と呼ばれる「開始」(初期化) 関数、もう 1 つは rmmoded の直前に呼び出される cleanup_module() と呼ばれる「終了」(クリーンアップ) 関数です。実際、カーネル 2.3.13 から状況が変わりました。モジュールの開始関数と終了関数に任意の名前を使用できるようになりました。実際、新しい方法が推奨される方法です。しかし、多くの人は依然として init_module() と cleanup_module() を開始関数と終了関数に使用しています。このコードでは、init 関数として hello_start() を使用し、クリーンアップ関数として hello_end() を使用しています。もうお気づきかもしれませんが、printf() 関数の代わりに printk() を使用していることです。これは、モジュールがコンソールに何も出力せず、/var/log/kern.log にメッセージを記録するためです。したがって、カーネルモジュールのデバッグに使用されます。さらに、printk() の使用中に必要となるヘッダーには 8 つのログレベル文字列が定義されています。重大度が低い順にそれらをリストします。 - KERN_EMERG: 緊急メッセージ (通常はクラッシュ前のメッセージ) に使用されます。
  - KERN_ALERT: 即時の対応が必要な状況。
  - KERN_CRIT: 多くの場合、深刻なハードウェアまたはソフトウェアの障害に関連する重大な状態。
  - KERN_ERR: エラー状態を報告するために使用されます。デバイス ドライバーは、多くの場合、ハードウェアの問題を報告するために KERN_ERR を使用します。
  - KERN_WARNING: それ自体はシステムに深刻な問題を引き起こすわけではない、問題のある状況に関する警告。
  - KERN_NOTICE: 正常ではあるものの、注意が必要な状況。このレベルでは、多くのセキュリティ関連の状態が報告されます。
  - KERN_INFO: 情報メッセージ。多くのドライバーは、起動時にこのレベルで検出したハードウェアに関する情報を出力します。
  - KERN_DEBUG: メッセージのデバッグに使用されます。
 KERN_INFO を使用してメッセージを出力しました。 コードを実行するためのシステムの準備:   The system must be prepared to build kernel code and to do this you must have the Linux headers installed on your device. On a typical Linux desktop machine you can use your package manager to locate the correct package to install. For example under 64-bit Debian you can use: 
akshat@gfg:~$ sudo apt-get install build-essential linux-headers-$(uname -r) 
   ソースコードをコンパイルするための Makefile:   obj-m = hello.o all: make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 
   **注: Makefile 内のタブスペースを忘れないでください。     モジュールのコンパイルとロード:   Run the make command to compile the source code. Then use insmod to load the module. akshat@gfg:~$ make make -C /lib/modules/4.2.0-42-generic/build/ M=/home/akshat/Documents/hello-module modules make[1]: Entering directory `/usr/src/linux-headers-4.2.0-42-generic' CC [M] /home/akshat/Documents/hello-module/hello.o Building modules stage 2. MODPOST 1 modules CC /home/akshat/Documents/hello-module/hello.mod.o LD [M] /home/akshat/Documents/hello-module/hello.ko make[1]: Leaving directory `/usr/src/linux-headers-4.2.0-42-generic' 
 Now we will use insmod to load the hello.ko object. akshat@gfg:~$ sudo insmod hello.ko 
   モジュールのテスト:   You can get information about the module using the modinfo command which will identify the description author and any module parameters that are defined: akshat@gfg:~$ modinfo hello.ko filename: /home/akshat/Documents/hello-module/hello.ko version: 0.1 description: A simple Hello world LKM author: Akshat Sinha license: GPL srcversion: 2F2B1B95DA1F08AC18B09BC depends: vermagic: 4.2.0-42-generic SMP mod_unload modversions 
 To see the message we need to read the kern.log in /var/log directory. akshat@gfg:~$ tail /var/log/kern.log ... ... Sep 10 17:43:39 akshat-gfg kernel: [26380.327886] Hello world To unload the module we run rmmod: akshat@gfg:~$ sudo rmmod hello Now run the tail command to get the exit message. akshat@gfg:~$ tail /var/log/kern.log ... Sep 10 17:43:39 akshat-gfg kernel: [26380.327886] Hello world Sep 10 17:45:42 akshat-gfg kernel: [26503.773982] Goodbye Mr.