视频选集

module_init 是 Linux 内核中用于定义模块初始化函数的关键宏,它在驱动模块开发中扮演着核心角色。下面我将从多个方面详细介绍这个宏。
  1. 基本定义和作用
    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)));
  1. 工作原理
    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 表示失败

  1. 初始化函数的编写规范
    一个典型的模块初始化函数应该:
    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 等打印函数输出调试信息

  1. 不同类型模块的初始化
    4.1 可加载模块
    对于可加载模块(.ko 文件),module_init 定义的函数会在 insmod 或 modprobe 时被调用。
    4.2 内置模块
    对于编译进内核的模块(built-in),module_init 的语义稍有不同。这些初始化函数会被收集到一个特殊的段中,在内核启动时按照特定顺序调用。
  2. 初始化级别
    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)