首先,看看我的内核版本。
[linc@localhost ~]$ uname -r 2.6.35.6-45.fc14.i686
*** Unable to find the ncurses libraries or the *** required header files. *** 'make menuconfig' requires the ncurses libraries. *** *** Install ncurses (ncurses-devel) and try again. *** make[1]: *** [scripts/kconfig/dochecklxdialog] 错误 1 make: *** [menuconfig] 错误
[root@localhost linux-2.6.35.6]# make bzImage CHK include/linux/version.h CHK include/generated/utsrelease.h CALL scripts/checksyscalls.sh CHK include/generated/compile.h CHK include/linux/version.h make[2]: `scripts/unifdef' is up to date. TEST posttest Succeed: decoded and checked 1249053 instructions Kernel: arch/x86/boot/bzImage is ready (#2)继续编译模块并将它们安装到系统标准位置:
#include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_ALERT "Hello,world.i am linc.\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "Goodbye, i am linc.\n"); } module_init(hello_init); module_exit(hello_exit);写个makefile来编译它:
#如果已经定义KERNELRELEASE,说明是从内核构造系统调用的, #可利用其内建语句 ifneq ($(KERNELRELEASE),) obj-m := test.o #否则是从命令行调用的,需要使用内核构造系统 else KDIR := /lib/modules/2.6.35.6/build all: make -C $(KDIR) M=$(PWD) modules clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers endif
insmod test.ko
rmmod test.ko如果此时仍然遇到问题:
[root@localhost drivers]# insmod test.ko insmod: error inserting 'test.ko': -1 Invalid module format我们看一下具体详细信息:
[root@localhost drivers]# dmesg | tail [ 356.269653] test: version magic '2.6.35.6 SMP mod_unload modversions 686 ' should be '2.6.35.6-45.fc14.i686 SMP mod_unload 686 '说明ko的kernel版本与当前运行的版本仍然不一致。此时我尝试重新编译内核,结果仍然一样。就参考
《Linux 2.6.x 内核模块加载错误 “Invalid module format” 解决办法》 将版本强制修改一下,让其保持一致。方法如下:
找到utsrelease.h文件,在源码树下linux-2.6.35.6/include/generated。将版本号修改。重新编译,发现仍有错误:
[ 1149.371180] test: version magic '2.6.35.6-45.fc14.i686 SMP mod_unload modversions 686 ' should be '2.6.35.6-45.fc14.i686 SMP mod_unload 686 '对比上述信息,发现我的VERMAGIC_STRING多了一个词“modversions”,好吧,为了一直,索性将linux-2.6.35.6/include/linux/vermagic.h文件中对VERMAGIC_STRING做
下调整。去掉MODULE_VERMAGIC_MODVERSIONS信息。如下:
#include <generated/utsrelease.h> #include <linux/module.h> /* Simply sanity version stamp for modules. */ #ifdef CONFIG_SMP #define MODULE_VERMAGIC_SMP "SMP " #else #define MODULE_VERMAGIC_SMP "" #endif #ifdef CONFIG_PREEMPT #define MODULE_VERMAGIC_PREEMPT "preempt " #else #define MODULE_VERMAGIC_PREEMPT "" #endif #ifdef CONFIG_MODULE_UNLOAD #define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload " #else #define MODULE_VERMAGIC_MODULE_UNLOAD "" #endif #ifdef CONFIG_MODVERSIONS #define MODULE_VERMAGIC_MODVERSIONS "modversions " #else #define MODULE_VERMAGIC_MODVERSIONS "" #endif #ifndef MODULE_ARCH_VERMAGIC #define MODULE_ARCH_VERMAGIC "" #endif #define VERMAGIC_STRING \ UTS_RELEASE " " \ MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ MODULE_VERMAGIC_MODULE_UNLOAD MODULE_ARCH_VERMAGIC
[root@localhost drivers]# insmod test.ko [root@localhost drivers]# rmmod test.ko [root@localhost drivers]# dmesg | tail [ 1586.792291] Hello,world.i am linc. [ 1696.536632] Goodbye, i am linc.
参考:
http://blog.csdn.net/xuxinyl/article/details/6996433
http://www.cnblogs.com/Jezze/archive/2011/12/23/2299871.html
《Linux设备驱动程序》第二章