Linux
vagrant
kernel
新人プログラマ応援

書いてみようカーネルモジュール。仮想環境を作ってカーネルモジュールでHello Worldまで。

仮想環境の準備

Vagrant上にLinuxを用意する

% vagrant box add debian-8-jessie https://github.com/holms/vagrant-jessie-box/releases/download/Jessie-v0.1/Debian-jessie-amd64-netboot.box
% vagrant box list
% vagrant init debian-8-jessie

% vagrant up
% vagrant ssh

必要ファイルの準備

カーネルパッケージのインストール

# apt-get install kernel-package

カーネルモジュールでhello world

まず、insmod/rmmodでロード/アンロードするだけの簡単なモジュールを作成する。

% mkdir helloworld
% cd helloworld

モジュールのコード

helloworld.c
#include <linux/module.h> // カーネルモジュールを作成するときは必ずlinux/module.hをinclude
#include <linux/kernel.h>

// モジュール初期化(insmod時に呼ばれる)
static int __init helloworld_module_init( void )
{
    printk( KERN_INFO "Hello World!\n" ); // カーネルランド版のprintf
    return 0;
}

//  モジュール解放(rmmod時に呼ばれる)
static void __exit helloworld_module_exit( void )
{
    printk( KERN_INFO "Goodby World!\n" );
}

module_init( helloworld_module_init );
module_exit( helloworld_module_exit );

MODULE_DESCRIPTION( "helloworld" ); // modinfoで見れる
MODULE_LICENSE( "GPL2" );
MODULE_AUTHOR("takish");

コンパイルのための準備

バージョン名を確認

% uname -rn
% jessie 3.16.0-4-amd64

コンパイル時に/lib/modules/build以下にheadersが必要なのでインストールする

% sudo apt-get install linux-headers-3.16.0-4-amd64

インストール先を確認

# dpkg -L linux-headers-3.16.0-4-amd64

/lib/modules以下にヘッダ群が入っていることを確認できます。

続いて、コンパイルするためにMakefileを用意

Makefile
KERNEL_DIR = /lib/modules/$(shell uname -r)/build 
BUILD_DIR := $(shell pwd)
VERBOSE := 0 

obj-m := helloworld.o 

all: 
    make -C $(KERNEL_DIR) SUBDIRS=$(BUILD_DIR) KBUILD_VERBOSE=$(VERBOSE) modules 
clean: 
    rm -rf *.o *.ko *.mod.c *.symvers *.order .tmp_versions .helloworld.*

modinfoにてモジュールの情報を確認

vagrant@jessie:~/helloworld$ /sbin/modinfo helloworld.ko
filename:       /home/vagrant/helloworld/helloworld.ko
author:         takish
license:        GPL2
description:    helloworld
depends:
vermagic:       3.16.0-4-amd64 SMP mod_unload modversions

insmod/rmmodにてモジュールのロード、アンロードを確認する

$ sudo /sbin/insmod helloworld.ko
$ lsmod
$ sudo /sbin/rmmod helloworld

dmesgにてprintkでの出力がされていることも確認して見てください。