Для того же уровня это определяется порядком Makefile, например, в моих драйверах / input / touchscreen / Makefile:
obj-$(CONFIG_TOUCHSCREEN_IT7259_I2C) += it7259_ts_i2c.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/
it7259 будет вызываться первым.
Порядок детализации можно найти в out / system.map:
c116ae80 T __initcall6_start
...
c116b278 t __initcall_it7259_ts_driver_init6
c116b27c t __initcall_fts_ts_init6
...
c116b6a4 T __initcall7_start
Если вы измените порядок в Makefile, обязательно очистите папку «out» и перестройте, тогда system.map будет обновлен с помощьюновый порядок.
Дополнительная информация:
Для создания раздела .init.data будет использовано следующее определение:
define module_init (x) __initcall (x);
определить __define_initcall (уровень, fn, id) \
статический initcall_t initcall _ ## fn ## id __used \ __atribute (( section (". Initcall" level ".init"))) = fn
каждый __initcall (x) станет элементом в разделе .init.data, например:
c116b27c t __initcall_fts_ts_init6
поток инициализации при загрузке: start_kernel -> rest_init -> kernel_init -> do_basic_setup -> do_initcalls
static void __init do_initcalls (void) {int level;
for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
do_initcall_level(level);
}
static void __init do_initcall_level (int level) {extern const struct kernel_param __start ___ param [], __stop ___ param [];initcall_t * п;
strcpy(static_command_line, saved_command_line);
parse_args(initcall_level_names[level],
static_command_line, __start___param,
__stop___param - __start___param,
level, level,
repair_env_string);
for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
do_one_initcall(*fn);
* * +1042} * 1 043 * *
статическая initcall_t initcall_levels [] __initdata = {__initcall0_start, __initcall1_start, __initcall2_start, __initcall3_start, __initcall4_start, __initcall5_start, __initcall6_start, __initcall7_start, __initcall_end,};
И в vmlinux.lds он пойдет по адресу в разделе .init.data.