initcall函数的声明:

/* include/linux/init.h */

/* initcalls are now grouped by functionality into separate 
 * subsections. Ordering inside the subsections is determined
 * by link order. 
 * For backwards compatibility, initcall() puts the call in 
 * the device init subsection.
 *
 * The `id' arg to __define_initcall() is needed so that multiple initcalls
 * can point at the same handler without causing duplicate-symbol build errors.
 */

//定义函数指针变量初始化变量所属段的优先级

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

/*
 * Early initcalls run before initializing SMP.
 *
 * Only for built-in code, not modules.
 */
#define early_initcall(fn) __define_initcall("early",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.
 */
#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)

//发现 __initcall(fn) 也是通过__define_initcall宏进行定义的

//level为6,基本代表设备驱动程序初始化调用

#define __initcall(fn) device_initcall(fn)

//这句话的意思为定义一个initcall_t型的初始化函数,函数存放在.initcall”level”.init section内

//.initcall”level”.init section定义在vmlinux.lds内
/* asm-generic/vmlinux.lds.h */
……
  __initcall_start = .;
   *(.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_end = .;
       ……
//vmlinux.lds.h里定义core_initcall的level等级的优先级.initcall”level”.init section.

//因此通过不同的*_initcall声明的函数指针最终都会存放不同level等级的.initcall”level”.init section内

//这些不同level的section按level等级高低依次存放。

#define __exitcall(fn) \
static exitcall_t __exitcall_##fn __exit_call = fn

#define console_initcall(fn) \
static initcall_t __initcall_##fn \
__used __section(.con_initcall.init) = fn

#define security_initcall(fn) \
static initcall_t __initcall_##fn \
__used __section(.security_initcall.init) = fn

//下面我们再来看看,内核是什么时候调用存储在.initcall”level”.init section内的函数的。

//内核是通过do_initcalls函数循环调用执行initcall.init section内的函数的,流程如下:
//start_kernel -> rest_init -> kernel_thread -> kernel_init-> do_basic_setup -> do_initcalls

kernel的initcall函数相关推荐

  1. 快速找到 Linux Kernel 中各种函数原型的方法

    如果你是使用VS Code的话,下面这个小技巧适合你 最近一直在研究Linux的kernel代码,有时候遇到需要查看具体struct定义的时候,但是使用VS Code的时候,每次在查询里面输入的时候, ...

  2. linux kernel中__setup()函数介绍

    setup 1.__setup使用示例 2.__setup宏原理 3.__setup链接函数的调用 ★★★ 友情链接 : 个人博客导读首页-点击此处 ★★★ 1.__setup使用示例 我们先看一个例 ...

  3. 思考:Linux Kernel的中断处理函数中是否会被其它程序(中断/异常)打断?

    快速链接: .

  4. Linux内核代码宏定义,Linux Kernel源代码中与段有关的重要宏定义

    __init, __initdata等属性标志,是要把这种属性的代码放入目标文件的.init.text节,数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链 ...

  5. Linux内核的l2tp实现,Linux Kernel gdth实现内核内存破坏漏洞

    Linux Kernel gdth实现内核内存破坏漏洞 发布日期:2010-11-04 更新日期:2010-11-16 受影响系统: Linux kernel 2.6.x 描述: ---------- ...

  6. arm+linux+entry.s,linux kernel 之底层中断机制entry_armv.S

    entry-armv.s中 当ARM处理器发生异常(中断是一种异常)时,会跳转到异常向量表(起始地址为0xFFFF_0000或 0x0000_0000). 如3.2节中所述,在中断机制的初始化过程中, ...

  7. Kernel Method核方法—基本概念

    这里只是简单叙述了核方法中运用到的几个概念和相互的关系,包括什么是核函数Kernel function.正定函数Positive definite function.再生核希尔伯特空间Reproduc ...

  8. OpenCL Function Qualifiers (函数限定符)

    OpenCL Function Qualifiers (函数限定符) OpenCL 3.0 Reference Pages -> OpenCL Compiler -> Function Q ...

  9. 探索C语言之字符串分割函数:strtok和strsep的区别

    探索C语言之字符串分割函数:strtok和strsep的区别 概述 strsep - extract token from string(linux 下) strtok, strtok_r - ext ...

  10. 新手玩转Linux Kernel漏洞之Null Pointer Dereference

    新手玩转Linux Kernel漏洞之Null Pointer Dereference 前言 这是我内核漏洞的入门篇, 不是很复杂, 希望能给徘徊在门外的小伙伴一点启发. 漏洞描述 A NULL po ...

最新文章

  1. BootStrap字体图标不显示、下拉菜单不显示
  2. matlab用于系统框图建模的函数,MATLAB产品家族中文
  3. python简单程序代码-简单python代码
  4. windbg !htrace 学习总结
  5. 平均分组 java_java – 按属性分组对象列表,并计算每个对象的对象属性的平均值...
  6. 用PyMC3进行贝叶斯统计分析(代码+实例)
  7. no segments* file found in org.apache.lucene.store.SimpleFSDirectory
  8. 机器学习入门一 ------- 什么是机器学习,机器学习的在实际中的用处
  9. 有几百万的房子,也吃不起西贝,感觉像在交税…….
  10. 交互式python解释器_从python脚本中调用python交互式解释器
  11. 浅谈Tomcat接收到一个请求后在其内部的执行流程(源码)
  12. Windows无法启动 VMware Workstation server服务解决方法
  13. 计算机并口回路测试工具,COM口和LPT口回路环的制作与CheckIT3.0测试方法
  14. 固件编辑器android,定制 Android 固件
  15. android手机壁纸
  16. 极速office(Word)怎么修改纸张方向
  17. 川崎机器人D系列as_川崎机器人|Profinet配置详解
  18. TOM、网易、腾讯企业邮箱 | 邮箱登录入口你了解多少?
  19. 海马汽车经销商管理系统技术解析(七)预约失败处理
  20. 荣耀30S入手体验分享 性能够用颜值深得我心

热门文章

  1. Android学习进阶路线导航线路(Android源码分享)
  2. 绝好的一套针对初学者的JavaScript教程
  3. api 读内存整数_10万+QPS 真的只是因为单线程和基于内存?
  4. python吃显卡还是内存条_用游戏本打游戏是显卡重要还是内存重要?
  5. azkaban的最简版搭建
  6. 《Android和PHP开发最佳实践》一第3章 PHP开发准备
  7. iOS地图 -- 定位初使用
  8. 用JS做关灯游戏(初级)
  9. GRIB格式转换心得(转自博客:http://windforestwing.blog.163.com/blog/static/19545412007103084743804/)...
  10. arm的bin二进制代码分析