Ответ 1
Встроенные драйверы не загружаются, следовательно, встроены. Их функции инициализации вызываются, и драйверы активируются, когда ядро настраивается. Эти функции init вызываются в init/main.c::do_initcalls()
. Все вызовы init классифицируются по уровням, которые определены в initcall_levels
и include/linux/init.h
Эти уровни являются исполнительными символами, определенными в компоновщике script (arch/*/kernel/vmlinux.lds.*
). Во время компиляции ядра компоновщик собирает все функции, отмеченные module_init()
или другие *_initcall()
, классифицирует уровни, объединяет все функции на одном уровне вместе в одном месте и создает как массив указателей функций.
Что делает do_initcall_level() во время выполнения, вызывать каждую функцию, указанную указателями в массиве. В do_initcall_level нет политики вызова, кроме уровней, но порядок в массиве определяется во время ссылки.
Итак, теперь вы можете видеть, что порядок инициации драйвера фиксирован во время ссылки, но что вы можете сделать?
- поместите свою функцию init на более высокий уровень или
- поставьте драйвер устройства в верхнее положение в
Makefile
Первое ясно, если вы прочитали выше. т.е.) используйте early_initcall(), если это подходит.
Во втором нужно немного больше объяснений. Причина, по которой порядок в вопросе Makefile
заключается в том, как работает текущая система сборки ядра и как работают компоновщики. Короче говоря, система сборки принимает все объектные файлы в obj-y
и связывает их вместе. Он сильно зависит от среды, но существует высокая вероятность того, что компоновщик разместит первый объектный файл в obj-y
в нижнем адресе, таким образом, названный ранее.
Если вы хотите, чтобы ваш драйвер вызывался раньше других драйверов в том же каталоге, это самый простой способ сделать это.