今天在看内核中无线的实现时,发现一个调用 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. 强大log

    http://lovelease.iteye.com/blog/1886907 import java.io.BufferedReader; import java.io.File; import j ...

  2. 洛谷P1012 拼数 string

    又是大水题... 这一题过水,令人无法接受...... 但是如果我们不知道string的一个神奇的性质的话,就会很难受. 我一开始手写 < 号,但是发现如果 string a 的前一部分恰好是 ...

  3. 关于:HTTP Header -> Content-Type: text/plain Cache-Control: no-cache IE浏览器弹出错误下载对话

    下午遇到一个很奇怪的现象,一个网址: http://192.168.1.3/login?action=a&fr=b.com 注意网址后面的参数形式,action参数在前,最后一个参数值的尾部含 ...

  4. 在Windows上部署dubbo-admin(监控中心)

    在Windows上部署dubbo-admin(监控中心) 2018年11月12日 22:45:13 zzz_er 阅读数:1004 标签: dubbo 更多 个人分类: dubbo   版权声明:本文 ...

  5. js兼容火狐显示上传图片预览效果

    js兼容火狐显示上传图片预览效果[谷歌也适用] <!doctype html> <html> <head> <meta content="text/ ...

  6. Apache Shiro 用户信息保存在session方案

    描述 在使用shiro的时候,经常会有一种需求: 把登录成功后的用户对象存放到session中,方面其他地方调用.存放到session这个步骤到底应该在哪里去做,有几个地方比较合适: 调用 Subje ...

  7. python爬虫 前程无忧网页抓取

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  8. OS + Linux RedHat 6 / redhat 6 configuration / configure / autoconf / make / make install

    s These critical programs are missing or too old: as ld http://blog.csdn.net/testcs_dn/article/detai ...

  9. Overload和Override的区别 C++ Java

    Overload:顾名思义,就是Over(重新)——load(加载),所以中文名称是重载. 它可以表现类的多态性,可以是函数里面可以有相同的函数名但是参数名.返回值.类型不能相同: 或者说可以改变参数 ...

  10. java RSA 加签验签【转】

    引用自: http://blog.csdn.net/wangqiuyun/article/details/42143957/ java RSA 加签验签 package com.testdemo.co ...