The init routines for a module that is initialized by the kernel (when they are
statically linked into the kernel) are wrapped in an initcall() macro that indicates
when in the startup sequence they should be run.
See the include file: include/linux/init.h for a list of the macros and their ordering.
The order specified there is:
- early_initcall
- pure_initcall
- core_initcall
- postcore_initcall
- arch_initcall
- subsys_initcall
- fs_initcall
- rootfs_initcall
- device_initcall
- late_initcall
Most of these have an "initcall_sync() phase, which is used to wait for completion of
all module initialization routines within that phase. The macros are used to build
a table of function pointers for each phase, which are called in sequence by
do_initcalls()
.
If "module_init()" is used to wrap the initialization function, then
by default initcall() puts the call in the "device" phase of initialization.
Within that phase, the items are ordered by link order. This means that
the table is created by the order of the functions as they are encountered
by the linker.
You may be able to move an initialization to an earlier phase, by changing which
initcall macro wraps the modules initialization function, but be careful because
there are order dependencies between the various modules. Another method of
changing the initialization order (within a phase) would be to adjust the link
order for the module in the kernel.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…