第四章Linux内核模块之三(模块加载函数)

4.3 模块加载函数

Linux内核模块加载函数一般以__init标识声明,典型的模块加载函数的形式如代码清单4.2所示。

代码清单4.2 内核模块加载函数

static int _ _init initialization_function(void)
{

     /* 初始化代码 */

    return 0; //初始化成功

 }

 module_init(initialization_function);

模块加载函数以“module_init(函数名)”的形式被指定。它返回整型值,若初始化成功,应返回0。而在初始化失败时,应该返回错误编码。在Linux内核里,错误编码是一个接近于0的负值,在<linux/errno.h>中定义,包含-ENODEV、-ENOMEM之类的符号值。总是返回相应的错误编码是种非常好的习惯,因为只有这样,用户程序才可以利用perror等方法把它们转换成有意义的错误信息字符串。

在Linux内核中,可以使用request_module(const char*fmt,…)函数加载内核模块,可以通过调用下列代码:request_module(module_name);灵活地加载其他内核模块。

在Linux中,所有标识为__init的函数如果直接编译进入内核,成为内核镜像的一部分,在连接的时候都会放在.init.text这个区段内。

#define _ _init        _ _attribute_ _ ((_ _section_ _ (".init.text")))

所有的__init函数在区段.initcall.init中还保存了一份函数指针,在初始化时内核会通过这些函数指针调用这些__init函数,在初始化完成后,释放init区段(包括.init.text、.initcall.init等)的内存

除了函数以外,数据也可以被定义为__initdata,对于只是初始化阶段需要的数据,内核在初始化完后,也可以释放它们占用的内存。例如,下面的代码将hello_data定义为__initdata:

#include <linux/init.h> 
#include <linux/module.h>

static int hello_data __initdata = 1;

static int __init hello_init(void)
{
     printk(KERN_INFO "Hello, world %d\n", hello_data);
     return 0;
}
module_init(hello_init);
static void __exit hello_exit(void)
{
    printk(KERN_INFO "Goodbye, world\n");
}
module_exit(hello_exit);









猜你喜欢

转载自blog.csdn.net/xiezhi123456/article/details/80310081