目標
- カーネルモジュールについて概要を理解する
カーネルモジュール
カーネルモジュールとは、オペレーティングシステムのカーネルに動的に追加できるプログラムのことです。LinuxなどのUnix系オペレーティングシステムでは、カーネルは基本的にシステムのハードウェアリソースを管理し、ユーザーからのリクエストに応じて適切に処理しますが、そのカーネル自体を変更せずに、機能を追加したり削除したりできるのがカーネルモジュールの特徴です。
カーネルモジュールの主な特徴
- 動的ロードとアンロード
- カーネルモジュールは、システム起動時に自動でロードされることもあれば、必要に応じて手動でロードすることも可能です。例えば、デバイスドライバやファイルシステムのサポートなどがモジュールとして提供されます。不要になった場合は、モジュールをアンロードすることもできます。
- カーネルの変更なしに機能追加
- カーネルを再コンパイルすることなく、機能の追加や修正を行うことができます。これにより、システムの安定性を保ちながら、柔軟に新しい機能を追加できます。
- ハードウェアドライバやファイルシステムなど
- 一般的なカーネルモジュールの用途としては、ハードウェアドライバやファイルシステムのサポートが多いです。例えば、USBデバイスのサポートや、特定のネットワークカードのドライバなどがモジュールとして提供されています。
カーネルモジュールの基本操作
ロード: insmod コマンドを使用してカーネルモジュールをロードします。
sudo insmod モジュール名.ko
insmod は、指定したカーネルモジュール(.koファイル)を手動でロードするコマンドです。ただし、insmod では、依存している他のモジュールを自動でロードすることがありません。もし依存しているモジュールが事前にロードされていないと、insmod でモジュールをロードしようとした際にエラーが発生します。
この問題を避けるために、insmod の代わりに modprobe を使用することが一般的です。modprobe は、モジュールが依存している他のモジュールも自動的にロードしてくれるため、手動で依存関係を確認する必要がありません。
アンロード: rmmod コマンドを使ってカーネルモジュールをアンロードします。
sudo rmmod モジュール名
rmmod は、指定したカーネルモジュールを手動でアンロードするコマンドです。しかし、rmmod では、モジュールが他のモジュールに依存しているかどうかを自動的に確認しません。つまり、アンロードしようとしているモジュールが他のモジュールに依存している場合、その依存関係を無視してしまうことがあります。
この問題を回避するために、rmmod の代わりに modprobe を使用することが推奨されます。modprobe は、モジュールのアンロード時に依存関係も考慮して、依存しているモジュールがまだ使用中でないかを確認し、依存関係を解決した上でアンロードを行います。
カーネルモジュールの状態確認: lsmod コマンドで現在ロードされているモジュールを確認できます。
lsmod は、現在ロードされているカーネルモジュールの一覧を表示するコマンドです。このコマンドを使うと、どのモジュールが現在アクティブで、どのモジュールが依存しているかを確認することができます。
lsmod
モジュールの詳細表示: modinfo コマンドでモジュールの情報を表示できます。
modinfo は、指定したカーネルモジュールに関する詳細情報を表示するコマンドです。モジュールのバージョン、作成者、依存関係、パラメータなどを確認することができます。
modinfo モジュール名
modprobeコマンド
modprobe はカーネルモジュールの管理を行うための便利なコマンドで、主にモジュールの ロードやアンロードを自動的に依存関係を考慮して行ってくれます。ここでは、modprobeの利用方法について、基本的な使い方を解説します。
モジュールのロード:modprobe はモジュールの依存関係を自動的に解決してくれるので、指定したモジュールが依存している他のモジュールも一緒にロードしてくれます。
sudo modprobe モジュール名
例えば、nfs モジュールをロードしたい場合は次のように入力します。
sudo modprobe nfs
これを実行すると、nfs モジュールだけでなく、その依存モジュールも自動的にロードされます。
モジュールのアンロード:modprobe はモジュールのアンロードも管理できます。rmmod と違って、modprobe はモジュールが依存している他のモジュールをチェックして、依存関係を解消した後にアンロードを行います。
sudo modprobe -r モジュール名
nfs モジュールをアンロードしたい場合は次のように入力します。
sudo modprobe -r nfs
これを実行すると、nfs モジュールが依存しているモジュールがまだ使用されていない場合に限り、nfs モジュールを安全にアンロードします。
モジュールの設定ファイルに関する情報を表示する:modprobe には、モジュールの設定ファイルに関する情報を確認するオプションもありますが、このコマンドはモジュールの実際の詳細情報を表示するものではありません(modinfo コマンドが詳細情報を表示します)。以下は設定ファイルに関する情報を表示するコマンドです。
modprobe -c
これを実行すると、システムにインストールされているモジュールに関する設定ファイルの情報が表示されます。modprobe -c は、モジュールの設定や依存関係を定義するファイルの内容を表示するもので、モジュール自体の詳細なメタデータ(例: バージョン、依存関係、パラメータ)は表示しません。
モジュールをロードする際のオプション指定:モジュールをロードするとき、特定のオプションを指定することができます。モジュールに必要なパラメータを渡すことで、モジュールの動作を調整できます。
sudo modprobe モジュール名 パラメータ=値
例えば、ip_vs モジュールに ip_vs_rr(ラウンドロビン方式)というパラメータを渡す場合は次のように入力します。
sudo modprobe ip_vs ip_vs_rr=1
モジュールの確認:システムにロードされているモジュールを確認するために、modprobe 自体には特別なコマンドはありませんが、lsmod を使うことでロードされているモジュールを確認することができます。
lsmod
このコマンドを実行すると、現在ロードされているモジュールとその依存関係が表示されます。
特定のモジュールの削除を強制する:通常、modprobe -r を使うと依存関係を考慮してアンロードされますが、どうしてもモジュールを強制的にアンロードしたい場合は、–force オプションを使用することもできます。
sudo modprobe -r --force モジュール名
ただし、強制的なアンロードはシステムに不安定さを引き起こす可能性(システムの不安定化やデータ損失の可能性)があるため、注意して使用してください。
カーネルモジュールの作成
カーネルモジュールを作成するには、通常C言語でプログラムを記述します。モジュールの基本的な構造は以下のようになります。
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL"); // モジュールのライセンス
MODULE_AUTHOR("Your Name"); // モジュールの作者
MODULE_DESCRIPTION("Simple Kernel Module"); // モジュールの説明
// モジュール初期化関数
static int __init my_module_init(void) {
printk(KERN_INFO "Hello, Kernel!\n"); // カーネルログにメッセージを出力
return 0;
}
// モジュール終了関数
static void __exit my_module_exit(void) {
printk(KERN_INFO "Goodbye, Kernel!\n"); // カーネルログに終了メッセージを出力
}
// モジュール初期化関数と終了関数を指定
module_init(my_module_init);
module_exit(my_module_exit);
説明
- MODULE_LICENSE でライセンスを指定します。GPL など、オープンソースライセンスを使うのが一般的です。これを指定しないと、カーネルの一部機能(例: デバッグ機能)が無効化されることがあります。
- MODULE_AUTHOR と MODULE_DESCRIPTION でモジュールの作者や説明を指定します。
- my_module_init はモジュールがロードされるときに呼び出される関数で、ここで初期化処理を行います。
- my_module_exit はモジュールがアンロードされるときに呼び出される関数で、後処理を行います。
- printk はカーネルのログにメッセージを出力するための関数で、KERN_INFO は情報レベルのログです。
コンパイル
カーネルモジュールは、カーネルのヘッダファイルを参照しながらコンパイルします。一般的にMakefileを使ってコンパイルします。
obj-m += my_module.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 # ビルド環境をクリア
説明
- obj-m += my_module.o は、カーネルモジュールとしてコンパイルする .o ファイルを指定します。
- make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules は、現在のカーネルバージョンに対応するビルドディレクトリを指定して、モジュールをコンパイルします。$(shell uname -r) は現在のカーネルバージョンを取得します。
- make clean は、コンパイルで生成されたファイルを削除してクリーンな状態に戻します。
必要なパッケージ:カーネルモジュールをコンパイルするには、カーネル開発ヘッダが必要です。これらは通常 kernel-devel パッケージに含まれています。
Ubuntu/Debian
sudo apt-get install linux-headers-$(uname -r)
CentOS/RHEL
sudo yum install kernel-devel-$(uname -r)
これにより、/lib/modules/$(uname -r)/build へのシンボリックリンクが作成され、カーネルモジュールをビルドするために必要なヘッダファイルにアクセスできるようになります。
カーネルモジュールのインストールとロード
1.コンパイル:Makefile を使ってモジュールをコンパイルすると、my_module.ko というカーネルオブジェクトファイルが生成されます。
2.モジュールのロード:insmod または modprobe を使ってコンパイルしたモジュールをカーネルにロードできます。
sudo insmod my_module.ko # モジュールを手動でロード
または、依存関係を考慮してロードするには modprobe を使用します。
sudo modprobe my_module # modprobe でロード(依存モジュールも自動でロード)
3.モジュールのアンロード:
rmmod または modprobe -r を使って、モジュールをアンロードできます。
sudo rmmod my_module # モジュールをアンロード
または、依存関係を考慮してアンロードするには modprobe を使用します。
sudo modprobe -r my_module # modprobe -r でアンロード
動作確認
モジュールをロードした後、カーネルログにメッセージが表示されることを確認できます。
dmesg | tail -n 10
これで、printk() 関数で出力されたログを確認することができます。
カーネルモジュールの例
- デバイスドライバ: 特定のハードウェアデバイス(例: グラフィックカード、ネットワークインターフェースカード)の操作を行うためのモジュール。
- ファイルシステムドライバ: 新しいファイルシステムのサポートを追加するモジュール。
- ネットワークモジュール: 新しいプロトコルのサポートやネットワークカードのドライバを提供するモジュール。
カーネルモジュールの利点
- 軽量で柔軟性が高い: カーネルを再起動することなく、新しい機能を追加できます。
- 動的管理:使用していないモジュールをアンロードすることで、システムのリソースを節約できます。
まとめ
カーネルモジュールは、カーネルの機能を拡張するために非常に便利であり、システムのカスタマイズや最適化に役立ちます。システム管理者や開発者にとっては、カーネルの理解とモジュールの活用は重要なスキルの一つです。
今回は以上になります。

ブックマークのすすめ
「ほわほわぶろぐ」を常に検索するのが面倒だという方はブックマークをお勧めします。ブックマークの設定は別記事にて掲載しています。

