1
0

More than 1 year has passed since last update.

kernel moduleのMakefileでプリプロセッサを機能させる

Last updated at Posted at 2023-05-08

初心者の備忘録
環境:
raspberry pi 2B (kernel 6.1.21-v7+)

問題

組み込みLinuxデバイスドライバの作り方 (2)を参考にデバイスドライバを勉強しているなか、ふとMakefileでプリプロセッサを機能させる方法を見かけたので試した。

make -C /lib/modules/$(shell uname -r)/build CFLAGS="-DDEBUG" M=$(shell pwd) modules
myDeviceDriver.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/sched.h>
#include <asm/current.h>
#include <asm/uaccess.h>

#define DRIVER_NAME "MyDevice_NAME"
#define DRIVER_MAJOR 63

static int myDevice_open(struct inode *inode, struct file *file) {
	printk("mydevice_open\n");
#ifdef DEBUG 
	printk("DEBUG\n");
#endif
	return 0;
}

static int myDevice_close(struct inode *inode, struct file *file) {
	printk("mydevice_close\n");
#ifdef DEBUG 
	printk("DEBUG\n");
#endif
	return 0;
}

static ssize_t myDevice_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos) {
	printk("mydevice_read\n");
#ifdef DEBUG 
	printk("DEBUG\n");
#endif
	buf[0] = 'A';
	return 1;
}

static ssize_t myDevice_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos) {
	printk("mydevice_write\n");
#ifdef DEBUG 
	printk("DEBUG\n");
#endif
	return 1;
}

struct file_operations s_myDevice_fops = {
	.open = myDevice_open,
	.release = myDevice_close,
	.read = myDevice_read,
	.write = myDevice_write,
};


static int myDevice_init(void) {
	printk("mydevice_init\n");
#ifdef DEBUG 
	printk("DEBUG\n");
#endif
	register_chrdev(DRIVER_MAJOR, DRIVER_NAME, &s_myDevice_fops);
	return 0;
}

static void myDevice_exit(void) {
	printk("myDevice_exit\n");
#ifdef DEBUG 
	printk("DEBUG\n");
#endif
	unregister_chrdev(DRIVER_MAJOR, DRIVER_NAME);
}

module_init(myDevice_init);
module_exit(myDevice_exit);
MODULE_LICENSE("GPL2");

しかし、下記のようにプリプロセッサが効かなかった。
どうもCFLAGSではだめらしい。

insmod MyDeviceModule.ko
dmesg
-> mydevice_init

結論

KernelのMakefileにはccflags-y, asflags-y, ldflags-yを使用すればよい(それぞれcc, as, ld用)
昔はEXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGSだったが現在は非推奨とのこと。
参考:
Linux Kernel Makefiles
LinuxカーネルのMakefileを解析する その7
How to set preprocessor directives in makefile for kernel module build target?
例: DEBUGを定義する

make -C /lib/modules/$(shell uname -r)/build ccflags-y="-DDEBUG" M=$(shell pwd) modules

但し、そのまま使うとMakefile内の同一変数の値を上書きする可能性があるため、下記のようにして回避するといいらしい。

ccflags-y += $(FOO_CFLAGS)

debug:
    make -C /lib/modules/$(shell uname -r)/build FOO_CFLAGS="-DDEBUG" M=$(shell pwd) modules

感想

普通のMakefileとKernel用のMakefileでフラグの作り方が違うことを知って勉強になった。
なんでCFLAGS相当がccflags-yなんだろう?という点が気になった。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0