当前位置: 技术问答>linux和unix
问斑竹个简单的问题。
来源: 互联网 发布时间:2016-09-01
本文导语: 我把一些驱动模块静态加载到内核,都是通过module_init,我如何知道他们的加载顺序, module_init的加载优先级是6,这些驱动在如何确定顺序。 | 本帖最后由 wenxy1 于 2009-12-30 15:45:41 编辑 linux kernel version: 2.6.32. /in...
我把一些驱动模块静态加载到内核,都是通过module_init,我如何知道他们的加载顺序,
module_init的加载优先级是6,这些驱动在如何确定顺序。
module_init的加载优先级是6,这些驱动在如何确定顺序。
|
linux kernel version: 2.6.32.
/include/linux/init.h
/*
* A "pure" initcall has no dependencies on anything else, and purely
* initializes variables that couldn't be statically initialized.
*
* This only exists for built-in code, not for modules.
*/
#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)
#define __initcall(fn) device_initcall(fn)
|
参见include/linux/init.h和vmlinux.lds
1)
所有标识为__init的函数在链接的时候都放在.init.text这个区段内,
在这个区段中,函数的摆放顺序是和链接的顺序有关的,是不确定的。
2)
所有的__init函数在区段.initcall.init中还保存了一份函数指针,
在初始化时内核会通过这些函数指针调用这些__init函数指针,
并在整个初始化完成后,释放整个init区段(包括.init.text,.initcall.init等),
注意,这些函数在内核初始化过程中的调用顺序只和这里的函数指针的顺序有关,
和1)中所述的这些函数本身在.init.text区段中的顺序无关。
在2.4内核中,这些函数指针的顺序也是和链接的顺序有关的,是不确定的。
在2.6内核中,initcall.init区段又分成7个子区段,分别是
.initcall1.init
.initcall2.init
.initcall3.init
.initcall4.init
.initcall5.init
.initcall6.init
.initcall7.init
当需要把函数fn放到.initcall1.init区段时,只要声明
core_initcall(fn);
即可。
其他的各个区段的定义方法分别是:
core_initcall(fn) --->.initcall1.init
postcore_initcall(fn) --->.initcall2.init
arch_initcall(fn) --->.initcall3.init
subsys_initcall(fn) --->.initcall4.init
fs_initcall(fn) --->.initcall5.init
device_initcall(fn) --->.initcall6.init
late_initcall(fn) --->.initcall7.init
而与2.4兼容的initcall(fn)则等价于device_initcall(fn)。
各个子区段之间的顺序是确定的,即先调用.initcall1.init中的函数指针
再调用.initcall2.init中的函数指针,等等。
而在每个子区段中的函数指针的顺序是和链接顺序相关的,是不确定的。
在内核中,不同的init函数被放在不同的子区段中,因此也就决定了它们的调用顺序。
这样也就解决了一些init函数之间必须保证一定的调用顺序的问题。
1)
所有标识为__init的函数在链接的时候都放在.init.text这个区段内,
在这个区段中,函数的摆放顺序是和链接的顺序有关的,是不确定的。
2)
所有的__init函数在区段.initcall.init中还保存了一份函数指针,
在初始化时内核会通过这些函数指针调用这些__init函数指针,
并在整个初始化完成后,释放整个init区段(包括.init.text,.initcall.init等),
注意,这些函数在内核初始化过程中的调用顺序只和这里的函数指针的顺序有关,
和1)中所述的这些函数本身在.init.text区段中的顺序无关。
在2.4内核中,这些函数指针的顺序也是和链接的顺序有关的,是不确定的。
在2.6内核中,initcall.init区段又分成7个子区段,分别是
.initcall1.init
.initcall2.init
.initcall3.init
.initcall4.init
.initcall5.init
.initcall6.init
.initcall7.init
当需要把函数fn放到.initcall1.init区段时,只要声明
core_initcall(fn);
即可。
其他的各个区段的定义方法分别是:
core_initcall(fn) --->.initcall1.init
postcore_initcall(fn) --->.initcall2.init
arch_initcall(fn) --->.initcall3.init
subsys_initcall(fn) --->.initcall4.init
fs_initcall(fn) --->.initcall5.init
device_initcall(fn) --->.initcall6.init
late_initcall(fn) --->.initcall7.init
而与2.4兼容的initcall(fn)则等价于device_initcall(fn)。
各个子区段之间的顺序是确定的,即先调用.initcall1.init中的函数指针
再调用.initcall2.init中的函数指针,等等。
而在每个子区段中的函数指针的顺序是和链接顺序相关的,是不确定的。
在内核中,不同的init函数被放在不同的子区段中,因此也就决定了它们的调用顺序。
这样也就解决了一些init函数之间必须保证一定的调用顺序的问题。