■
Linuxデバイスドライバを書いるとき、insmod module.ko, rmmod moduleを繰り返しているうちに、デバッグメッセージがいつ実行したドライバのメッセージがわからなくなる。いつ実行したか確実にわかるように、insmod, rmmodなどを実行したとき、printk()で現在の時刻を表示したいのだが、ctime(3)のような関数がカーネル内では存在しないようだ。
do_gettimeofday()でUNIX時間を取得し変換する方法もあるが、しかしこの方法は結構めんどくさいのもっと手軽にRTC(Real Time Clock)の情報を使えばいいのではないかと思う。サンプルのプログラムは以下の様になる。
testdrv.c
#include <linux/init.h> #include <linux/module.h> #include <asm-generic/rtc.h> MODULE_LICENSE("Dual BSD/GPL"); static char *months[12] ={"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; #define LOG(msg, ...) \ _log(__FILE__, __LINE__); \ printk(msg, ## __VA_ARGS__) static inline void _log(const char *file, const int line) { struct rtc_time t; get_rtc_time(&t); printk("%s %d %d:%d:%d %d: %s:%d: ", months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, 2000 + (t.tm_year % 10), file, line); } static int testdrv_init(void) { LOG("test driver init"); return 0; } static void testdrv_exit(void) { LOG("test driver exit"); } module_init(testdrv_init); module_exit(testdrv_exit);
obj-m := testdrv.o KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) .PHONY: modules modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) .PHONY: clean clean: rm -rf *.o *~ core .*.cmd *.ko *.mod.c .tmp_versions Module.symvers
上のコードを試すと以下のような出力結果を得られる。
$ make $ sudo insmod testdrv.ko $ dmesg ... ... Sep 17 2:34:20 2007: /home/yusuke/work/testdrv/testdrv.c:22: test driver init $ sudo rmmod testdrv $ dmesg ... ... Sep 17 2:40:41 2007: /home/yusuke/work/testdrv/testdrv.c:29: test driver exit