Linux kernel moduleビルドのメモ

ArchLinux(4.17.10)上でのkernel moduleビルドを試したメモ。

Linux kernelのソースコードを入手する

prepare_kernel_source.sh

#!/usr/bin/env sh
set -eu
KERNEL_VERSION=`uname -r | sed -r 's/([0-9]+\.[0-9]+\.[0-9]+).*$/\1/'`
LINUX_VERSION=linux-${KERNEL_VERSION}

if [ -e $LINUX_VERSION ]; then
    echo "$LINUX_VERSION is already exist."
    exit 1
fi

wget https://www.kernel.org/pub/linux/kernel/v4.x/${LINUX_VERSION}.tar.xz
tar -xvJf ${LINUX_VERSION}.tar.xz
ln -s ${LINUX_VERSION} kernel-source
cd ${LINUX_VERSION}
make clean && make mrproper

# prepare kernel
zcat /proc/config.gz > .config
make oldconfig
make prepare && make scripts
$ cd $HOME
$ sh prepare_kernel_source.sh

kernel moduleのソースコードMakefileを書く

hello.c

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

MODULE_LICENSE("MIT");

static int hello_init(void)
{
    printk(KERN_INFO "Hello, World!\n");
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_INFO "Goodbye...\n");
}

module_init(hello_init);
module_exit(hello_exit);

Makefile

obj-m := hello.o

KERNEL_SRC_DIR=${HOME}/kernel-source
PWD:=$(shell pwd)
BUILD_DIR=$(PWD)
VERBOSE=0

all:
    make -C ${KERNEL_SRC_DIR} M=${BUILD_DIR} KBUILD_VERBOSE=${VERBOSE} modules

clean:
    make -C ${KERNEL_SRC_DIR} M=${BUILD_DIR} clean
$ make
-> hello.ko

libelf-dev でのコンパイルエラーが起こったら

コンパイルエラー

$ make
make -C /root/kernel-source M=/root/workspace/hello KBUILD_VERBOSE=0 modules
make[1]: Entering directory '/root/kernel-source'
Makefile:970: *** "Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel".  Stop.
make[1]: Leaving directory '/root/kernel-source'
Makefile:8: recipe for target 'all' failed
make: *** [all] Error 2

解決方法

$ apt-get install libelf-dev

Install/Remove kernel module

$ sudo insmod hello.ko
$ lsmod
-> Module                  Size  Used by
   hello                  16384  0
$ dmesg
-> [11869.696026] Hello, World!
$ sudo rmmod hello
$ lsmod
$ dmesg
-> [11900.796428] Goodbye...

参考