求教:linux2.6 启动时驱动加载顺序是如何的?
向各位请假一下linux2.6在启动的过程中驱动的加载的顺序是在哪里定义,如果更改这些启动顺序?
最近在调试一个键盘驱动,通过启动时的打印信息发现键盘驱动的加载早于I2C驱动的加载,而键盘驱动里需要调用I2C读取键盘信息,如果调整驱动的加载顺序让I2C先于键盘加载呢?
------解决方案--------------------阅读include/linux/init.h 头文件, 参考: http://blogold.chinaunix.net/u2/72751/showart_1074704.html
------解决方案--------------------/lib/modules/2.6.35-24-generic/modules.dep
这个文件里面有依赖关系,如果你的驱动是在磁盘里面,用modprobe来加载的话,正常的话这个配置文件depmod命令会自动生成一个正确的。不过你也可以手工自己改一下。
驱动在initrd image里面的话,看看里面有没有modules.dep 文件 ,或者一下脚本里面insmod顺序
------解决方案--------------------我猜想keybd_attach_adapter应该只是作了一个注册动作,并没有真正调用I2C的功能,而且驱动本身没有执行(你作了内核线程除外)什么动作,都需要外部事件来驱动它去作,所以初始化的时候并没有什么问题。而到你真正相应操作的时候I2C驱动也已经加载了。
------解决方案--------------------如果想把模块的加载提前,可以把module_init改为core_initcall,这样此模块的初始化函数就会在内核初始化时调用,比一般模块的初始化要早。我把自己的i2c模块这么提前是没有问题的。
在<内核>/include/linux/init.h中定义了各种初始化的优先级:
/*
* Early initcalls run before initializing SMP.
*
* Only for built-in code, not modules.
*/
#define early_initcall(fn) __define_initcall("early",fn,early)
/*
* 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)