驱动模块的加载顺序由什么决定的呢? 如何将模块加载的顺序提前或者延后呢?
#define module_init(x) __initcall(x); #define __initcall(fn) device_initcall(fn) #define core_initcall(fn) __define_initcall(fn, 1) #define core_initcall_sync(fn) __define_initcall(fn, 1s) #define postcore_initcall(fn) __define_initcall(fn, 2) #define postcore_initcall_sync(fn) __define_initcall(fn, 2s) #define arch_initcall(fn) __define_initcall(fn, 3) #define arch_initcall_sync(fn) __define_initcall(fn, 3s) #define subsys_initcall(fn) __define_initcall(fn, 4) #define subsys_initcall_sync(fn) __define_initcall(fn, 4s) #define fs_initcall(fn) __define_initcall(fn, 5) #define fs_initcall_sync(fn) __define_initcall(fn, 5s) #define rootfs_initcall(fn) __define_initcall(fn, rootfs) #define device_initcall(fn) __define_initcall(fn, 6) #define device_initcall_sync(fn) __define_initcall(fn, 6s) #define late_initcall(fn) __define_initcall(fn, 7) #define late_initcall_sync(fn) __define_initcall(fn, 7s) start_kernel -> rest_init -> kernel_init -> kernel_init_freeable -> do_basic_setup -> do_initcalls //遍历各个优先级 -> do_initcall_level//遍历相同优先级各个函数 -> do_one_initcall遍历相同优先级的initcall时,是按照地址从低到高进行的,因此调用顺序就是编译时链接到initcall section的顺序,通过System.map可以查到顺序,例如:
62054:ffffffc000e61c38 T __initcall_start 62055:ffffffc000e61c38 t __initcall_trace_init_flags_sys_exitearly 62057:ffffffc000e61c40 t __initcall_trace_init_flags_sys_enterearly 62058:ffffffc000e61c48 t __initcall_init_hw_perf_eventsearly 62059:ffffffc000e61c50 t __initcall_cpu_suspend_initearly 链接顺序可以通过调整Makefile中的.o文件的先后进行调整。