首页 > 技术文章 > XXX_initcall()函数分析

emlslxl 2016-09-01 17:10 原文

1. 先看这些宏的定义(定义在文件include/linux/init.h中)

 1 #define pure_initcall(fn)                __define_initcall("0",fn,0)
 2 #define core_initcall(fn)                __define_initcall("1",fn,1)
 3 #define core_initcall_sync(fn)        __define_initcall("1s",fn,1s)
 4 #define postcore_initcall(fn)        __define_initcall("2",fn,2)
 5 #define postcore_initcall_sync(fn)    __define_initcall("2s",fn,2s)
 6 #define arch_initcall(fn)                __define_initcall("3",fn,3)
 7 #define arch_initcall_sync(fn)        __define_initcall("3s",fn,3s)
 8 #define subsys_initcall(fn)        __define_initcall("4",fn,4)
 9 #define subsys_initcall_sync(fn)    __define_initcall("4s",fn,4s)
10 #define fs_initcall(fn)            __define_initcall("5",fn,5)
11 #define fs_initcall_sync(fn)        __define_initcall("5s",fn,5s)
12 #define rootfs_initcall(fn)        __define_initcall("rootfs",fn,rootfs)
13 #define device_initcall(fn)        __define_initcall("6",fn,6)
14 #define device_initcall_sync(fn)    __define_initcall("6s",fn,6s)
15 #define late_initcall(fn)                __define_initcall("7",fn,7)
16 #define late_initcall_sync(fn)        __define_initcall("7s",fn,7s)
initcall

2. __define_initcall

/* 初始化调用函数依据功能分组成独立的子段,这些字段的内部排列顺序由链接顺序决定 */

/* 为了向后的兼容性,initcall()放置这些函数在器件的初始化字段 */

/* __define_initcall 中 id 这个参数是必要的,这样多个initcalls可以同时指向同一个handler */

1 #define __define_initcall(level,fn,id) \
2     static initcall_t __initcall_##fn##id __used \
3     __attribute__((__section__(".initcall" level ".init"))) = fn
__define_initcall

其中initcall_t是函数指针,原型如下

1 typedef int (*initcall_t)(void);

而属性 __attribute__((__section__())) 则表示把对象放在一个这个由括号中的名称所指代的section中。

所以__define_initcall的含义是:

1) 声明一个名称为__initcall_##fn##id 的函数指针;

2) 将这个函数指针指向传入的函数名fn;

3) 编译的时候需要把这个函数指针变量放置到名称为 ".initcall" level ".init"的section中。

 

推荐阅读