linux内核模块编程入门

本文介绍了一个用于解决Linux内核模块卸载难题的方法。通过修改模块状态并设置引用计数为0来实现强制卸载。文章提供了具体代码示例及操作步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内核模块0.1版本

这个例子是照着《linux 内核编程》Claudia Salzberg Rodriguez 等著 陈莉君译书上的例子写的,修正了书中例子中的部分错误.

/*************************************************************************
    > File Name: hellomod.c
    > Author: guoqingyao
    > Mail: stepbystepto@163.com 
    > Created Time: 2016年07月06日 星期三 20时19分57秒
 ************************************************************************/

#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
MODULE_LICENSE("GPL"); //原书是 : #MODULE_LICENCE("GPL"); 有编译错误,语法和拼写都有问题.

static int __init lkp_init(void )
{
    printk("<1> Hello world ! from kernel space!");
    return 0;
}

static void __init lkp_exit(void )
{
    printk("<1> Byebye world ! from kernel space!");
    return ;
}

module_init(lkp_init);
module_exit(lkp_exit);

对应的Makefile文件如下:

obj-m += hellomod.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
    rm -rf  *.o *.ko *.mod.c *.mod.o modules.* Mod* 

然后在超级用户权限下面:
root@dotheright# make clean
root@dotheright# make
root@dotheright# insmod hellomod.ko
root@dotheright# lsmod | head #查看你的模块信息
root@dotheright# rmmod hellomod #这里会出现卸载不掉的现象
root@dotheright# tail /var/log/kern.log #查看内核打印

如何解决模块卸载不掉的问题

  1. 使用的内核,在编译的时候,使能了CONFIG_MODULE_FORCE_UNLOAD ,然后使用 rmmod -f XXX
  2. 将模块的状态设置为0;
    代码如下:
/*************************************************************************
    > File Name: mymod.c
    > Author: guoqingyao
    > Mail: stepbystepto@163.com 
    > Created Time: 2016年10月04日 星期三 11时10分57秒
 ************************************************************************/
#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/list.h>

MODULE_AUTHOR("GuoQingyao");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("deal module can not be removed");
static int __init mymod_init(void)
{
        struct module *pmod;
        // 打印本模块的模块名和模块状态
        printk(KERN_ALERT"[insmod mymod] name:%s state:%d\n",THIS_MODULE->name,THIS_MODULE->state);

       // 遍历模块列表,查找target模块
        list_for_each_entry(pmod,THIS_MODULE->list.prev,list)
        {
                if(strcmp(pmod->name,"mymod") ==0)
                { 

                        // 模块名、模块状态、引用计数
                        printk(KERN_ALERT"init     name:%s state:%d refcnt:%u ",pmod->name,pmod->state,module_refcount(pmod));
                        // 把target的引用计数置为0
                        pmod->state =0;

                        // 再看看 模块名、状态、引用计数
                        printk(KERN_ALERT"modified name:%s state:%d refcnt:%u\n",pmod->name,pmod->state,module_refcount(pmod));
                }
        }
        return 0;
}

static void __exit mymod_exit(void)
{
        printk(KERN_ALERT"[rmmod mymod] name:%s state:%d\n",THIS_MODULE->name,THIS_MODULE->state);
}

module_init(mymod_init);
module_exit(mymod_exit);

对应的Makefile

obj-m += mymod.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
    rm -rf  *.o *.ko *.mod.c *.mod.o modules.* Mod* 

对应的操作记录:

root@dotheright:/home/dotheright/mylovelycodes/linux_c/kernel# make
make -C /lib/modules/4.4.0-38-generic/build M=/home/dotheright/mylovelycodes/linux_c/kernel modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-38-generic'
  Building modules, stage 2.
  MODPOST 1 modules
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-38-generic'
root@dotheright:/home/dotheright/mylovelycodes/linux_c/kernel# insmod mymod
insmod: ERROR: could not load module mymod: No such file or directory
root@dotheright:/home/dotheright/mylovelycodes/linux_c/kernel# insmod mymod.ko
root@dotheright:/home/dotheright/mylovelycodes/linux_c/kernel# lsmod | head
Module                  Size  Used by
mymod                  16384  0
hellomode              12288  0
rndis_host             16384  0
cdc_ether              16384  1 rndis_host
usbnet                 45056  2 rndis_host,cdc_ether
rfcomm                 65536  4
bnep                   20480  2
arc4                   16384  2
snd_hda_codec_conexant    20480  1
root@dotheright:/home/dotheright/mylovelycodes/linux_c/kernel# rmmod mymod
root@dotheright:/home/dotheright/mylovelycodes/linux_c/kernel# tail -4 /var/log/kern.log
Oct  4 12:21:47 dotheright kernel: [73360.963002] [insmod mymod] name:mymod state:1
Oct  4 12:21:47 dotheright kernel: [73360.963009] init     name:mymod state:1 refcnt:1 
Oct  4 12:21:47 dotheright kernel: [73360.963012] modified name:mymod state:0 refcnt:1
Oct  4 12:22:06 dotheright kernel: [73380.012431] [rmmod mymod] name:mymod state:2
root@dotheright:/home/dotheright/mylovelycodes/linux_c/kernel# 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值