参考: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 regex

    re.match: match from the beginning of the string re.search: scan through the whole string to find a ...

  2. ztr loves lucky numbers 傻逼的我来了个大模拟

    http://acm.hdu.edu.cn/showproblem.php?pid=5676 这题的正解因该是dfs的,但是有18个位,然后我一算,全排列的话,有18!个啊,那不是很大?但是有很多是相 ...

  3. myBati初学

    创建数据库(y2165) MyBatis环境搭建1.在pom.xml引入依赖2.得替换build节点,为了让程序编译在main中所有子包下的配置文件3.构建大配置,位于resources<?xm ...

  4. JAVA-汉字转换成汉语拼音(pinyin4j-2.5.0-sources.jar)

    在项目中,经常会使用汉语拼音,特别是把汉字转换成汉语拼音.下面给出一种常用的工具. 在使用该程序必须添加 pinyin4j-2.5.0-sources.jar包. import net.sourcef ...

  5. 使用Spring Cloud Feign

    使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务 在spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就 ...

  6. 关于IE兼容的问题

    以下内容,均来自不同的网站,非本人原创,只是收集一下放在一起! =============================== [一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10 ...

  7. Yii 2.0排序功能的使用

    在Yii2.0项目的实际开发中,经常会遇到使用Yii2.0自带的排序功能.下面是排序功能的具体使用方法. 一.设置排序规则 注意引入Sort类,如:use yii\data\Sort; // 设置排序 ...

  8. IOS弹出视图preferredContentSize

    UIViewController.preferredContentSize代理旧方法 contentSizeForViewInPopover. self.contentSizeForViewInPop ...

  9. Azure 项目构建 – 部署 Drupal 网站

    通过完整流程详细介绍了如何通过 Azure Web 应用. MySQL DB on Azure 等服务在 Azure 平台上快速搭建 Drupal 服务器,并将其连接到 MySQL 数据库. 此系列的 ...

  10. Spring 配置定时器(注解+xml)方式—整理

    一.注解方式 1. 在Spring的配置文件ApplicationContext.xml,首先添加命名空间 xmlns:task="http://www.springframework.or ...