Linux内核两个同名struct module区分、THIS_MODULE宏解析及modpost struct访问方法
两个同名
struct module不存在运行时选择逻辑 首先要明确,这两个同名结构体从编译阶段就完全隔离,根本不存在“内核要判断用哪个”的场景:
- 位于
include/linux/module.h的结构体,是内核运行时的核心数据结构,服务所有跑在内核空间的代码:包括内核镜像本体、所有可加载的内核模块,用来存储模块的运行时元数据,比如引用计数、导出符号表、加载状态、模块依赖关系。 - 位于
scripts/mod/modpost.h的结构体,是内核构建流程里主机侧工具modpost的私有数据结构:modpost是编译阶段跑在用户态的辅助程序,用来处理模块的符号依赖、生成模块加载需要的元数据,它永远不会被编译进内核镜像,也不会和内核运行时代码产生链接关系。 - 两者的隔离程度甚至远高于普通的同文件同名结构体冲突场景:一个是编译成运行在内核空间的代码,另一个是编译成编译阶段跑在用户态的主机工具,甚至经常会出现主机架构和目标内核架构不一致的情况,完全不存在交叉引用的可能。
THIS_MODULE宏的实现逻辑解释 这段宏的判断完全靠编译期的条件分支,没有任何运行时判断:
#ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) #else #define THIS_MODULE ((struct module *)0) #endif
逐段的逻辑:
- 分支判断的依据是编译宏
MODULE:这个宏只有在编译独立可加载内核模块的代码时才会被定义,编译内核本体代码时不会开启这个宏。 - 当
MODULE宏开启(即编译内核模块)时:- 声明外部链接符号
__this_module,这个符号是模块构建流程自动生成的,指向当前模块的、由include/linux/module.h定义的struct module实例; - 此时
THIS_MODULE就是指向当前模块自身运行时元数据的指针。
- 声明外部链接符号
- 当
MODULE宏未开启(即编译内核本体)时:- 直接将
THIS_MODULE定义为空指针NULL:内核本身没有可加载模块的归属概念,传空指针完全可以满足所有需要传入struct module*类型参数的函数调用。
*注意:这段宏里引用的struct module,全程都是include/linux/module.h中的定义——所有包含export.h的内核运行时代码,都会间接引入module.h的结构体定义,根本不会接触到modpost中的同名结构体。
- 直接将
如何访问
modpost.h中定义的module结构体 这个结构体的适用场景非常有限:
- 正常的内核驱动开发、内核核心代码开发场景下,你完全不需要、也不应该访问这个结构体,它和内核运行时逻辑没有任何关系。
- 只有在修改、开发modpost构建工具本身的场景下,才可以通过在对应的工具源码中引入
scripts/mod/modpost.h头文件使用这个结构体;脱离了这个主机侧工具的编译环境,这个结构体定义就不会生效。
内容的提问来源于stack exchange,提问作者div Mi
相关产品推荐
相关产品推荐

