Linux中与“内核模块”相关的数据结构

news/2025/2/6 12:50:28/

【摘要】本文详细解释了linux中与模块相关的内核数据结构,便于大家在学习理解内核源码或驱动编程中理解相应代码和思想。

三、内核模块相关的数据结构

目录

  • THIS_MODULE宏
  • module结构体
  • module_use

3.1 THIS_MODULE宏

  • 和CURRENT宏有几分相似,可以通过THIS_MODULE宏来引用模块的struct module结构指针。

  • 位于\linux-2.6.32.63\include\linux\module.h

    #ifdef MODULE#define MODULE_GENERIC_TABLE(gtype,name)            \extern const struct gtype##_id __mod_##gtype##_table        \__attribute__ ((unused, alias(__stringify(name))))extern struct module __this_module;#define THIS_MODULE (&__this_module)
    #else  /* !MODULE */#define MODULE_GENERIC_TABLE(gtype,name)#define THIS_MODULE ((struct module *)0)
    #endif
    
  • __this_module这个符号是在加载到内核后才产生的。insmod命令执行后,会调用kernel/module.c里的一个系统调用sys_init_module,它会调用load_module函数,将用户空间传入的整个内核模块文件创建成一个内核模块,并返回一个struct module结构体,从此,内核中便以这个结构体代表这个内核模块。THIS_MODULE类似进程的CURRENT。

  • 关于sys_init_module、load_module的系统调用内核代码原理分析,请参阅http://www.cnblogs.com/LittleHann/p/3920387.html

3.2 module结构体

  • struct module在内核中代表一个内核模块,通过insmod(实际执行sys_init_module系统调用)把自己编写的内核模块插入内核时,模块便与一个 struct module结构体相关联,并成为内核的一部分,也就是说在内核中,以module这个结构体代表一个内核模块(和windows下kprocess、kthread的概念很类似)。

    struct module
    {/*1. enum module_state stateenum module_state{MODULE_STATE_LIVE,    	//模块当前正常使用中(存活状态) MODULE_STATE_COMING,    //模块当前正在被加载MODULE_STATE_GOING,    	//模块当前正在被卸载};load_module函数:完成模块的部分创建工作后,把状态置为 MODULE_STATE_COMINGsys_init_module函数:完成模块的全部初始化工作后,把模块加入全局的模块列表,调用模块本身的初始化函数),把模块状态置为MODULE_STATE_LIVE使用rmmod工具卸载模块时,会调用系统调用delete_module,会把模块的状态置为MODULE_STATE_GOING*/enum module_state state;/*2. struct list_head listlist是作为一个列表的成员,所有的内核模块都被维护在一个全局链表中,链表头是一个全局变量struct module *modules。任何一个新创建的模块,都会被加入到这个链表的头部*/struct list_head list;/*3. char name[MODULE_NAME_LEN]name是模块的名字,一般会拿模块文件的文件名作为模块名。它是这个模块的一个标识*/char name[MODULE_NAME_LEN];struct module_kobject mkobj;	//见下文注释struct module_param_attrs *param_attrs;const char *version;const char *srcversion;/* Exported symbols */const struct kernel_symbol *syms;unsigned int num_syms;const unsigned long *crcs;/* GPL-only exported symbols. */const struct kernel_symbol *gpl_syms;unsigned int num_gpl_syms;const unsigned long *gpl_crcs;unsigned int num_exentries;const struct exception_table_entry *extable;int (*init)(void);/*初始化相关*/void *module_init;void *module_core;unsigned long init_size, core_size;unsigned long init_text_size, core_text_size;struct mod_arch_specific arch;int unsafe;int license_gplok;#ifdef CONFIG_MODULE_UNLOADstruct module_ref ref[NR_CPUS];struct list_head modules_which_use_me;struct task_struct *waiter;void (*exit)(void);
    #endif#ifdef CONFIG_KALLSYMSElf_Sym *symtab;unsigned long num_symtab;char *strtab;struct module_sect_attrs *sect_attrs;
    #endifvoid *percpu;char *args;
    };
    
  • 关于struct module_kobject mkobj

    • 该成员是一个结构体类型,结构体的定义如下:

      struct module_kobject
      {struct kobject kobj;struct module *mod;	//指向包容它的struct module成员 
      }; 
      
    • module_kobject结构体中的kobject是组成设备模型的基本结构。设备模型是在2.6内核中出现的新的概念,实现对系统的一般性抽象描述。它最初只是被理解为一个简单的引用计数,但现在也有了很多成员,
      它所能处理的任务以及它所支持的代码包括:对象的引用计数;sysfs表述;结构关联;热插拔事件处理。下面是kobject结构的定义:

      struct kobject
      {            //k_name和name都是该内核对象的名称,在内核模块的内嵌kobject中,名称即为内核模块的名称 const char      *k_name;char            name[KOBJ_NAME_LEN];/**kref是该kobject的引用计数,新创建的kobject被加入到kset时(调用kobject_init),*引用计数被加1,然后kobject跟它的parent建立关联时,引用计数被加1,所以一个新创建的*kobject,其引用计数总是为2*/struct kref     kref; //entry是作为链表的节点,所有同一子系统下的所有相同类型的kobject被链接成一个链表 struct list_head    entry; //parent指向该kobject所属分层结构中的上一层节点,所有内核模块的parent是modulestruct kobject      *parent;/** 成员kset就是嵌入相同类型结构的kobject集合。下面是struct kset结构体的定义:struct kset {struct subsystem    *subsys;struct kobj_type    *ktype;struct list_head    list;spinlock_t          list_lock;struct kobject      kobj;struct kset_uevent_ops  * uevent_ops;};*/struct kset         *kset; //ktype则是模块的属性,这些属性都会在kobject的sysfs目录中显示struct kobj_type    *ktype;//dentry则是文件系统相关的一个节点struct dentry       *dentry;
      };
      
  • 从struct module结构体可以看出,在内核态,我们如果要引用当前内核模块的链表,可以使用以下三个中的任意一个:

    • struct module->list
    • struct module->mkobj->kobj->entry
    • struct module->mkobj->kobj->kset
  • 拓展链接

    • http://lxr.free-electrons.com/source/include/linux/module.h
    • http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/module.h
    • http://blog.chinaunix.net/uid-9525959-id-2001630.html
    • http://blog.csdn.net/linweig/article/details/5044722

3.3 module_use

/**source/include/linux/module.h*//* modules using other modules: kdb wants to see this. */
struct module_use 
{struct list_head source_list;struct list_head target_list;struct module *source, *target;
};
  • "struct module_use"和"struct module->module_which_use_me"这两个结果共同组合和保证了内核模块中的依赖关系。
  • 如果模块B使用了模块A提供的函数,那么模块A和模块B之间就存在关系,可以从两个方面来看这种关系:
    1. 模块B依赖模块A——除非模块A已经驻留在内核内存,否则模块B无法装载。
    2. 模块B引用模块A——除非模块B已经移除,否则模块A无法从内核移除,在内核中,这种关系称之为"模块B使用模块A"。
  • 对每个使用了模块A中函数的模块B,都会创建一个module_use结构体实例,该实例将被添加到模块A(被依赖的模块)的module实例中的modules_which_use_me链表中,modules_which_use_me指向模块B的module实例。明白了模块间的依赖关系在数据结构上的表现,可以很容易地枚举出所有模块的依赖关系。

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

相关文章

【逐函数详细讲解ORB_SLAM2算法和C++代码|KeyFrameDatabase|1-11】

在ORB_SLAM2算法中,KeyFrameDatabase类是一个关键帧数据库的实现,用于存储和检索与关键帧相关的信息。关键帧数据库在SLAM中的主要用途是提供循环检测(Loop Detection)和重定位(Relocalization)功能。 循环…

OpenPCDet框架解析文章导航

注意:本文章没有任何实质内容,主要是为OpenPCDet框架解析进行相应的文章导航,内容全部见《点云检测OpenPCDet专栏》 最近基于OpenPCDet来对PointPillars算法做一些实验,打算用一个完整的专栏来记录整个OpenPCDet的整体框架以及各个模块之间的结构。耗时一个多月,耗费精力较…

欧拉函数详解

欧拉函数 定义 在[1,n]的范围内所有与n互质的数字的个数。 我们用 φ ( n ) \varphi(n) φ(n)来表示数字n的欧拉函数的值,例如: φ ( 4 ) 2 \varphi(4)2 φ(4)2,与在[1,4]中与4互质的数字是:1 3,有两个&#xff0c…

MySQL查询优化总结

MySql的性能优化其实有很多方面,比如从客户端层面,从应用层面等等,在这里暂只关注SQL的优化,后续遇到非SQL的MySQL优化的真实的场景,再做进一步介绍。 索引创建和使用的一些原则 除了前面case中或多或少提到过的一些…

字节跳动ByteHouse与亚马逊云科技携手打造新一代云数仓服务

随着全球化的发展,越来越多的中国企业开始涉足海外市场,开展跨境业务。在这个过程中,强大的数据分析能力是出海企业不可或缺的重要一环。通过有效的数据分析,能帮助企业更好地了解全球市场对产品的需求便于调整产品战略&#xff0…

K8S:K8S自动化运维容器化(Docker)集群程序

目录 一、K8S概述 1、什么是K8S 2、为什么要用K8S 3、作用及功能 二、K8S的特性 1、弹性伸缩 2、自我修复 3、服务发现和复制均衡 5、自动发布和回滚 6、集中化配置管理和秘钥管理 7、存储编排 8、任务批量处理运行 三、K8S的集群架构 四、K8S的核心组件 1、Mast…

四元数快速入门【Quaternion】

四元数(Quaternion)是用于旋转和拉伸向量的数学运算符。 本文提供了一个概述,以帮助理解在空间导航等应用程序中对四元数的需求。 推荐:用 NSDT场景设计器 快速搭建3D场景。 可以通过多种方式在空间中准确定位、移动和旋转物体。 …

作为团队管理者,如何获得团队成员的信任和认可?

作为团队管理者,获得团队成员的信任和认可是非常重要的。只有当团队成员信任你并认可你的领导能力,才能更好地协同工作,提高工作效率和完成团队目标。那么,如何才能获得团队成员的信任和认可呢?以下是一些实用的建议。…