Linux模块代码、编译、加载、卸载一条龙

news/2024/12/5 5:30:17/

最近要写一个Linux的内核模块,记录一下内核模块的代码编写、编译、加载和卸载的基本流程,以作备忘,也希望能帮到有需要的同学。

模块代码

//代码来自https://yangkuncn.cn/kernel_INIT_WORK.html
//init_works.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>struct my_struct_t {char* name;struct work_struct my_work;
};static struct my_struct_t my_name;
static struct workqueue_struct* my_wq = NULL;
static int count;void my_func(struct work_struct *work)
{struct my_struct_t* my_name = container_of(work, struct my_struct_t, my_work);printk(KERN_INFO "Hello kernel, my name is %s", my_name->name);for (count = 1; count < 20; count ++){printk(KERN_INFO"count = %d\n", count);usleep_range(1000000, 1000000);}
}static int __init example_init(void)
{int ret;printk(KERN_INFO"init kernel module\n");my_wq = create_workqueue("my wq");if (!my_wq){printk(KERN_ERR "no memory for workqueue.\n");return 1;}printk(KERN_INFO "create workqueue succussfully.\n");my_name.name = "tom";INIT_WORK(&(my_name.my_work), my_func);ret = queue_work(my_wq, &(my_name.my_work));printk(KERN_INFO"queue work ret = :%d", ret);return 0;
}static void __exit example_exit(void)
{printk(KERN_INFO "Begin exiting work now...\n");flush_workqueue(my_wq);if (my_wq){destroy_workqueue(my_wq);}printk(KERN_INFO "Exit work ok.\n");
}module_init(example_init);
module_exit(example_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("DEBUG");

代码大体功能就是创建一个工作队列,在这个队列上每隔1秒打印一次count数字。

编译

Makefile 此处仅是单源文件的Makefile
多源文件Makefile编写

KVERS = $(shell uname -r)# 要生成的模块名,这里会生成init_works.ko
MODULE_NAME := init_works# 源文件目录
SRC_PATH := init_works/# 作为一个ko模块进行编译
CONFIG_RUNYEE_CAMVIB=m# Kernel modules
obj-$(CONFIG_RUNYEE_CAMVIB) := $(SRC_PATH)$(MODULE_NAME).o# 指定模块的一些编译选项
EXTRA_CFLAGS=-g -O0build: kernel_modules
kernel_modules:make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modulesclean:make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

Makefile和源代码相对路径
代码目录
执行make命令
编译输出

编译产物
执行完make之后,得到一堆东西,其中init_works.ko就是我们需要的内核模块文件。

加载模块

执行命令insmod

insmod init_works/init_works.ko

然后在终端再执行

dmesg --follow 

可以在终端看到一下输出
加载ko模块的输出
再用lsmod命令查看系统已经加载的模块
在这里插入图片描述
可以看到我们的模块已经成功加载到系统上了。

卸载

模块不需要的时候,我们可以卸载它
使用命令

rmmod init_works

卸载输出
从终端的输出可以看到,模块已经被卸载了。
再执行lsmod命令就会发现init_works模块没了,卸载成功!!!

参考

https://yangkuncn.cn/kernel_INIT_WORK.html
https://www.cnblogs.com/mrlayfolk/p/16119159.html
https://www.cnblogs.com/jjzd/p/6438641.html


http://www.ppmy.cn/news/7949.html

相关文章

Java死锁

一.死锁是什么&#xff1f; 死锁指两个或者两个以上的线程在执行过程中&#xff0c;去争夺同样一个共享资源&#xff0c;造成的相互等待的现象&#xff0c;如果没有外部干预&#xff0c;线程会一直阻塞&#xff0c;无法往下执行&#xff0c;这样一直处于相互等待资源的线程叫做…

什么品牌的蓝牙耳机音质最好?高品质蓝牙耳机排行榜

近年来&#xff0c;大量的蓝牙耳机品牌厂商涌入市场&#xff0c;蓝牙耳机的需求不断提高&#xff0c;但质量一直是人们担心的问题&#xff0c;今天就为大家盘点几款当前音质表现不错的真无线蓝牙耳机。 一、南卡小音舱蓝牙耳机 发声单元&#xff1a;13.3mm 网友推荐系数&…

力扣(LeetCode)363. 矩形区域不超过 K 的最大数值和(2022.12.30)

给你一个 m x n 的矩阵 matrix 和一个整数 k &#xff0c;找出并返回矩阵内部矩形区域的不超过 k 的最大数值和。 题目数据保证总会存在一个数值和不超过 k 的矩形区域。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,0,1],[0,-2,3]], k 2 输出&#xff1a;2 解释&…

UE4 SoundCue声音节点总结

最近撸了一下音效&#xff0c;做个总结Mark一下&#xff1a; 1.Cue文件&#xff1a;音频序列化文件&#xff0c;能够对多个音频文件进行排序、组合、淡入淡出等操作&#xff0c;做出新的音频文件 2.Cue文件中的“声音节点” 2.1按参数交叉淡化&#xff1a; 节点及参数详解&…

【数组】leetcode704.二分查找(C/C++/Java/Js)

leetcode704.二分查找1 题目2 思路2.1 二分法区间--左闭右闭写法2.2 二分法区间--左闭右开写法3 代码&#xff08;均使用左闭右闭&#xff09;3.1 Java版本3.2 C版本3.3 C版本3.4 JavaScript版本4 小结1 题目 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nu…

【基础强训】day4

一、选择题 &#x1f308;第1题 有以下程序 #include<iostream> #include<cstdio> using namespace std; int main(){ int m0123, n123; printf("%o %o\n", m, n); return 0; } 程序运行后的输出结果是&#xff08;&#xff09; A 0123 0173 B 01…

vscode+opencv+mingw+cmake配置vscode下的opencv环境

目录介绍安装VsCode安装mingw安装cmake安装opencv&#xff0c;以及其扩展库 opencv_contrib安装python利用cmake生成opencv的Makefile文件cmake命令进行编译&#xff0c;安装配置opencv环境变量配置VSCODE测试DEMO介绍 参考链接&#xff1a;https://www.cnblogs.com/czlhxm/p/…

机器学习和深度学习的关系

机器学习和深度学习的关系 机器学习是一种实现人工智能的方法&#xff0c;深度学习是一种实现机器学习的技术 机器学习&#xff1a;使用算法来解析数据&#xff0c;从中学习&#xff0c;然后对真实世界中的时间做出决策和预测。比如&#xff0c;垃圾邮件检测&#xff0c;房价…