linux initcall机制

图1
进入子系统初始化时,在内核init进程中进行设备初始化,最为复杂、诡异的机制莫过于do_initcalls()函数调用,该函数完成了所有需要静态加载模块的初始化,需要进行静态加载的内核模块,需要使用一些特定的宏进行处理,下面详细来说明一些linux内核中initcalls机制。
先来看看do_initcalls()函数原型:

图2
核心部分是639~671之间,该部分是一个函数指针调用,遍历_initcall_start~_initcall_end范围,逐个调用函数指针。
那_initcall_start~_initcall_end之间存放的是什么呢,可以以下面一幅示意图来说明。

图3
图左边是地址指针,右边是相关宏,使用相关宏处理函数指针,可以将被处理的函数指针放在特定的指针范围内。例如,网络设备层初始化函数是net_dev_init(),定义在net/core/dev.c中,在该函数下方有条宏处理subsys_initcall(net_dev_init),该宏完成将net_dev_init函数指针放在上图中.initcall4.init段中,在do_initcalls()函数调用时,其处于_initcall_start~_initcall_end直接,所以net_dev_init()就这样被调用了。
这种机制真是比较巧妙,也比较难以理解,设计初衷就是为了实现一个通用的启动流程,使移植或扩展时,只需要对需要启动加载的模块进行宏处理即可。
下面来详细了解这种机制的实现方法。
先说一说gcc对手动定位代码段位置的支持,_attribute_是gcc的关键字,指示编译器给符号设置特定属性。编译完成后输入到链接器的是各个带有符号表的文件,链接器对各个文件中符号进行重定位,_attribute_在该阶段进行处理,将指定符号放在链接生成文件段中特定位置,不单只指代码段,也包括数据段,如系统初始化中经常见到的_initdata,即将指定符号放到数据段特定位置。
当然,具体这些段是如何生成的,也是有文件进行配置,即在链接配置文件arch/xxx/vmlinux.ds.S.中,如下

图4
在2.6.16内核中INITCALLS已直接被替换为
*(.initcall1.init)
*(.initcall2.init)
*(.initcall3.init)
*(.initcall4.init)
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
这和图3中的结构是对应的。接下来看看内核提供了哪些宏定义用来处理特定函数指针和数据。在include/linux/init.h文件中,包括各种常见的包装。
#define __define_initcall(level,fn) \
static initcall_t __initcall_##fn __attribute_used__ \
__attribute__((__section__(".initcall" level ".init"))) = fn #define core_initcall(fn) __define_initcall("1",fn)
#define postcore_initcall(fn) __define_initcall("2",fn)
#define arch_initcall(fn) __define_initcall("3",fn)
#define subsys_initcall(fn) __define_initcall("4",fn)
#define fs_initcall(fn) __define_initcall("5",fn)
#define device_initcall(fn) __define_initcall("6",fn)
#define late_initcall(fn) __define_initcall("7",fn)
可以看出,内核为满足不同初始化等级,设计了1~7共7个等级,不同等级初始化代码用对应的宏进行处理,读者可以对照上表进行理解一下。还有其它一些宏,用于各种任务需求,如模块加载宏module_init(),module_exit(),其处理又略有不同,读者可以自己理解一下。
总的来说,initcalls机制提供给内核开发者或驱动开发者一个借口,方便将自己的函数添加到内核初始化列表中,在内核初始化最后阶段进行处理。
原文链接: http://blog.csdn.net/u012497906/article/details/46234675
linux initcall机制的更多相关文章
- linux的initcall机制
linux的initcall机制(针对编译进内核的驱动) initcall机制的由来 我们都知道,linux对驱动程序提供静态编译进内核和动态加载两种方式,当我们试图将一个驱动程序编译进内核时,开发者 ...
- initcall机制
参考:initcall机制 /* include/linux/init.h: */ /* For assembly routines */ #define __HEAD .section " ...
- Linux模块机制浅析
Linux模块机制浅析 Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! ...
- android & Linux uevent机制
Linux uevent机制 Uevent是内核通知android有状态变化的一种方法,比如USB线插入.拔出,电池电量变化等等.其本质是内核发送(可以通过socket)一个字符串,应用层(andro ...
- 利用linux信号机制调试段错误(Segment fault)
在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...
- Linux 内存机制详解宝典
Linux 内存机制详解宝典 在linux的内存分配机制中,优先使用物理内存,当物理内存还有空闲时(还够用),不会释放其占用内存,就算占用内存的程序已经被关闭了,该程序所占用的内存用来做缓存使用,对于 ...
- Linux Namespaces机制——实现
转自:http://www.cnblogs.com/lisperl/archive/2012/05/03/2480573.html 由于Linux内核提供了PID,IPC,NS等多个Namespace ...
- Linux Namespaces机制
转自:http://www.cnblogs.com/lisperl/archive/2012/05/03/2480316.html Linux Namespaces机制提供一种资源隔离方案.PID,I ...
- Linux分页机制之概述--Linux内存管理(六)
1 分页机制 在虚拟内存中,页表是个映射表的概念, 即从进程能理解的线性地址(linear address)映射到存储器上的物理地址(phisical address). 很显然,这个页表是需要常驻内 ...
随机推荐
- 转:asp.net获取url各项参数
假设当前页完整地址是:http://www.test.com/aaa/bbb.aspx?id=5&name=kelli "http://"是协议名 "www.te ...
- 2016年国内开源maven镜像站点汇总
本文系转载,原文链接:https://www.cnblogs.com/xunianchong/p/5684042.html 一.站点版 (一).企业站 1.网易:http://mirrors.163. ...
- linux crontab命令 自动下载文件
#crontab -e#download stock data, Mon-Fri, 9:15 - 11:30, 13:00 - 15:0015,30,40,50 9 * * 1-5 (cd /home ...
- 【JavaScript】键盘控制小球
参考: 1.Simple Canvas Game 2.javaScript 事件监听 <!DOCTYPE html> <html> <head> <meta ...
- JSP Tomcat8.0运行连接池时发生异常【AbstractMethodError oracle.jdbc.driver.T4CConnection.isValid(I)Z】
原创 2015年12月28日 11:38:01 2004 一.Tomcat8.0运行连接池时发生异常: AbstractMethodError oracle.jdbc.driver.T4CConnec ...
- invalid derived query的解决办法
标签: eclipse / invalid / derived / 解决办法 / 校验功能 479 在Eclipse的运行过程中,突然有一个接口跳出如下错误: invalid derived quer ...
- Mysql数据库导出sql脚本
1. 运行环境Centos mysqldump -h localhost -u root -p etv > ./etv.sql etv 是要导出的数据库名 > 设置导出的路径和文件名
- tomcat常用配置详解和优化方法
tomcat常用配置详解和优化方法 参考: http://blog.csdn.net/zj52hm/article/details/51980194 http://blog.csdn.net/wuli ...
- LeetCode——Keyboard Row
LeetCode--Keyboard Row Question Given a List of words, return the words that can be typed using lett ...
- Codeforces 9C Hexadecimal's Numbers - 有技巧的枚举
2017-08-01 21:35:53 writer:pprp 集训第一天:作为第一道题来讲,说了两种算法, 第一种是跟二进制数联系起来进行分析: 第二种是用深度搜索来做,虽然接触过深度搜索但是这种题 ...