Linux カーネル モジュール プログラミング: Hello World プログラム
カーネル モジュールは、要求に応じてカーネルにロードおよびアンロードできるコードの一部です。これらは、システムを再起動することなく、カーネルの機能を拡張します。カスタム コードは 2 つの方法で Linux カーネルに追加できます。
- 基本的な方法は、コードをカーネル ソース ツリーに追加し、カーネルを再コンパイルすることです。
- これを行うより効率的な方法は、実行中にカーネルにコードを追加することです。このプロセスはモジュールのロードと呼ばれます。モジュールとは、カーネルに追加するコードを指します。
- デバイスドライバー
- ファイルシステムドライバーと
- システムコール。
/** * @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 world n ' ); 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 modversionsTo 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.