Linux核心驅動程式初始化順序的調整(轉)

ba發表於2007-08-16
Linux核心驅動程式初始化順序的調整(轉)[@more@]今天在做一個驅動的時候要用到另一個驅動(I2C)提供的API,在核心初始化時碰到了一個依賴問題。
我的驅動在I2C初始化之前就執行起來了,而這時I2C提供的API還處於不可用狀態。查了很多資料,網上有人說所有使用module_init這個宏的驅動程式的起動順序都是不確定的(我沒有查到權威的資料)。後來在linuxforum上看到一張帖子,這裡面講了一下這個問題:

所有的__init函式在區段.initcall.init中還儲存了一份函式指標,
在初始化時核心會透過這些函式指標呼叫這些__init函式指標,
並在整個初始化完成後,釋放整個init區段(包括.init.text,.initcall.init等),

注意,這些函式在核心初始化過程中的呼叫順序只和這裡的函式指標的順序有關,
和1)中所述的這些函式本身在.init.text區段中的順序無關。

在2.4核心中,這些函式指標的順序也是和連結的順序有關的,是不確定的。

在2.6核心中,initcall.init區段又分成7個子區段,分別是
.initcall1.init
.initcall2.init
.initcall3.init
.initcall4.init
.initcall5.init
.initcall6.init
.initcall7.init

當需要把函式fn放到.initcall1.init區段時,只要宣告
core_initcall(fn);
即可。

其他的各個區段的定義方法分別是:
core_initcall(fn) ---&gt.initcall1.init
postcore_initcall(fn) ---&gt.initcall2.init
arch_initcall(fn) ---&gt.initcall3.init
subsys_initcall(fn) ---&gt.initcall4.init
fs_initcall(fn) ---&gt.initcall5.init
device_initcall(fn) ---&gt.initcall6.init
late_initcall(fn) ---&gt.initcall7.init

而與2.4相容的initcall(fn)則等價於device_initcall(fn)。

各個子區段之間的順序是確定的,即先呼叫.initcall1.init中的函式指標
再呼叫.initcall2.init中的函式指標,等等。
而在每個子區段中的函式指標的順序是和連結順序相關的,是不確定的。

在核心中,不同的init函式被放在不同的子區段中,因此也就決定了它們的呼叫順序。
這樣也就解決了一些init函式之間必須保證一定的呼叫順序的問題。

按照include/linux/init.h檔案所寫的,我在驅動裡償試了這樣兩種方式:
__define_initcall("7", fn);
late_initcall(fn);
都可以把我的驅動調整到最後呼叫。實際上上面兩個是一回事:
#define late_initcall(fn) __define_initcall("7", fn)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-960602/,如需轉載,請註明出處,否則將追究法律責任。

相關文章