Managing Hardware and Kernel Modules with Linux
Hardware and Modules
An important part of managing any Linux server is to know how to display your current hardware and modules that are currently loaded into your kernel. Thankfully there are some commands that can be used to display this information.
Listing hardware information
A commonly used command to list information regarding your hardware is the "lsdev" command. The "lsdev" command is used to display your systems interrupt addresses and I/O ports. Information is also displayed for IRQ and DMA channel information.
To display information about your installed hardware you simply issue the "lsdev" command. There are no parameters or arguments that can be passed to this command. The example below has been run on a openSUSE system:
linux-pd5y:~ # lsdev Device DMA IRQ I/O Ports ------------------------------------------------ 0000:00:01.1 0170-0177 01f0-01f7 0376-0376 03f6-03f6 d000-d00f 0000:00:03.0 d010-d017 0000:00:04.0 d020-d03f 0000:00:05.0 d100-d1ff d200-d23f 0000:00:0d.0 d240-d247 d250-d257 d260-d26f acpi 9 ACPI 4000-4003 4004-4005 4008-400b 4020-4021 ahci 5 d240-d247 d250-d257 d260-d26f ata_piix 14 15 0170-0177 01f0-01f7 0376-0376 03f6-03f6 d000-d00f cascade 4 2 dma 0080-008f dma1 0000-001f dma2 00c0-00df e1000 d010-d017 eth0 10 fpu 00f0-00ff i8042 1 12 Intel d100-d1ff d200-d23f keyboard 0060-0060 0064-0064 ohci_hcd:usb1 11 PCI 0cf8-0cff pic1 0020-0021 pic2 00a0-00a1 rtc0 8 0070-0071 rtc_cmos 0070-0071 snd_intel8x0 5 timer 0 timer0 0040-0043 timer1 0050-0053 vboxguest 9 vesafb 03c0-03df
The information displayed from the "lsdev" command retrieves information from the "/proc" directories:
IRQ channels : /proc/interrupts
I/O memory addresses : /proc/ioports
DMA channels : /proc/dma
The "lspci" command is used to display information about PCI buses in the system and devices connected to them. Below are some of the options that can be passwd to the "lspci" command:
Basic display modes -m Dump PCI device data in a backward-compatible machine readable form. See below for details. -mm Dump PCI device data in a machine readable form for easy parsing by scripts. See below for details. -t Show a tree-like diagram containing all buses, bridges, devices and connections between them. Display options -v Be verbose and display detailed information about all devices. -vv Be very verbose and display more details. This level includes everything deemed useful. -vvv Be even more verbose and display everything we are able to parse, even if it doesn't look interesting at all (e.g., undefined memory regions). -k Show kernel drivers handling each device and also kernel modules capable of handling it. Turned on by default when -v is given in the normal mode of output. (Currently works only on Linux with kernel 2.6 or newer.) -x Show hexadecimal dump of the standard part of the configuration space (the first 64 bytes or 128 bytes for CardBus bridges). -xxx Show hexadecimal dump of the whole PCI configuration space. It is available only to root as several PCI devices crash when you try to read some parts of the config space (this behaviour probably doesn't violate the PCI standard, but it's at least very stupid). However, such devices are rare, so you needn't worry much. -xxxx Show hexadecimal dump of the extended (4096-byte) PCI configuration space available on PCI-X 2.0 and PCI Express buses. -b Bus-centric view. Show all IRQ numbers and addresses as seen by the cards on the PCI bus instead of as seen by the kernel. -D Always show PCI domain numbers. By default, lspci suppresses them on machines which have only domain 0.
Examples of lspci command
Issuing "lspci" by itself with no parameters will display output in a format similar to the example below:
linux-pd5y:~ # lspci 00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02) 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II] 00:01.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01) 00:02.0 VGA compatible controller: InnoTek Systemberatung GmbH VirtualBox Graphics Adapter 00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02) 00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service 00:05.0 Multimedia audio controller: Intel Corporation 82801AA AC'97 Audio Controller (rev 01) 00:06.0 USB Controller: Apple Computer Inc. KeyLargo/Intrepid USB 00:07.0 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08) 00:0d.0 SATA controller: Intel Corporation 82801HBM/HEM (ICH8M/ICH8M-E) SATA AHCI Controller (rev 02)
Adding the "-k" option to the "lspci" command will display kernel drivers handling each device:
linux-pd5y:~ # lspci -k 00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02) 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II] 00:01.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01) Kernel driver in use: ata_piix 00:02.0 VGA compatible controller: InnoTek Systemberatung GmbH VirtualBox Graphics Adapter 00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02) Subsystem: Intel Corporation PRO/1000 MT Desktop Adapter Kernel driver in use: e1000 00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service 00:05.0 Multimedia audio controller: Intel Corporation 82801AA AC'97 Audio Controller (rev 01) Subsystem: Intel Corporation Device 0000 Kernel driver in use: snd_intel8x0 00:06.0 USB Controller: Apple Computer Inc. KeyLargo/Intrepid USB Kernel driver in use: ohci_hcd 00:07.0 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08) 00:0d.0 SATA controller: Intel Corporation 82801HBM/HEM (ICH8M/ICH8M-E) SATA AHCI Controller (rev 02) Kernel driver in use: ahci
The "lsusb" command is used to display usb buses and devices that are connected to them on your system. Below is an example of the "lsusb" commend used with the "-t" option. The "-t" option causes the output to be displayed in a tree like hierarchy.
john@john-desktop:~$ lsusb -t /: Bus 05.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M /: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M |__ Port 2: Dev 2, If 0, Class=stor., Driver=usb-storage, 12M /: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M |__ Port 1: Dev 2, If 0, Class=HID, Driver=usbhid, 1.5M /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/8p, 480M
-v, --verbose Tells lsusb to be verbose and display detailed information about the devices shown. This includes configuration descriptors for the device's current speed. Class descriptors will be shown, when available, for USB device classes including hub, audio, HID, communications, and chipcard. -s [[bus]:][devnum] Show only devices in specified bus and/or devnum. Both ID's are given in decimal and may be omitted. -d [vendor]:[product] Show only devices with the specified vendor and product ID. Both ID's are given in hexadecimal. -D device Do not scan the /dev/bus/usb directory, instead display only information about the device whose device file is given. The device file should be something like /dev/bus/usb/001/001. This option displays detailed information like the v option; you must be root to do this.
A list of all known vendors, products, classes, subclasses and protocols can be found in "/usr/share/hwdata/usb.ids"
It is always useful to use the "dmesg" command to check that the kernel has recognised your usb device. This can be achieved by issuing the "dmesg | grep -i usb command. Below is an example of the dmesg command being run shortly after attaching a mobile device via usb connection.
[ 8093.796041] usb 1-4: new high-speed USB device number 4 using ehci_hcd [ 8093.942460] scsi5 : usb-storage 1-4:1.0 [ 8094.943212] scsi 5:0:0:0: Direct-Access HTC Android Phone 0100 PQ: 0 ANSI: 2 [ 8094.948449] sd 5:0:0:0: Attached scsi generic sg6 type 0 [ 8094.953351] sd 5:0:0:0: [sdf] Attached SCSI removable disk [ 8128.490339] sd 5:0:0:0: [sdf] 3911680 512-byte logical blocks: (2.00 GB/1.86 GiB)
Displaying information about currently loaded Modules
The command used for displaying information about the status of loaded modules in the Linux kernel is the "lsmod" command.
Basically "lsmod" is a command that is used to display the output from the "/proc/modules" file. Below is an example of the "lsmod" command in action:
linux-pd5y:~ # lsmod Module Size Used by ip6t_LOG 12847 5 xt_tcpudp 12788 2 xt_pkttype 12456 3 ipt_LOG 12880 5 xt_limit 12541 10 af_packet 26605 0 vboxvideo 12511 1 drm 208159 2 vboxvideo vboxsf 46523 0 ip6t_REJECT 12809 3 nf_conntrack_ipv6 13936 3 nf_defrag_ipv6 18017 1 nf_conntrack_ipv6 ip6table_raw 12603 1 xt_NOTRACK 12456 4 ipt_REJECT 12512 3 iptable_raw 12598 1 iptable_filter 12706 1 ip6table_mangle 12652 0 nf_conntrack_netbios_ns 12585 0 nf_conntrack_broadcast 12541 1 nf_conntrack_netbios_ns nf_conntrack_ipv4 14319 3 nf_defrag_ipv4 12649 1 nf_conntrack_ipv4 ip_tables 18302 2 iptable_raw,iptable_filter xt_conntrack 12664 6 nf_conntrack 79552 6 nf_conntrack_ipv6,xt_NOTRACK,nf_conntrack_netbios_ns,nf_conntrack_broadcast,nf_conntrack_ipv4,xt_conntrack ip6table_filter 12711 1 ip6_tables 18432 4 ip6t_LOG,ip6table_raw,ip6table_mangle,ip6table_filter x_tables 26199 16 ip6t_LOG,xt_tcpudp,xt_pkttype,ipt_LOG,xt_limit,ip6t_REJECT,ip6table_raw,xt_NOTRACK,ipt_REJECT,iptable_raw,iptable_filter,ip6table_mangle,ip_tables,xt_conntrack,ip6table_filter,ip6_tables processor 43803 0 thermal_sys 20200 1 processor hwmon 12936 1 thermal_sys mperf 12603 0 joydev 17393 0 ppdev 17430 0 sg 35770 0 sr_mod 22048 0 cdrom 46732 1 sr_mod parport_pc 36673 0 parport 40930 2 ppdev,parport_pc ac 12895 0 snd_intel8x0 33318 2 snd_ac97_codec 114276 1 snd_intel8x0 ac97_bus 12642 1 snd_ac97_codec snd_pcm 97316 2 snd_intel8x0,snd_ac97_codec snd_timer 28930 1 snd_pcm snd 69952 8 snd_intel8x0,snd_ac97_codec,snd_pcm,snd_timer soundcore 14635 1 snd button 13661 0 i2c_piix4 13516 0 vboxguest 217577 5 vboxsf i2c_core 34010 2 drm,i2c_piix4 snd_page_alloc 14108 2 snd_intel8x0,snd_pcm pcspkr 12614 0 e1000 147176 0 edd 14172 0 autofs4 37842 2 usbhid 51576 0 hid 81463 1 usbhid ohci_hcd 36590 0 ehci_hcd 60362 0 rtc_cmos 18167 0 usbcore 190567 4 usbhid,ohci_hcd,ehci_hcd ata_generic 12809 0 ata_piix 30627 0 ahci 25620 3 libahci 30095 1 ahci libata 205032 4 ata_generic,ata_piix,ahci,libahci
The output from the lsmod command is formatted into three columns:
Module: Module Name
Size: Size of the Module
Used by: The dependent module that is using it.
To display information regarding a specific module we can pipe the output of the "lsmod" command into "grep":
"lsmod | grep usbcore"
linux-pd5y:~ # lsmod | grep usbcore usbcore 190567 4 usbhid,ohci_hcd,ehci_hcd
Working with Modules
Modules are simply code that can be loaded and unloaded into the kernel. Modules allow the functionality of the kernel to be extended without the need for a system re-boot. A good example of a module is one that is used for a device driver. Device drivers allow the kernel to access hardware connected to the system. Typically when working with modules, you will use commands such as "lsmod", "modinfo", "modprobe", "insmod" and "rmmod". These commands are generally used for displaying, loading and unloading modules.
"insmod" is used for inserting modules into the kernel. The preferred method of inserting modules into the kernel is to use the command "modprobe" as this handles dependencies.
Modinfo is used to display information about a Linux Kernel module. "modinfo" extracts information from the Linux Kernel modules given on the command line. If the module name is not a filename, then the "/lib/modules/version" directory is searched.
linux-pd5y:~ # modinfo usbcore filename: /lib/modules/3.1.10-1.19-default/kernel/drivers/usb/core/usbcore.ko license: GPL srcversion: 9023860545ED738FD260BB4 alias: usb:v*p*d*dc*dsc*dp*ic09isc*ip* alias: usb:v*p*d*dc09dsc*dp*ic*isc*ip* depends: vermagic: 3.1.10-1.19-default SMP mod_unload modversions 586TSC parm: usbfs_snoop:true to log all usbfs traffic (bool) parm: authorized_default:Default USB device authorization: 0 is not authorized, 1 is authorized, -1 is authorized except for wireless USB (default, old behaviour (int) parm: blinkenlights:true to cycle leds on hubs (bool) parm: initial_descriptor_timeout:initial 64-byte descriptor request timeout in milliseconds (default 5000 - 5.0 seconds) (int) parm: old_scheme_first:start with the old device initialization scheme (bool) parm: use_both_schemes:try the other device initialization scheme if the first one fails (bool) parm: autosuspend:default autosuspend delay (int) parm: nousb:bool
Modprobe is a command that is used to load a module into the Linux Kernel or remove a module from the Linux kernel. Modprobe is a wrapper around the insmod command. Modprobe is the preferred method of loading a module into the kernel because it is capable of handling dependencies. Modprobe also has the capability of removing modules with the "-r" option. Below is an example of modprobe removing and loading a module into the kernel:
The following example will remove the module "parport". First lets use the "lsmod" command to check to see if any other modules are dependant on "parport".
linux-pd5y:~ # lsmod Module Size Used by ppdev 17430 0 parport_pc 36673 0 parport 40930 2 ppdev,parport_pc
From the above output we can see that the modules "ppdev" and "parport_pc" are dependant on "parport". This means that if we unload the module "parport", then these modules will need to be unloaded too:
linux-pd5y:~ # modprobe -r parport_pc linux-pd5y:~ # modprobe -r ppdev linux-pd5y:~ # modprobe -r parport linux-pd5y:~ # lsmod | grep ppdev linux-pd5y:~ # lsmod | grep parport_pc linux-pd5y:~ # lsmod | grep parport linux-pd5y:~ # modprobe ppdev linux-pd5y:~ # lsmod Module Size Used by parport_pc 36673 0 ppdev 17430 0 parport 40930 2 parport_pc,ppdev
In the above, we unloaded the modules parpoprt_pc, ppdev and parport. The lsmod command was then used to verify these modules were no longer loaded. Finally we issued "modprobe ppdev" to reload our modules and any dependencies.
Another way to check for dependencies is to look directly at the "modules.dep" file. On this openSUSE system our modules are stored in the following location: "/lib/modules/3.1.10-1.19-default". Dependencies are handled by modprobe by looking at the "modules.dep" file:
linux-pd5y:/lib/modules/3.1.10-1.19-default # grep ppdev modules.dep kernel/drivers/char/ppdev.ko: kernel/drivers/parport/parport.ko
OPTIONS -a --all Insert all module names on the command line. -b --use-blacklist This option causes modprobe to apply the blacklist commands in the configuration files (if any) to module names as well. It is usually used by udev(7). -C --config This option overrides the default configuration directory/file (/etc/modprobe.d or /etc/modprobe.conf). This option is passed through install or remove commands to other modprobe commands in the MODPROBE_OPTIONS environment variable. -c --showconfig Dump out the effective configuration from the config directory and exit. --dump-modversions Print out a list of module versioning information required by a module. This option is commonly used by distributions in order to package up a Linux kernel module using module versioning deps. -d --dirname Directory where modules can be found, /lib/modules/RELEASE by default. --first-time Normally, modprobe will succeed (and do nothing) if told to insert a module which is already present or to remove a module which isn't present. This is ideal for simple scripts; however, more complicated scripts often want to know whether modprobe really did something: this option makes modprobe fail in the case that it actually didn't do anything. --force-vermagic Every module contains a small string containing important information, such as the kernel and compiler versions. If a module fails to load and the kernel complains that the "version magic" doesn't match, you can use this option to remove it. Naturally, this check is there for your protection, so this using option is dangerous unless you know what you're doing. This applies to any modules inserted: both the module (or alias) on the command line and any modules on which it depends. --force-modversion When modules are compiled with CONFIG_MODVERSIONS set, a section detailing the versions of every interfaced used by (or supplied by) the module is created. If a module fails to load and the kernel complains that the module disagrees about a version of some interface, you can use "--force-modversion" to remove the version information altogether. Naturally, this check is there for your protection, so using this option is dangerous unless you know what you're doing. This applies any modules inserted: both the module (or alias) on the command line and any modules on which it depends. -f --force Try to strip any versioning information from the module which might otherwise stop it from loading: this is the same as using both --force-vermagic and --force-modversion. Naturally, these checks are there for your protection, so using this option is dangerous unless you know what you are doing. This applies to any modules inserted: both the module (or alias) on the command line and any modules it on which it depends. -i --ignore-install --ignore-remove This option causes modprobe to ignore install and remove commands in the configuration file (if any) for the module specified on the command line (any dependent modules are still subject to commands set for them in the configuration file). Both install and remove commands will currently be ignored when this option is used regardless of whether the request was more specifically made with only one or other (and not both) of --ignore-install or --ignore-remove. See modprobe.conf(5). -l --list List all modules matching the given wildcard (or "*" if no wildcard is given). This option is provided for backwards compatibility and may go away in future: see find(1) and basename(1) for a more flexible alternative. -n --dry-run --show This option does everything but actually insert or delete the modules (or run the install or remove commands). Combined with -v, it is useful for debugging problems. For historical reasons both --dry-run and --show actually mean the same thing and are interchangeable. -q --quiet With this flag, modprobe won't print an error message if you try to remove or insert a module it can't find (and isn't an alias or install/remove command). However, it will still return with a non-zero exit status. The kernel uses this to opportunistically probe for modules which might exist using request_module. -R --resolve-alias Print all module names matching an alias. This can be useful for debugging module alias problems. -r --remove This option causes modprobe to remove rather than insert a module. If the modules it depends on are also unused, modprobe will try to remove them too. Unlike insertion, more than one module can be specified on the command line (it does not make sense to specify module parameters when removing modules). There is usually no reason to remove modules, but some buggy modules require it. Your distribution kernel may not have been built to support removal of modules at all. -S --set-version Set the kernel version, rather than using uname(2) to decide on the kernel version (which dictates where to find the modules). --show-depends List the dependencies of a module (or alias), including the module itself. This produces a (possibly empty) set of module filenames, one per line, each starting with "insmod" and is typically used by distributions to determine which modules to include when generating initrd/initramfs images. Install commands which apply are shown prefixed by "install". It does not run any of the install commands. Note that modinfo(8) can be used to extract dependencies of a module from the module itself, but knows nothing of aliases or install commands. -s --syslog This option causes any error messages to go through the syslog mechanism (as LOG_DAEMON with level LOG_NOTICE) rather than to standard error. This is also automatically enabled when stderr is unavailable. This option is passed through install or remove commands to other modprobe commands in the MODPROBE_OPTIONS environment variable. -t --type Restrict -l to modules in directories matching the dirname given. This option is provided for backwards compatibility and may go away in future: see find(1) and basename(1) for a more flexible alternative. -V --version Show version of program and exit. -v --verbose Print messages about what the program is doing. Usually modprobe only prints messages if something goes wrong. This option is passed through install or remove commands to other modprobe commands in the MODPROBE_OPTIONS environment variable. --allow-unsupported-modules Load unsupported modules even if disabled in configuration.