【Linux】Linux 内核 ko 编译运行

啥事 ko?

ko(Kernel Object)是Linux内核中的可加载模块,它可以动态地向内核添加功能。在运行时,可以通过加载或卸载ko模块来扩展或减少内核功能。

我们可以通过编写内核模块扩展内核功能,添加新的驱动程序或文件系统,或者修改内核的行为,而不需要重新编译整个内核。

基本步骤

  • 编写模块代码:包括初始化清除函数,以及其他需要的函数。
  • 编写Makefile文件:定义编译模块的规则,指定编译器和编译选项等。
  • 编译模块:使用make命令编译模块,生成ko文件。
  • 查看模块信息:使用modinfo命令查看模块的信息,包括作者、版本、描述等。
  • 加载模块:使用insmod命令加载模块。
  • 卸载模块:使用rmmod命令卸载模块。

示例代码

1、demo.c

  • KLOGS_ERR 封装了一次 printk() 函数。
  • KERN_ERR 应该是内核的一种输出类型,类似的还有 KERN_INFOKERN_DEBUG
  • int __init hello_init(void) 是初始化函数
  • void __exit hello_exit(void) 是清理函数

为什么不用 C 的库函数输出?

因为 ko 就是跑在内核里边的,没有标准的C库函数。(我猜的)

c 复制代码
#include <linux/init.h>  //头文件信息
#include <linux/module.h>

#define KLOGS_ERR(fmt, args...) do { \
	struct timespec64 ts; \
	struct tm tm; \
	ktime_get_real_ts64(&ts); \
	time64_to_tm(ts.tv_sec, 0, &tm); \
	printk(KERN_ERR "[%04ld-%02d-%02d %02d:%02d:%02d][timer_demo]:" fmt "\n", \
		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, \
		tm.tm_hour, tm.tm_min, tm.tm_sec, ##args); \
} while(0)


static int __init hello_init(void)  //初始化函数
{
    KLOGS_ERR("Hello World!");
    return 0;
}

static void __exit hello_exit(void)	//清理函数
{
    KLOGS_ERR("Good Bye World!");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL"); //表明该模块的源代码使用 GPL 许可证,可以在 GPL 许可证下被复制、修改和重新发布。如果模块没有正确声明许可证,那么它将被认为是专有软件,从而可能违反 GPL 许可证的条款。
MODULE_AUTHOR("wyt"); //作者信息
MODULE_DESCRIPTION("How to write a ko demo."); //内核模块描述

2、Makefile

在 Makefile 中赋值,尽量使用:=或者+=,因为=会将Makefile展开,获取到的值是最后计算完成的值。

  • M=:指定模块所需源码的所在目录。
  • -C:将工作目录,转移至指定目录。(一般转移至当前系统正在运行的内核的源代码目录
  • modules:不懂,但是写内核模块就要加这个属性。

注意:make 命令之前不能有空格,一定要用 tab。

makefile 复制代码
obj-m := demo.o #内核模块名字,即生成demo.ko。demo是模块名,也是.c的文件名

KDIR := /lib/modules/$(shell uname -r)/build  #指向当前系统正在运行的内核的源代码目录

PWD := $(shell pwd) #当前路径

all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	make -C $(KDIR) M=$(PWD) clean

编译KO,并查看模块信息

bash 复制代码
[root@w ko_demo]# make
make -C /lib/modules/5.10.0-182.0.0.95.oe2203sp3.x86_64/build   M=/ko_demo  modules
make[1]: Entering directory '/usr/src/kernels/5.10.0-182.0.0.95.oe2203sp3.x86_64'
  CC [M]  /ko_demo/demo.o
  MODPOST /ko_demo/Module.symvers
  CC [M]  /ko_demo/demo.mod.o
  LD [M]  /ko_demo/demo.ko
make[1]: Leaving directory '/usr/src/kernels/5.10.0-182.0.0.95.oe2203sp3.x86_64'
BASH 复制代码
[root@w ko_demo]# modinfo demo.ko
filename:       /ko_demo/demo.ko
description:    How to write a ko demo.
author:         w
license:        GPL
srcversion:     DF352F197303CAAD611B0F1
depends:        
retpoline:      Y
name:           demo
vermagic:       5.10.0-182.0.0.95.oe2203sp3.x86_64 SMP mod_unload modversions

运行KO

首先将 ko 文件传输到本地,然后传输至目标机。

确认当前编译环境内核版本,发现与ko版本一致,则可直接在目标机上运行ko文件。

bash 复制代码
[root@localhost w]# uname -r
5.10.0-182.0.0.95.oe2203sp3.x86_64

修改 ko 文件的读写权限。

bash 复制代码
[root@localhost w]# chmod 777 demo.ko
[root@localhost w]# ll
-rwxrwxrwx. 1 root root     64408 Aug 23 17:53 demo.ko

新建窗口使用dmesg打开内核日志。

bash 复制代码
[root@localhost w]# dmesg -Hw
  • -H:把时间戳修改为人能看懂的年月日
  • -w:持续跟踪新的内核消息,直到退出

插入模块。

bash 复制代码
insmod demo.ko

拔出模块。

bash 复制代码
rmmod demo.ko

通过下图可以看到,内核消息同步输出了 Error 类型的日志。

相关推荐
孙克旭_39 分钟前
PXE_Kickstart_无人值守自动化安装系统
linux·运维·自动化
皓月盈江2 小时前
Linux电脑本机使用小皮面板集成环境开发调试WEB项目
linux·php·web开发·phpstudy·小皮面板·集成环境·www.xp.cn
深井冰水2 小时前
mac M2能安装的虚拟机和linux系统系统
linux·macos
leoufung2 小时前
内核内存锁定机制与用户空间内存锁定的交互分析
linux·kernel
菜菜why3 小时前
AutoDL租用服务器教程
服务器
IT专业服务商3 小时前
联想 SR550 服务器,配置 RAID 5教程!
运维·服务器·windows·microsoft·硬件架构
忧虑的乌龟蛋4 小时前
嵌入式Linux I2C驱动开发详解
linux·驱动开发·嵌入式·iic·i2c·读数据·写数据
?abc!4 小时前
缓存(5):常见 缓存数据淘汰算法/缓存清空策略
java·算法·缓存
BioRunYiXue4 小时前
一文了解氨基酸的分类、代谢和应用
人工智能·深度学习·算法·机器学习·分类·数据挖掘·代谢组学
I_Scholar4 小时前
OPENSSL-1.1.1的使用及注意事项
linux·ssl