LoginSignup
7
9

More than 5 years have passed since last update.

カーネルモジュールを作成してみる

Posted at

helloを出力するだけの簡単なカーネルモジュールを作成してみる。

環境の作成

gccなど既に入っているのであればここは不要である。
クリーンな環境を想定するので以下のdockerコンテナで作業する。

$ docker run --rm -i -v /lib/modules:/lib/modules \
                     -v /usr/src/kernels/:/usr/src/kernels/ \
                     -v /tmp/hello:/tmp/hello \
                     -t centos:centos7 /bin/bash
# chmod 777 /tmp/hello
# cd /tmp/hello
  • 説明
    • 終了後削除されるコンテナを作成する(--rm)
    • ビルドに必要なデータをコンテナに渡す(-v)
    • コンテナではkmod(insmod,rmmod)が入らないのでホストへ受け渡し用にtmpを渡す
    • 権限を変えてしまうのは行儀が良くないが面倒なので気にしない

ビルドに必要なものをインストールする

ダウンロードとインストールに少々時間がかかるが、一行で済む。

# yum groupinstall "Development Tools" -y
  • 説明
    • 特になし。

ソースの作成

ここが本題。
hello.cとMakefileを作成する。
注意点としてはMakefileのインデントはTABなので下のをそのままコピペすると
Makefile:7: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
となる。

# useradd ymko
# su - ymko
$ cd /tmp/hello
$ ls 
Makefile hello.c
hello.c
#include <linux/module.h>
#include <linux/kernel.h>

static int __init hello_init( void )
{
    printk( KERN_INFO "hello module insmod\n" );
    return 0;
}

static void __exit hello_exit( void )
{
    printk( KERN_INFO "hello module rmmod\n" );
}

module_init( hello_init );
module_exit( hello_exit );

MODULE_DESCRIPTION( "hello world!" );
MODULE_LICENSE( "MIT" );
Makefile
obj-m := hello.o

KDIR    := /lib/modules/$(shell uname -r)/build
PWD     := $(shell pwd)
VERBOSE = 0

default:
    $(MAKE) -C $(KDIR) M=$(PWD) KBUILD_VERBOSE=$(VERBOSE) modules

clean:
    rm -f *.o *.ko *.mod.c

make

makeである。

$ make 
make -C /lib/modules/3.10.0-327.28.2.el7.x86_64/build M=/tmp/hello KBUILD_VERBOSE=0 modules
make[1]: Entering directory `/usr/src/kernels/3.10.0-327.28.2.el7.x86_64'
  CC [M]  /tmp/hello/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /tmp/hello/hello.mod.o
  LD [M]  /tmp/hello/hello.ko
make[1]: Leaving directory `/usr/src/kernels/3.10.0-327.28.2.el7.x86_64'

モジュールのロード・アンロード

ホスト側のroot権限で実行する。
なおコンテナではkmodがないのでinsmod,rmmodがない。kmodをインストールしようとうするとsystemdと衝突して入らない。

# cd /tmp/hello
# insmod hello.ko
# rmmod hello.ko
# dmesg | tail
[292475.726061] hello module insmod
[292488.733643] hello module rmmod

トラブルシュート

  • Makefile:7: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.

    • Makefileのインデントがタブじゃない。
  • make: *** /lib/modules/3.10.0-327.28.2.el7.x86_64/build: No such file or directory. Stop.

    • /lib/modules/3.10.0-327.28.2.el7.x86_64/buildがない。
    • リンクが切れている場合はkernel-develがない。
    • ".config"がない。/boot/config-*をコピーしてmake oldconfig、make prepareをしないといけない

参考

Building External Modules(公式ドキュメント)
https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/kbuild/modules.txt

Building a custom kernel - FedoraProject
https://fedoraproject.org/wiki/Building_a_custom_kernel?rd=Docs/CustomKernel
HowTos/BuildingKernelModules - CentOS Wiki
https://wiki.centos.org/HowTos/BuildingKernelModules

カーネルモジュール作成メモ
http://www.hakodate-ct.ac.jp/~tokai/tokai/research/kmod.html

[Linux][kernel module] 簡単なローダブルカーネルモジュールのビルドとロード
http://qiita.com/koara-local/items/39002cc1f611e26114f8

SUBDIRS variable in kernel module makefile - Stack Overflow
http://stackoverflow.com/questions/21129224/subdirs-variable-in-kernel-module-makefile

Same as M=. The SUBDIRS= syntax is kept for backwards compatibility.
M =と同じです。SUBDIRS =構文は下位互換性のために保持されています。

7
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9