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

2023-05-16

【摘要】本文详细解释了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 state
        enum module_state
        {
            MODULE_STATE_LIVE,    	//模块当前正常使用中(存活状态) 
            MODULE_STATE_COMING,    //模块当前正在被加载
            MODULE_STATE_GOING,    	//模块当前正在被卸载
        };
        load_module函数:完成模块的部分创建工作后,把状态置为 MODULE_STATE_COMING
        sys_init_module函数:完成模块的全部初始化工作后,把模块加入全局的模块列表,
        					调用模块本身的初始化函数),把模块状态置为MODULE_STATE_LIVE
        使用rmmod工具卸载模块时,会调用系统调用delete_module,会把模块的状态置为MODULE_STATE_GOING
        */
        enum module_state state;
    
        /*
        2. struct list_head list
        list是作为一个列表的成员,所有的内核模块都被维护在一个全局链表中,
        链表头是一个全局变量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_UNLOAD
        struct module_ref ref[NR_CPUS];
        struct list_head modules_which_use_me;
        struct task_struct *waiter;
        void (*exit)(void);
    #endif
    
    #ifdef CONFIG_KALLSYMS
        Elf_Sym *symtab;
        unsigned long num_symtab;
        char *strtab;
        struct module_sect_attrs *sect_attrs;
    #endif
        void *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是module
            struct 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实例。明白了模块间的依赖关系在数据结构上的表现,可以很容易地枚举出所有模块的依赖关系。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • windows下配置apache+php环境

    PHP 配置PHP7 43 Apache2 4 环境 首先讲一下电脑环境与版本 电脑 window10 X64 Apache httpd 2 4 33 o102o x64 vc14 r2 zip xff08 官网下载http www apa
  • Content-Type引发的服务端收不到HTTP请求参数的问题

    问题现象 xff1a 前端POST请求参数已经传过来了 xff0c Java后端Debug也能进到请求里 xff0c 可就是取不到请求参数 用Chrome 开发者工具可以看到请求的不同 xff1a 可以看到请求参数一个在Form Data中
  • C++中两个头文件相互引用

    这种做法很显然会出错 xff08 定义一个头文件需要先引进这个头文件自己 xff0c 编译必然报错 xff09 解决方法 xff0c 在头文件中声明另一个类 xff0c 再在源文件中引入头文件 xff0c 就像这样 xff1a a h cl
  • 安装teamveaver时 报错 未安装软件包 libqt5qml5 记录一下

    iser 64 iser 下载 sudo dpkg i teamviewer 15 11 6 amd64 deb sudo iser 的密码 xff1a 正在读取数据库 系统当前共安装有 217060 个文件和目录 正准备解包 teamvi
  • Django教务管理系统|学生选课系统(关注下载源码)

    关注即可下载源码 写在前面 采用Django框架以及MySQL数据库实现BS架构的教务管理系统 xff0c 网页界面模仿了正方软件股份有线公司开发的教务管理系统 题目 建立一个学生选课系统 编写应用程序完成系统开发 建立基本表 xff1a
  • c/c++|解线性方程组的迭代法(高斯-赛德尔迭代法)

    span class token macro property span class token directive keyword include span span class token string lt bits stdc 43
  • C++ 字符(char)转字符串(string)

    char转string 误区 无法使用to string 方法 span class token keyword char span c span class token operator 61 span span class token
  • B树和B+树

    B树 上图是一颗完整的5阶B树 xff0c 符合以下特点 xff1a 对于一个m阶B树 xff0c 每个节点最多有m个分支 xff1b 根节点且不是叶子节点则至少有2个分支 xff0c 而非根非叶节点至少有m 2 xff08 上取整 xff
  • R-Tree

    R Tree R Tree是一颗用来存储高维数据的平衡树 xff0c 它把B树的思想扩展到了多维空间 xff0c 采用了B树分割空间思想 xff0c 并在添加 删除操作时采用合并 分解节点的方法 xff0c 保证树的平衡性 数据结构 每个R
  • 【AI炼丹术】写深度学习代码的一些心得体会

    写深度学习代码的一些心得体会 体会1体会2体会3总结内容来源 一般情况下 xff0c 拿到一批数据之后 xff0c 首先会根据任务先用领域内经典的Model作为baseline跑通 xff0c 然后再在这个框架内加入自己设计的Model x
  • win10配置MMClassification+PyTorch+CUDA

    Win10配置MMClassification 依赖 Python 3 8CUDA 10 2Microsoft Visual C 43 43 14 0PyTorch 1 10 0MMCV 1 3 17MMClassification 0 1
  • 逢七过

    试题描述 相信大家都玩过这个游戏 xff0c 一群人围坐一圈 xff0c 开始喊数 xff0c 是7的倍数或者数中含有7的均要说 过 xff0c 其余的数就直接说出数的大小 为了简化问题 xff0c 我们规定 xff0c 对于下面的情况我们
  • 斐波那契数列

    试题描述 斐波那契数列指的是这样一个数列 xff1a 1 1 2 3 5 8 13 21 34 这个数列从第三项开始 xff0c 每一项都等于前两项之和 请你输出斐波那契数列的前N项 xff08 0 lt N lt 30 xff09 请用循
  • 允许并列的排名

    试题描述 在我们参加的各种竞赛中 xff0c 允许并列的排名方式是经常遇到的 例如有四名选手的成绩分别为50 80 50 30分 xff0c 则80分的选手为第一名 xff0c 50分的两名选手均为第二名 xff0c 30分的选手为第三名
  • n位水仙花数

    试题描述 n位水仙花数是指一个n位数 xff0c 它的每个位上的数字的n次幂之和等于它本身 例如 xff1a 三位水仙花数是指一个三位数 xff0c 它的每个位上的数字的3次幂之和等于它本身 xff08 例如 xff1a 13 43 53
  • 成绩的最高分问题

    试题描述 编写函数ReadScore 和FindMax xff0c 输入某班学生某门课的成绩和学号 xff08 最多不超过40人 xff09 xff0c 当输入为负值时 xff0c 表示输入结束 xff0c 用函数编程通过返回数组中最大元素
  • xcode编译静态库时:**** is not an object file (not allowed in a library)

    出现此错误 xff1a 第一步 xff1a 链接的库是否是存在的且正确的库 a 第二步 xff1a 如果还出现错误 xff0c 那么确定Xcode搜索库路径 Library search paths xff0c 是否有错误 如果在工程目录中
  • Ubuntu桥接模式下无法连接网络的问题

    新装的VMware虚拟机 xff0c 作为开发 xff0c 需要使用桥接模式 xff0c 但是一直无法正常连接网络 xff0c ifconfig一直没有IPV4地址显示 xff0c ping外网也不通 网上的方法也几乎试了个遍 xff0c
  • 黑马程序员————数组,字符串,函数,指针

    Java培训 Android培训 iOS培训 Net培训 期待与您交流 xff01 一 数组的基本概念 只能存放一种类型的数据 xff0c 比如int类型的数组 float类型的数组 里面存放的数据称为 元素 二数组的定义 1 定义 声明数
  • QT控件提升之QPushButton提升为QMenu

    当一个控件进行提升之后 xff0c 就有了新的功能 xff0c 在原来的一些特性基础上 xff0c 发生一些新的改变 QT控件提升方法 xff1a 1 需要写一个需要提升为某种功能的类 2 打开qt设计师 xff0c 在对应需要提升的控件

随机推荐

  • 【Hugging Face】Hugging Face 主要类和函数介绍

    Hugging Face 主要类和函数介绍 Hugging face是什么 xff1f 什么是自然语言处理 xff1f PipelineDatasetPipeline on GPUMetricsAutoClasses在本地保存和加载模型结论
  • 基于ubuntu server 16.04环境安装kvm虚拟机并创建windows系统

    由于项目需要 xff0c 最近在研究 kvm 虚拟机 xff0c 将这个过程中遇到的一些问题做一些记录 由于本人水平有限 xff0c 其中不妥之处还请网友们不吝赐教 1 操作环境 ubuntu server 16 04 默认的安装后没有桌面
  • Linux炫酷代码秀

    cmatrix 命令 这个很酷 xff01 黑客帝国 那种矩阵风格的动画效果 安装 sudo apt get install cmatrix 运行 cmatrix
  • keil中include 头文件循环引用问题

    在头文件中使用 ifdef和 xff03 ifndef是非常重要的 xff0c 可以防止双重定义的错误 有时候 xff0c 在b h中会include 34 a h 34 xff0c 在 34 c h 34 中会include 34 b h
  • 并查集(加入、查找、删除)

    并查集 来源洛谷 题目描述 如题 xff0c 现在有一个并查集 xff0c 你需要完成合并和查询操作 输入格式 第一行包含两个整数 N M 表示共有 N 个元素和 M 个操作 接下来 M 行 xff0c 每行包含三个整数Z i X i Y
  • Centos7查看防火墙以及端口开放情况

    1 查看防火墙状态 firewall cmd state 2 开关防火墙 systemctl start firewalld service systemctl stop firewalld service systemctl restar
  • 完美解决“当前不会命中断点,还未为文档加载任何符号”的问题

    遇到这个问题是我正在用vc2008 调试一个 C 43 43 写的 Dll xff0c dll 在编译中没有报错 xff0c 但在用VB net写的程序调用此 Dll 时 xff0c 才会报告 于 34 xxx dll 中找不到 XXX 函
  • switch 以string为条件 做判断的方法

    c 43 43 和java语言中的switch都是只接受 整型 c 语言中可以在switch中 xff0c 以字符串作为case的条件 我觉得宏定义不行 xff0c 用map尝试一下 xff0c 下面是给你一个例子 map lt strin
  • nginx那点事儿——nginx日志详解

    nginx日志 前言一 日志配置 格式二 日志格式包含的变量三 日志缓存1 缓存设置2 作用位置 四 日志切割1 切割配置文件2 日志切割原理 五 日志分析 前言 Nginx有非常灵活的日志记录模式 每个级别的配置可以有各自独立的访问日志
  • 最全详解关键路径法

    关键路径法是软考的知识点 我分析了常见的模棱两可的知识点 并进行了图解说明 现在分享给正在准备参加软考试的广大考友 01什么是关键路径法CPM 关键路径法用于在进度模型中估算项目最短工期 确定逻辑网络路径的进度灵活性大小 这种进度网络分析技
  • 【LLM】LLaMA简介:一个650亿参数的基础大型语言模型

    LLaMA简介 xff1a 一个650亿参数的基础大型语言模型 PaperSetup其他资料 作为 Meta 对开放科学承诺的一部分 xff0c 今天我们将公开发布 LLaMA 大型语言模型 Meta AI xff0c 这是一个最先进的大型
  • Cache-主存效率问题

    本文主要明确在软考中经常遇到的缓存效率问题 第零 xff0c 明确一个问题 xff1a 如果Cache不命中时 xff0c 不同的系统有不同的应对策略 一是直接从主存中拿走待取数据 xff0c 它的时间消耗仅仅是一个访问主存周期 二是把待取
  • filezilla 严重文件传输错误 550permission denied

    问题描述 xff1a FileZilla工具使用ftp账户 xff0c 密码 xff0c 端口21 xff0c 快速链接到自己搭建的外网ftp服务器 xff0c 提示登录成功 xff0c 选择本地文件 xff0c 右键文件上传 xff0c
  • ubuntu与windows互传文件的3种方法

    一般在进行编程作业的时候 xff0c 我们会采用 开发在Windows中编辑源代码 xff0c 在linux中编译 执行源代码 这往往需要需要将在Windows下编辑好的源代码上传到linux系统种进行编译 怎么来进行上传呢 xff1f 其
  • ubuntu下如何设置环境变量

    一 设置环境变量的三种方法 1 1 临时设置 export PATH 61 home yan share usr local arm 3 4 1 bin PATH 1 2 当前用户的全局设置 打开 bashrc xff0c 添加行 xff1
  • ssh免密登录设置方法

    1 前提条件 主机A xff0c 用户名为aris xff0c IP地址为192 168 1 1主机B xff0c 用户名为leon xff0c IP地址为192 168 1 2这两台主机上均安装了SSH服务器 xff0c 且已经打开ssh
  • 软考高项你想要的全在这

    2021年准备参加软考获取高级职业技术资格认证的小伙伴咱们约起吧 xff1f xff01 自软考系列文章发表之后有很多准备参加软考的小伙伴加我微信 xff0c 关注我的微博 xff0c 也有很多因此成了好朋友 xff0c 甚至是同事 自前年
  • Makefile语法及通用模板

    简介 xff1a 本文主要讲解了在开发常规项目时 xff0c 用于自动化部署生成目标文件的Makefile 对其包含的主要语法进行了讲解 xff0c 最后给出了一个项目通用的Makefile模板 xff0c 以帮助大家理解 1 Makefi
  • ubuntu镜像源的配置

    摘要 xff1a 你是否遇到过按照网上教程更改了自己的镜像源之后 xff0c 貌似还是不兼容 xff0c 许多安装包还是下不了 xff1f 其实不是他们写的教程有错误 xff0c 而是你没用根据自己使用的ubuntu的版本去正确配置镜像源
  • Linux中与“内核模块”相关的数据结构

    摘要 本文详细解释了linux中与模块相关的内核数据结构 xff0c 便于大家在学习理解内核源码或驱动编程中理解相应代码和思想 三 内核模块相关的数据结构 目录 THIS MODULE宏module结构体module use 3 1 THI