购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.3
模块加载函数

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

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

1static int _ _init initialization_function(void)
2{      
3    /* 初始化代码 */
4}
5module_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这个区段内。

#def ine _ _init    _ _attribute_ _ ((_ _section_ _ (".init.text")))

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

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

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);
点击中间区域
呼出菜单
上一章
目录
下一章
×