Sometimes, we need to build a module for specified kernel. Following is an example:
ENV:
[root@atest-guest ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.0 (Maipo)
[root@atest-guest ~]# uname -a
Linux atest-guest 3.10.0-123.el7.x86_64 #1 SMP Mon May 5 11:16:57 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux
(1), Problem:
[root@atest-guest linux_btrfs]# make -j 4 fs/btrfs/
[root@atest-guest linux_btrfs]# insmod fs/btrfs/btrfs.ko
insmod: ERROR: could not insert module fs/btrfs/btrfs.ko: Invalid module format
[root@atest-guest linux_btrfs]# dmesg
[ 2976.500283] btrfs: disagrees about version of symbol module_layout
<------------------------- It means the version of module_layout in this module is not same with the current kernel.
(2), More information:
[root@atest-guest linux_btrfs]# cat /lib/modules/3.10.0-123.el7.x86_64/build/Module.symvers |grep module_layout
0x28950ef1 module_layout vmlinux EXPORT_SYMBOL
|<-------- That means what required by the running kernel is 0x28950ef1.
[root@atest-guest linux_btrfs]# cat Module.symvers |grep module_lay
0x8798da3e module_layout vmlinux EXPORT_SYMBOL
[root@atest-guest linux_btrfs]# modprobe --dump-modversions fs/btrfs/btrfs.ko |grep module_lay
0x8798da3e module_layout
|<-------- But what we get in our module is 0x8798da3e
(3), Reason
There is a function named module_layout in kernel only for modversions, we can only insmod a module
with the modversions all matched.
(4), Solution
We need to reuse the Module.symvers of running kernel to build our module. This file store the all version
of each functions. we need to use these to build our module, then we will link the all related symbols with
the correct address.
[root@atest-guest linux_btrfs]# make -j 4 -C /lib/modules/3.10.0-123.el7.x86_64/build/ M=/data/linux_btrfs/drivers/mtd/
[root@atest-guest linux_btrfs]# modprobe --dump-modversions drivers/mtd/mtd.ko |grep module_lay
0x28950ef1 module_layout
[root@atest-guest linux_btrfs]# cat /lib/modules/3.10.0-123.el7.x86_64/build/Module.symvers |grep module_lay
0x28950ef1 module_layout vmlinux EXPORT_SYMBOL
>>>>>>>>>>>>>>>>>>>>>currently, the version of module_layout in our module of mtd.ko is same with running kernel.
[root@atest-guest linux_btrfs]# cat Module.symvers |grep module_lay
0x8798da3e module_layout vmlinux EXPORT_SYMBOL
>>>>>>>>>>>>>>>>>>>>>We use -C in make command to use the environment of the specified path, I guess it's chroot but not sure.
[root@atest-guest linux_btrfs]# insmod drivers/mtd/mtd.ko
[root@atest-guest linux_btrfs]# echo $?
0