Raspberry Piのデバイスドライバの開発環境を構築します。imageには、カーネルのヘッダが入っていないので、このままでは、作成した、Raspberry Piのドライバのコンパイルができません。このため、Raspbian “wheezy”のソースコードをダウンロードします。
最初に、root権限で作業するので、rootでログインできるように「sudo passwd root」でrootのパスワードを設定します。
pi@raspberrypi:~$ sudo passwd root Enter new UNIX password:
rootになります。
pi@raspberrypi:~$ su –
デバイスドライバ開発のためのヘッダファイルの設定
まず、コンパイルするための開発環境をインストールします。
root@raspberrypi:~# apt-get install build-essential
git(ソースコードのダウンロードツール)をインストールします。
root@raspberrypi:~# apt-get install git
※既に最新パッケージが入っている場合は、インストールは行われません。
ソースコードの作業用ディレクトリに移動します。
root@raspberrypi:~# cd /usr/src root@raspberrypi:/usr/src#
Raspbian “wheezy”のソースコードをダウンロードします。
root@raspberrypi:/usr/src# sudo apt-get install linux-image-rpi-rpfv linux-headers-rpi-rpfv
「/usr/src」と「/lib/modules/」にダウンロードされたファイルを確認します。
root@raspberrypi:/usr/src# ls linux-headers-3.12-1-common linux-headers-3.12-1-rpi linux-kbuild-3.12
root@raspberrypi:/usr/src# cd /lib/modules/ root@raspberrypi:/lib/modules# ls 3.12-1-rpi
新規のカーネルをブート時にロードするために、/boot/config.txtの最後の行に次のラインを追加します。
# Parameters to boot on raspbian kernel (linux-image-rpi-rpfv package) kernel=vmlinuz-3.12-1-rpi initramfs initrd.img-3.12-1-rpi followkernel
再起動します
root@raspberrypi:/usr/src# sudo reboot
カーネルのバージョンを調べます。
pi@raspberrypi ~ $ uname -a Linux raspberrypi 3.12-1-rpi #1 Debian 3.12.9-1+rpi2 (2014-12-14) armv6l GNU/Linux
テスト用デバイスドライバのソースコード
テスト用に次のCコードを作ります。作成したテスト用のプログラムは、ディレクトリ「/home/pi/hello-module」を作成して保存します。
hellow-1.c
/* * hello-1.c - The simplest kernel module. */ #include <linux/module.h> /* Needed by all modules */ #include <linux/kernel.h> /* Needed for KERN_INFO */ int init_module(void) { printk(KERN_INFO "Hello world 1.\n"); /* * A non 0 return means init_module failed; module can't be loaded. */ return 0; } void cleanup_module(void) { printk(KERN_INFO "Goodbye world 1.\n"); }
makeファイルは次のようにします。作成したmakeファイルは、ディレクトリ「/home/pi/hello-module」に保存します。
Makefile
KERNEL_HEADERS=/lib/modules/$(shell uname -r)/build obj-m := hellow-1.o all: $(MAKE) -C $(KERNEL_HEADERS) M=$(PWD) modules clean: $(MAKE) -C $(KERNEL_HEADERS) M=$(PWD) clean
- obj-m
- ローダブルモジュール(.ko)を作成する場合です。insmod コマンドでロードする場合です。obj-yは、カーネル起動時にロードする場合です。zImageやuImageに含める場合です。
- makeコマンドのCオプション
- makeは指定したディレクトリに移動してから処理を開始します。KERNEL_HEADERS変数であらかじめカーネルソースコードへのパスを指定しています。
- makeコマンドの「M=パス」
- modulesターゲットを作成する前に,モジュールのソースディレクトリにあるMakefileに戻ることを表します。
- $(MAKE)、$(PWD)
- あらかじめ定義されている変数を示します。また、特殊変数は、ターゲットと依存ファイルの関係を示す値を格納します。例えば次のようなものがあります。
- 「$@」は依存行のターゲットファイル名を示します。
- 「$^」は依存行のすべての依存ファイル名を示します。
コマンドの前にはタブを挿入します。スペースを入れると次のエラーメッセージが発生します。
Makefile:6: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
makefileの構成
makefileの構成は次のようになっています。
ターゲットファイル : 依存ファイル (タブ)コマンド (空行) (上記設定の繰り返し。)
デバイスドライバ開発環境の確認
rootになり、/home/pi/hello-moduleに移動して、次のmakeコマンドを実行します。。
root@raspberrypi:/home/pi/hello-module# make make -C /lib/modules/3.12-1-rpi/build M=/home/pi/hello-module modules make[1]: Entering directory `/usr/src/linux-headers-3.12-1-rpi’ CC [M] /home/pi/hello-module/hello-1.o Building modules, stage 2. MODPOST 1 modules CC /home/pi/hello-module/hello-1.mod.o LD [M] /home/pi/hello-module/hello-1.ko make[1]: Leaving directory `/usr/src/linux-headers-3.12-1-rpi’ root@raspberrypi:/home/pi/hello-module#
次のファイルが作成されています。
root@raspberrypi:/home/pi/hello-module# ls hellow-1.c hellow-1.mod.c hellow-1.o modules.order hellow-1.ko hellow-1.mod.o Makefile Module.symvers
insmod コマンドと、rmmodコマンドで登録して削除してみます。syslogを見ると正常に実行されていることが確認できできます。
root@raspberrypi:/home/pi/hello-module# sudo insmod hellow-1.ko root@raspberrypi:/home/pi/hello-module# tail -1 /var/log/syslog Dec 20 16:02:36 raspberrypi kernel: [ 110.341449] Hello world 1. root@raspberrypi:/home/pi/hello-module# sudo rmmod hellow-1.ko root@raspberrypi:/home/pi/hello-module# tail -1 /var/log/syslog Dec 20 16:02:59 raspberrypi kernel: [ 133.035910] Goodbye world 1.
「Invalid module format」エラー
出来上がったドライバプログラムをinsmodコマンドで実行すると、次のような、「Invalid module format」エラーがでることがあります。カーネルのバージョンと コンパイルしたドライバのバージョンが異なるのが原因のようです。この時は、/boot/config.txtに追加したコードをもう一度確認してみてください。
root@raspberrypi:/home/pi/hello-module# sudo insmod hello-1.ko Error: could not insert module hello-1.ko: Invalid module format