内核中 xxx_initcall 的调用过程分析
内核版本:linux-4.19
上一篇文章提到了这段代码:
arch_initcall_sync(of_platform_default_populate_init);
它的功能是完成 device_node 到 platform_device 的转换。这篇文章就来大概的分析一下,它是怎样被调用的。
arch_initcall_sync 定义如下:
#define ___define_initcall(fn, id, __sec) \
static initcall_t __initcall_##fn##id __used \
__attribute__((__section__(#__sec ".init"))) = fn;
#define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id)
#define arch_initcall_sync(fn) __define_initcall(fn, 3s)
根据 LDS 文件的定义,会将这些 data 存储在指定的位置:
#define INIT_CALLS_LEVEL(level) \
__initcall##level##_start = .; \
KEEP(*(.initcall##level##.init)) \
KEEP(*(.initcall##level##s.init)) \
#define INIT_CALLS \
__initcall_start = .; \
KEEP(*(.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) \
__initcall_end = .;
在内核中,想要调用到这些数据,就会用到
__initcall##level##_start = .;
这个标识。
数据的位置已经搞定了,那么内核又是怎样调用的呢?接下来找到这些函数调用。
调用流程如下:
start_kernel
-->rest_init
-->kernel_thread(kernel_init, NULL, CLONE_FS);
-->kernel_init
-->kernel_init_freeable
-->do_basic_setup
-->do_initcalls
-->do_initcall_level
do_initcall_level 代码如下:
static void __init do_initcall_level(int level)
{
initcall_entry_t *fn;
strcpy(initcall_command_line, saved_command_line);
parse_args(initcall_level_names[level],
initcall_command_line, __start___param,
__stop___param - __start___param,
level, level,
NULL, &repair_env_string);
trace_initcall_level(initcall_level_names[level]);
for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
do_one_initcall(initcall_from_entry(fn));
}
根据下表,分别调用 do_one_initcall 来执行每一个 initcall。
static initcall_entry_t *initcall_levels[] __initdata = {
__initcall0_start,
__initcall1_start,
__initcall2_start,
__initcall3_start,
__initcall4_start,
__initcall5_start,
__initcall6_start,
__initcall7_start,
__initcall_end,
};
表中的 xxx_start 恰恰就是前面所提到的存储标识,那么这些调用就联系到了一起,实现函数的调用。
分析到这里,相信关于 xxx_initcall 调用的云雾就已经拨开了吧!
内核中 xxx_initcall 的调用过程分析的更多相关文章
- 浅析linux内核中timer定时器的生成和sofirq软中断调用流程(转自http://blog.chinaunix.net/uid-20564848-id-73480.html)
浅析linux内核中timer定时器的生成和sofirq软中断调用流程 mod_timer添加的定时器timer在内核的软中断中发生调用,__run_timers会spin_lock_irq(& ...
- 浅析linux内核中timer定时器的生成和sofirq软中断调用流程【转】
转自:http://blog.chinaunix.net/uid-20564848-id-73480.html 浅析linux内核中timer定时器的生成和sofirq软中断调用流程 mod_time ...
- Linux 2.6内核中新的锁机制--RCU
转自:http://www.ibm.com/developerworks/cn/linux/l-rcu/ 一. 引言 众所周知,为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁 ...
- Linux 内核中的 Device Mapper 机制
本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...
- 内核中用于数据接收的结构体struct msghdr(转)
内核中用于数据接收的结构体struct msghdr(转) 我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程中涉及到的相关数据结构.在我们的虚拟机上发送icmp回显请求包,pin ...
- 向linux内核中添加外部中断驱动模块
本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...
- [php-src]窥探Php内核中的变量
内容均以php-5.6.14为例. 在看各种组合数据类型之前,有必要先熟悉下 Zend/zend_types.h 里面的自定义数据类型. #ifndef ZEND_TYPES_H // 防止多次 in ...
- [php-src]理解Php内核中的函数与INI
内容均以php-5.6.14为例. 一. 函数结构 内核中定义一个php函数使用 PHP_FUNCTION 宏 包装,扩展也不例外,该宏在 ./main/php.h:343 有着一系列类似以 PHP ...
- Openvswitch原理与代码分析(5): 内核中的流表flow table操作
当一个数据包到达网卡的时候,首先要经过内核Openvswitch.ko,流表Flow Table在内核中有一份,通过key查找内核中的flow table,即可以得到action,然后执行acti ...
随机推荐
- let和const
ES6新增了let取代var,let主要有以下特点. 1 只在代码块内有效,代码块外不能使用let声明的变量.let很适合声明循环体的变量. 它可以解决一些闭包的问题存在的问题比如: var a = ...
- Js 运行机制和Event Loop
一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. Java ...
- maven <include>与<exclude>划定的范围存在冲突,则以<exclude>配置为准。
maven 与划定的范围存在冲突,则以配置为准.
- Android Studio 全局内替换字符串
Ctrl+Shift+R
- svn错误:更新源码出现校验和不匹配问题
svn 的文本校验和不匹配: 最近在更新自动化源代码的时候出现了一个错误:svn: Checksum mismatch while updating.... 查了下google,原来是在更新源码出现校 ...
- nova boot from volume代码分析
首先要创建一个bootable volume curl -i http://16.158.166.197:8776/v1/c24c59846a7f44538d958e7548cc74a3/volume ...
- linux入门--Linux桌面环境(桌面系统)大比拼[附带优缺点]
早期的 Linux 系统都是不带界面的,只能通过命令来管理,比如运行程序.编辑文档.删除文件等.所以,要想熟练使用 Linux,就必须记忆很多命令. 后来随着 Windows 的普及,计算机界面变得越 ...
- Redis 设计与实现 (六)--发布订阅
发布订阅 相关命令:publish(发布) subscribe(订阅) psubscribe(支持通配符匹配) 发布者--频道--订阅者(发布和订阅都是客户端频道是服务端) 1.publish- ...
- vs2013+opencv3.2配置
opencv库在3.0以后分为opencv库和opencv_contrib库两部分,其中opencv_contrib库是一个扩展库,如果需要使用SIFT和SURF算法就需要安装这个扩展库,否则只用安装 ...
- BBS论坛(二十九)
29.帖子详情页布局 (1)front/hooks.py @bp.errorhandler def page_not_found(): return render_template('front/fr ...