__init and __exit

翻译 2006年05月17日 13:47:00
The __init and __exit declarations are special kernel macros designed to tell the kernel to flag these
functions for special handling in cases where they are compiled in statically rather than included as
parts of modules.
 The __init declaration allows the kernel to reclaim the space used by initialization
functions, while the __exit declaration tells the kernel to just plain ignore the function altogether. If
you’re only going to write your device driver as a module, with no possibility that it will be included
statically, it is perfectly safe to leave these special declarations out.

1 __init:

/* These macros are used to mark some functions or
 * initialized data (doesn't apply to uninitialized data)
 * as `initialization' functions. The kernel can take this
 * as hint that the function is used only during the initialization
 * phase and free up used memory resources after
 *
 * Usage:
 * For functions:
 *

 * You should add __init immediately before the function name, like:
 *
 * static void __init initme(int x, int y)
 * {
 *    extern int z; z = x * y;
 * }
 *
 * If the function has a prototype somewhere, you can also add
 * __init between closing brace of the prototype and semicolon:
 *
 * extern int initialize_foobar_device(int, int, int) __init;
 *
 * For initialized data:
 * You should insert __initdata between the variable name and equal
 * sign followed by value, e.g.:
 *
 * static int init_variable __initdata = 0;
 * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
 *
 * Don't forget to initialize data not at file scope, i.e. within a function,
 * as gcc otherwise puts the data into the bss section and not into the init
 * section.
 *
 * Also note, that this data cannot be "const".

其主要作用是初始化.

2)module_init:
/**
 * module_init() - driver initialization entry point
 * @x: function to be run at kernel boot time or module insertion
 *
 * module_init() will add the driver initialization routine in
 * the "__initcall.int" code segment if the driver is checked as
 * "y" or static, or else it will wrap the driver initialization
 * routine with init_module() which is used by insmod and
 * modprobe when the driver is used as a module.
 */
/**
 * module_exit() - driver exit entry point
 * @x: function to be run when driver is removed
 *
 * module_exit() will wrap the driver clean-up code
 * with cleanup_module() when used with rmmod when
 * the driver is a module.  If the driver is statically
 * compiled into the kernel, module_exit() has no effect.
 */

注意一下initcleanup这两个函数定义的变化。__init宏使内建模块中的init函数在执行完成后释放掉,不过可装载的模块不受影响。如果你关心init函数什么时候调用,这一点是很有用的。

还有个__initdata,和__init的作用基本上一样,不过它是针对变量而不是函数的。

__exit宏会使那些内建到内核的模块省略掉cleanup函数,不过和__init一样,对loadable模块没影响。再说一遍,如果你关心cleanup运行的时机,这是重要的。Built-in的驱动不需要cleanup,反正它们也不能退出,不过loadable式的模块显然是需要一个的。

这些宏都定义在linux/init.h中,它们会释放内核的内存。你启动内核的时候会看到一些诸如Freeing unused kernel memory:236k freed,之类的信息,这多半就是它们干的。

_init修饰,以及.init开头的节,在模块插入完毕运行之后,这一部分
的内存空间会被释放,因此dump的时候这些信息是无法得到的。


内核模块至少要有两个函数:一个叫做init_module()的“start”初始化函数供insmod的时候调用,一个叫clean_module()的“end”清除函数供rmmod的时候调用。实际上,2.3.13之后的内核这两个函数不再必须使用这两个名字了。你给它们起什么名字都可以,2.3节我会将具体怎么做。给这两个函数自己起名字其实是个挺好的主意,不过还是有很多人使用init_moduleclean_module函数。L

很经典的,init_module函数会向内核注册一些什么东西,或者用自己的代码替换内核的一些什么功能(通常它们做点什么动作之后还是会调用原来的函数)。而clean_module函数则会把init_module干的事情做个了结,以便安全的卸载模块。

最后,每个内核模块都要包含linux/module.h。仅仅为了KERL_ALERT2.1.1节会讲到它)还需要在这个例子中包括linux/kernel.h



__init和__exit宏的作用

__init和__exit宏的作用 内核的部分函数带有__init和__exit宏,负责“初始化”和“清理收尾”该函数。如果该模块被编译进内核,而不是动态加载。宏 __init的使用会在初始化完...
  • zhenwenxian
  • zhenwenxian
  • 2013年02月02日 07:50
  • 4073

内核中_init,_exit中的作用

__init, __initdata等属性标志,是要把这种属性的代码放入目标文件的.init.text节,数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链...
  • pugu12
  • pugu12
  • 2015年04月29日 09:55
  • 301

内核中_init,_exit中的作用

文章转自:http://blog.csdn.net/maopig/article/details/7409870 __init, __initdata等属性标志,是要把这种属性的代码放入目标文件的....
  • dabusideqiang
  • dabusideqiang
  • 2014年08月25日 21:56
  • 271

内核中_init,_exit中的作用

__init, __initdata等属性标志,是要把这种属性的代码放入目标文件的.init.text节,数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链...
  • chunlovenan
  • chunlovenan
  • 2014年07月31日 20:16
  • 793

内核中_init,_exit中的作用

__init, __initdata等属性标志,是要把这种属性的代码放入目标文件的.init.text节,数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链...
  • flydownup
  • flydownup
  • 2015年01月26日 16:23
  • 136

内核中_init,_exit中的作用

__init, __initdata等属性标志,是要把这种属性的代码放入目标文件的.init.text节,数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链...
  • lee244868149
  • lee244868149
  • 2017年03月25日 21:32
  • 143

linux设备驱动之__init和__exit

像你写C程序需要包含C库的头文件那样,Linux内核编程也需要包含Kernel头文件,大多的Linux驱动程序需要包含下面三个头文件:  #include #include #inc...
  • CD_keanu
  • CD_keanu
  • 2013年04月26日 13:43
  • 673

Android7.0 init进程源码分析

主要对Android 7.0中,init进程的源码进行分析。
  • Gaugamela
  • Gaugamela
  • 2016年08月07日 20:07
  • 7673

exit函数和_exit函数的区别

高级I/O函数在Linux标准库中,有一套称为高级I/O函数,例如我们所熟知的printf,fopen,fread,fwrite都在此列,他们也被称为缓冲I/O。其特征是对应每一个打开的文件,都存在一...
  • bit_clearoff
  • bit_clearoff
  • 2017年01月14日 10:51
  • 1414

exit()与_exit()函数的区别

注:exit()就是退出,传入的参数是程序退出时的状态码,0表示正常退出,其他表示非正常退出,一般都用-1或者1,标准C里有EXIT_SUCCESS和EXIT_FAILURE两个宏,用exit(EXI...
  • zz709196484
  • zz709196484
  • 2017年01月29日 00:47
  • 468
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:__init and __exit
举报原因:
原因补充:

(最多只允许输入30个字)