ARM用Linuxのカーネルモジュールを作成する

ARMシステム用のカーネルモジュールの基本的な作成方法を紹介します。

カーネルモジュールとは?

カーネルモジュールとは、動的に(カーネルが動作しているときに)カーネルに組み込んで、動作させられるプログラムのことです。一般に拡張子は".ko"で、insmod/rmmodまたはそのラッパであるmodprobeといったコマンドでカーネルに組み込んだり、カーネルから取り除いたりできます。通常は、".ko"のファイルといえば、デバイスドライバであることが多いと思いますが、カーネルモジュールは必ずしもデバイスドライバである必要ありません。アプリケーションプログラムとは違い、カーネルに組み込まれてからカーネル空間で動作するので、カーネル内部のデータ構造やメモリ空間にアクセスできます。

The Linux Kernelの13. モジュールの章では、カーネルモジュールは以下のように定義されています。

Linux では、必要に応じて、オペレーティングシステムのコンポーネントを動的にロードしたり、アンロードしたりできる。 Linux カーネルモジュール(module)とは、システム起動後ならいつでも動的にカーネルにリンクすることができるコード群である。それらは、必要がなくなれ ばカーネルとのリンクを解消して削除することができる。大部分の Linux カーネルモジュールは、デバイスドライバや、ネットワークドライバなどの仮想ドライバ、あるいはファイルシステムなどである。


オリジナルのデバイスドライバを作りたいなど、カーネルプログラミングをしたいときには、いきなりカーネル内にコードを追加するのではなく、カーネルモ ジュールとして作成することで、比較的簡単にカーネルプログラミングを始めることができます。本ページでは、カーネルモジュールを作る際の基本を紹介しま す。

準備

まず、ARMクロス開発環境構築のページを参照してビルド環境を用意してください。

また、カーネルモジュールの作成にはターゲットシステム用に設定されたカーネルソースが必要です。カーネルソースは、Linuxカーネルをソースからビルドするのページを参照して用意してください。

Hello Worldカーネルモジュール

カーネルモジュールの基本として、モジュールをカーネルに組み込んだときに"Hello World!"と表示するだけのモジュールを作成します。

基本的な手順やソースコードは、i386など他のアーキテクチャと変わりません。ですが、ARM用にクロスコンパイルするためにMakefileが多少異なります。

ソースコードは以下のものを使用します。モジュールがロードされたときに呼ばれるhello_init()関数で"Hellor World!"と表示し、アンロードされたときに呼ばれるhello_exit()関数で"Goodby..."と表示するだけです。

hello_mod.c

#include <linux/module.h>
#include <linux/init.h>

static int __init hello_init(void)
{
    pr_info("Hello World!\n");

    return 0;
}

static void __exit hello_exit(void)
{
    pr_info("Goodby...\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_AUTHOR("kotak");
MODULE_DESCRIPTION("Simple Module Sample");
MODULE_LICENSE("GPL v2");



Makefileは以下のようになります。

Makefile

KERNEL_SRC = ../linux-2.6.26
BUILD_DIR := $(shell pwd)

MODULES = hello_mod.o

obj-m := $(MODULES)

CROSS_COMPILE = arm-linux-gnueabi-
ARCH = arm
MAKEARCH = $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE)

all:
    $(MAKEARCH) -C $(KERNEL_SRC) SUBDIRS=$(BUILD_DIR) modules

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


※上記のファイルはhello_mod.c, Makefileからダウンロードできます。

KERNEL_SRCには、ターゲット用のLinuxカーネルのソースコードのディレクトリを指定してください。

MODULESに指定したものがモジュールの名前になります。xxx.oを指定すると、xxx.cからxxx.koという名前のモジュールを作成します。

ARCHにarmを指定し、CROSS_COMPILEに使用するツールチェインのプレフィックスを指定するのはカーネルをビルドする場合と同じです。

ビルドと実行

モジュールをビルドするには、上記のMakefileとソースファイル(hello_mod.c)を同じディレクトリに置いて、makeコマンドを実行するだけです。

KERNEL_SRCに相対パスを指定した場合は、Linuxカーネルのソースディレクトリとの相対的な位置に気をつけてください。

$ ls
Makefile hello_mod.c
$ make
$ ls *.ko
hello_mod.ko

作成されたhello_mod.koをターゲットシステムに転送します。

その後、ターゲットシステムのrootユーザで以下を実行します。
# insmod hello_mod.ko
Hello World!
# rmmod hello_mod
Goodby...

Comments