您的位置:首页 > 运维架构 > Linux

LINUX内核中的xx_initcall初始化标号

2012-01-02 22:29 323 查看
LINUX内核中的xx_initcall初始化标号


田海立@CSDN 2011-07-02



LINUX内核中有很多的初始化指示标志postcore_initcall(), arch_initcall(), subsys_initcall(), device_initcall(), etc. 这些起什么作用呢?查阅源代码(android goldfish-2.6.29)并搜索网上相关文章,对此做一总结。

初始化标号

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

view plaincopy to clipboardprint?

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

#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)

view plaincopy to clipboardprint?

#define __define_initcall(level,fn,id) \
   
        static initcall_t __initcall_##fn##id __used \  

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

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



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

view plaincopy to clipboardprint?

typedef int (*initcall_t)(void);

view plaincopy to clipboardprint?

#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 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)



__initcall_start和__initcall_end以及INITCALLS中定义的SECTION都是在arch/xxx/kernel/vmlinux.lds.S中放在.init段的。

view plaincopy to clipboardprint?

SECTIONS
{
.init : {
__initcall_start = .;
INITCALLS
__initcall_end = .;
}
}

view plaincopy to clipboardprint?

for (call = __early_initcall_end; call < __initcall_end; call++)  

        do_one_initcall(*call);  

        for (call = __early_initcall_end; call < __initcall_end; call++)
                do_one_initcall(*call);



*************************** 本文完 *****************************
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: