分类: LINUX
2015-09-10 01:12:42
43 #define __init __attribute__ ((__section__ (".init.text")))
__attribute__是什么?Linux内核代码使用了大量的GNU C扩展,以至于GNU C成为能够编译内核的唯一编译器,GNU C的这些扩展对代码优化、目标代码布局、安全检查等方面也提供了很强的支持。而__attribute__就是这些扩展中的一个,它主要被用来声明一些特 殊的属性,这些属性主要被用来指示编译器进行特定方面的优化和更仔细的代码检查。GNU C支持十几个属性,section是其中的一个,我们查看GCC的手册可以看到下面的描述
‘section ("section-name")'
Normally, the compiler places the code it generates in the `text'
section. Sometimes, however, you need additional sections, or you
need certain particular functions to appear in special sections.
The `section' attribute specifies that a function lives in a
particular section. For example, the declaration:
extern void foobar (void) __attribute__ ((section ("bar")));
puts the function ‘foobar' in the ‘bar' section.
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.
通常编译器将函数放在.text节,变量放在.data或.bss节,使用section属性,可以让编译器将函数或变量放在指定的节中。那么前面 对__init的定义便表示将它修饰的代码放在.init.text节。连接器可以把相同节的代码或数据安排在一起,比如__init修饰的所有代码都会 被放在.init.text节里,初始化结束后就可以释放这部分内存。
问题可以到此为止,也可以更深入,即内核又是如何调用到这些__init修饰的初始化函数?要回答这个问题,还需要回顾一下subsys_initcall宏,它也在include/linux/init.h里定义
125 #define subsys_initcall(fn) __define_initcall("4",fn,4)
这里又出现了一个宏__define_initcall,它用于将指定的函数指针fn放到initcall.init节里 而对于具体的subsys_initcall宏,则是把fn放到.initcall.init的子节.initcall4.init里。要弄清 楚.initcall.init、.init.text和.initcall4.init这样的东东,我们还需要了解一点内核可执行文件相关的概念。
3,内核可执行文件