参考文件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月

xxx_initcall相关知识的更多相关文章

  1. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸

    类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...

  2. 移动WEB像素相关知识

    了解移动web像素的知识,主要是为了切图时心中有数.本文主要围绕一个问题:怎样根据设备厂商提供的屏幕尺寸和物理像素得到我们切图需要的逻辑像素?围绕这个问题以iphone5为例讲解涉及到的web像素相关 ...

  3. listener监听器的相关知识

    从别人的博客上我学习了listener的相关知识现在分享给大家 1.概念: 监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上 ...

  4. UIViewController相关知识

    title: UIViewController 相关知识date: 2015-12-13 11:50categories: IOS tags: UIViewController 小小程序猿我的博客:h ...

  5. 【转】java NIO 相关知识

    原文地址:http://www.iteye.com/magazines/132-Java-NIO Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的 ...

  6. NSString使用stringWithFormat拼接的相关知识

    NSString使用stringWithFormat拼接的相关知识 保留2位小数点 1 2 3 4 //.2代表小数点后面保留2位(2代表保留的数量) NSString *string = [NSSt ...

  7. iOS网络相关知识总结

    iOS网络相关知识总结 1.关于请求NSURLRequest? 我们经常讲的GET/POST/PUT等请求是指我们要向服务器发出的NSMutableURLRequest的类型; 我们可以设置Reque ...

  8. 电路相关知识--读<<继电器是如何成为CPU的>>

    电路相关知识–读<<继电器是如何成为CPU的>> */--> *///--> *///--> 电路相关知识–读<<继电器是如何成为CPU的> ...

  9. 地址标记,SpringMVC转发与调用相关知识存档

    1.mytest_mavenprj1中,index的 <a href="login/login.html">点击登录</a> 与 <a href=&q ...

随机推荐

  1. UDP发送的数据 以数据包形式发送

    UDP发送的数据 以数据包形式发送

  2. 分离IE9以下浏览器

    /*判断浏览器版本是否过低*/ function IETester(userAgent) { var UA = userAgent || navigator.userAgent; if (/msie/ ...

  3. Skills - CF613B

    Lesha plays the recently published new version of the legendary game hacknet. In this version charac ...

  4. BZOJ3653 & 洛谷3899:谈笑风生——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3653 https://www.luogu.org/problemnew/show/P3899 设 ...

  5. 爆款PHP面试题

    $a = 3; $b = 6; if ($a = 4 || $b = 4) { $a++; $b++; } echo $a; //输出 1 echo $b; //输出 7 逛鸟哥博客,看评论区有个新手 ...

  6. 从零开始学Linux系统(三)安装CentOS-7及软件包管理操作

    推荐博文: VirtualBox安装CentOS7步骤详解: https://my.oschina.net/AaronDMC/blog/840753 如何安装CentOS7字符界面 :http://b ...

  7. Blender绘制大脑表层,并高亮染色

    首先, 有必要熟悉一下Blender的一些快捷键.(实在不想吐槽Blender反人类的交互操作了) 按鼠标右键是选择某个物体.(是右键,而不是左键!) 按A键,取消选中或者选中全部物体. 按H键,隐藏 ...

  8. JavaScript的性能优化:加载和执行

    随着 Web2.0 技术的不断推广,越来越多的应用使用 javascript 技术在客户端进行处理,从而使 JavaScript 在浏览器中的性能成为开发者所面临的最重要的可用性问题.而这个问题又因 ...

  9. AngularJs 中的CheckBox前后台交互

    前台页面: <div class="form-group"> <label for="CompanyName" class="col ...

  10. 使用localhost调试本地代码,setcookie无效

    今天在本地调试代码的时候,再域名中使用localhost,结果一直调试不成功,最后发现在登录时,setcookie()没有设置进去 于是发现了,在使用localhost调试时,保存cookie是无效的 ...