Bcache KO 编译

301 阅读3分钟

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情

下载kernel源码包

wget http://vault.centos.org/7.9.2009/updates/Source/SPackages/kernel-3.10.0-1160.66.1.el7.src.rpm
#安装源码包
rpm -ivh kernel-3.10.0-1160.66.1.el7.src.rpm
#安装编译依赖
yum install -y m4 bc xmlto asciidoc hmaccalc python-devel newt-devel pesign elfutils-libelf-devel elfutils-devel  zlib-devel binutils-devel bison audit-libs-devel java-devel numactl-devel pciutils-devel ncurses-devel python-docutils flex perl-ExtUtils-Embed

修改config文件,打开bcache支持

vim rpmbuild/SOURCES/kernel-3.10.0-x86_64.config
​
# CONFIG_MD_MULTIPATH is not set
CONFIG_MD_FAULTY=m
# CONFIG_BCACHE is not set
CONFIG_BCACHE=m
CONFIG_BLK_DEV_DM_BUILTIN=y
CONFIG_BLK_DEV_DM=m
​
#kernel config文件,y 表示 是 (相应功能将直接编译进内核),m 表示 模块 (相应功能将编译为一个模块,在需要时加载)

修改spec文件重新加载kernel config文件

# Should make listnewconfig fail if there's config options
# printed out?
%define listnewconfig_fail 0
​
#修改listnewconfig_fail为0,重新加载config文件,spec文件后面有检查,当修改listnewconfig_fail为01时,有配置更新时,编译退出

执行kernel编译

rpmbuild -bb rpmbuild/SPECS/kernel.spec

ko加载失败1

[root@vm-complie ~]# insmod bcache.ko
[root@vm-complie ~]# insmod /lib/modules/3.10.0-1160.66.1.el7.x86_64/kernel/drivers/md/bcache/bcache.ko
insmod: ERROR: could not insert module /lib/modules/3.10.0-1160.66.1.el7.x86_64/kernel/drivers/md/bcache/bcache.ko: Invalid module format
[root@vm-complie ~]# dmseg -T
[Mon Jul  4 02:04:17 2022] bcache: disagrees about version of symbol module_layout
[Mon Jul  4 02:09:11 2022] bcache: disagrees about version of symbol module_layout
[Mon Jul  4 02:25:57 2022] bcache: disagrees about version of symbol module_layout
[Mon Jul  4 02:26:02 2022] bcache: disagrees about version of symbol module_layout
[Mon Jul  4 02:26:05 2022] bcache: disagrees about version of symbol module_layout
[root@vm-complie ~]# rpm -qa | grep kernel
kernel-3.10.0-1160.66.1.el7.x86_64
kernel-tools-libs-3.10.0-1160.66.1.el7.x86_64
kernel-devel-3.10.0-1160.71.1.el7.x86_64
kernel-tools-3.10.0-1160.66.1.el7.x86_64
kernel-headers-3.10.0-1160.71.1.el7.x86_64

#问题分析

通过message消息分析可知,ko中的module_layout和系统中的module_layout不匹配,通过make编译ko需要先生成 /root/rpmbuild/BUILD/kernel-3.10.0-1160.66.1.el7/linux-3.10.0-1160.66.1.el7.x86_64/Module.symvers ,然后通过Makefile执行/root/rpmbuild/BUILD/kernel-3.10.0-1160.66.1.el7/linux-3.10.0-1160.66.1.el7.x86_64/scripts/mod/modpost生成/root/rpmbuild/BUILD/kernel-3.10.0-1160.66.1.el7/linux-3.10.0-1160.66.1.el7.x86_64/drivers/md/bcache/bcache.mod.c 文件。bcache.mod.c文件包含了所有ko所需要的参数配置

#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>MODULE_INFO(vermagic, VERMAGIC_STRING);
​
struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
     .name = KBUILD_MODNAME,
     .init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
     .exit = cleanup_module,
#endif
     .arch = MODULE_ARCH_INIT,
};
​
MODULE_INFO(intree, "Y");
​
static const struct modversion_info ____versions[]
__used
__attribute__((section("__versions"))) = {
     { 0x5c1f381e, __VMLINUX_SYMBOL_STR(module_layout) },
     { 0x61b7b126, __VMLINUX_SYMBOL_STR(simple_strtoull) },
     { 0x54554948, __VMLINUX_SYMBOL_STR(kobject_put) },

编译生成的module_layout和系统的中的/usr/src/kernels/3.10.0-1160.66.1.el7.x86_64/Module.symvers(需要安装kernel-devel-3.10.0-1160.66.1.el7.x86_64)的不匹配了

可以通过系统的/usr/src/kernels/3.10.0-1160.66.1.el7.x86_64/Module.symvers配置编译ko,则需要进入对应的module路径然后执行编译

[root@vm-complie ~]# cd /root/rpmbuild/BUILD/kernel-3.10.0-1160.66.1.el7/linux-3.10.0-1160.66.1.el7.x86_64/drivers/md/bcache/
[root@vm-complie bcache]# make -C  /usr/src/kernels/3.10.0-1160.66.1.el7.x86_64/ M=$(pwd) modules#编译需要修改Makefile,CONFIG_BCACHE需要修改为对应的值,例如m或者y
[root@vm-complie bcache]# cat Makefile 
​
obj-$(CONFIG_BCACHE)    += bcache.o
​
bcache-y        := alloc.o btree.o bset.o io.o journal.o writeback.o\
    movinggc.o request.o super.o sysfs.o debug.o util.o trace.o stats.o closure.o
​
CFLAGS_request.o    += -Iblock -DCONFIG_BCACHE

编译成功后可得ko文件

[root@vm-complie bcache]# ll bcache.ko 
-rw-r--r--. 1 root root 6377456 Jul  7 12:19 bcache.ko

ko 加载失败2

[root@vm-complie ~]# insmod bcache.ko
insmod: ERROR: could not insert module bcache.ko: Invalid module format
[root@vm-complie ~]# dmseg -T
[Sat Jul  9 17:37:25 2022] bcache: no symbol version for module_layout

#问题分析

通过message报错信息可知,当前ko文件缺少参数module_layout,也就是make modules时/Module.symvers没有产生module_layout的配置,编译ko需要先执行make产生系统的环境变量以及配置,然后执行make modules -j12 编译对应模块的ko

开机自动加载ko,需要编辑/etc/modules-load.d/目录,创建加载ko的配置, depmod(会在/lib/modules/#uname -r#/目录下生成modules.dep和modules.dep.bb文件,表明模块的依赖关系)

[root@vm-complie bcache]# cat /etc/modules-load.d/bcache.conf
bcache
[root@vm-complie bcache]# 

修改文件并编译KO

修改文件后会导致ko文件的属性改变,需要获取对应kernel的属性文件,Module.kabi_x86_64文件是编译rpm时用来检查KO的变化

cp /root/rpmbuild/SOURCES/Module.kabi_x86_64 ./Module.symvers
make  -C /root/rpmbuild/BUILD/kernel-3.10.0-1160.66.1.el7/linux-3.10.0-1160.66.1.el7.x86_64 M=$(pwd)/drivers/md/bcache/  modules

\