Linux 内核模块中的 module_init 和 init_module 有什么区别

作者:编程家 分类: linux 时间:2025-06-28

在 Linux 内核模块中,有两个常用的宏:module_init 和 init_module,它们在内核模块的初始化过程中发挥着重要的作用。尽管它们的功能相似,但它们在使用方式和一些细节上存在一些区别。

module_init 宏

module_init 宏是 Linux 内核提供的一个宏,用于指定内核模块初始化时调用的函数。这个宏将函数标记为模块的入口点,并在内核加载模块时被调用。这个宏的定义如下:

c

#define module_init(initfn) __initcall(initfn);

其中,initfn 是我们定义的初始化函数的名称。

init_module 函数

init_module 函数是 Linux 内核中的一个函数,用于初始化内核模块。当内核加载模块时,会调用该函数进行初始化。init_module 函数的定义如下:

c

int init_module(void)

{

// 模块的初始化代码

return 0;

}

在这个函数中,我们可以编写模块的初始化代码。如果初始化成功,可以返回 0,否则返回一个负数作为错误码。

两者的区别

虽然 module_init 和 init_module 都可以用于内核模块的初始化,但它们在使用方式和一些细节上存在一些区别。

1. module_init 宏是一个宏定义,用于指定初始化函数,在编译时展开,而 init_module 是一个函数,在运行时被调用。

2. module_init 宏必须在模块源代码中使用,用于指定模块的入口点函数;而 init_module 函数是模块源代码中的一个函数,用于实际的模块初始化。

3. module_init 宏只能指定一个初始化函数,而 init_module 函数可以包含多个初始化操作。

4. 当模块被加载时,module_init 宏指定的函数会被调用,而 init_module 函数会在 module_init 宏指定的函数之后被调用。

示例代码

下面是一个简单的示例代码,展示了 module_init 宏和 init_module 函数的用法:

c

#include

#include

static int __init my_module_init(void)

{

printk(KERN_INFO "Hello, module_init!\n");

return 0;

}

static void __exit my_module_exit(void)

{

printk(KERN_INFO "Goodbye, module_exit!\n");

}

module_init(my_module_init);

module_exit(my_module_exit);

MODULE_LICENSE("GPL");

在这个示例中,my_module_init 函数被 module_init 宏指定为模块的入口点函数。当模块被加载时,会调用 my_module_init 函数进行初始化。同样地,my_module_exit 函数被 module_exit 宏指定为模块的退出点函数,在模块被卸载时会调用。

在 Linux 内核模块中,module_init 宏和 init_module 函数都是用于指定模块的初始化函数。它们的区别在于使用方式、语法形式和调用顺序等细节。合理地使用这两个宏和函数,可以为内核模块的初始化和退出提供便利。