加载模块:sudo insmod dnw_usb.ko
insmod: error inserting 'dnw_usb.ko': -1 Invalid module format
查看内核版本:uname –a
Linux ubuntu 3.2.0-29-generic-pae #46-Ubuntu SMP Fri Jul 27 17:25:43 UTC 2012 i686 i686 i386 GNU/Linux
查看模块信息:modinfo dnw_usb.ko
filename: dnw_usb.ko
license: GPL
srcversion: B52853423AD4901986E4D47
depends:
vermagic: 2.6.32-279.el6.i686 SMP mod_unload modversions 686
1.Invalid module format
编译环境:PC Ubuntu 9.10(Linux-2.6.31)
比如编译2.6.31下的usbserial.ko,当insmod之后出现
insmod: error inserting 'usbserial.ko': -1 Invalid module format
dmesg后有如下信息:
usbserial: no symbol version for module_layout
网络上查找信息,说是当前编译的源码版本跟系统内核的版本没有一致。这就无法理解了,我的源码是用Ubuntu自带的新立得下的,说版本不一致很让人费解。至于相关的信息可查看:内核模块加载时的版本检查
也有些人说是编译器版本不同造成的,觉得不太可能。而且也有高人指点,明确这跟编译器无关,就是源码问题。网上找的帖子确实未能解决掉这个问题。
解决办法:使用PC自带的头文件,首先用uname -a查看自己内核版本,比如我的是:
Linux Pro 2.6.31-15-generic #50-Ubuntu SMP Tue Nov 10 14:54:29 UTC 2009 i686 GNU/Linux
于是在Makefile中将路径改为:
KERNELDIR := /usr/src/linux-headers-2.6.31-15-generic
或者KERNELDIR := /usr/src/linux-headers-$(uname -r)
再次编译,成功通过。
2.insmod时出现Unknown symbol in module
添加MODULE_LICENSE("GPL");
=============简 单 的 分 割 线=============
同样在PC下编译内核驱动模块。这次的原因是编译工具版本不一致导致的问题。
具体现象如下:
编译后的.ko可以insmod,但是无法rmmod。执行rmmod,会提示“ERROR: Removing 'hello': Device or resource busy”。
使用rmmod -f命令也不行。
使用lsmod查看,则会显示permanent信息,表示无法卸载模块。
hello 12448 0 [permanent]
原因:
系统默认的内核使用gcc版本与当前编译模块的gcc不同导致。
解决办法:(ubuntu 12.04)
查看系统内核模块的编译信息:
$ cd /lib/modules/`uname -r`/build/include/generated/
$ cat compile.h
显示信息为:
/* This file is auto generated, version 70-Ubuntu */
/* SMP */
#define UTS_MACHINE "i386"
#define UTS_VERSION "#70-Ubuntu SMP Wed May 29 20:31:05 UTC 2013"
#define LINUX_COMPILE_BY "buildd"
#define LINUX_COMPILE_HOST "allspice"
#define LINUX_COMPILER "gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) "
可以看到官方编译的gcc版本为 4.6.3
修改Makefile,如下:
KERNELDIR=/usr/src/linux-headers-$(shell uname -r)
obj-m := hello.o
all:
make modules -C $(KERNELDIR) M=$(PWD) cc=gcc-4.6
clean:
make clean -C $(KERNELDIR) M=$(PWD)
再次编译后,问题解决。