Модули драйверов загружаются и выгружаются автоматически?

15

В Ubuntu 14.04 я обнаружил, что когда я не подключаю внешний беспроводной адаптер, его модуль rt2800usbвсе еще отображается lsmod.

  1. когда происходит автоматическая загрузка модуля драйвера? Это когда устройство подключено к компьютеру или когда загружается ОС?

  2. когда происходит автоматическая выгрузка модуля драйвера? Это когда устройство отключено от компьютера или когда ОС выключается?

Тим
источник

Ответы:

13

Когда ядро ​​обнаруживает новое устройство, оно запускает программу modprobeи передает ему имя, которое идентифицирует устройство. Большинство устройств идентифицируются по зарегистрированным номерам для поставщика и модели, например, идентификаторы PCI или USB . modprobeПрограмма обращается к таблице модуля псевдонима , чтобы найти имя файла , который содержит драйвер для данного устройства. Аналогичный принцип применяется к драйверам для вещей, которые не являются аппаратными устройствами, такими как файловые системы и криптографические алгоритмы. Для получения дополнительной информации см. Debian не обнаруживает последовательную карту PCI после перезагрузки./lib/modules/VERSION/modules.alias

Как только modprobe определит, какой модуль file ( .ko) содержит запрошенный драйвер, он загружает файл модуля в ядро: код модуля динамически загружается в ядро. Если модуль загружен успешно, он появится в списке из lsmod.

Автоматическая загрузка модулей происходит, когда ядро ​​обнаруживает новое горячее подключаемое оборудование, например, когда вы подключаете периферийное устройство USB. Операционная система также выполняет перечисление всего оборудования, которое присутствует в системе на ранних этапах запуска, чтобы загрузить драйверы для периферийных устройств, которые присутствуют во время загрузки.

Также можно вручную запросить загрузку модуля с помощью команды modprobeили insmod. Большинство дистрибутивов содержат скрипт запуска, который загружает модули, перечисленные в /etc/modules. Другой способ загрузки модулей - это если они зависят от модуля: если модуль A зависит от модуля B, то modprobe Aзагружает B перед загрузкой A.

После загрузки модуля он остается загруженным до тех пор, пока не будет явно выгружен, даже если все устройства, использующие этот драйвер, были отключены. Давным-давно существовал механизм автоматической выгрузки неиспользуемых модулей, но он был удален, если я правильно помню, когда на сцену вышел udev. Я подозреваю, что автоматическая выгрузка модулей не является обычной функцией, потому что системы, которые, как правило, нуждаются в этом, в основном являются настольными ПК с большим количеством памяти в любом случае (в масштабе кода драйвера).

Жиль "ТАК - перестань быть злым"
источник
Благодарю. Я не изменил /etc/modules. rt2800usbнаходится в выводе lsmod, и означает ли это, что я подключил его устройство к компьютеру до загрузки?
Тим
1
@Tim Если модуль загружен, и вы не загрузили его явно, и его нет в списке /etc/modules, то да, вероятно, причина загрузки модуля заключается в том, что устройство присутствовало в какой-то момент.
Жиль "ТАК - перестань быть злым"
5

Модули загружаются при загрузке системы через начальный RAM-диск, называемый initrd . Раздел обоснования утверждает:

Многие дистрибутивы Linux содержат один общий образ ядра Linux, который разработчики дистрибутива специально создают для загрузки на самых разных аппаратных средствах. Драйверы устройств для этого общего образа ядра включены в качестве загружаемых модулей ядра, поскольку статическая компиляция многих драйверов в одно ядро ​​приводит к тому, что образ ядра становится намного больше, возможно, слишком большим для загрузки на компьютерах с ограниченной памятью. Это тогда поднимает проблему обнаружения и загрузки модулей, необходимых для монтирования корневой файловой системы во время загрузки, или, в этом отношении, определения, где или что находится корневая файловая система.

Ubuntu, как и многие другие дистрибутивы, выбирает загрузку каждого драйвера устройства в этот initrd, независимо от того, нужен драйвер или нет, а также независимо от того, присутствует ли устройство в системе или нет. Как указал Джайлс, все это загружается в ОЗУ, а затем при запуске обнаруживаются используемые модули, а неиспользуемые модули удаляются из ОЗУ. Использование этого подхода гарантирует, что Ubuntu всегда будет запускаться в любой системе независимо от настроек. Ubuntu имитирует монолитное ядро, используя микроядерные конструкции. Посмотрите причину это работает


  1. Модуль rt2800usbвсегда будет загружаться при загрузке, потому что модуль был включен в initramfs, на который ссылался Жиль. Initramfs является преемником initrd, поэтому он всегда будет показан как lsmod. Обратите внимание, что вы можете вставить вновь скомпилированный модуль в ядро, используя modprobeимя модуля.

В качестве теста перезагрузите систему с отключенным беспроводным адаптером. Если все идет хорошо, модуль не будет указан в lsmodвыводе s, потому что во время загрузки процесс обнаружения, запущенный initramfs и системой init, не обнаружил устройство во время исследования, и модуль был удален из ОЗУ.

  1. Чтобы удалить модуль во время работы системы, вы можете использовать такие команды, как rmmodили modprobe -rпосле имени модуля. При следующей загрузке модуль будет перезагружен. Смотрите выше. В большинстве случаев модуль не удаляется динамически, так как это отключило бы горячее подключение, т. Е. После удаления модуля устройство, использующее его, не может быть снова обнаружено при повторном подключении.

Чтобы удалить модуль из lsmod, вы должны удалить его из образа initramfs, созданного путем перекомпиляции ядра без выбранного модуля и последующей перестройки образа. Это отключает все обнаружение указанного модуля.

eyoung100
источник
3
Вы путаете загрузку файла в RAM как часть RAM-диска и загрузку (т.е. динамическое связывание) модуля в работающее ядро. Модули временно загружаются в память, а не в ядро, из initrd (технически в настоящее время это initramfs), но затем они удаляются из памяти после монтирования реального корня. Модули загружаются в ядро ​​только при обнаружении устройства, использующего их (за некоторыми исключениями).
Жиль "ТАК - перестань быть злым"
Хотя я согласен здесь, он говорил о выгрузке и загрузке одного модуля, что невозможно сделать, если он не решит перенастроить RAM-диск Ubuntu, что не рекомендуется, поскольку Ubuntu выбирает загрузку всех модулей в RAM при каждом обновлении ядра. Все модули загружаются каждый раз, просто они не все используются.
eyoung100
2
Нет, речь идет о загрузке и выгрузке модуля в ядро. Ни ваш оригинальный ответ, ни ваш исправленный ответ не обращаются к этому. Initramfs не имеет отношения к данному вопросу (или, по крайней мере, имеет отношение к периферии).
Жиль "ТАК - перестань быть злым"
@ Жиль, это лучше ??
eyoung100
1
@ eyoung100, я согласен с Жилем. Обсуждение initramfs не имеет отношения к вопросу. Модули обычно загружаются путем перечисления устройств /sysи загрузки драйверов для устройств, которые фактически находятся в системе. Это происходит независимо от того, присутствует ли устройство при загрузке или подключено позже. udevимеет гораздо больше общего с этим, чем initramfs / initrd, и то, будут ли все, большинство или только некоторые модули скопированы в initramfs (опция конфигурации в /etc/initramfs-tools/initramfs.conf), не имеет особого значения.
Селада