自定义内核模块的编译与加载
不同环境下的编译
linux内核模块vermagic修改
在自己的内核编译环境下编译的内核模块,需要加载到其他环境的内核中时,insmod报错“Invalid module format”
运行一下cat /var/log/messages
或dmesg
查看详细信息:
可以看到是version magic不匹配导致的。
在编译内核树下修改下面的信息:
1、./include/config/kernel.release
2、./include/generated/utsrelease.h
3、./include/linux/vermagic.h
4、./Makefile
根据需要修改为对应目标的版本号即可。
编译模块所在的目录:
make -C ./ M=./drivers/char/ modules
查看模块信息:
modinfo ./drivers/char/hello.ko
可以看到已经修改成功了。
现在加载到目标内核中不会报错“Invalid module format”了,但是3.7后的内核可能会加入模块签名校验机制,在编译内核时可以选择是否开启:
而RedHat7.9刚好就开了这个校验,加载模块报错:
在目标系统下编译
redhat7.9下编译自定义内核模块
在目标系统(Redhat7.9)下编译对应目标内核的模块。
安装依赖(yum源替换方法见这里):
yum install kernel-devel-$(uname -r) gcc elfutils-libelf-devel
创建测试文件:
mkdir /home/admin/test
vi /home/admin/test/test.c
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void)
{ printk("Hello World\n This is a test\n"); return 0; }
void cleanup_module(void)
{ printk("Good Bye World"); }
MODULE_LICENSE("GPL");
创建Makefile文件:
vi /home/admin/test/Makefile
obj-m := test.o
编译内核模块,注意内核目录和模块目录都用绝对路径:
make -C /lib/modules/$(uname -r)/build M=/home/admin/test modules
把编译好的ko文件复制到/lib/modules/$(uname -r)/目录下:
cp /home/admin/test/test.ko /lib/modules/$(uname -r)/
更新模块依赖项列表:
depmod -a
载入内核模块,-f选项强制载入模块:
modprobe -v -f test
列举已加载的模块:
lsmod
用dmesg
查看输出:
如果直接用insmod
加载模块的话会报错:
说是没有对应的符号文件,如果用modprob 不带-f参数也是类似的报错:
尝试了把/usr/src/kernels/3.10.0-1160.el7.x86_64/Module.symvers
文件复制到test目录下,仍有相同的报错出现。
除非是重新编译整个内核,否则没法消除这个报错。
那么还是认定用下面的命令来加载吧:
modprobe -v -f test
卸载模块使用:
modprobe -r test
从内核源码编译
安装包:
yum install mock
yum install rpm-build
安装完后会创建/root/rpmbuild/SPECS目录,运行命令安装源码树:
rpmbuild -bp --tartget=$(uname -m) kernel.spec
提示缺失下面的依赖包,yum安装即可:
yum install m4 net-tools xmlto asciidoc hmaccalc python-devel newt-devel perl pesign elfutils-libelf-devel elfutils-devel binutils-devel bison audit-libs-devel java-devel numactl-devel pciutils-devel ncurses-devel python-docutils flex
安装完后进入源码树,重新编译内核:
cd /root/rpmbuild/BUILD/kernel-3.10.0-1160.el7/linux-3.10.0-1160.el7.x8
make menuconfig
make -j2
之后就能用这个源码树来编译内核模块了。
Makefile:
obj-m += test.o
KERNEL_PATH:=/root/rpmbuild/BUILD/kernel-3.10.0-1160.el7/linux-3.10.0-1160.el7.x86_64
all:
make -C $(KERNEL_PATH) M=$(shell pwd) modules
clean:
make -C $(KERNEL_PATH) M=$(shell pwd) clean
可直接insmod模块,虽然会报错没过签名验证,但能正常执行:
近期评论