编译模块时遇到Invalid module format

加载模块: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.10Linux-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)
再次编译后,问题解决。

你可能感兴趣的:(嵌入式,ARM体系结构,系统移植,驱动开发)