CentOS7.6编译tipc.ko
这里主要讲解tipc.ko驱动模块的编译及编译过程中可能出现的问题。
编译环境:CentOS7.6,内核版本 3.10.0-957.el7.x86_64
一般最好是选择你需要的内核版本和你的编译机内核版本一致进行编译,这样会最小化可能存在的问题。Ubuntu系统时自带这个内核模块的,只是没有安装,CentOS则是没有。
常用命令:
查看内核版本: uname -r
查看系统版本:cat /etc/redhat-release
一、编译环境搭建
1、搭建编译所需的依赖包
[root@localhost ~]# yum install rpm-build perl-ExtUtils-Embed pesign xmlto -y
[root@localhost ~]# yum install audit-libs-devel binutils-devel elfutils-libelf-devel java-devel -y
[root@localhost ~]# yum install numactl-devel pciutils-devel python-devel zlib-devel -y
[root@localhost ~]# yum install make gcc bc openssl-devel -y
[root@localhost ~]# yum groupinstall "Development Tools" -y
其实这个地方应该自己感受一下编译错误提示 ^ _ ^ 哈哈哈
大部分依赖没有的话,会提示:
perl(ExtUtils::Embed) is needed by kernel-3.10.0-1127.el7.x86_64
这种形式,那么只需要安装即可(后接 -y 就可以不用在安装过程输入 Y):
yum install perl -y
yum install perl-ExtUtils-Embed
需要注意的一个地方是,如果提示:rpmbuile 不可用,则需要安装的是
yum install rpm-build
还有一个是可能需要升级GCC版本,如果是高版本的 kernel 的话。
1.1、安装centos-release-scl
sudo yum install centos-release-scl
1.2、安装devtoolset,注意,如果想安装7.版本的,就改成devtoolset-7-gcc,以此类推
sudo yum install devtoolset-8-gcc*
1.3、激活对应的devtoolset,所以你可以一次安装多个版本的devtoolset,需要的时候用下面这条命令切换到对应的版本
scl enable devtoolset-8 bash
1.4 执行 gcc -v 即可查看当前版本
二、源代码获取
1.源码获取
源代码的官网:http://vault.centos.org/
进入官网后,依次是进入 7.6.1810/,进入os/,进入Source/,进入SPackages/,找到 3.10.xxxx-957.el7.xxxxx.src.rpm,下载就行了。
当然也可以:
rpm -i http://vault.centos.org/7.9.2009/updates/Source/SPackages/kernel-3.10.xxx-957.el7.xxxxx.src.rpm 2>&1 | grep -v exist
2.解压并安装源码
如果是执行上面的命令,那么应该就已经安装好了。
如果不是可以用一下命令
rpm -i your_name.rpm 安装 your_name.rpm 包;
rpm -iv your_name.rpm 安装 your_name.rpm 包并在安装过程中显示正在安装的文件信息;
rpm -ivh your_name.rpm 安装 your_name.rpm 包并在安装过程中显示正在安装的文件信息及安装进度
解压并安装后应该会有一个目录叫 rpmbuild,其下会有6个子目录,在执行:
[root@localhost ~] cd ~/rpmbuild/SPECS
[root@localhost ~] rpmbuild -bp --target=$(uname -m) kernel.spec
$(uname -m) 这个值将目标结构设置为你的现有内核的结构。一般来说这是可行的,因为多数人需要以 i686 或 x86_64 为目标
现在内核的源代码目录树可以在 ~/rpmbuild/BUILD/kernel*/linux*/ 这个目录内找得到
3.开始编译
先说下我自己的方式,再说下比较官方的方式(主要是官方的方式配置选择上不懂,你就不敢随便选)
我这个是为了在本编译机同版本内核 3.10.0-957.el7.x86_64 的机器上运行。 **所以直接将该编译机的 /boot/config-3.10.0-957.el7.x86_64 ** 拷贝到的源码目录下,把名字改成 .config
这样就直接获取了编译机内核的配置,这个是非必要,但这样会尽可能的减少不必要的麻烦,不是嘛!
官方中给出的是 使用:make oldconfig,但是实际使用中会出来很多选择,不知道的情况下,难免会出错。
然后执行以下命令:
cp /usr/src/kernels/3.10.0-957.el7.x86_64/Module.symvers ./ # ./ 是源码的顶层目录,其实以下一直都是在源码的顶层目录操作的
make menuconfig # 会出现界面,然后配置tipc 为 M
make prepare
make modules_prepare # 创建编译外置模块时所需的文件。
make M=net/tipc #开始编译
cp 的那一步功能好像是 使模块在安装时,能被成功校验,否则会提示 “tipc: no symbol version for module_layout” 错误。 具体的解释还没弄清楚,希望懂的大佬给指点一二!!!不胜感激!
在 make menuconfig 中可以使用 “/” 进行查找你需要的模块,可能有多个,然后直接输入 序号就会进入配置。配置完成保存退出即可。
注:模块的目录可以位於任何一个位置。举个例说,假如它位於 ~/mycifs/,你可以在内核源代码的主目录里执行以下的指令:
4.编译错误
该版本内核中,源码会出现编译错误:
4.1、genl_register_family_with_ops函数不存在,修改方案:
- res = genl_register_family_with_ops(&tipc_genl_family,
- tipc_genl_ops);
+ res = genl_register_family(&tipc_genl_family);
if (res) {
pr_err("Failed to register netlink interface\n");
return res;
4.2、GENL_ID_GENERATE不存在,修改方案
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 4b94f3cfe3af4..383b8fedabc76 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -136,7 +136,6 @@ const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = {
* so we have a separate genl handling for the new API.
*/
struct genl_family tipc_genl_family = {
- .id = GENL_ID_GENERATE,
.name = TIPC_GENL_V2_NAME,
.version = TIPC_GENL_V2_VERSION,
.hdrsize = 0,
5.编译产物
编译产物就在 linux.xxx.xx/net/tipc 目录中,就是tipc.ko
insmod tipc.ko 即可安装。只要其他主机,是相同架构,内核版本相同,这个ok文件也是可以直接使用的。
比较有意思的是,我在kernel版本为 5.10.4的源代码(来自于kernel官网)中,用同样的方法编译方式编译tipc.ko ,使用的编译机内核版本5.10.4-1.el7.elrepo.x86_64,自然也是cp他这个配置文件。
编译的整个过程没有任何告警和错误,包括安装也是一步就成功了,但就是无法正常使用,并且一旦卸载该模块,这个编译机都挂死了。。。。。。。
如果有什么建议欢迎各位指点!^ _ ^
参考文档:
https://wiki.centos.org/zh/HowTos/BuildingKernelModules
https://wiki.centos.org/zh/HowTos/I_need_the_Kernel_Source
https://blog.csdn.net/liuqun69/article/details/89223813
https://github.com/torvalds/linux/commit/a7b11d738282337488ae158c975d76271ad43a98