当前位置: 首页 > 工具软件 > ko > 使用案例 >

linux编译ko文件

穆英飙
2023-12-01

示例文件源码

随便在网上找了一个demo:

#include <linux/init.h>  
#include <linux/kernel.h>  
#include <linux/module.h>  
static int funcIn(void)  
{  
    printk("in module");  
    return 0;  
}  
static void funcOut(void)  
{  
    printk("out module");  
    return;  
}  
module_init(funcIn);  
module_exit(funcOut);  
MODULE_LICENSE("GPL");  

链接如下:
https://blog.csdn.net/yangbingzhou/article/details/51177066

该文件编译得到ko文件后,执行sudo insmod xxx.ko命令插入ko后,使用dmesg 命令后可以看到内核日志中有 in module 字符串,然后执行sudo rmmod xxx命令卸载ko后,使用dmesg命令后可以看到 out module 字符串。

编写Makefile文件

其实也可以用gcc直接编译,如下:

gcc -DMODULE -D__KERNEL__ -isystem /lib/modules/`uname -r`/build/include -c test.c -o test.ko

不过有些版本的内核,可能会报头文件找不到的错误,原因可能是 /lib/modules/uname -r/build/include 目录的子目录的名字与源码include使用的名字不一致导致的,解决方法可以参考如下链接:
https://stackoverflow.com/questions/54343325/lkm-cant-compile-module-missing-headers-files-but-header-packages-are-insta

为了避免产生上述问题,直接采用make进行编译,Makefile文件示例如下:

KDIR := /lib/modules/$(shell uname -r)/build # 内核头文件目录
KO_NAME := test # 输出生成的ko文件的名字
PWD = $(shell pwd) # Makefile文件所在目录

obj-m = $(KO_NAME).o
$(KO_NAME)-objs = test.o # 此处.o文件的名字必须与源码的.c文件保持一致
modules:
	# 使用EXTRA_CFLAGS可以传入指定编译选项,比如 -fno-stack-protector 关闭SP保护
	# -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -O0 关闭Fortify检查 等
	$(MAKE) -C $(KDIR) M=$(PWD) EXTRA_CLFAGS+="" modules
clean:
	$(MAKE) -C $(KDIR) M=$(PWD) clean

将上述文件保存到名字为 Makefile 的文件中,然后在同一目录下新建 test.c 文件,将上一步的示例代码放进去,执行make KO_NAME="hello"命令即可获得一个名为hello.ko的文件。
关于ko文件的Makefile文件的书写,可以参考如下链接:
https://www.cnblogs.com/downey-blog/p/10486907.html

关于编译选项

在编译内核文件时,可以在Makefile文件中的 $(MAKE) 命令一行使用 EXTRA_CLFAGS 选项来添加编译选项或者定义宏,常用的一些安全编译选项如下:

安全功能开启/关闭命令功能描述
NX(DEP)-z execstack / -z noexecstack开启NX保护 堆栈禁止执行
RELRO-z lazy(部分开启) / -z now(全部开启) / -z norelro(关闭)开启NX保护 堆栈禁止执行
PIE(ASLR)-fpie -pie (开启PIE,此时强度为1) / -fPIE -pie (开启PIE,此时为最高强度2)代码段、数据段地址随机化
CANARY-fstack-protector(开启) / -fstack-protector-all(完全开启) / -fno-stack-protector(关闭)堆栈溢出检测
FORTIFY-U_FORTIFY_SOURCE -O0 (关闭) / -D_FORTIFY_SOURCE=1 -O1 (较弱的检查) / -D_FORTIFY_SOURCE=2 -O2 (较强的检查)常用函数加强检查,编译器会对memcpy、strcpy等内存操作相关函数增加检测,详情可自行百度

注意,FORTIFY 需要配合 -O 编译选项进行设置

 类似资料: