在kernel中有很多__init,这个东东到底是何方神圣捏?且听小生我一一道来。 下面是其定义: file:/include/linux/init.h 43 #define __init __attribute__ ((__section__ (".init.text"))) __cold 44 #define __initdata __attribute__ ((__section__ (".init.data"))) 45 #define __exitdata __attribute__ ((__section__(".exit.data"))) 46 #define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) 也许你会问那 __attribute__ ((__section__ (".init.text"))) __cold是什么东东阿? 且看 info gcc C Extensions Attribute Syntax section ("SECTION-NAME")' Normally, the compiler places the objects it generates in sections like `data' and `bss'. Sometimes, however, you need additional sections, or you need certain particular variables to appear in special sections, for example to map to special hardware. The `section' attribute specifies that a variable (or function) lives in a particular section. For example, this small program uses several specific section names: struct duart a __attribute__ ((section ("DUART_A"))) = { 0 }; struct duart b __attribute__ ((section ("DUART_B"))) = { 0 }; char stack[10000] __attribute__ ((section ("STACK"))) = { 0 }; int init_data __attribute__ ((section ("INITDATA"))) = 0;
/* Turn on the serial ports */ init_duart (&a); init_duart (&b); }
Use the `section' attribute with an _initialized_ definition of a _global_ variable, as shown in the example. GCC issues a warning and otherwise ignores the `section' attribute in uninitialized variable declarations.
You may only use the `section' attribute with a fully initialized global definition because of the way linkers work. The linker requires each object be defined once, with the exception that uninitialized variables tentatively go in the `common' (or `bss') section and can be multiply "defined". You can force a variable to be initialized with the `-fno-common' flag or the `nocommon' attribute.
Some file formats do not support arbitrary sections so the `section' attribute is not available on all platforms. If you need to map the entire contents of a module to a particular section, consider using the facilities of the linker instead. 简单来说是指示gcc把标记的数据或者函数放到指定sector。 linux中把一些启动及初始化时候用的数据用__init标识,然后在适当的时候把它们释放,回收内存。 说到这个__init,就不能不说module_init,subsys_initcall。 在init.h中我们能够找到 #define subsys_initcall(fn) __define_initcall("4",fn,4) 又是一个宏定义,简直是无极中的圆环套圆环之城阿。 file:/include/linux/init.h 100 /* initcalls are now grouped by functionality into separate 101 * subsections. Ordering inside the subsections is determined 102 * by link order. 103 * For backwards compatibility, initcall() puts the call in 104 * the device init subsection. 105 * 106 * The `id' arg to __define_initcall() is needed so that multiple initcalls 107 * can point at the same handler without causing duplicate-symbol build errors. 108 */ 109 110 #define __define_initcall(level,fn,id) \ 111 static initcall_t __initcall_##fn##id __attribute_used__ \ 112 __attribute__((__section__(".initcall" level ".init"))) = fn