【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 类型的日志。

相关推荐
学***542342 分钟前
换新电脑如何迁移原有数据?4 种高效数据迁移方法详解
服务器·电脑·负载均衡
DuHz6 小时前
论文精读:大语言模型 (Large Language Models, LLM) —— 一项调查
论文阅读·人工智能·深度学习·算法·机器学习·计算机视觉·语言模型
vortex56 小时前
Debian 包管理全指南:从底层 dpkg 到高层 apt 及其日志追踪
linux·运维·debian
加农炮手Jinx6 小时前
LeetCode 72. Edit Distance 题解
算法·leetcode·力扣
借雨醉东风6 小时前
程序分享--常见算法/编程面试题:旋转矩阵
c++·线性代数·算法·面试·职场和发展·矩阵
_深海凉_6 小时前
LeetCode热题100-打家劫舍
算法·leetcode·职场和发展
偶尔上线经常挺尸6 小时前
《每日一命令08:scp——安全的远程复制》
linux·安全·scp·文件传输·运维基础·远程复制
计算机安禾7 小时前
【Linux从入门到精通】第17篇:日志系统——系统运行的黑匣子
linux·运维·服务器
l1t7 小时前
DeepSeek辅助解决windows 11 wsl2中Linux版Dbeaver显示中文
linux·运维·windows
jghhh017 小时前
使用 MATLAB 实现支持向量回归 (SVR) 预测未来数据
算法·matlab