module_init的内核调用顺序
来源:互联网 发布:深圳网络推广惠信 编辑:程序博客网 时间:2024/06/05 04:20
现在以module_init为例分析initcall在内核中的调用顺序
在头文件include/linux/init.h中,有如下定义:
#define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
继续看:
#define device_initcall(fn) __define_initcall("6",fn,6)
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __used \
__attribute__((__section__(".initcall" level ".init"))) = fn
最终我们看到的是module_init的真身:__define_initcall(level,fn,id),仔细推敲这个真身,知道这是个宏,它把传给module_init的函数名组装成以__initcall为前缀的、以6为后缀的函数名,并把这个函数定义到代码段.initcall6.init里面。
在代码段.initcall6.init里面?这函数躲在这里干嘛,啥时候才轮得到它出头啊!找到有此字符串的文件vmlinux.lds.h,相关代码如下所示:
#define INITCALLS \
*(.initcallearly.init) \
VMLINUX_SYMBOL(__early_initcall_end) = .; \
*(.initcall0.init) \
*(.initcall0s.init) \
*(.initcall1.init) \
*(.initcall1s.init) \
*(.initcall2.init) \
*(.initcall2s.init) \
*(.initcall3.init) \
*(.initcall3s.init) \
*(.initcall4.init) \
*(.initcall4s.init) \
*(.initcall5.init) \
*(.initcall5s.init) \
*(.initcallrootfs.init) \
*(.initcall6.init) \
*(.initcall6s.init) \
*(.initcall7.init) \
*(.initcall7s.init)
在vmlinux.lds.S里面
__initcall_start = .;
INITCALLS
__initcall_end = .;
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
__security_initcall_start = .;
*(.security_initcall.init)
__security_initcall_end = .;
言归正传,INITCALLS在__initcall_start = .与__initcall_end = .之间,表示INITCALLS宏内涵的相关段代码顺序存放在这里,module_init所代表段的镶嵌其中
#define pure_initcall(fn) __define_initcall("0",fn,0)
#define core_initcall(fn) __define_initcall("1",fn,1)
#define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
#define postcore_initcall(fn) __define_initcall("2",fn,2)
#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
#define arch_initcall(fn) __define_initcall("3",fn,3)
#define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
#define subsys_initcall(fn) __define_initcall("4",fn,4)
#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
#define fs_initcall(fn) __define_initcall("5",fn,5)
#define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
#define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
#define device_initcall(fn) __define_initcall("6",fn,6)
#define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
#define late_initcall(fn) __define_initcall("7",fn,7)
#define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
至此我们应该明白了各个initcall是如何来的以及在代码存储空间上是怎么组织的了吧,下面来看看内核是什么时候调用它的。
内核启动流程如下所示
Main()àlinux_main()àstart_uml()àstart_kernel_proc()àstart_kernelàrest_inità kernel_inità do_basic_setupà do_initcalls
do_initcalls的代码如下所示
static void __init do_initcalls(void)
{
initcall_t *call;
for (call = __early_initcall_end; call < __initcall_end; call++)
do_one_initcall(*call);
/* Make sure there is no pending stuff from the initcall sequence */
flush_scheduled_work();
}
上面的代码中,__early_initcall_end在INITCALLS内定义,__initcall_end在文件vmlinux.lds.S中定义,他们代表的是一些初始化函数的指针数组起始与结束地址,执行函数do_initcalls时,包含在这各指针数组里面的函数顺序的被调用以执行一些必要的初始化工作。至此,明白的各initcall的执行时刻了吧。
- module_init的内核调用顺序
- module_init的内核调用顺序
- module_init的内核调用顺序
- module_init的调用顺序
- android底层驱动学习之 module_init的内核调用顺序
- 内核中module_init()是被如何调用
- 内核中module_init()是被如何调用
- 各种initcall的执行顺序: module_init subsys_initcall ....
- 内核调用__init函数的顺序
- 内核调用__init函数的顺序
- 内核调用顺序
- 内核驱动之module_init
- module_init调用过程
- module_init 和 late_initcall 区别 调整Linux内核启动中的驱动初始化顺序
- module_init/subsys_initcall/postcore_initcall 执行顺序。
- linux module_init 的秘密
- module_init 的优先级
- module_init机制的理解
- java读取html页面并解析<table><tr><td>
- 什么是DNS,如何设置,和host file的关系。
- 手动调用gpload进行数据的加载
- 这是我的第一篇博客
- mysql查询语句speed select
- module_init的内核调用顺序
- MFC Http Post请求步骤
- MySQL的log-bin的日志功能
- jvm学习
- [drp 3]读取Xml配置文件,连接数据库
- 227. Basic Calculator 2
- Android前置摄像头视频录制失败(MediaRecorder: start failed: -19)
- Ext本地数据在Grid中分页显示,隐藏指定字段
- cocos2dx 3.3 cocos studio的交互性问题