zoukankan      html  css  js  c++  java
  • xxx_initcall相关知识

    参考文件include/linux/init.h

    /*
     * Early initcalls run before initializing SMP.
     *
     * Only for built-in code, not modules.
     */
    #define early_initcall(fn)		__define_initcall(fn, early)
    
    /*
     * A "pure" initcall has no dependencies on anything else, and purely
     * initializes variables that couldn't be statically initialized.
     *
     * This only exists for built-in code, not for modules.
     * Keep main.c:initcall_level_names[] in sync.
     */
    #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)
    

    仅仅在未定义宏MODULE的时候才是上面那样定义的,也就是说,如果编译成模块,那么以上定义全部会自动定义为module_init__define_initcall的最终展开:

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

    也就是说该宏定义了一个initcall_t类型的变量,变量名由输入参数fn(函数名)及输入参数id(通过id来确定优先顺序)构成,同时指定变量对应的section为.initcall #id .init,也就是说会根据相同id的xxx_initcall会放在相同section,具体section的处理需要看链接脚本,文件arch/arm/kernel/vmlinux.lds:

     .init.data : {                                                                 
      *(.init.data) *(.meminit.data) *(.init.rodata) *(.meminit.rodata) . = ALIGN(8); __clk_of_table = .; *(__clk_of_table) *(__clk_of_table_end) . = ALIGN(8); __reservedmem_of_table = .; *(__reservedmem_of_table) *(__reservedmem_of_table_end) . = ALIGN(8); __clksrc_of_table = .; *(__clksrc_of_table) *(__clksrc_of_table_end) . = ALIGN(8); __cpu_method_of_table_begin = .; *(__cpu_method_of_table) __cpu_method_of_table_end = .; . = ALIGN(32); __dtb_start = .; *(.dtb.init.rodata) __dtb_end = .; . = ALIGN(8); __irqchip_begin = .; *(__irqchip_of_table) *(__irqchip_of_end)
      . = ALIGN(16); __setup_start = .; *(.init.setup) __setup_end = .;      
    
           
      __initcall_start = .; *(.initcallearly.init) __initcall0_start = .; *(.initcall0.init) *(.initcall0s.init) __initcall1_start = .; *(.initcall1.init) *(.initcall1s.init) __initcall2_start = .; *(.initcall2.init) *(.initcall2s.init) __initcall3_start = .; *(.initcall3.init) *(.initcall3s.init) __initcall4_start = .; *(.initcall4.init) *(.initcall4s.init) __initcall5_start = .; *(.initcall5.init) *(.initcall5s.init) __initcallrootfs_start = .; *(.initcallrootfs.init) *(.initcallrootfss.init) __initcall6_start = .; *(.initcall6.init) *(.initcall6s.init) __initcall7_start = .; *(.initcall7.init) *(.initcall7s.init) __initcall_end = .;
      __con_initcall_start = .; *(.con_initcall.init) __con_initcall_end = .;       
      __security_initcall_start = .; *(.security_initcall.init) __security_initcall_end = .;
      . = ALIGN(4); __initramfs_start = .; *(.init.ramfs) . = ALIGN(8); *(.init.ramfs.info)
     }  
    

    下面看内核启动的时候对它们的处理部分,调用流程start_kernel-->rest_init-->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND)-->kernel_init_freeable-->do_pre_smp_initcalls:

    static void __init do_pre_smp_initcalls(void)
    {
    	initcall_t *fn;
    
    	for (fn = __initcall_start; fn < __initcall0_start; fn++)
    		do_one_initcall(*fn);
    }
    

    从调用流程可以看出,它的调用是在内核启动初始化的结束阶段。也就是说在内核的各种机制初始化之后,但在驱动加载之前。

    完!
    2013年6月

  • 相关阅读:
    Android Studio安装与配置
    T-SQL:qualify和window 使用(十七)
    《c#图解教程》
    c# 创建,加载,修改XML文档
    c# 使用迭代器来创建可枚举类型
    C#上手练习3(while、do while语句)(添加机器人聊天)
    C#上手练习2(FOR语句)
    C#上手练习1(if语句、Swich语句)
    解决java导入project出现红叉
    ABAP ALV显示前排序合并及布局显示
  • 原文地址:https://www.cnblogs.com/rongpmcu/p/7662217.html
Copyright © 2011-2022 走看看