XMU->九天揽月->五湖抓鳖->DSP->driver->kernel/OpenWRT->ISP/RTOS
分类: LINUX
2014-12-26 14:14:58
在嵌入式target上insmod kmods失败。
root@rootfs:/lib/modules/2.6.36# insmod helloExample.ko
[5646.820000] helloExample: no symbol version for module_layout
kmod: failed to insert helloExample.ko
而且,加载kernel内可编成module的模块也有这个问题?!编进kernel则没有问题。
网上的资料,
一说内核build目录下没有Module.symvers
确认内核编译下面肯定是有生成这个文件的。
一说kmod的Makefile中必须添加明确的KERNELDIR
all clean :
$(MAKE) -C $(KERNELDIR) M=`pwd` $@
绝对路径KERNELDIR添加后依旧不行
内核编译后的生成的Module.symvers,此文件内计算出了内核中所有被EXPORT修饰的符号。格式为:
0xea147363 printk vmlinux EXPORT_SYMBOL
如果新的kmod中使用了内核或者其他kmod的符号,那么这些符号必须在Module.symvers,否则在insmod时,就会有Unknown symbol in module的错误。
除了有符号是否存在的检测外,还有一项更严格的符号CRC的检测,kmod在编译过程中,工具modpost被scripts/Makefile.modpost调用,生成*.mod.c 及文件Module.symvers。若打开了内核选项CONFIG_MODVERSIONS,Makefile.Build就调用genksyms进一步生成符号CRC信息。
*.mod.c此文件一般组织如下:
其中modversion_info ____versions[]这个数组内,是模块引用的外部符号CRC值和名称的总表。那么在insmod kmod时,若此处的CRC值与内核中的符号CRC值不符合,也会导致模块加载失败。
*.mod.c中定义了ko文件的三个section及其内容。Mod加载时的检验信息正是存放其中。
objdump --section=.modinfo –s kmod.ko
======================================================
这个问题到最后其实非常简单,因为内核编译时恰好有很多关于EXPOR_SYMBOL的告警,想得复杂了。要解决这个问题,就把menuconfig的CONFIG_MODVERSIONS和CONFIG_MODULE_SRCVERSION_ALL关掉即可。如此Module.symvers中就不会计算符号的CRC,而*.mod.c中也不会存放struct modversion_info ____versions[]。
经典教程 http://www.ibm.com/developerworks/cn/linux/l-cn-kernelmodules/