• Linux 内核模块API之find_module


    前言

    最近再看一些涉及内核模块的常用API,学习的过程记录下来。

    函数find_module( )用来获得一个指向模块的指针。它是根据给定的模块名字查找模块链表,如果找到一个与给定的模块名字相匹配的模块,则返回该模块的指针。由于一个模块的名字是唯一的且不允许有重名的模块,因此基于模块名查找模块是可行的。

    一、find_module源码解析

    // linux-3.10/include/linux/module.h
    
    enum module_state {
    	MODULE_STATE_LIVE,	/* Normal state. */
    	MODULE_STATE_COMING,	/* Full formed, running module_init. */
    	MODULE_STATE_GOING,	/* Going away. */
    	MODULE_STATE_UNFORMED,	/* Still setting it up. */
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    MODULE_STATE_LIVE表示模块在正常运行中,已经完成初始化任务之后。
    MODULE_STATE_COMING表示在加载模块期间。
    MODULE_STATE_GOING表示模块在卸载期间。

    // linux-3.10/kernel/module.c
    
    /* Search for module by name: must hold module_mutex. */
    static struct module *find_module_all(const char *name,
    				      bool even_unformed)
    {
    	struct module *mod;
    
    	//遍历模块双向链表
    	list_for_each_entry(mod, &modules, list) {
    		if (!even_unformed && mod->state == MODULE_STATE_UNFORMED)
    			continue;
    		if (strcmp(mod->name, name) == 0)
    			return mod;
    	}
    	return NULL;
    }
    
    struct module *find_module(const char *name)
    {
    	return find_module_all(name, false);
    }
    EXPORT_SYMBOL_GPL(find_module);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    // linux-3.10/include/linux/list.h
    
    /**
     * list_for_each_entry	-	iterate over list of given type
     * @pos:	the type * to use as a loop cursor.
     * @head:	the head for your list.
     * @member:	the name of the list_struct within the struct.
     */
    #define list_for_each_entry(pos, head, member)				\
    	for (pos = list_entry((head)->next, typeof(*pos), member);	\
    	     &pos->member != (head); 	\
    	     pos = list_entry(pos->member.next, typeof(*pos), member))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    find_module实现逻辑很简单,遍历内核全局双向链表modules,比较链表上模块的名字与传入的参数名字是否相等,相等则表示找到。

    注意调用该函数时要加锁访问:

    /*
     * Mutex protects:
     * 1) List of modules (also safely readable with preempt_disable),
     * 2) module_use links,
     * 3) module_addr_min/module_addr_max.
     * (delete uses stop_machine/add uses RCU list operations). */
    DEFINE_MUTEX(module_mutex);
    EXPORT_SYMBOL_GPL(module_mutex);
    static LIST_HEAD(modules);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    mutex_lock(&module_mutex);
    find_module(mod_name);
    mutex_unlock(&module_mutex);
    
    • 1
    • 2
    • 3

    二、API使用

    # include 
    # include 
    # include 
    
    #define MODULE_NAME "nf_conntrack"
    
    static int __init lkm_init(void)
    {
        struct module *mod;
    
        mutex_lock(&module_mutex);
        mod = find_module(MODULE_NAME);
        mutex_unlock(&module_mutex);
    
        if(mod){
            printk("module name = %s\n", mod->name);
            printk("module core_size = %d\n", mod->core_size);
            printk("module refcount = %ld\n", module_refcount(mod));
        }
    	return -1;
    }
    
    
    module_init(lkm_init);
    
    MODULE_LICENSE("GPL");
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    通过字符串"nf_conntrack"找到nf_conntrack模块:
    在这里插入图片描述

    参考资料

    Linux 3.10.0

  • 相关阅读:
    Ubuntu 生成ffmpeg安卓全平台so
    实习中做大数据平台搭建设计
    Python版股市情感分析源代码,提取投资者情绪,为决策提供参考
    【vscode】远程容器内开发python
    flurl监听报错返回的信息
    使用POI实现基于Excel的考试成绩分析
    获取淘宝商品详情API、商品主图、图片搜索api
    Day17-Java进阶-网络编程(IP, 端口, 协议)&TCP和UDP&三次握手和四次挥手
    输尿管结石的症状表现有哪些?
    算法通关村第一关-链表白银经典问题笔记
  • 原文地址:https://blog.csdn.net/weixin_45030965/article/details/127427846