みつきんのメモ

組み込みエンジニアです。Interface誌で「My オリジナルLinuxの作り方」連載中

YoctoのSDKでOut-of-treeのカーネルモジュールをビルドする

はじめに

bitbake meta-toolchain-c populate_sdkで作成したSDKを使用してOut-of-treeのカーネルモジュール(ドライバ)をビルドする時に少しハマったのでメモしておく。

SDKカーネルソースを含める

作成されたSDKに確実にカーネルソースコードを含めるためにlocal.confに下記を追加する。

TOOLCHAIN_TARGET_TASK_append = " kernel-devsrc"

SDKを作成する

カーネルカーネルモジュールをビルドしたいだけであればmeta-toolchainでも問題ない。

$ bitbake meta-toolchain

もちろんイメージをpopulate_sdkしても構わない。

$ bitbake core-image-base -c populate_sdk

環境設定

SDKを使用できるようにするために環境変数を設定する。

また、カーネルソースの場所を簡単にアクセスできるようにするために、KERNEL_SRCという環境変数を定義しておく。

$ source /opt/poky/3.1.4/environment-setup-aarch64-poky-linux
$ export KERNEL_SRC=${OECORE_TARGET_SYSROOT}/usr/src/kernel

カーネルモジュールをビルドするための準備

Out-of-treeのカーネルモジュールをビルドするためには下記のようにあらかじめカーネルのソースツリーでmake scriptsなどを実行しておく必要がある。

SDKにインストールされたカーネルのソースツリーの所有者がrootになっているため下記のようにする。

$ cd ${KERNEL_SRC}
$ sudo chown -R ${USER} .
$ make scripts
$ make prepare
$ sudo chown -R root .

この時make scriptsmake prepareを直接sudoで実行すると、実行時の環境変数が切り替わってしまうためうまくいかない。

作成するモジュール

Yoctoターゲットのセルフコンパイル環境でカーネルモジュールをビルドの回でもお世話になったhello-modをここでも試してみる。

~/helloにソースとMakefileを作成する。

# mkdir ~/hello
# cd hello

~/hello/hello.cを次の内容で作成する。

#include <linux/module.h>

int init_module(void)
{
    printk("Hello World!\n");
    return 0;
}

void cleanup_module(void)
{
    printk("Goodbye Cruel World!\n");
}

MODULE_LICENSE("GPL");

~/hello/Makefileを次の内容で作成する。

obj-m := hello.o

SRC := $(shell pwd)

all:
    $(MAKE) -C $(KERNEL_SRC) M=$(SRC)

modules_install:
    $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install

clean:
    rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
    rm -f Module.markers Module.symvers modules.order
    rm -rf .tmp_versions Modules.symvers

ビルド

$ make

まとめ

YoctoのSDKでOut-of-treeをビルドする時は注意が必要。

参考