__init在Linux内核代码中意味着什么?

在Linux内核源代码中我find了这个函数:

static int __init clk_disable_unused(void) { // some code } 

在这里我不明白__init含义。

include/linux/init.h

 /* 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, eg: * * static int init_variable __initdata = 0; * static const char linux_logo[] __initconst = { 0x32, 0x36, ... }; * * Don't forget to initialize data not at file scope, ie 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". */ /* These are for everybody (although not all archs will actually discard it in modules) */ #define __init __section(.init.text) __cold notrace #define __initdata __section(.init.data) #define __initconst __section(.init.rodata) #define __exitdata __section(.exit.data) #define __exit_call __used __section(.exitcall.exit) 

这些只是macros定位到最后执行的二进制文件的特殊区域的一部分的Linux代码。 __init ,例如(或者更好的__attribute__ ((__section__ (".init.text")))这个macros扩展到)指示编译器以特殊的方式标记这个函数。 最后,链接器在二进制文件的结尾(或开始)收集带有该标记的所有函数。

当内核启动时,这个代码只运行一次(初始化)。 运行后,内核可以释放这个内存来重用它,你会看到内核消息:

释放未使用的内核内存:释放108k

要使用此function,您需要一个特殊的链接器脚本文件,告诉链接器在哪里find所有标记的function。

这演示了内核2.2及更高版本的function。 注意initcleanup函数定义的变化。 __initmacros导致init函数被丢弃,并且一旦init函数完成内置驱动程序,而不是可加载模块,则释放其内存。 如果你考虑init函数被调用的时候,这是非常有意义的。

资源

在linux / ini.h中阅读评论(和文档同时)。

你也应该知道gcc有一些特别为linux内核代码做的扩展,看起来这个macros使用了其中的一个。

__init是一个在./include/linux/init.h中定义的macros,扩展为__attribute__ ((__section__(".init.text")))

它指示编译器以特殊的方式标记这个函数。 最后,链接器在二进制文件的结尾(或开始)收集带有该标记的所有函数。 当内核启动时,这个代码只运行一次(初始化)。 运行后,内核可以释放这个内存来重用它,你会看到内核