参考:initcall机制

/*
include/linux/init.h:
*/
/* For assembly routines */
#define __HEAD .section ".head.text","ax"
#define __INIT .section ".init.text","ax"
#define __CPUINIT .section ".cpuinit.text", "ax" #define __init __section(.init.text) __cold notrace
/*
__initcall_start = .;
*(.initcallearly.init) //#define early_initcall(fn) __define_initcall("early",fn,early)
__early_initcall_end = .;
*(.initcall0.init) //#define pure_initcall(fn) __define_initcall("0",fn,0)
*(.initcall0s.init)
*(.initcall1.init) //#define core_initcall(fn) __define_initcall("1",fn,1)
*(.initcall1s.init) //#define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
*(.initcall2.init) //#define postcore_initcall(fn) __define_initcall("2",fn,2)
*(.initcall2s.init) //#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
*(.initcall3.init) //#define arch_initcall(fn) __define_initcall("3",fn,3)
*(.initcall3s.init) //#define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
*(.initcall4.init) //#define subsys_initcall(fn) __define_initcall("4",fn,4)
*(.initcall4s.init) //#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
*(.initcall5.init) //#define fs_initcall(fn) __define_initcall("5",fn,5)
*(.initcall5s.init) //#define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
*(.initcallrootfs.init) //#define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
*(.initcall6.init) //#define device_initcall(fn) __define_initcall("6",fn,6)
*(.initcall6s.init) //#define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
*(.initcall7.init) //#define late_initcall(fn) __define_initcall("7",fn,7)
*(.initcall7s.init) //#define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
__initcall_end = .; #define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
#define device_initcall(fn) __define_initcall("6",fn,6) */

下面以arch_initcall(customize_machine);为例分析宏的展开过程

static int __init customize_machine(void)
{
/* customizes platform devices, or adds new ones */
if (machine_desc->init_machine)
machine_desc->init_machine();
return ;
}
arch_initcall(customize_machine);

typedef int (*initcall_t)(void); //定义函数指针,无参数,返回int

#define arch_initcall(fn)    __define_initcall("3",fn,3)
/* 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

arch_initcall(customize_machine)展开为

static initcall_t __initcall_customize_machine3 __used __attribute__((__section__(".initcall3.init"))) = customize_machine

initcall机制的更多相关文章

  1. linux的initcall机制

    linux的initcall机制(针对编译进内核的驱动) initcall机制的由来 我们都知道,linux对驱动程序提供静态编译进内核和动态加载两种方式,当我们试图将一个驱动程序编译进内核时,开发者 ...

  2. linux initcall机制

    Linux系统启动过程很复杂,因为它既需要支持模块静态加载机制也要支持动态加载机制.模块动态加载机制给系统提供了极大的灵活性,驱动程序既可支持静态编译进内核,也可以支持动态加载机制.Linux系统中对 ...

  3. Linux动态频率调节系统CPUFreq之二:核心(core)架构与API

    上一节中,我们大致地讲解了一下CPUFreq在用户空间的sysfs接口和它的几个重要的数据结构,同时也提到,CPUFreq子系统把一些公共的代码逻辑组织在一起,构成了CPUFreq的核心部分,这些公共 ...

  4. 设备树处理之——device_node转换成platform_device【转】

    转自:https://www.cnblogs.com/downey-blog/p/10486568.html 以下讨论基于linux4.14,arm平台 platform device 设备树的产生就 ...

  5. linux设备驱动程序-设备树(2)-device_node转换成platform_device

    设备树处理之--device_node转换成platform_device 以下讨论基于linux4.14,arm平台 platform device 设备树的产生就是为了替代driver中过多的pl ...

  6. linux内核makefile概览

    linux内核makefile概览 本博客参照内核官方英文文档 linux的内核makefile主要用于编译整个内核源码,按照用户的需求生成各种目标文件,对于用户来说,编译内核时非常简单的,只需要几个 ...

  7. linux设备驱动程序-i2c(1):i2c总线的添加与实现

    linux设备驱动程序-i2c(1):i2c总线的添加与实现 (基于4.14内核版本) 在上一章节linux设备驱动程序-i2c(0)-i2c设备驱动源码实现中,我们演示了i2c设备驱动程序的源码实现 ...

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

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

  9. Linux内核启动流程与模块机制

    本文旨在简单的介绍一下Linux的启动流程与模块机制: Linux启动的C入口位于/Linux.2.6.22.6/init/main.c::start_kernel() 下图简要的描述了一下内核初始化 ...

随机推荐

  1. python入门之流程控制

    if else 格式: if 条件 command1 command2elif 条件: command3    command4 else: command3 command4 注意条件后和else后 ...

  2. 排错:expected unqualified-id before string constant

    一个低级但是不好定位的编译错误,常见的问题是: 1. 语句的 { 括号不匹配. 2. 缺少 : , 特别是类的定义或声明,枚举的定义. 3. 变量名或函数名使用了保留字.

  3. [已读]JavaScript高级程序设计(第2版)

    经典红皮书~~

  4. MVC ef 连接数据库

    1.创建数据库 2.创建表 <pre name="code" class="sql">CREATE TABLE [dbo].[Student]( [ ...

  5. java 并发容器一之ConcurrentHashMap(基于JDK1.8)

    上一篇文章简单的写了一下,BoundedConcurrentHashMap,觉得https://www.cnblogs.com/qiaoyutao/p/10903813.html用的并不多:今天着重写 ...

  6. Java编程基础-选择和循环语句

    一.选择结构语句 选择结构:也被称为分支结构.选择结构有特定的语法规则,代码要执行具体的逻辑运算进行判断,逻辑运算的结果有两个,所以产生选择,按照不同的选择执行不同的代码. Java语言提供了两种选择 ...

  7. vue样式操作与事件绑定

    Vue笔记 1 Vue实例 (VM) var vm = new Vue({    el:'#app', //挂载元素        //数据    data: {        title:'值', ...

  8. 怎样将python的文件转化为windows的可执行程序

    最近我在刚入手python,其中就学到了怎样将python的py格式文件转化为windows的exe执行程序, 是这样的,首先要创建一个py文件,这里给截图吧 接下来就以这个python文件为例创建一 ...

  9. uvm_globals——告诉这个世界我爱你

    uvm_globals.svh 存放全局的变量和方法.当UVM平台启动时,便在uvm_globals查找相应的方法,uvm_globals 的方法实现也比较简单,就是调用uvm_root对应的方法.其 ...

  10. 修改nagios登录界面密码

    htpasswd -c /usr/local/nagios/etc/htpasswd.user nagiosadmin 输入密码: 重启httpd服务.