カーネルモジュールを作ってみよう 1

Linuxカーネルのカーネルモジュールの作り方を説明します

概要

Linuxカーネルのローダブルカーネルモジュールの作成方法を説明します.
モジュールのプログラムはカーネル空間で動作します.

ローダブルカーネルモジュールとは

Linuxカーネルにはローダブルカーネルモジュールという仕組みがあります.
カーネルのある機能を,カーネルプログラムのファイルの中には含めずに,モジュールという別ファイルとして保存しておき,
OS(カーネル)の起動後に,そのファイル(機能)をロードしたり,アンロードしたりすることができます.
モジュールファイルは,/lib/modules/<カーネル名>/kernel/ の下にあり,*.ko という名前をしています.(かつては *.o でした)
モジュールプログラムはカーネル空間で動作します.

モジュールのロードは insmod コマンドで,アンロードは rmmod コマンドで行います.
現在ロードされているモジュール一覧は lsmod コマンドで確認できます.

最初のモジュール (hello)

ロード(insmod)をすると,
printk(KERN_INFO "Hello,World!\n");
を実行し,アンロード(rmmod)すると
printk(KERN_INFO "Good-bye,World!\n");
を実行するモジュールプログラムを作ります.

プログラム

hello.c

#include <linux/module.h>
static int __init hello_init(void) {
        printk(KERN_INFO "Hello,World!\n");
        return 0;
}
static void __exit hello_exit(void) {
        printk(KERN_INFO "Good-bye,World!\n");
}
module_init(hello_init);
module_exit(hello_exit);

Makefile

obj-m := hello.o

コンパイル方法

make -C /lib/modules/`uname -r`/build M=`pwd` modules

コンパイルスト,hello.ko というファイルができあがります.

実行方法 (ロード,アンロード方法)

太字がユーザ入力

# insmod hello.ko
# dmesg | tail -1
[ 1117.948137] Hello,World!
lsmod | grep hello
hello 16384 0
# rmmod hello
# dmesg | tail -1
[ 1140.169794] Good-bye,World!

ロード(insmod)をすると,
printk(KERN_INFO "Hello,World!\n");
が実行されます.
printkの出力内容は,dmesgコマンドで確認できます.

ロードしたあとは,lsmodで表示される一覧の中に hello が含まれます.

アンロードは,rmmod hello で,rmmod hello.ko ではありません.

実行環境

OS: Ubuntu 20.04.4 Server

# uname -a
Linux xxxx 5.4.186 #2 SMP Mon Mar 21 xx:xx:xx UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
# gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0
:

おまけ

コンパイルをもう少し楽にするには.

Makefile

obj-m := hello.o
all :
        $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

コンパイル方法

make

この記事が気に入ったらサポートをしてみませんか?