Как узнать, есть ли драйвер устройства (скомпилированный в /kernel module), управляющий устройством на работающем Linux?

Как узнать, поддерживается ли устройство на работающем Linux, и если да, то какой драйвер устройства контролирует его? Например, lspci на сервере (PowerEdge 2900) дает:

00:00.0 Host bridge: Intel Corporation 5000X Chipset Memory Controller Hub (rev 12)
00:02.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4 Port 2 (rev 12)
00:03.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4 Port 3 (rev 12)
00:04.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4 Port 4 (rev 12)
00:05.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4 Port 5 (rev 12)
00:06.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x8 Port 6-7 (rev 12)
00:07.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4 Port 7 (rev 12)
00:08.0 System peripheral: Intel Corporation 5000 Series Chipset DMA Engine (rev 12)
00:10.0 Host bridge: Intel Corporation 5000 Series Chipset FSB Registers (rev 12)
00:10.1 Host bridge: Intel Corporation 5000 Series Chipset FSB Registers (rev 12)
00:10.2 Host bridge: Intel Corporation 5000 Series Chipset FSB Registers (rev 12)
00:11.0 Host bridge: Intel Corporation 5000 Series Chipset Reserved Registers (rev 12)
00:13.0 Host bridge: Intel Corporation 5000 Series Chipset Reserved Registers (rev 12)
00:15.0 Host bridge: Intel Corporation 5000 Series Chipset FBD Registers (rev 12)
00:16.0 Host bridge: Intel Corporation 5000 Series Chipset FBD Registers (rev 12)
00:1c.0 PCI bridge: Intel Corporation 631xESB/632xESB/3100 Chipset PCI Express Root Port 1 (rev 09)
00:1d.0 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (rev 09)
00:1d.1 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (rev 09)
00:1d.2 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (rev 09)
00:1d.3 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #4 (rev 09)
00:1d.7 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset EHCI USB2 Controller (rev 09)
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev d9)
00:1f.0 ISA bridge: Intel Corporation 631xESB/632xESB/3100 Chipset LPC Interface Controller (rev 09)
00:1f.1 IDE interface: Intel Corporation 631xESB/632xESB IDE Controller (rev 09)
00:1f.2 IDE interface: Intel Corporation 631xESB/632xESB/3100 Chipset SATA IDE Controller (rev 09)
01:00.0 PCI bridge: Intel Corporation 80333 Segment-A PCI Express-to-PCI Express Bridge
01:00.2 PCI bridge: Intel Corporation 80333 Segment-B PCI Express-to-PCI Express Bridge
02:0e.0 RAID bus controller: Dell PowerEdge Expandable RAID controller 5
04:00.0 PCI bridge: Broadcom EPB PCI-Express to PCI-X Bridge (rev c3)
05:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet (rev 12)
06:00.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express Upstream Port (rev 01)
06:00.3 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express to PCI-X Bridge (rev 01)
07:00.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E1 (rev 01)
07:01.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E2 (rev 01)
08:00.0 PCI bridge: Broadcom EPB PCI-Express to PCI-X Bridge (rev c3)
09:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet (rev 12)
0b:02.0 Multimedia audio controller: Creative Labs SB Audigy (rev 03)
0b:02.1 Input device controller: Creative Labs SB Audigy Game Port (rev 03)
0b:02.2 FireWire (IEEE 1394): Creative Labs SB Audigy FireWire Port
10:0d.0 VGA compatible controller: ATI Technologies Inc ES1000 (rev 02)

Как найти:

  • какой драйвер устройства (модуль ядра) управляет каждым устройством?
  • какое устройство управляется драйвером устройства, скомпилированным в ядре (а не как модуль)
  • какое устройство не имеет драйвера устройства (скомпилировано в или как модуль)?

Этот script (адаптированный из другого в "Ядре Linux в двух словах" ) частично разрешает # 1:

#!/bin/bash
for i in $(find /sys/ -name modalias); do
 echo "----------------------------------"
 modalias=$(cat $i)
 echo "$(dirname $i) --> $modalias" 
 /sbin/modprobe --config /dev/null --show-depends $(cat $i) 2>&1
done

Но есть некоторые проблемы:

  • Я не знаю автоматизированного способа конвертировать /sys/devices/pci0000:00/0000:00:1e.0/0000:10:0d.0 --> pci:************************************************* в 10:0d.0 VGA compatible controller: ATI Technologies Inc ES1000 (rev 02)

  • В некоторых случаях устройства являются внутренними для МБ, и я даже не знаю, как найти настоящее имя устройства. Например:

/sys/devices/platform/dcdbas --> platform:dcdbas
/sys/devices/platform/iTCO_wdt --> platform:iTCO_wdt
/sys/devices/LNXSYSTM:00 --> acpi:LNXSYSTM:
/sys/devices/LNXSYSTM:00/device:00/PNP0C33:00 --> acpi:PNP0C33:PNP0C01:
/sys/devices/LNXSYSTM:00/device:00/PNP0A08:00 --> acpi:PNP0A08:PNP0A03:
/sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/PNP0200:00 --> acpi:PNP0200:

и многие другие.

  1. Когда драйвер устройства скомпилирован (или не существует), ответ FATAL: Module _XXXX_ not found. Указывает, что для устройства нет модуля.

В некоторых случаях драйвер скомпилирован в (например)

/sys/devices/platform/serial8250 --> platform:serial8250
FATAL: Module platform:serial8250 not found.
/sys/devices/platform/i8042 --> platform:i8042
FATAL: Module platform:i8042 not found.

В других случаях драйвер просто не существует. Но я не знаю способа сказать разницу.

Кто-нибудь знает?

5 ответов

Попробуйте диспетчер устройств HAL, который также доступен как "менеджер устройств KDE HAL" и "gnome-device-manager". В принципе, это интерфейсы к уровню абстракции оборудования (HAL), который читает /sysfs/ et al.

Он дает информацию типа "info.linux.driver", см. снимок экрана ниже:

Мне жаль, что я не знаю, как выставить эту информацию самостоятельно в sysfs, но она должна быть где-то, если HAL сможет ее найти: -)


Я не думаю, что вы можете получить 100% -ный ответ, который вы можете получить в диспетчере устройств Windows.

  • Устройство может управляться несколькими модулями ядра (скажем nvidia + agpgart).
  • Модуль ядра может управлять более чем одним устройством (usbhid).
  • Вы также можете иметь отношения "многие ко многим" (usbcore + usbhid).


lspci -n предоставит вам идентификаторы PCI, которые вы можете найти в базе данных драйвера ядра Linux. Это скажет вам, какие опции ядра включить.


Хорошо, это немного поздно, и, возможно, в то время (2008) даже не существовало, но lspci -n или лучше lspci -k должен исправить проблему; например:

04: 00.0 Сетевой контроллер: Broadcom Corporation BCM4312 802.11b/g (rev 01)

Kernel driver in use: wl
 Kernel modules: wl, ssb


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

#!/bin/bash
/sbin/lsmod | tail -n+2 | cut -d" " -f1 | xargs /sbin/modinfo -n | sort ;

Я не уверен, насколько релевантно, остальное это относится к вашему вопросу, но подумал, что вы или другие могли бы найти его полезным.

В следующем коде будет показано, какие параметры .config управляют каждым из динамически загружаемых модулей ядра, хотя я еще не выяснил способ сделать то же самое для динамических модулей в пакете ubuntu lum (этот script все еще продолжается работа):

#!/usr/bin/perl -w
use strict;
use Getopt::Long;
my ($kernConfigIn, $kernConfigOut, $kernSourceDir, $lumSourceDir, $lumConfigIn, $lumConfigOut, $help);
GetOptions(
 'ksd=s' => \$kernSourceDir,
 'lsd=s' => \$lumSourceDir,
 'kci=s' => \$kernConfigIn,
 'lci=s' => \$lumConfigIn,
 'kco=s' => \$kernConfigOut,
 'lco=s' => \$lumConfigOut,
 'help' => \$help);
if ($help || !$kernSourceDir || !$lumSourceDir ) { Usage($0); }
sub Usage { print "usage error\n"; exit; };
my @modules = `/sbin/lsmod | tail -n+2 | cut -d" " -f1 | xargs /sbin/modinfo -n | sort ;`;
my @kconfig;
foreach my $module (@modules) {
 my ($package, $path, $modName) = ( $module =~ m/\/((?:kernel)|(?:ubuntu))\/(.*)\/(.*)\.ko/) ;
 $package eq 'kernel' ? push @kconfig, kernel($package, $path, $modName) : ubuntu($package, $path, $modName); 
}
# kernel package
sub kernel {
 my ($package, $path, $modName) = @_;
 my $makefile = $kernSourceDir.$path."/Makefile"; 
# print "$package, $path, $modName\n";
# print "$makefile\n";
 my $option;
 chomp($option = `cat $makefile | sed -n "s/^obj-\\\$(CONFIG_\\([A-Z0-9_]*\\))\\W*+=.*"$modName"\\.o.*/CONFIG_\\1/p"`);
 print "$option\n";
 return $option;
}
# deal with lum configs
sub ubuntu {
}

Существует Andrea Goelzer script, который с небольшими изменениями отключит все неиспользуемые модули ядра в вашем .config, что значительно ускорит ваши компиляции.

Вы можете найти его здесь:

http://andreas.goelzer.de/kernel-config-based-on-lsmod-output

licensed under cc by-sa 3.0 with attribution.