initcall的执行顺序

转载 2015年11月18日 14:56:02

Init.h中有相关initcall的启动次序,在system.map中可看出具体的__initcall指针的前后次序

 

#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)

 

module_init在的启动序号为6,它的展开后就是__define_initcall("6",fn,6)

#definedevice_initcall(fn) __define_initcall("6",fn,6)

#define__initcall(fn) device_initcall(fn)

#definemodule_init(x) __initcall(x);


Kernel通过调用do_initcalls(void)加载模块,具体流程如下图:



static void__init do_initcalls(void)

{

initcall_t*fn;

for (fn =__early_initcall_end; fn < __initcall_end; fn++)

do_one_initcall(*fn);

/* Makesure there is no pending stuff from the initcall sequence */

flush_scheduled_work();

}

因此驱动模块在Kernel启动过程中的启动次序是非常靠后的


具体的每个驱动的启动次序可以从system.map看出,特别对于同一个优先级的各类驱动:

c003288ct __initcall_i2c_init2

c00328b0 t__initcall_video_early_init3

c00328b4 t__initcall_video2_early_init3

c00328b8t __initcall_aml_i2c_init3

c0032c18t __initcall_i2c_dev_init6

c0032c28 t__initcall_videodev_init6

c0032c30t __initcall_v4l2_i2c_drv_init6

c0032c34t __initcall_v4l2_i2c_drv_init6

c0032d24 t__initcall_video_init6

c0032d28 t__initcall_video2_init6

对于同一级别的 __initcall的次序 主要由MakeFile中.o文件的链接次序决定,具体看Kernel下的主Makefile ---- Build vmlinux

以及kernel/driver 下的obj-y

相关文章推荐

内核驱动初始化顺序 ---- __define_initcall

内核驱动初始化顺序: 内核第一个C函数 main.c/start_kernel() ---> rest_init() ---> kernel_thread(kernel_init, NULL, CL...

各种initcall的执行先后顺序(module_init、postcore_initcall、arch_initcall、subsys_initcall、 fs_initcall)

现在以module_init为例分析initcall在内核中的调用顺序 在头文件init.h中,有如下定义: #define module_init(x)     __initcall(x); ...

linux initcall机制

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

分析kernel的initcall函数

先来看看这些initcall函数的声明: /* include/linux/init.h */ /* initcalls are now grouped by functionality into...
  • xuan_h
  • xuan_h
  • 2014年10月06日 09:23
  • 362

Linux驱动late_initcall和module_init相关分析

文章来源:http://blog.chinaunix.net/uid-29570002-id-4387097.html Linux系统启动过程很复杂,因为它既需要支持模块静态加载机制也要支持动态...
  • jzjhome
  • jzjhome
  • 2017年05月26日 11:27
  • 377

subsys_initcall

宏定义__define_initcall(level,fn)对于内核的初始化很重要,他指示编译器在编译的时候,将一系列初始化函数的起始地址值按照一定的顺序放在一个section中。在内核初始化段,do...

kernel 启动过程之五, initcall 的来由, console 的初始化

参见include/linux/init.h和vmlinux.lds 1) 所有标识为__init的函数在链接的时候都放在.init.text这个区段内, 在这个区段中,函数的摆放顺序是和链接的...

Linux内核中的xx_initcall初始化标号

初始化标号 先看这些宏的定义(定义在文件include/linux/init.h中) [cpp] view plaincopy #define pure_initcall(f...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:initcall的执行顺序
举报原因:
原因补充:

(最多只允许输入30个字)