如何知道是否有一个(嵌入式/内核模块)设备驱动程序来控制运行中的Linux上的设备?
我如何知道正在运行的Linux是否支持某个设备,如果支持,则由哪个设备驱动程序来控制它?
例如,服务器(PowerEdge 2900)上的lspci
给出:
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)
我如何找到:
- 哪个设备驱动程序(内核模块)控制每个设备?
- 哪个设备由内核中编译的设备驱动程序控制(而不是作为模块)
- 哪个设备没有设备驱动程序(以模块形式编译或者以模块形式编译)?
该脚本(从"坚果壳中的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:v00001002d0000515Esv00001028sd000001B1bc03sc00i00
转换为10:0d.0 VGA兼容控制器:ATI Technologies Inc ES1000(rev 02)
- 在某些情况下,设备位于MB的内部,我什至不知道找到设备真实名称的方法。例如:
/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:
和许多其他。
- 当设备驱动程序被编译(或者不存在)时,响应为" FATAL:找不到模块_XXXX_。"表明没有设备模块。
在某些情况下,驱动程序是在(例如)中编译的
/sys/devices/platform/serial8250 --> platform:serial8250 FATAL: Module platform:serial8250 not found. /sys/devices/platform/i8042 --> platform:i8042 FATAL: Module platform:i8042 not found.
在其他情况下,该驱动程序根本不存在。但是我不知道一种区别的方法。
有人知道吗?
解决方案
我认为我们无法在Windows设备管理器中获得100%明确的答案。
- 一个设备可以由几个内核模块来控制(例如" nvidia" +" agpgart")。
- 内核模块可以控制多个设备(" usbhid")。
- 我们也可以具有多对多关系(
usbcore
+usbhid
)。
尝试使用HAL设备管理器,它也可以作为" KDE HAL设备管理器"和" gnome-device-manager"使用。基本上,这些是硬件抽象层(HAL)的前端,该层读取为/ sysfs /
等。
它提供类似" info.linux.driver"的信息,请参见下面的屏幕截图:
对不起,我不知道如何在sysfs中自己弄乱这些信息,但是如果HAL能够找到它,它就必须在某处:-
lspci -n将为我们提供PCI ID,我们可以在linux内核驱动程序数据库中进行搜索。这将告诉我们要启用哪些内核选项。
下面的脚本将告诉我们正在运行哪些动态加载的驱动程序,尽管我还希望以一种自动的方式来确定实际使用的模块中已编译的模块,因此我可以使内核更加膨胀。
#!/bin/bash /sbin/lsmod | tail -n+2 | cut -d" " -f1 | xargs /sbin/modinfo -n | sort ;
我不确定其余的内容对问题有多重视,但认为我们或者其他人可能会觉得有用。
以下代码将找出由哪个.config选项控制每个动态加载的内核模块,尽管我还没有找到对ubuntu lum软件包中的动态模块执行相同操作的方法(此脚本仍在开发):
#!/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(04:00.0 Network controller: Broadcom Corporation BCM4312 802.11b/g (rev 01) Kernel driver in use: wl Kernel modules: wl, ssb); } 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 { }
Andreas Goelzer提供了一个脚本,只需稍加修改即可关闭.config中所有未使用的内核模块,从而显着加快了编译速度。
你可以在这里找到它:
http://andreas.goelzer.de/kernel-config-based-on-lsmod-output
嗯,这有点晚了,也许在那时(2008年)甚至还不存在,但是lspci -n或者更好的lspci -k应该可以解决此问题;例如:
##代码##