網絡模塊初始化

初始化相關的文件

include/linux/init.h  初始化相關的宏定義

include/asm-generic/vmlinux.lds.h  編譯鏈接相關的宏定義

init/main.c  啓動時的高級初始化

net/core/dev.c  網絡設備註冊、輸入和輸出等接口

drivers/net/e100.c  e100驅動程序

初始化函數調用關係


對模塊的初始化,一般通過module_init()宏來登記初始化函數,設備驅動程序可以靜態編譯到內核,也可以作爲一個內核模塊動態加載和卸載。這兩種方法初始化過程是不一樣的。而module_init()宏可以自動根據編譯條件來選擇初始化的方法。

靜態編譯條件下的module_init()宏定義

includle/linux/init.h

  1. typedef int (*initcall_t)(void);
  2. #define __define_initcall(level,fn,id) \
  3. static initcall_t __initcall_##fn##id __used \
  4. __attribute__((__section__(".initcall" level ".init"))) = fn
  5. #define device_initcall(fn) __define_initcall("6",fn,6)
  6. #define __initcall(fn) device_initcall(fn)
  7. #define module_init(x) __initcall(x);
include/asm-generic/vmlinux.lds.h

  1. #define INITCALLS \
  2. *(.initcallearly.init) \
  3. VMLINUX_SYMBOL(__early_initcall_end) = .; \
  4. *(.initcall0.init) \
  5. *(.initcall0s.init) \
  6. *(.initcall1.init) \
  7. *(.initcall1s.init) \
  8. *(.initcall2.init) \
  9. *(.initcall2s.init) \
  10. *(.initcall3.init) \
  11. *(.initcall3s.init) \
  12. *(.initcall4.init) \
  13. *(.initcall4s.init) \
  14. *(.initcall5.init) \
  15. *(.initcall5s.init) \
  16. *(.initcallrootfs.init) \
  17. *(.initcall6.init) \
  18. *(.initcall6s.init) \
  19. *(.initcall7.init) \
  20. *(.initcall7s.init)
  21. #define INIT_CALLS \
  22. VMLINUX_SYMBOL(__initcall_start) = .; \
  23. INITCALLS \
  24. VMLINUX_SYMBOL(__initcall_end) = .;
init/main.c

  1. static void __init do_initcalls(void)
  2. {
  3. initcall_t *call;
  4. for (call = __early_initcall_end; call < __initcall_end; call++)
  5. do_one_initcall(*call);
  6. /* Make sure there is no pending stuff from the initcall sequence */
  7. flush_scheduled_work();
  8. }
模塊加載函數的module_init()宏定義

  1. #define module_init(initfn) \
  2. static inline initcall_t __inittest(void) \
  3. { return initfn; } \
  4. int init_module(void) __attribute__((alias(#initfn)));

module_init(x)的實現在模塊中定義一個別名爲init_module的x函數。作爲能動態加載的模塊,如需初始化,Linux規定初始化接口必須爲init_module,模塊被加載時,init_module()系統調用會根據x得到初始化函數的地址,並調用。





修飾函數的宏

宏                 使用宏的函數說明

__init             啓動時初始化函數,在啓動階段執行,通常只執行一次。後期不再需要,這種函數在初始                    化完成後被從內存中清除

__exit             和__init匹配,相關內核組件卸載時調用,常用於module_exit所修飾的函數

core_initcall

postcore_initcall

arch_initcall

subsys_initcall

fs_initcall        用於標記啓動時需要執行的初始化函數

device_initcall

late_initcall

__initcall         device_initcall的別名

__exitcall         標識退出函數,相關內核組件卸載時調用。通常僅用於標記module_exit函數

初始化數據結構的宏

宏                 使用宏的數據說明

__initdata         僅在啓動時用於已初始化的數據結構

__exitdata         僅被由__exitcall修飾的函數使用的數據結構


網絡設備處理層初始化

文件                    初始化函數及宏                    說明

net/socket.c           core_initcall(sock_init)        套接口層的初始化函數

net/core/sock.c        subsys_initcall(proto_init)     傳輸層的初始化函數

net/ipv4/af_inet.c     fs_initcall(inet_init)          Internet協議族的初始化函數

net/core/dev.c         subsys_initcall(net_dev_init)   設備處理層的初始化函數

drivers/net/e100.c     module_init(e100_init_module)   e100型號的網絡設備驅動的初始化函數

發佈了9 篇原創文章 · 獲贊 1 · 訪問量 1110
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章