初始化相關的文件
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
- typedef int (*initcall_t)(void);
- #define __define_initcall(level,fn,id) \
- static initcall_t __initcall_##fn##id __used \
- __attribute__((__section__(".initcall" level ".init"))) = fn
- #define device_initcall(fn) __define_initcall("6",fn,6)
- #define __initcall(fn) device_initcall(fn)
- #define module_init(x) __initcall(x);
include/asm-generic/vmlinux.lds.h
- #define INITCALLS \
- *(.initcallearly.init) \
- VMLINUX_SYMBOL(__early_initcall_end) = .; \
- *(.initcall0.init) \
- *(.initcall0s.init) \
- *(.initcall1.init) \
- *(.initcall1s.init) \
- *(.initcall2.init) \
- *(.initcall2s.init) \
- *(.initcall3.init) \
- *(.initcall3s.init) \
- *(.initcall4.init) \
- *(.initcall4s.init) \
- *(.initcall5.init) \
- *(.initcall5s.init) \
- *(.initcallrootfs.init) \
- *(.initcall6.init) \
- *(.initcall6s.init) \
- *(.initcall7.init) \
- *(.initcall7s.init)
-
- #define INIT_CALLS \
- VMLINUX_SYMBOL(__initcall_start) = .; \
- INITCALLS \
- VMLINUX_SYMBOL(__initcall_end) = .;
init/main.c
- static void __init do_initcalls(void)
- {
- initcall_t *call;
-
- for (call = __early_initcall_end; call < __initcall_end; call++)
- do_one_initcall(*call);
-
- /* Make sure there is no pending stuff from the initcall sequence */
- flush_scheduled_work();
- }
模塊加載函數的module_init()宏定義
- #define module_init(initfn) \
- static inline initcall_t __inittest(void) \
- { return initfn; } \
- 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型號的網絡設備驅動的初始化函數