2012-07-25 83 views

回答

29

內置驅動程序不會是加載,因此內置。它們的初始化函數被調用,當內核自行建立時驅動程序被激活。這些初始化函數在init/main.c::do_initcalls()中調用。所有初始化呼叫分類水平,這是在initcall_levels定義和include/linux/init.h

這些級別是在連接器腳本(arch/*/kernel/vmlinux.lds.*)定義實際工作中的符號。在內核編譯時,鏈接器收集標記爲module_init()或其他*_initcall()的所有函數,按級別進行分類,將所有函數放在同一級別,並創建一個類似於函數指針數組的函數。

do_initcall_level()在運行時所做的是調用數組中指針指向的每個函數。除do_initcall_level中的級別之外,沒有調用策略,但數組中的順序在鏈接時間中確定。

所以,現在你可以看到司機的啓動順序是固定在鏈接時間,但你可以做什麼?

  1. 把你的初始化函數在較高的水平,或
  2. 把你的設備驅動程序在較高位置Makefile

如果你看了上面的第一個是明確的。即)使用early_initcall(),而不是適當的。

第二個需要更多的解釋。爲什麼Makefile問題中的命令是當前內核構建系統如何工作以及連接器如何工作的原因。長話短說,構建系統將獲取obj-y中的所有對象文件並將它們鏈接在一起。它依賴於環境,但鏈接器很有可能將第一個目標文件放置在較低地址的obj-y中,因此早些時候調用該文件。

如果你只是想讓你的驅動程序比同一個目錄下的其他驅動程序更早被調用,這是最簡單的方法。

+0

感謝@Yasushi Shoji爲您提供了非常詳細的解釋! – 2012-07-26 06:49:11

+0

這是一個很好的答案! – VividD 2014-08-20 08:39:18

0

正確的模塊順序和相關性由modprobe處理,即使在initrd內也是如此。

2

depmod檢查每個模塊導出和需要的符號,並對它們進行拓撲排序,以便modprobe稍後可以用來以正確的順序加載模塊。要求你想依賴的模塊中的符號足以讓它做正確的事情。

0

最近我遇到了這個問題,我的充電器驅動程序依賴ADC驅動程序,因此在加載ADC驅動程序充電器驅動程序之前已加載並檢查在DTS文件中定義的adc phandle並且必須通過ADC驅動程序進行初始化。它通過更改驅動程序/ Makefile中模塊的順序得到解決