视频选集

module_init 是 Linux 内核中用于定义模块初始化函数的关键宏,它在驱动模块开发中扮演着核心角色。下面我将从多个方面详细介绍这个宏。
- 基本定义和作用
module_init 宏定义在 include/linux/init.h 中,其主要作用是指定模块的初始化函数,即当模块被加载时需要执行的函数。
c
复制
下载
define module_init(initfn) \
static inline initcall_t __maybe_unused __inittest(void) \
{ return initfn; } \
int init_module(void) __attribute__((alias(#initfn)));
- 工作原理
2.1 宏展开示例
假设我们有如下代码:
c
复制
下载
module_init(my_init_function);
宏展开后实际上会生成:
一个用于编译时检查的测试函数 __inittest
将 init_module 作为 my_init_function 的别名
2.2 实际执行流程
当使用 insmod 加载模块时,内核会查找并调用 init_module 函数
由于 init_module 是 my_init_function 的别名,实际执行的是你的初始化函数
初始化函数返回 0 表示成功,非 0 表示失败
- 初始化函数的编写规范
一个典型的模块初始化函数应该:
c
复制
下载
static int __init my_init_function(void)
{
/* 初始化代码 */
pr_info("Module initialized\n");
return 0;
}
module_init(my_init_function);
关键点:
使用 __init 宏标记,表示这个函数只在初始化时使用,之后可以释放其内存
返回类型为 int
成功返回 0,失败返回负的错误码
通常使用 pr_info 等打印函数输出调试信息
- 不同类型模块的初始化
4.1 可加载模块
对于可加载模块(.ko 文件),module_init 定义的函数会在 insmod 或 modprobe 时被调用。
4.2 内置模块
对于编译进内核的模块(built-in),module_init 的语义稍有不同。这些初始化函数会被收集到一个特殊的段中,在内核启动时按照特定顺序调用。 - 初始化级别
Linux 内核定义了多个初始化级别,module_init 默认对应 device_initcall 级别(级别6):
c
复制
下载
define device_initcall(fn) __define_initcall(fn, 6)
其他初始化级别包括:
pure_initcall (0)
core_initcall (1)
postcore_initcall (2)
arch_initcall (3)
subsys_initcall (4)
fs_initcall (5)
device_initcall (6)
late_initcall (7)