天天看點

linux網絡驅動初始化module_init函數跟蹤

module_init函數對做驅動開發的同學是在太熟悉了,但是關于底層的知識可能大家有些不願去了解,而其中知識對于網絡初始化也直接相關,是以先将此分享。

在驅動程式中有module_init函數,該函數定義在檔案

<b>include/linux/module.h</b><b>中</b><b>(</b><b>以前好像在</b><b>include/linux/init.h</b><b>中</b><b>)</b><b>,如下。</b>

#define module_init(x)  __initcall(x);

       該函數是驅動初始化函數入口,在核心啟動或子產品加載時候執行。每個子產品一個module_init函數。

       不過module_init隻是個宏,聲明為__initcall,又聲明在<b>arch/um/include/shared/init.h</b><b>檔案中。</b>

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

#define __define_initcall(level,fn) \

        static initcall_t __initcall_##fn __used \

        __attribute__((__section__(".initcall" level ".init"))) = fn

__define_initcall(level,fn)這個宏的作用就是将初始化函數放在".initcall"

level ".init"中。

       其中##表示連接配接的意思,__initcall_##fn##id

為__initcall_fn_id

如果fn = test_init,id = 6時,__initcall_##fn##id 為 __initcall_test_init6。(如果是#是字元串化的意思,#id 為“id”,id=6時,#id 為“6”。)

通過__attribute__(__section__)設定函數屬性,也就是将test_init放在.initcall6.init段中。這個涉及連接配接的腳本。

       這些宏用于标記一些初始化函數或初始化數。核心在初始化階段使用這些函數并在之後釋放記憶體資源。

       平台裝置的初始化(注冊)用arch_initcall()調用,initcall的level為3;驅動的注冊用module_init調用,即device_initcall,它的initcall 的level為6。

#define pure_initcall(fn)              

__define_initcall(fn, 0)                                                    

#define core_initcall(fn)              

__define_initcall(fn, 1)

#define core_initcall_sync(fn)         

__define_initcall(fn, 1s)

#define postcore_initcall(fn)          

__define_initcall(fn, 2)

#define postcore_initcall_sync(fn)     

__define_initcall(fn, 2s)

#define arch_initcall(fn)              

__define_initcall(fn, 3)

#define arch_initcall_sync(fn)         

__define_initcall(fn, 3s)

#define subsys_initcall(fn)            

__define_initcall(fn, 4)

#define subsys_initcall_sync(fn)       

__define_initcall(fn, 4s)

#define fs_initcall(fn)                

__define_initcall(fn, 5)

#define fs_initcall_sync(fn)           

__define_initcall(fn, 5s)

#define rootfs_initcall(fn)            

__define_initcall(fn, rootfs)

#define device_initcall(fn)            

__define_initcall(fn, 6)

#define device_initcall_sync(fn)       

__define_initcall(fn, 6s)

#define late_initcall(fn)              

__define_initcall(fn, 7)

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

然後會調用do_initcalls函數調用通過xxx_initcall注冊的各種函數,優先級高的先執行。是以通過module_init注冊的函數在kernel啟動的時候會被順序執行。

繼續閱讀