android源码分析--从logger内核驱动开始

<p>logger的驱动程序为文件logger.c, 位于内核driver/staging/android目录.</p><p>从最后一行<code>device_initcall</code>(<code>logger_init</code>)入口, 内核在启动时调用<code>logger_init</code>函数.</p><p>device_initcall是在内核include/linux/init.h中定义的宏, 其临近有多个如xxx_initcall的定义.根据init.h中定义, 在配置为非module的驱动中, xxx_initcall最终都是#define_initcall(level, fn, id), 其中level决定在内核启动过程当中调用优先级,以下:<br /> </p><pre> <code>#define device_initcall(fn) __define_initcall("6",fn,6) </code> </pre><p>在配置为module的驱动中, xxx_initcall定义为`module_init`.<br /> </p><pre> <code>#define device_initcall(fn) module_init(fn) </code> </pre><p>注意配置为非module模块时, init.h中一样定义了`module_init`宏, 可是有以下定义:<br /> </p><pre> <code>#define __initcall(fn) device_initcall(fn) #define module_init(x) __initcall(x) </code> </pre><p>从Kconfig配置可知, logger驱动可配置为内置模块或可卸载模块, 而binder和ashm模块只能配置为内置模块.<br />关于__define_initcall的解释能够参考<a href="http://blog.csdn.net/zyhorse2010/article/details/6454879">这篇</a>文章, 或者参考linux内核分析或linux驱动开发的相关书籍.摘录修改部份内容:<br />宏定义__define_initcall(level,fn, id)对于内核的初始化很重要,他指示编译器在编译的时候,将一系列初始化函数的起始地址值按照必定的顺序放在一个section中。在内核初始化段,do_initcalls() 将按顺序从该section中以函数指针的形式取出这些函数的起始地址,来依次完成相应的初始化。<br /> </p><pre> <code>#define __define_initcall(level,fn,id) \ static initcall_t __initcall_##fn##id __used \ __attribute__((__section__(".initcall" level ".init"))) = fn其中 initcall_t 是个函数指针类型: </code> </pre><p> </p><pre> <code>typedef int (*initcall_t)(void); </code> </pre><p>而属性 __attribute__((__section__())) 则表示把对象放在一个这个由括号中的名称所指代的section中。因此这个宏定义的的含义是:</p><p>1) 声明一个名称为__initcall_##fn##id的函数指针(其中##表示替换链接,);</p><p>2) 将这个函数指针初始化为fn;</p><p>3) 编译的时候须要把这个函数指针变量放置到名称为 ".initcall" level ".init"的section中(好比level="1",表明这个section的名称是 ".initcall1.init")。</p>linux

相关文章
相关标签/搜索