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

相關文章
相關標籤/搜索