🙆

【WSL2】自作LinuxデバイスドライバでHello worldを出力してみる

2023/12/29に公開

前回の記事でWSL2のカーネルをビルドすることができたので、今回はデバイスドライバを作成してみようと思う。
デバイスドライバを作るのは初めてなので、今回はほんとに簡単なHelloWorldを出すだけのものでやる。

手順

HelloWorld.cを準備

前回カーネルをビルドしたディレクトリと同階層にドライバビルド用フォルダ(driver)を作成する。
その中にHelloWorld.cを置く。

$ ls
WSL2-Linux-Kernel
$ mkdir driver
$ cd driver
$ touch HelloWorld.c

HelloWorld.cをエディタで開き以下のように書く。

HelloWorld.c
#include <linux/module.h>

MODULE_LICENSE("GPL");

static int test_init(void)
{
    printk("Hello world init\n");
    return 0;
}

static void test_exit(void)
{
    printk("Hello world exit\n");
}

module_init(test_init);
module_exit(test_exit);

今回のドライバはカーネルモジュールがロードされた時に"Hello world init"、アンロードされた時に"Hello world exit"を出力するだけのとてもシンプルなもの。
.cファイルの修正はこれで終わり。

Makefileを準備

次にHelloWorld.cと同階層にMakefileも作成する。

$ touch Makefile

これもエディタで開いて以下のように書く。

Makefile
obj-m := HelloWorld.o

all:
	make -C ../WSL2-Linux-Kernel M=$(shell pwd) modules
clean:
	make -C ../WSL2-Linux-Kernel M=$(shell pwd) clean

ファイルを保存したらビルドする。

$ make
make -C ../WSL2-Linux-Kernel M=/home/meloq/work/build_kernel/driver modules
make[1]: Entering directory '/home/meloq/work/build_kernel/WSL2-Linux-Kernel'
  CC [M]  /home/meloq/work/build_kernel/driver/HelloWorld.o
  MODPOST /home/meloq/work/build_kernel/driver/Module.symvers
  CC [M]  /home/meloq/work/build_kernel/driver/HelloWorld.mod.o
  LD [M]  /home/meloq/work/build_kernel/driver/HelloWorld.ko
  BTF [M] /home/meloq/work/build_kernel/driver/HelloWorld.ko
make[1]: Leaving directory '/home/meloq/work/build_kernel/WSL2-Linux-Kernel'

ビルドが終わったらlsして以下のようにフォルダ内にHelloWorld.koというファイルが作成されていればOK。これがビルドされたLinuxカーネルモジュールファイル。

$ ls
HelloWorld.c  HelloWorld.ko  HelloWorld.mod  HelloWorld.mod.c  HelloWorld.mod.o  HelloWorld.o  Makefile  Module.symvers  modules.order

作成したモジュールファイルの情報をmodinfoコマンドを使用して確認する。

$ modinfo HelloWorld.ko
filename:       /home/meloq/work/build_kernel/driver/HelloWorld.ko
license:        GPL
srcversion:     644AC10C809A8417C0D44EE
depends:        
retpoline:      Y
name:           HelloWorld
vermagic:       5.15.133.1-microsoft-standard-WSL2-meloq+ SMP mod_unload modversions 

vermagicの行を確認すると前回ビルドしたカーネルを使用してモジュールが作成されていることが分かる。

それでは以下のコマンドでモジュールのロードとアンロードを実行してみる。

$ sudo insmod HelloWorld.ko
$ sudo rmmod HelloWorld.ko

コマンドを実行しても特に標準出力には出力されないが、dmesgを実行してログを確認することで正しくロード・アンロードがされたかどうかが分かる。
以下を実行して確認。

$ dmesg | grep Hello
[ 1634.246493] HelloWorld: loading out-of-tree module taints kernel.
[ 1634.257786] Hello world init
[ 1673.217596] Hello world exit

ログの内容から正しくロード・アンロードができていることが分かった。

Discussion