下载了linux无线backports驱动包,在编译成功加载驱动模块时,报如下错误:
insmod: ERROR: could not insert module compat/compat.ko: Invalid module format
起初以为是驱动的vermagic不匹配导致的,随即查看驱动模块信息:
# modinfo compat/compat.ko filename: /data/backports-5.15.92-1/compat/compat.ko version: backported from Linux (v5.15.92-0-ge515b9902f5f) using backports v5.15.92-1-0-gdfe0f60c license: GPL description: Kernel backport module author: Luis R. Rodriguez srcversion: B4DC065C5A4358B469C48C1 depends: retpoline: Y name: compat vermagic: 5.15.0-56-generic SMP mod_unload modversions parm: backported_kernel_name:The kernel tree name that was used for this backport (Linux) (charp) parm: backported_kernel_version:The kernel version that was used for this backport (v5.15.92-0-ge515b9902f5f) (charp) parm: backports_version:The git version of the backports tree used to generate this backport (v5.15.92-1-0-gdfe0f60c) (charp)
然后查看内核版本号:
# uname -r 5.15.0-56-generic
发现驱动模块的vermagic和内核的版本号对得上。
查看dmesg信息,发现有如下错误:
compat: disagrees about version of symbol module_layout
查看compat.ko的module_layout值:
# modprobe --dump-modversions compat/compat.ko | grep module_layout 0x0f704969 module_layout
然后查看内核中已加载的任意一模块的module_layout值,比如cfg80211.ko:
# modprobe --dump-modversions /lib/modules/5.15.0-56-generic/kernel/net/wireless/cfg80211.ko | grep module_layout 0x7d0e2edf module_layout
如上所示,模块加载报错的原因找到了,原来是新编译的模块compat.ko的module_layout值不匹配导致模块加载时报错。
为什么编译出的模块module_layout值不匹配?
原因:由于当前使用的内核和模块是重新编译过的,导致/usr/src/linux-headers-5.15.0-56-generic/Module.symvers里的module_layout值和当前使用的内核(及模块)module_layout值不匹配,所以在编译compat.ko时,指定KLIB和KLIB_BUILD为当前内核源码的路径去编译,问题即可解决。
即:
make KLIB=/path_to_kernel_source/ KLIB_BUILD=/path_to_kernel_source/
或者:
用内核源码路径下编译生成的Module.symvers替换掉/usr/src/linux-headers-5.15.0-56-generic/Module.symvers,再编译compat.ko模块即可。