天天看點

Linux驅動加載順序

Linux核心為不同驅動的加載順序對應不同的優先級,定義了一些宏:

include\linux\init.h

#define pure_initcall(fn)   __define_initcall("0",fn,1)

#define core_initcall(fn)   __define_initcall("1",fn,1)

#define core_initcall_sync(fn)   __define_initcall("1s",fn,1s)

#define postcore_initcall(fn)   __define_initcall("2",fn,2)

#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)

#define arch_initcall(fn)   __define_initcall("3",fn,3)

#define arch_initcall_sync(fn)   __define_initcall("3s",fn,3s)

#define subsys_initcall(fn)   __define_initcall("4",fn,4)

#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)

#define fs_initcall(fn)    __define_initcall("5",fn,5)

#define fs_initcall_sync(fn)   __define_initcall("5s",fn,5s)

#define rootfs_initcall(fn)   __define_initcall("rootfs",fn,rootfs)

#define device_initcall(fn)   __define_initcall("6",fn,6)

#define device_initcall_sync(fn) __define_initcall("6s",fn,6s)

#define late_initcall(fn)   __define_initcall("7",fn,7)

#define late_initcall_sync(fn)   __define_initcall("7s",fn,7s)

#define __initcall(fn) device_initcall(fn)

把自己的驅動的函數名用這些宏去定義之後,

就會對應不同的加載時候的優先級。

其中,我們寫驅動中所用到的module_init對應的是

#define module_init(x) __initcall(x);

#define __initcall(fn) device_initcall(fn)

是以,驅動對應的加載的優先級為6

在上面的不同的優先級中,

數字越小,優先級越高。

同一等級的優先級的驅動,加載順序是連結過程決定的,結果是不确定的,我們無法去手動設定誰先誰後。

不同等級的驅動加載的順序是先優先級高,後優先級低,這是可以确定的。

是以,像我們之前在驅動中用:

module_init(i2c_dev_init);

module_init(as352x_afe_init);

module_init(as352x_afe_i2c_init);

module_init(enc28j60_init);

是以,大家都是同一個優先級去初始化,

最後這些驅動加載的順序,可以檢視在根目錄下,

生成的system.map:

研究mx53開發闆上sgtl5000的音頻驅動時,發現有sgtl5000_i2c_driver和

imx_3stack_sgtl5000_audio_driver兩個驅動,前面的驅動總是在前面執行,

但是好像二者都是用的module_init,那麼是什麼地方決定了它的執行順序呢?

找到makefile内容如下:

snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o

obj-$(CONFIG_SND_SOC) += snd-soc-core.o

obj-$(CONFIG_SND_SOC) += codecs/

obj-$(CONFIG_SND_SOC) += fsl/

obj-$(CONFIG_SND_SOC)   += imx/

obj-$(CONFIG_SND_SOC) += mxs/

sgtl5000_i2c_driver驅動是在codecs目錄下,imx_3stack_sgtl5000_audio_driver

是在imx目錄下,難道與編譯順序有關?

調整makefile中的順序後,再編譯運作,果然,二者的執行順序變過來了。

看來如果使用同一級别的初始化,執行順序與編譯順序有關。

繼續閱讀