__init 在 Linux 内核代码中是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8832114/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does __init mean in the Linux kernel code?
提问by Jeegar Patel
In the Linux kernel source code I found this function:
在 Linux 内核源代码中我发现了这个函数:
static int __init clk_disable_unused(void)
{
// some code
}
Here I can not understand what does __init
means.
在这里我无法理解是什么__init
意思。
采纳答案by Sangeeth Saravanaraj
include/linux/init.h
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, e.g.:
*
* static int init_variable __initdata = 0;
* static const char linux_logo[] __initconst = { 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".
*/
/* 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)
回答by sashoalm
These are only macros to locate some parts of the linux code into special
areas in the final executing binary.
__init
, for example (or better the __attribute__ ((__section__
(".init.text")))
this macro expands to) instructs the compiler to mark this
function in a special way. At the end the linker collects all functions
with this mark at the end (or beginning) of the binary file.
这些只是用于将 linux 代码的某些部分定位到最终执行二进制文件中的特殊区域的宏。
__init
,例如(或更好的__attribute__ ((__section__
(".init.text")))
this 宏扩展到)指示编译器以特殊方式标记此函数。最后,链接器收集二进制文件末尾(或开头)带有此标记的所有函数。
When the kernel starts, this code runs only once (initialization). After it runs, the kernel can free this memory to reuse it and you will see the kernel message:
当内核启动时,这段代码只运行一次(初始化)。运行后,内核可以释放此内存以重新使用它,您将看到内核消息:
Freeing unused kernel memory: 108k freed
释放未使用的内核内存:释放 108k
To use this feature, you need a special linker script file, that tells the linker where to locate all the marked functions.
要使用此功能,您需要一个特殊的链接器脚本文件,它告诉链接器在哪里可以找到所有标记的函数。
回答by elmo
Read comment (and docs at the same time) in linux/init.h.
在linux/init.h 中阅读评论(同时阅读文档)。
You should also know that gcc has some extensions made specially for linux kernel code and it looks like this macro uses one of them.
你还应该知道 gcc 有一些专门为 linux 内核代码制作的扩展,看起来这个宏使用了其中之一。
回答by Geoffroy
__init is a macro defined in ./include/linux/init.h which expands to __attribute__ ((__section__(".init.text")))
.
__init 是 ./include/linux/init.h 中定义的宏,它扩展为__attribute__ ((__section__(".init.text")))
.
It instructs the compiler to mark this function in a special way. At the end the linker collects all functions with this mark at the end (or begin) of the binary file. When the kernel starts, this code runs only once (initialization). After it runs, the kernel can free this memory to reuse it and you will see the kernel
它指示编译器以特殊方式标记此函数。最后,链接器收集二进制文件末尾(或开头)带有此标记的所有函数。当内核启动时,这段代码只运行一次(初始化)。它运行后,内核可以释放这块内存以重用它,您将看到内核
回答by naveen kumar r
This demonstrates a feature of kernel 2.2 and later. Notice the change in the definitions of the init
and cleanup
functions. The __init
macro causes the init
function to be discarded and its memory freed once the init
function finishes for built-in drivers, but not loadable modules. If you think about when the init
function is invoked, this makes perfect sense.
这演示了内核 2.2 及更高版本的功能。注意init
和cleanup
函数定义的变化。该__init
宏导致的init
被丢弃的功能和它的内存一旦释放init
功能完成对内置的驱动程序,但没有可加载模块。如果您考虑init
调用函数的时间,这是完全合理的。
回答by Nnaik
When you compile and insert a Linux kernel module into the kernel the first function to be executed is __init.This function is basically used to perform initialization before you perform the main operations like registering a device driver etc, There is another function with the opposite effect __exit which is called when you remove the kernel module which is again used to remove some registered device or any such similar function
当你编译并插入一个 Linux 内核模块到内核中时,首先要执行的函数是 __init。这个函数基本上是用来在你执行注册设备驱动程序等主要操作之前进行初始化,还有另一个函数具有相反的效果__exit 删除内核模块时调用,该模块再次用于删除某些已注册的设备或任何此类类似功能