1/进入源码目录
cd linux.4.9.1
- 从当前机器的启动目录拷贝配置信息到源代码目录。这步操作的意思是我们编译内核的配置采用用当前环境一致的配置。
cp -v /boot/config-$(uname -r) .config
3.配置界面
make menuconfig
4/先编译所有模块,确保正确
make -j 6
5/编译完成后,再修改代码,编译自己的模块(/net/ceph编译出来为libceph.ko)
make modules ./net/ceph -j6 (本以为之编译/net/ceph,结果全部给编译了,主要是很慢)、
也可以使用下面这个:
进入./net/ceph执行make -j编译。但是有时候这样子会报错。
6/若需要clean自己的模块
进入./net/ceph,make clean
7/查看符合表是否包含ceph_osdc_call函数
cat /proc/kallsyms |grep ceph_osdc_call
8/报错insmod: cannot insert ‘/lib/modules/adc.ko’: unknown symbol in module or invalid parameter
错误时:
0.lsmod |grep xxx检查模块是否加载
1.先使用cat /proc/kallsyms |grep xxx查看符号表是否有符号,注意需要先加载成功模块。
2.如果前面步骤符号表中包含的话,可能是编译的ko有问题,可以用如下方法解决;
引用别人的:**我就是先编译被依赖的模块A,然后将A中Module.symvers拷贝到B的编译目录解决的问题。**
这是linux kernel 2.6.26 之后版本的bug (详细描述, 请看http://bugzilla.kernel.org/show_bug.cgi?id=12446)
并且这个bug不会被fix
解决办法是把mod_a的Module.symvers放到mod_b的当前路径,从而编译mod_b,符号信息会自动连接进去.
或者在mod_b的makefile中使用KBUILD_EXTRA_SYMBOLS指定mod_a的Module.symvers, 如:
KBUILD_EXTRA_SYMBOLS=/mod_a/Module.symvers
编译mod_b时,搜索Module.symvers的路径是:
1, kernel source path, e.g. /usr/src/kernels/linux-2.6.28.10
2, makefile中M=所指定的路径, 它等效于变量KBUILD_EXTMOD的值
3, 变量KBUILD_EXTRA_SYMBOLS的值
我按照上面所叙述的对我的内核模块的Makefile 做了修改,在编译命令那行加了“KBUILD_EXTRA_SYMBOLS=/linux-3.1.4/Module.symvers”参数,编译问题仍没解决。我想细心地朋友,也许发现了问题根本所在,adc: module license 'unspecified' taints kernel.
对,主要问题就是没有模块许可证声明。而我在添加MODULE_LICENSE("GPL"); 后问题解决了。
9/加载内核模块
modprobe rbd 卸载内核模块: modprobe -r rbd
10/刷新依赖:depmod -a
10/加载时遇到报错
在确保前面的符号正常的情况下,重新加载报错。
更换libceph模块的路径后,加载时报错:
libkmod: ERROR …/libkmod/libkmod-module.c:186 kmod_module_parse_depline: ctx=0x557c256a6010 path=/lib/modules/4.9.0-8-linx-security-amd64/kernel/drivers/block/libceph.ko error=No such file or directory
解决:depmod -a