在Linux系统中实现一个可加载的内核模块

Intro

坐标成都电讯大专, 某操作系统课老师在PPT上草草写下3个内核线程API后就要求编程, 感受一下:

include/linux/kthread.h,你就看到了它全部的API,一共三个函数。

这里是代码声明,略

kthread_run()负责内核线程的创建, kthread_stop()负责结束创建的线程,参数是创建时返回的task_struct指针。 kthread_should_stop()返回should_stop标志。它用于创建的线程检查结束标志,并决定是否退出。

利用上面提到的系统调用,在Linux系统中实现一个可加载的内核模块,里面至少包含一个内核线程


我看完之后的感受

在这里插入图片描述

编程准备

准备一个CentOS 6.10的虚拟机, 下面是可能用得到的链接

CentOS 6.10
换源

安装完毕后给自己的账户添加root权限或者直接用root账户(并不推荐这么做)

然后更新yum源(不会的见前面的链接)

由于CentOS 6年久失修, 需要先更换yum的软件源才能使用yum来安装必要的组件

我使用的源如下

# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the 
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-6.10 - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos-vault/6.10/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-6
 
#released updates 
[updates]
name=CentOS-6.10 - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos-vault/6.10/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-6
 
#additional packages that may be useful
[extras]
name=CentOS-6.10 - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos-vault/6.10/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-6
 
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-6.10 - Plus - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos-vault/6.10/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-6
 
#contrib - packages by Centos Users
[contrib]
name=CentOS-6.10 - Contrib - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos-vault/6.10/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-6

换源后清除缓存, 刷新缓存

sudo yum clean all
sudo yum makecache

安装一些必须品

sudo yum install gcc make
sudo yum install kernel-devel-2.6.32-754.el6.x86_64

注: 这里安装内核头文件包(也就是第二条命令)中的版本号需要使用uname -r命令来确定

开始编程

叫来ChatGPT, 生成下面的代码

my_module.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>

static struct task_struct *my_thread;

static int thread_function(void *data)
{
    while (!kthread_should_stop())
    {
        printk(KERN_INFO "My kernel thread is running\n");
        msleep(1000);  // sleep for 1 second
    }
    return 0;
}

static int __init my_module_init(void)
{
    printk(KERN_INFO "My kernel module is loaded\n");
    my_thread = kthread_create(thread_function, NULL, "my_thread");
    if (my_thread)
        wake_up_process(my_thread);
    return 0;
}

static void __exit my_module_exit(void)
{
    printk(KERN_INFO "My kernel module is unloaded\n");
    if (my_thread)
        kthread_stop(my_thread);
}

module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple kernel module with a kernel thread");

Makefile

注意: 此处的文件名首字母一定要大写, 即一定要写成Makefile而不是makefile

# 下面一行的"my_module"需要与上面的C源文件的名字部分保持一致
obj-m += my_module.o

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean

写完保存, 然后在项目目录下打开终端, 输入

make

使用模块

编译出来的模块文件名应该是[_a-zA-Z]\w*\.ko形式的, 比如说本教程的my_module.ko
以本教程为例, 在项目目录下打开终端并输入

sudo insmod my_module.ko

没有信息输出即为加载模块成功

然后在终端中输入

dmesg

查看加载的模块的输出, 教程中的模块开启的线程每秒钟输出一行字
同时由于教程中的模块在__init()函数中添加了输出, 第一行输出为其中设置的内容

当你不想要这个模块了的时候, 使用命令

sudo rmmod my_module.ko

没有输出即为成功
本教程中的实例由于在__exit()函数中添加了一行输出, 所以在卸载模块之后使用dmesg命令后, 最后一行输出会是该函数中设置的内容

Outro

任务乍一看很简单, 然而实际操作一堆坑. 把学生当踩雷王了

focnal 祝你: 离这种事逼越远越好

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值