今天在看内核中无线的实现时,发现一个调用 subsys_initcall(cfg80211_init);搜索一些资料:

subsys_initcall 的定义在 include/linux/init.h 中,定义如下:

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

查看宏定义 _define_initcall 定义在同一个文件中(include/linux/init.h)

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

定义了一个函数指针赋值的实现,    __initcall_##fn##id  函数的实现为  fn函数;编译的时候需要把这个函数指针变量放置到名称为 ".initcall" level ".init"的section中。

明确了__define_initcall的含义,就知道了是分别将这些初始化标号修饰的函数指针放到各自的section中的。

SECTION“.initcall”level”.init”被放入INIT_CALLS(include/asm-generic/vmlinux.lds.h)(内核3.10.14)

#define INIT_CALLS       \
  VMLINUX_SYMBOL(__initcall_start) = .;   \
  *(.initcallearly.init)     \
  INIT_CALLS_LEVEL(0)     \
  INIT_CALLS_LEVEL(1)     \
  INIT_CALLS_LEVEL(2)     \
  INIT_CALLS_LEVEL(3)     \
  INIT_CALLS_LEVEL(4)     \
  INIT_CALLS_LEVEL(5)     \
  INIT_CALLS_LEVEL(rootfs)    \
  INIT_CALLS_LEVEL(6)     \
  INIT_CALLS_LEVEL(7)     \
  VMLINUX_SYMBOL(__initcall_end) = .;

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

  1. SECTIONS
  2. {
  3. .init : {
  4. __initcall_start = .;
  5. INITCALLS
  6. __initcall_end = .;
  7. }
  8. }

而这些SECTION里的函数在初始化时被顺序执行(init内核线程->do_basic_setup()[main.c #778]->do_initcalls())。

程序(init/main.c文件do_initcalls()函数)如下,do_initcalls()把.initcallXX.init中的函数按顺序都执行一遍。

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

参考文档  :  http://blog.csdn.net/thl789/article/details/6581146#

内核中 subsys_initcall 以及初始化标号的更多相关文章

  1. Linux2.6 内核中结构体初始化(转载)

    转自:http://hnniyan123.blog.chinaunix.net/uid-29917301-id-4989879.html 在Linux2.6版本的内核中,我们经常可以看到下面的结构体的 ...

  2. 如何查看linux内核中驱动的初始化顺序?

    答:通过生成的System.map可以查看到,主要关注__initcall_<module_entry_function>_init<level>,如: __initcall_ ...

  3. 嵌入式C语言自我修养 02:Linux 内核驱动中的指定初始化

    2.1 什么是指定初始化 在标准 C 中,当我们定义并初始化一个数组时,常用方法如下: ] = {,,,,,,,,}; 按照这种固定的顺序,我们可以依次给 a[0] 和 a[8] 赋值.因为没有对 a ...

  4. linux内核中网络文件系统的注册初始化

    针对内核3.9 系统开启时,会使用init/main.c,然后再里面调用kernel_init(),在里面会再调用do_basic_setup(),调用do_initcalls(),调用do_one_ ...

  5. linux-3.2.36内核启动2-setup_arch中的内存初始化1(arm平台 分析高端内存和初始化memblock)【转】

    转自:http://blog.csdn.net/tommy_wxie/article/details/17093307 上一篇微博留下了这几个函数,现在我们来分析它们         sanity_c ...

  6. Linux内核中流量控制

    linux内核中提供了流量控制的相关处理功能,相关代码在net/sched目录下:而应用层上的控制是通过iproute2软件包中的tc来实现, tc和sched的关系就好象iptables和netfi ...

  7. Linux内核中SPI/I2c子系统剖析

    Linux内核中,SPI和I2C两个子系统的软件架构是一致的,且Linux内核的驱动模型都以bus,driver,device三种抽象对象为基本元素构建起来.下文的分析将主要用这三种抽象对象的创建过程 ...

  8. 详解Linux2.6内核中基于platform机制的驱动模型 (经典)

    [摘要]本文以Linux 2.6.25 内核为例,分析了基于platform总线的驱动模型.首先介绍了Platform总线的基本概念,接着介绍了platform device和platform dri ...

  9. linux-2.6.26内核中ARM中断实现详解(转)

    转载:http://www.cnblogs.com/leaven/archive/2010/08/06/1794293.html 更多文档参见:http://pan.baidu.com/s/1dDvJ ...

随机推荐

  1. 树莓派上使用Pi-FM-RDS工具打造FM调频电台

    安装Pi-FM-RDS 安装依赖.sudo apt-get install libsndfile1-dev 克隆Pi-FM-RDS到本地.git clone https://github.com/Ch ...

  2. IntelliJ IDEA的使用操作链接

    一:IntelliJ IDEA导入多个eclipse项目到同一个workspace下: http://www.cnblogs.com/ThinkVenus/p/6783961.html?utm_sou ...

  3. Apache模块 mod_proxy

    转: Apache模块 mod_proxy 转自http://www.php100.com/manual/apache2/mod/mod_proxy.html Apache模块 mod_proxy 说 ...

  4. AllSame.java

    /****************************************************************************** * Compilation: javac ...

  5. 2018acm-icpc西安邀请赛后记

    第一次参加icpc的邀请赛,有一点小激动,深知大一弱队实力弱,赛前给队友的目标就是拿块铜,不打铁. 热身赛因为没有用过pc^2,codeblocks又用不习惯的原因,开始调工程调了很久,差一点拿到A题 ...

  6. HTTPS理解

    摘要:本文尝试一步步还原HTTPS的设计过程,以理解为什么HTTPS最终会是这副模样.但是这并不代表HTTPS的真实设计过程.在阅读本文时,你可以尝试放下已有的对HTTPS的理解,这样更利于“还原”过 ...

  7. java实现word转pdf在线预览(前端使用PDF.js;后端使用openoffice、aspose)

    背景 之前一直是用户点击下载word文件到本地,然后使用office或者wps打开.需求优化,要实现可以直接在线预览,无需下载到本地然后再打开. 随后开始上网找资料,网上资料一大堆,方案也各有不同,大 ...

  8. 仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'Address'中的标识列指

    在有自增长的SQL表格里面插入指定ID的数据的时候,会禁止你操作,提示如题目,解决办法: set identity_insert address on ,,,) set identity_insert ...

  9. iframe伪造ajax

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. pyppeteer 报错-无法连接到浏览器

    问题 程序报错: Failed to connect to browser port: http://127.0.0.1:57899/json/version 原因 虽然pyppeteer在首次启动时 ...