加载中断模块错误提示:Unknown symbol in module
2017-01-24 11:09
806 查看
第一次写博客,分享心得。
在学习内核驱动时,韦东山老师所用的内核版本是2.6.26,我的内核版本是2.6.32。因为烧写进开发板的内核映像就是2.6.32的,为了保持版本号一致,就没有跟随老师用同一个版本。学习过程中就会遇到所讲课内容和我的内核内容冲突的问题,例如有的宏或者函数在2.6.26中有定义,但是在2.6.32中就取消了或者采用其他的定义方式。这样就需要自己深入内核代码中去查找差异,可以比较当前内核中自带的函数如何处理类似的问题。
我在学习按键中断驱动时就遇到了这样的问题,尝试各种办法,最终得以解决,分享一下。
第一次make时出现错误提示:
error:implicit declaration of function 'request irq',
提示说request_irq这个中断注册函数定义模糊(不知道标准的翻译是什么,我的理解如此)。于是在《Linux设备驱动程序》中查找到了request_irq的函数定义:
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int , void *, struct pt_regs *),
unsigned long flags,
const char *dev_name,
void *dev_id);
然后我就把这段函数定义加入到驱动程序中,竟然编译成功(当然会有一些警告)。之所以说竟然,是因为我之后看到这个定义是属于2.4内核的,2.6中定义是不一样的。当然也尝试了用2.6中的定义,下面会提到。错误更多,就没有再次罗列。
难得生成的.ko文件,立刻下载到开发板上加载,果然好景不长。又出现了问题:
insmod: cannot insert 'button_drv.ko': unknown symbol in module or invalid parameter
到底是模块出问题,还是内核。于是百度搜索了一些,也有碰到类似问题,最后的解决办法是加入'GPL',但是我的认证是加过的。然后看到有提到开发板内核和加载内核方式不同的问题,因为我下载到开发板的内核映像是出厂光盘里跟的。于是我再次在2.6.32内核中make uImage,最后把生成的映像下载到开发板。再次加载模块发现并无济于事!还是出现一样的错误。
冷静下!
仔细想一下,可以编译并不代表可以加载进内核。一定是内核在尝试运行这个模块时,出现了无法识别的东西,有可能就是request_irq这个注册函数的定义出了问题!再次用Source Insignt钻进2.6.32的内核代码中,搜索查找分析,不能再盲目的粘贴函数定义。链接到request_irq函数定义如下:
extern int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev);
这是2.6中的函数定义,当然开始我也傻乎乎的把它加到了驱动中,前面提到了,最后错误百出。最终发现,我忽略了一个重要问题:头文件!这段函数定义是在<linux/interrupt>中定义的,于是我把头文件添加在驱动程序中,编译和模块加载都通过了。
查看教程中的程序,却没有包含这个头文件,却可以编译加载通过。看来2.6.32相对2.6.26对函数定义出现了更新,内核的更新带来定义的不同,以后或许还会碰到类似问题。韦老师传授的方法是不合理的,他说看别人用了什么头文件我们就用什么,这种方法虽然可以奏效,但是自己并不知道哪个函数需要哪个头文件。一股脑放进去,不仅会造成代码冗余,还是影响可读性。
小建议:学习中遇到问题首先不应该想着问别人或者百度,可以自己尝试解决。英文提示看不懂就挨个单词查看,错误提示也是内核中编译进去的,就会用一定编写规则,同样一句话就可能出现多次,看多了就熟悉问题出在哪里了。如果只是一味的寻求帮助,就丧失了自主解决问题的能力,这并不是作为一个研发人员应有的职业素养。扯远了......继续学习,共同进步!
在学习内核驱动时,韦东山老师所用的内核版本是2.6.26,我的内核版本是2.6.32。因为烧写进开发板的内核映像就是2.6.32的,为了保持版本号一致,就没有跟随老师用同一个版本。学习过程中就会遇到所讲课内容和我的内核内容冲突的问题,例如有的宏或者函数在2.6.26中有定义,但是在2.6.32中就取消了或者采用其他的定义方式。这样就需要自己深入内核代码中去查找差异,可以比较当前内核中自带的函数如何处理类似的问题。
我在学习按键中断驱动时就遇到了这样的问题,尝试各种办法,最终得以解决,分享一下。
第一次make时出现错误提示:
error:implicit declaration of function 'request irq',
提示说request_irq这个中断注册函数定义模糊(不知道标准的翻译是什么,我的理解如此)。于是在《Linux设备驱动程序》中查找到了request_irq的函数定义:
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int , void *, struct pt_regs *),
unsigned long flags,
const char *dev_name,
void *dev_id);
然后我就把这段函数定义加入到驱动程序中,竟然编译成功(当然会有一些警告)。之所以说竟然,是因为我之后看到这个定义是属于2.4内核的,2.6中定义是不一样的。当然也尝试了用2.6中的定义,下面会提到。错误更多,就没有再次罗列。
难得生成的.ko文件,立刻下载到开发板上加载,果然好景不长。又出现了问题:
insmod: cannot insert 'button_drv.ko': unknown symbol in module or invalid parameter
到底是模块出问题,还是内核。于是百度搜索了一些,也有碰到类似问题,最后的解决办法是加入'GPL',但是我的认证是加过的。然后看到有提到开发板内核和加载内核方式不同的问题,因为我下载到开发板的内核映像是出厂光盘里跟的。于是我再次在2.6.32内核中make uImage,最后把生成的映像下载到开发板。再次加载模块发现并无济于事!还是出现一样的错误。
冷静下!
仔细想一下,可以编译并不代表可以加载进内核。一定是内核在尝试运行这个模块时,出现了无法识别的东西,有可能就是request_irq这个注册函数的定义出了问题!再次用Source Insignt钻进2.6.32的内核代码中,搜索查找分析,不能再盲目的粘贴函数定义。链接到request_irq函数定义如下:
extern int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev);
这是2.6中的函数定义,当然开始我也傻乎乎的把它加到了驱动中,前面提到了,最后错误百出。最终发现,我忽略了一个重要问题:头文件!这段函数定义是在<linux/interrupt>中定义的,于是我把头文件添加在驱动程序中,编译和模块加载都通过了。
查看教程中的程序,却没有包含这个头文件,却可以编译加载通过。看来2.6.32相对2.6.26对函数定义出现了更新,内核的更新带来定义的不同,以后或许还会碰到类似问题。韦老师传授的方法是不合理的,他说看别人用了什么头文件我们就用什么,这种方法虽然可以奏效,但是自己并不知道哪个函数需要哪个头文件。一股脑放进去,不仅会造成代码冗余,还是影响可读性。
小建议:学习中遇到问题首先不应该想着问别人或者百度,可以自己尝试解决。英文提示看不懂就挨个单词查看,错误提示也是内核中编译进去的,就会用一定编写规则,同样一句话就可能出现多次,看多了就熟悉问题出在哪里了。如果只是一味的寻求帮助,就丧失了自主解决问题的能力,这并不是作为一个研发人员应有的职业素养。扯远了......继续学习,共同进步!
相关文章推荐
- linux驱动加载时错误“Unknown symbol in module”的分析与处理
- kvm 模块加载时报错:insmod: error inserting 'kvm.ko': -1 Unknown symbol in module
- 内核模块加载后提示错误: no symbol version for ***
- linux内核插入模块时 Unknown symbol in module
- 往开发板写led驱动时出现错误:insmod: can't insert 's3c_led.ko': unknown symbol in module or invalid parameter
- 解决DPDK安装KNI模块时遇到“Unknown symbol in module”的问题
- linux驱动模块加载出错insmod: error inserting './usb_driver.ko': -1 Unknown symbol in module
- arm上加载insmod驱动时出现Unknown symbol in module
- 安装Dahdi模块出现insmod: can't insert 'dahdi.ko': unknown symbol in module or invalid parameter
- Linux 2.6.x 内核模块加载错误 “Invalid module format” 解决办法
- Linux 2.6.x 内核模块加载错误 “Invalid module format” 解决办法
- 在php添加mongo过程中出现的mongo.so: > undefined symbol: php_json_encode in Unknown on line 0. After installation mongo driver for php 的错误
- Linux 2.6.x 内核模块加载错误 “Invalid module format” 解决办法
- insmod: error inserting './igb.ko': -1 Unknown symbol in module 的问题所在
- insmod: error inserting './sctp.ko': -1 Unknown symbol in module
- root@kali:~# insmod /usb/serial/cp210x.ko :Unknown symbol in module
- insmod: error inserting 'myvivi.ko': -1 Unknown symbol in module 问题解决办法
- Linux加载模块时:disagrees about version of symbol struct_module
- insmod: error inserting './scull.ko': -1 Unknown symbol in module
- insmod: Unknown symbol in module or no symbol version for