module_init

カーネルのビルドはしんどいので、あれぐらいにしてデバイスドライバとかになるカーネルモジュールを作る。

HelloWorld作成 | Linuxデバイスドライバ開発入門

まず、バージョン確認。

$ uname -a
Linux localhost.localdomain 5.3.7-301.fc31.x86_64 #1 SMP Mon Oct 21 19:18:58 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$

あ、言い忘れてた。

実はbg1じゃなくて元々のほうに戻してる
実はbg1じゃなくて元々のほうに戻してる

実はbg1じゃなくて元々のほうに戻してる。

fedora — yum install kernel-develが私のカーネルバージョンと異なる

カーネルバージョンをヘッダやソースと完全に合わせた方がいいらしいので。

$ sudo yum install kernel-devel kernel-headers
[sudo] bg1 のパスワード:
Fedora Modular 31 - x86_64                       28 kB/s | 4.9 kB     00:00    
Fedora Modular 31 - x86_64 - Updates            7.5 kB/s | 4.8 kB     00:00    
Fedora 31 - x86_64 - Updates                     11 kB/s | 4.9 kB     00:00    
パッケージ kernel-headers-5.3.6-300.fc31.x86_64 は既にインストールされています。
依存関係が解決しました。
================================================================================
 Package             Architecture  Version                 Repository      Size
================================================================================
インストール:
 kernel-devel        x86_64        5.8.18-100.fc31         updates         13 M

トランザクションの概要
================================================================================
インストール  1 パッケージ

ダウンロードサイズの合計: 13 M
インストール済みのサイズ: 52 M
これでよろしいですか? [y/N]: y
パッケージのダウンロード:
kernel-devel-5.8.18-100.fc31.x86_64.rpm         1.2 MB/s |  13 MB     00:11    
--------------------------------------------------------------------------------
合計                                            1.1 MB/s |  13 MB     00:11    
トランザクションの確認を実行中
トランザクションの確認に成功しました。
トランザクションのテストを実行中
トランザクションのテストに成功しました。
トランザクションを実行中
  準備             :                                                        1/1
  インストール中   : kernel-devel-5.8.18-100.fc31.x86_64                    1/1
  scriptletの実行中: kernel-devel-5.8.18-100.fc31.x86_64                    1/1
  検証             : kernel-devel-5.8.18-100.fc31.x86_64                    1/1

インストール済み:
  kernel-devel-5.8.18-100.fc31.x86_64                                          

完了しました!
$

kernel-develとkernel-headersをインストール。
バージョン合わせないといけないという割に、kernel-headers-5.3.6-300.fc31.x86_64だったり、kernel-devel-5.8.18-100.fc31.x86_64だったり、合ってない。

$ sudo yum install "kernel-devel-uname-r == $(uname -r)"
メタデータの期限切れの最終確認: xx:xx:xx 時間前の xxxx年xx月xx日 xx時xx分xx秒 に実施しました。
依存関係が解決しました。
================================================================================
 Package             Architecture  Version                  Repository     Size
================================================================================
インストール:
 kernel-devel        x86_64        5.3.7-301.fc31           fedora         12 M

トランザクションの概要
================================================================================
インストール  1 パッケージ

ダウンロードサイズの合計: 12 M
インストール済みのサイズ: 54 M
これでよろしいですか? [y/N]: y
パッケージのダウンロード:
kernel-devel-5.3.7-301.fc31.x86_64.rpm          1.2 MB/s |  12 MB     00:10    
--------------------------------------------------------------------------------
合計                                            1.1 MB/s |  12 MB     00:11    
トランザクションの確認を実行中
トランザクションの確認に成功しました。
トランザクションのテストを実行中
トランザクションのテストに成功しました。
トランザクションを実行中
  準備             :                                                        1/1
  インストール中   : kernel-devel-5.3.7-301.fc31.x86_64                     1/1
  scriptletの実行中: kernel-devel-5.3.7-301.fc31.x86_64                     1/1
  検証             : kernel-devel-5.3.7-301.fc31.x86_64                     1/1

インストール済み:
  kernel-devel-5.3.7-301.fc31.x86_64                                            

完了しました!
$

develは入れ直した。

$ sudo yum install "kernel-headers-uname-r == $(uname -r)"
メタデータの期限切れの最終確認: xx:xx:xx 時間前の xxxx年xx月xx日 xx時xx分xx秒 に実施しました。
一致した引数がありません: kernel-headers-uname-r == 5.3.7-301.fc31.x86_64
エラー: 一致するものが見つかりません: kernel-headers-uname-r == 5.3.7-301.fc31.x86_64
[bg1@localhost ~]$

headersはやっぱりない。

$ koji download-build --arch=src kernel-5.3.7-301.fc31.x86_64
Downloading: kernel-5.3.7-301.fc31.src.rpm
File kernel-5.3.7-301.fc31.src.rpm already downloaded, skipping
$

kojiだと既にダウンロードしてるから、もしかしてカーネルビルド時にダウンロードしたモノでいいのかな。
custom_module.cを作成し、

custom_module_initという初期化関数を作って、module_initで登録するということらしい。

__initcall()/module_init() include/linux/init.h

で、Makefileは、

obj-mは、custom_module.cをコンパイルしてできるcustom_module.oを指定するらしい。
-Cはそこのフォルダに移動してからmakeするらしいが、これわかりにくいけどbuildはシンボリックリンクで実体は、/usr/src/kernels/5.3.7-301.fc31.x86_64らしい。Mも変数でそこに現在パスを渡して、make先で使ってるらしい。
(難しいので詳細は今回は説明しない。いずれ・・・。)
とりあえず、

$ vi custom_module.c
$ vi Makefile
$ ls
Makefile  custom_module.c
$ make
make -C /lib/modules/5.3.7-301.fc31.x86_64/build M=/home/bg1/project/cloud/github.com/Sample/linuxkernel/module_init/module_init/src/module_init modules
make[1]: ディレクトリ '/usr/src/kernels/5.3.7-301.fc31.x86_64' に入ります
  CC [M]  /home/bg1/project/cloud/github.com/Sample/linuxkernel/module_init/module_init/src/module_init/custom_module.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: modpost: missing MODULE_LICENSE() in /home/bg1/project/cloud/github.com/Sample/linuxkernel/module_init/module_init/src/module_init/custom_module.o
see include/linux/module.h for more information
  CC      /home/bg1/project/cloud/github.com/Sample/linuxkernel/module_init/module_init/src/module_init/custom_module.mod.o
  LD [M]  /home/bg1/project/cloud/github.com/Sample/linuxkernel/module_init/module_init/src/module_init/custom_module.ko
make[1]: ディレクトリ '/usr/src/kernels/5.3.7-301.fc31.x86_64' から出ます
$ ls
Makefile        custom_module.c   custom_module.mod    custom_module.mod.o  modules.order
Module.symvers  custom_module.ko  custom_module.mod.c  custom_module.o
$

makeした。
custom_module.koが完成。

$ sudo insmod custom_module.ko
[sudo] bg1 のパスワード:
$ dmesg

insmodしてdmesgしてみると、

とりあえずcustom_module_initが呼ばれたのはわかった
とりあえずcustom_module_initが呼ばれたのはわかった

とりあえずcustom_module_initが呼ばれたのはわかった。

lsmodでもcustom_moduleが上にいる
lsmodでもcustom_moduleが上にいる

lsmodでもcustom_moduleが上にいる。

しかし、自力でrmmodができない。
しかし、自力でrmmodができない。

しかし、自力でrmmodができない。
再起動するしかない。

Sample/linuxkernel/module_init/module_init/src/module_init at master · bg1bgst333/Sample · GitHub