Сага о драйверах
Статья пишется на основе знаменитой статьи "Сага о драйверах"
Замечания и предложения по статье можно посылать в телеграмм канал Saga_o_Driverah
У вас не работает "железо", что делать
Часто на форуме можно встретить вопрос такого типа:
"Я поставил ваш дистрибутив на свой ноутбук и у меня не работает WiFi карточка".
Давайте на примере этого вопроса узнаем кое-что об оборудовании компьютера (дальше для краткости я его буду просто называть "железо") и о программах,которые с ним работают (для краткости - драйвера).
"Железо" может быть внутри компьютера, или внешним. Оно может подсоединяться к "сердцу" компьютера, его процессору по различным шинам (линиям связи). Для обеспечения этой связи обычно используется "материнская плата" (видел я и компьютеры, в которрых она называлась просто "задняя стенка" ;-) ).
Существует достаточно много различных типов таких шин - USB, PCI, PS/2, SATA, Com-порт, LPT порт и т.п.
Если мы говорим про Wi-Fi карточку в ноутбуке, то она может находится или на шине USB или на шине PCI (я говорю о них как о типе шин, так-как например, USB бывают разными, как впрочем и PCI ).
Для обнаружения таких устройств существуют две команды lspci и lsusb.
lsusb
Вот я сейчас сижу за ноутбуком и даю команду :
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 002: ID 0bda:57b4 Realtek Semiconductor Corp. USB Camera
Bus 006 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 008 Device 002: ID 13d3:3501 IMC Networks
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 007 Device 004: ID 1ea7:0064 SHARKOON Technologies GmbH 2.4GHz Wireless rechargeable vertical mouse [More&Better]
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Что мы видим?
Bus 007 Device 004: ID 1ea7:0064 SHARKOON Technologies GmbH 2.4GHz Wireless rechargeable vertical mouse [More&Better]
Bus 007 - устройство висит на седьмой шине USB
Device 004:- оно на этой шине четвертое
ID 1ea7:0064 - это его идентификатор, определяющая какая фирма произвела устройство и идентификатор самого устройства
SHARKOON Technologies GmbH 2.4GHz Wireless rechargeable vertical mouse [More&Better] - имя устройства (за его идентификацию отвечает пакет usbids)
Допустим нам надо посмотреть какой драйвер (в данном случае модуль ядра) "обслуживает" устройство мыши.
Для этого даём команду :
lsusb -tv
/: Bus 08.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/5p, 12M
ID 1d6b:0001 Linux Foundation 1.1 root hub
|__ Port 5: Dev 2, If 0, Class=Wireless, Driver=btusb, 12M
ID 13d3:3501 IMC Networks
|__ Port 5: Dev 2, If 1, Class=Wireless, Driver=btusb, 12M
ID 13d3:3501 IMC Networks
/: Bus 07.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/5p, 12M
ID 1d6b:0001 Linux Foundation 1.1 root hub
|__ Port 1: Dev 4, If 0, Class=Human Interface Device, Driver=usbhid, 12M
ID 1ea7:0064 SHARKOON Technologies GmbH 2.4GHz Wireless rechargeable vertical mouse [More&Better]
/: Bus 06.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/5p, 480M
ID 1d6b:0002 Linux Foundation 2.0 root hub
|__ Port 4: Dev 2, If 0, Class=Video, Driver=uvcvideo, 480M
ID 0bda:57b4 Realtek Semiconductor Corp.
|__ Port 4: Dev 2, If 1, Class=Video, Driver=uvcvideo, 480M
ID 0bda:57b4 Realtek Semiconductor Corp.
/: Bus 05.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/5p, 480M
ID 1d6b:0002 Linux Foundation 2.0 root hub
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M
ID 1d6b:0003 Linux Foundation 3.0 root hub
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
ID 1d6b:0002 Linux Foundation 2.0 root hub
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=vhci_hcd/8p, 5000M
ID 1d6b:0003 Linux Foundation 3.0 root hub
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=vhci_hcd/8p, 480M
ID 1d6b:0002 Linux Foundation 2.0 root hub
lsusb -t наглядно показывает какое USB устройство подсоединено к конкретному порту USB, Но нам в данном случае важнo, что команда показывает какой драйвер использует то, или иное устройство. В данном случае, мы видим, например, что "IMC Networks" использует модуль ядра (драйвер) btusb. И мы видим что это составное устройство. Зная устройство своего ноутбука, могу сразу сказать, что это комбинированная внутренняя карточка, одновременно работающая и с Wi-Fi и c bluetooth (сам в своё время покупал, заменив старую карточку).
lspci
Ну и для примера приведу как работать с командой lspci. На другом компьютере даю команду lspci
00:00.0 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Root Complex
00:00.2 IOMMU: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) I/O Memory Management Unit
00:04.0 PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Root Port
00:10.0 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB XHCI Controller (rev 03)
00:10.1 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB XHCI Controller (rev 03)
00:11.0 SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI mode] (rev 40)
00:12.0 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB OHCI Controller (rev 11)
00:12.2 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller (rev 11)
00:13.0 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB OHCI Controller (rev 11)
00:13.2 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller (rev 11)
00:14.0 SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 14)
00:14.2 Audio device: Advanced Micro Devices, Inc. [AMD] FCH Azalia Controller (rev 01)
00:14.3 ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)
00:14.4 PCI bridge: Advanced Micro Devices, Inc. [AMD] FCH PCI Bridge (rev 40)
00:15.0 PCI bridge: Advanced Micro Devices, Inc. [AMD] Hudson PCI to PCI bridge (PCIE port 0)
00:15.2 PCI bridge: Advanced Micro Devices, Inc. [AMD] Hudson PCI to PCI bridge (PCIE port 2)
00:15.3 PCI bridge: Advanced Micro Devices, Inc. [AMD] Hudson PCI to PCI bridge (PCIE port 3)
00:18.0 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 0
00:18.1 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 1
00:18.2 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 2
00:18.3 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 3
00:18.4 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 4
00:18.5 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 5
01:00.0 VGA compatible controller: NVIDIA Corporation GF119 [GeForce GT 610] (rev a1)
01:00.1 Audio device: NVIDIA Corporation GF119 HDMI Audio Controller (rev a1)
03:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8812AE 802.11ac PCIe Wireless Network Adapter (rev 01)
04:00.0 Ethernet controller: Qualcomm Atheros AR8161 Gigabit Ethernet (rev 10)
05:00.0 USB controller: Renesas Technology Corp. uPD720201 USB 3.0 Host Controller (rev 03)
Нас интересует это устройство:
03:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8812AE 802.11ac PCIe Wireless Network Adapter (rev 01)
03:00.0 - это "порт" подключения устройства
Network controller: Realtek Semiconductor Co., Ltd. RTL8812AE 802.11ac PCIe Wireless Network Adapter (rev 01) - его название (за него отвечает пакет pciids)
Для поиска драйверов важны идентификаторы вендора и устройства, именно по ним ищет "опреационка" какой драйвер (модуль ядра нужно загрузить). И по ним легче искать в интернете какой драйвер нужно использовать. Для примера, посмотрим эти идентификаторы у карточки "Network controller: Realtek Semiconductor Co., Ltd. RTL8812AE 802.11ac PCIe Wireless Network Adapter (rev 01)". Мы видим из предыдущей команды, что она подключяена к порту 03:00.0. Даём следующую команду:
$ lspci -n -s 03:00.0
03:00.0 0280: 10ec:8812 (rev 01)
Здесь $ - это не часть команды, а приглашение bash и в котексте статьи означает, что команду можно давать от обычного пользователя
Что мы видим :
03:00.0 - это "порт"подключения
0280: идентификатор контроллера
10ec:8812 - идентификатор вендора и идентификатор устройства
Иногда удобнее увидеть и имя устройства, тогда можно дать такую команду:
$ lspci -nn -s 03:00.0
03:00.0 Network controller [0280]: Realtek Semiconductor Co., Ltd. RTL8812AE 802.11ac PCIe Wireless Network Adapter [10ec:8812] (rev 01)
Для того, чтобы посмотреть какой модуль ядра (драйвер) "обслуживает" сейчас данное устройство надо дать команду:
# lspci -k -s 03:00.0
03:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8812AE 802.11ac PCIe Wireless Network Adapter (rev 01)
Subsystem: Realtek Semiconductor Co., Ltd. RTL8812AE 802.11ac PCIe Wireless Network Adapter
Kernel driver in use: rtl8821ae
Значок # - это приглашение root, а не команда, говорит о том, что команда требует прав root.
Как мы видим используется драйвер rtl8821ae
Хуже бывает, если система не говорит о загруженном драйвере , т.е. отсутствует строчка
Kernel driver in use: rtl8821ae
В этом случае нам надо искать какой драйвер надо использовать.
Немного теории
Под драйверами часто понимают все программы, обеспечивающие работу устройств.
В Линукс можно выделить несколько видов программ, работающих с устройств.
Наибольшая часть из таких программ в Линукс входят в ядро. Это почти все драйвера, работающие с внутренними устройствами компьютера и многие устройства использующие шину USB. Большинство из таких драйверов входят в основную ветку разработки ядра и входят в пакет kernel-image. Кроме того, помимо модулей ядра, входящих в основную ветку ядра, существуют модули ядра по какой-либо причине в него не входящие. Обычно это или модули ядра с закрытыми частями от разработчиков "железа", или новые, ещё не отлаженные до конца модули.
Поскольку Linux достаточно динамичная "среда" программного обеспечения, то иногда появляется ситуация, что какое-то оборудование могут поддерживать несколько модулей ядра.
При наличии нескольких конкурирующих модулей, для работы с конкретным устройством, возникает задача указать какой модуль применять. Для этого применяются опции блокировки конкретного модуля. Для этого в каталоге /etc/modprobe.d для этого создаётся файл, обычно с именем blacklist_суффикс.conf и с опцией blacklist имя_модуля.
Например, в пакет kernel-modules-e1000e-std-def входит файл blacklist-e1000e.conf с содержимым:
blacklist e1000e
Модули ядра расположены в каталоге /lib/modules/имя_релиза_ядра. Имя релиза загруженного ядра выдаёт команда uname -r.
Помимо модулей ядра с оборудованием работают и модули других программ, которые в обыденной жизни тоже называют драйверами.
Так со сканерами работают модули программы sane, расположенные в каталоге (для архитектуры x86_64) /usr/lib64/sane (входят в пакет libsane). Поддерживаемые сканеры проектом Sane можно посмотреть в http://www.sane-project.org/sane-supported-devices.html
А с принтерами работают модули cups, который имеет свои модули поддержки принтеров. Про поддержку принтеров проектом cups можно посмотреть https://openprinting.org/printers
Где искать драйвер
- во-первых, стоит поставить пакет типа kernel-doc-std-def, но там обычно есть описания только модулей ядра, которые уже входят в ядро.
- во-вторых, на сайте https://linux-hardware.org есть возможность поискать по идентификаторам вендора и устройства какой драйвер нужен для вашего устройства Например поиск Ищем карточку Realtek Semiconductor Co., Ltd. RTL8812AE 802.11ac PCIe Wireless Network Adapter по его id и потм по ссылке смотрим какой драйвер ядра её поддерживает
- ну и в совсем плохом случае искать в интернете по идентификаторам , лучше в виде как выдают их команды lsusb и lspci. Искать по названию устройств не эффективно, так как в поиске получите или описание драйверов для Windows или рекламу купить это устройство.