警告メッセージ

Howtoは、Armadilloシリーズを有効に活用するための参考資料です。使用ソフトウェアのバージョンなど諸条件の差異によって、記載内容と実際の動作が異なる場合があります。また、すべての機能検証や長期の動作試験を行ったものではありませんので、必ずご使用目的に適合した検証・試験を行ってください。

Howto : カーネルモジュールの作成

対象製品: Armadillo-810Armadillo-500 FXArmadillo-500Armadillo-460Armadillo-440Armadillo-420Armadillo-300Armadillo-9Armadillo-240Armadillo-230Armadillo-220Armadillo-210Armadillo(HT1070)Armadillo-J

本 Howto では、ターゲットボードで動作する Linux カーネルモジュールを作成する方法と、作成したカーネルモジュールをターゲットボードで動作させる方法を説明します。

カーネルモジュールとは、必要なときに動的にカーネルにロードまたはアンロードし、カーネルの機能を拡張することができるプログラムです。通常、デバイスドライバなどに使用されます。

本 Howto では、ロード時とアンロード時にメッセージを表示するだけの、簡単なカーネルモジュールを作成します。ビルドは、atmark-distに手を加えない、Out of Treeでおこないます。なお、使用する Linux カーネルは、2.6系を想定しています。

おおまかな手順は下記のようになります。

  1. atmark-distを使用して、カーネルをビルドする。
  2. カーネルモジュールをビルドする。
  3. カーネルイメージにモジュールを組み込む
  4. カーネルにモジュールをロード/アンロードする。

1. atmark-distを使用して、カーネルをビルドする。

カーネルモジュールを作成する前の準備として、atmark-dist Developpers Guideなどを参考に、ターゲットボード用のカーネルをビルドしてください。ターゲットボードで動作しているカーネルのバージョンと、ビルドに使用するカーネルのバージョンは一致している必要があります。

2. カーネルモジュールをビルドする。

今回はOut of Treeコンパイルで作成するので、まず、atmark-distの外にソースファイルとMakefileを用意します。作成するカーネルモジュールのモジュール名は、hello とします。


[PC ~]$ ls
atmark-dist
[PC ~]$ mkdir hello_module
[PC ~]$ ls
atmark-dist hello_module
[PC ~]$ ls hello_module
Makefile hello.c

hello.cは下記のものを使用します。


/*
 * Kernel Module Sample
 * file name: hello.c
 */
#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("GPL v2");

/* インストール時に実行 */
static int hello_init(void) {
    printk(KERN_ALERT "Hello World!\n");
    return 0;
}

/* アンインストール時に実行 */
static void hello_exit(void) {
    printk(KERN_ALERT "Goodbye World!\n");
}

module_init(hello_init);
module_exit(hello_exit);

Makefileは下記のものを使用します。


MODULES = hello.o

ifneq ($(KERNELRELEASE), )

obj-m := $(MODULES)
#CFLAGS_MODULE += -DDEBUG

else

ROOTDIR ?= ../atmark-dist

ROMFSDIR = $(ROOTDIR)/romfs

include $(ROOTDIR)/.config
include $(ROOTDIR)/config.arch

MAKEARCH = $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE)

LINUXDIR = $(CONFIG_LINUXDIR)
KERNELRELEASE = ${shell make -sC $(ROOTDIR)/$(LINUXDIR) kernelrelease}

all: modules romfs

modules:
        $(MAKEARCH) -C $(ROOTDIR)/$(LINUXDIR) M=${shell pwd} modules

romfs:
        make -C $(ROOTDIR) INSTALL_MOD_DIR=kernel \
        M=${shell pwd} modules_install
        $(ROOTDIR)/user/busybox/examples/depmod.pl -b \
        $(ROMFSDIR)/lib/modules/$(KERNELRELEASE) &> /dev/null

clean:
        -rm -f *.[oas] *.ko *.mod.c .*.d .*.tmp .*.cmd *.symvers
        -rm -rf .tmp_versions

distclean: clean
        -rm -f *~

endif

MODULES には <モジュール名>.o[1] を、ROOTDIR には atmark-dist のディレクトリを指定してください。

準備ができたら、カーネルモジュールをビルドします。ビルドには make コマンドで moduels ターゲットを使用します。ビルドが完了するとモジュールファイル hello.ko がディレクトリ内に生成されます。


[PC ~]$ cd hello_module
[PC ~/hello_module]$ make modules
[PC ~/hello_module]$ ls
Makefile  hello.c  hello.ko  hello.mod.c  hello.mod.o  hello.o

3. カーネルイメージにモジュールを組み込む

手順2. で作成した、モジュールファイル hello.ko を、そのままターゲットボードへコピーしても動作させることもできますが、今回はカーネルイメージにモジュールを組み込む方法を紹介します。

モジュールファイルを atmark-dist の romfs ディレクトリにインストールするために、make コマンドで romfs ター ゲットを指定します。[2][3]


[PC ~/hello_module]$ make romfs
[PC ~/hello_module]$  ls ../atmark-dist/romfs/lib/modules/2.6.12.3-a9-13/kernel/
hello.ko

次に、atmark-dist のディレクトリに移動して、make image を実行することで、hello.ko モジュールを含んだターゲットボード用のイメージファイルがimage ディレクトリに生成されます。


[PC ~/hello_module]$ cd ../atmark-dist/
[PC ~/atmark-dist]$ make image
[PC ~/atmark-dist]$ ls images/
linux.bin  linux.bin.gz  romfs.img  romfs.img.gz

4. カーネルにモジュールをロード/アンロードする。

ターゲットボードに、作成したカーネル及びユーザーランドのイメージを書き込みます。

カーネルモジュールのロードは、insmodでおこないます。[3]


[armadillo ~]# insmod /lib/modules/2.6.12.3-a9-13/kernel/hello.ko
Hello World!

現在カーネルにロードされているモジュールは、lsmod または /proc/modules によって調べることができます。


[armadillo ~]# lsmod
Module                  Size  Used by    Not tainted
hello 928 0 - Live 0xbf000000
[armadillo ~]# cat /proc/modules
hello 928 0 - Live 0xbf000000

アンロードはrmmodでおこなうことができます。


[armadillo ~]# rmmod hello
Goodbye World!
[armadillo ~]# lsmod
Module                  Size  Used by    Not tainted

本 Howto で使用したソースコードは、下記から取得することができます。

ダウンロード


[1] 最終的に作成されるカーネルモジュールは、<モジュール名>.ko という名前になりますが、MODULES に指定するのは <モジュール名>.o という名前です。

[2] 事前に、atmark-dist ディレクトリでmake をおこない、romfs ディレクトリを作成しておく必要があります。

[3] パス中の「2.6.12.3-a9-13」の部分は、カーネルのバージョンによって変わりますので、適宜読みかえてください。