强制删除异常驱动设备

目录

背景

解决方案

具体实现

编译

卸载异常驱动


背景

        在进行驱动编程的时候, 如果驱动出现了异常, insmod、 rmmod、 或者使用过程中出现了异常, 那么导致系统的驱动加载了, 但是却无法被卸载, 或者卸载时出错,如下错误:rmmod: ERROR: Module kerneloops is in use.

解决方案

通过force_rmmod外部驱动模块强制卸载异常驱动.

具体实现

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/cpumask.h>
#include <linux/list.h>
#include <asm-generic/local.h>
#include <linux/platform_device.h>
#include <linux/kallsyms.h>
#include <linux/sched.h>


/*
 *  加载模块的时候, 传递字符串到模块的一个全局字符数组里面
 *
 *  module_param_string(name, string, len, perm)
 *
 *  @name   在加载模块时,参数的名字
 *  @string 模块内部的字符数组的名字
 *  @len    模块内部的字符数组的大小
 *  #perm   访问权限
 *
 * */
static char *modname = NULL;
module_param(modname, charp, 0644);
MODULE_PARM_DESC(modname, "The name of module you want do clean or delete...\n");

static int force_cleanup_module(char *del_mod_name)
{
    struct module   *mod = NULL, *relate = NULL;
    int              cpu;

    //  方法一, 遍历内核模块树list_mod查询
    struct module *list_mod = NULL;
    /*  遍历模块列表, 查找 del_mod_name 模块  */
    list_for_each_entry(list_mod, THIS_MODULE->list.prev, list)
    {
        if (strcmp(list_mod->name, del_mod_name) == 0)
        {
            mod = list_mod;
        }
    }
    /*  如果未找到 del_mod_name 则直接退出  */
    if(mod == NULL){
        printk("[%s] module %s not found\n", THIS_MODULE->name, modname);
        return -1;
    }

    //  如果有其他驱动依赖于当前驱动, 则不能强制卸载, 立刻退出
    /*  如果有其他模块依赖于 del_mod  */
    if (!list_empty(&mod->source_list)){
        /*  打印出所有依赖target的模块名  */
        list_for_each_entry(relate, &mod->source_list, source_list){
            printk("[relate]:%s\n", relate->name);
        }
    } else {
        printk("No modules depond on %s...\n", del_mod_name);
    }


    //  清除驱动的状态和引用计数
    //  修正驱动的状态为LIVE
    mod->state = MODULE_STATE_LIVE;
    //  清除驱动的引用计数
    for_each_possible_cpu(cpu) {
        local_set((local_t*)per_cpu_ptr(&(mod->refcnt), cpu), 0);
    }
    atomic_set(&mod->refcnt, 1);
    printk("[after] name:%s, state:%d, refcnt:%u\n", mod->name, mod->state, module_refcount(mod));

    return 0;
}


static int __init force_rmmod_init(void)
{
    return force_cleanup_module(modname);
}


static void __exit force_rmmod_exit(void)
{
    printk("name : %s, state : %d EXIT \n", THIS_MODULE->name, THIS_MODULE->state);
}

module_init(force_rmmod_init);
module_exit(force_rmmod_exit);

MODULE_LICENSE("GPL");

编译

#KERNELDIR := /home/scs/project/linux-6.1.18
KERNELDIR := /lib/modules/$(shell uname -r)/build
CURRENT_PATH := $(shell pwd)
obj-m := force_rmmod.o

build: kernel_modules

kernel_modules:
   $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
clean:
   $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

卸载异常驱动

sudo insmod force_rmmod.ko modname=异常驱动名

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值