https://wiki.archlinux.org/api.php?action=feedcontributions&user=Tey%27&feedformat=atomArchWiki - User contributions [en]2024-03-29T06:31:11ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=Modalias&diff=199464Modalias2012-04-27T14:48:27Z<p>Tey': /* What is a 'modalias' file? */ Added the definition of "i".</p>
<hr />
<div>[[Category:Kernel]]<br />
{{i18n|Modalias}}<br />
<br />
I figured I'd write something like this up, as I've seen a lot of questions about it, and this would be a good place to answer them. This document will serve as an intro to how the Linux kernel and modules see and understand hardware, and how this translates into a sysfs 'modalias'<br />
<br />
==What is this 'modalias' you speak of?==<br />
Modalias is a little sysfs trick that exports hardware information to a file named 'modalias'. This file simply contains a formatted form of the information normal hardware exposes. Let's look at a quick example before we continue:<br />
$ cat /sys/devices/pci0000:00/0000:00:1f.1/modalias<br />
pci:v00008086d000024DBsv0000103Csd0000006Abc01sc01i8A<br />
<br />
Don't worry, it will all become clear soon.<br />
<br />
==What is a 'modalias' file?==<br />
As described above, a modalias file simply exposes the information that a give piece of hardware already tells the kernel. This file simply specifies a structure for exposing this information. Let's return to the example above:<br />
$ cat /sys/devices/pci0000:00/0000:00:1f.1/modalias<br />
pci:v00008086d000024DBsv0000103Csd0000006Abc01sc01i8A<br />
What the hell? What does this mean? Let's take it apart piece-by-piece. First, the file name.<br />
/sys/devices/pci0000:00/0000:00:1f.1/modalias<br />
* '''pci0000:00''' is the id for the first PCI bus. For most machines this will be the only PCI bus you have, but it's possible this can extend to '''pci0000:01''' or '''pci0000:02''' - the exacts are unimportant, as it's a good guess that you only have one PCI bus (''HINT:'' try ls /sys/devices/pci* to check)<br />
* '''0000:00:1f.1''' is the index of the given device on the PCI bus. Specifically, this is on bus 0000:00 and has index '''1f.1'''<br />
* All this is rather unimportant, unless you want to know where all these numbers come from. For completeness, if you check the output of ''lspci'' you will see the same information:<br />
$ lspci<br />
00:1f.1 IDE interface: Intel Corp.: Unknown device 24db (rev 02)<br />
<br />
Now, let's take a peek at the contents of this modalias file for device 00:1f.1:<br />
pci:v00008086d000024DBsv0000103Csd0000006Abc01sc01i8A<br />
Well, hey, I can see pci! I recognize that, but what's all this gibberish at the end?<br />
This gibberish is actually structured data. You will notice a repeating letter/number scheme. Let's split this apart to make it easier to read:<br />
v 00008086<br />
d 000024DB<br />
sv 0000103C<br />
sd 0000006A<br />
bc 01<br />
sc 01<br />
i 8A<br />
Each of these identifiers, and corresponding hex numbers represent some of the info that a given device exposes. For starters, '''v''' is the ''vendor id'' and '''d''' is the ''device id'' - these are very standard numbers, and are the same exact numbers that tools like '''hwd''' uses to lookup a device. You can even find websites to look up specific hardware identification based on the vendor and device ids, for instance, http://www.pcidatabase.com/<br />
<br />
We can also see these numbers here:<br />
$ lspci -n<br />
00:1f.1 Class 0101: 8086:24db (rev 02)<br />
See how the 8086:24db matches to the ''v'' and ''d'' tokens listed above?<br />
<br />
For the record, '''sv''' and '''sd''' are "subsystem" versions of both vendor and device. A majority of the time these are ignored. They are mainly used by the hardware developers to distinguish slight differences in the inner workings which do not change the device as a whole.<br />
<br />
'''bc''' (base class) and '''sc''' (sub class) are used to create the "Class" listed by lspci, in order "bcsc". This is the device class, which is fairly generic. In this case, the "class" is looked up in the normal lspci output. We can see that "Class 0101" maps to "IDE Interface" (lspci also looks up the vendor and device id's - 8086 maps to "Intel Corp." and 24DB maps to 'Unknown Device', hehe)<br />
<br />
'''i''' is the "Programming interface", which is only meaningful for a few devices classes.<br />
<br />
==How is this information used?==<br />
Ok, now we all know what this information is. A bunch of obscure numbers that each device exposes. Big deal. How does this matter when talking about modules?<br />
<br />
One thing which people tend to ignore, is all the work '''depmod''' does. When you run depmod, it builds a series of "map" files in /lib/modules/`uname -r` which tell modprobe how to handle certain things it needs to do. In this case we can ignore most of them. The important one is '''modules.alias'''. This file contains aliases, or secondary names for modules. Just for a demonstration, let's look at aliases for, say, snd_intel8x0m:<br />
<br />
$ grep snd_intel8x0m /lib/modules/`uname -r`/modules.alias<br />
alias pci:v00008086d00002416sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v00008086d00002426sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v00008086d00002446sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v00008086d00002486sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v00008086d000024C6sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v00008086d000024D6sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v00008086d0000266Dsv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v00008086d000027DDsv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v00008086d00007196sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v00001022d00007446sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v00001039d00007013sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v000010DEd000001C1sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v000010DEd00000069sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v000010DEd00000089sv*sd*bc*sc*i* snd_intel8x0m<br />
alias pci:v000010DEd000000D9sv*sd*bc*sc*i* snd_intel8x0m<br />
<br />
Hey, wait! I recognize that! That's the vendor/device id information from before!<br />
<br />
Yes, it is. It's a rather simple format of "alias <something> <actual module>". In fact, you can alias just about anything you want. I can add "alias boogabooga snd_intel8x0m" and then safely "modprobe boogabooga".<br />
<br />
The "*" indicates it will match anything, much like filesystem globbing (''ls somedir/*''). As stated before, most aliases ignore sv, sd, bc, sc, and i by way of the "*" matching.<br />
<br />
==Where does this modules.alias file come from?==<br />
Ok, now you may be thinking "Well, hwd used to look things up based on a device table, what makes this any different?"<br />
<br />
The difference is that this lookup table is not static. It is not maintained by hand. In fact, it is built dynamically whenever you run depmod. "Where does this information come from?", you ask? Why, from the '''modules themselves'''. When you think about it, each specific module should know what hardware it supports, as it's coded specifically for that hardware. I mean, the ''nvidia'' module developers know that their modules only works for Nvidia (vendor) Graphics Cards (class). In fact, the module actually exports this information. It says "Hey, I can support this:".<br />
$ modinfo nvidia<br />
filename: /lib/modules/2.6.14-ARCH/kernel/drivers/video/nvidia.ko<br />
license: NVIDIA<br />
alias: char-major-195-*<br />
vermagic: 2.6.14-ARCH SMP preempt 686 gcc-4.1<br />
depends: agpgart<br />
alias: pci:v000010DEd*sv*sd*bc03sc00i00*<br />
<br />
As you can see by the alias listed, it looks specifically for vendor "10DE" (Nvidia) and bc/sc 0300 (which is most likely 'graphics cards'). In fact, if you look at the modinfo for '''snd_intel8x0m''':<br />
$ modinfo snd_intel8x0m<br />
filename: /lib/modules/2.6.14-ARCH/kernel/sound/pci/snd-intel8x0m.ko<br />
author: Jaroslav Kysela <perex@suse.cz><br />
description: Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7013; NVidia MCP/2/2S/3 modems<br />
license: GPL<br />
vermagic: 2.6.14-ARCH SMP preempt 686 gcc-4.1<br />
depends: snd-ac97-codec,snd-pcm,snd-page-alloc,snd<br />
alias: pci:v00008086d00002416sv*sd*bc*sc*i*<br />
alias: pci:v00008086d00002426sv*sd*bc*sc*i*<br />
alias: pci:v00008086d00002446sv*sd*bc*sc*i*<br />
alias: pci:v00008086d00002486sv*sd*bc*sc*i*<br />
alias: pci:v00008086d000024C6sv*sd*bc*sc*i*<br />
alias: pci:v00008086d000024D6sv*sd*bc*sc*i*<br />
alias: pci:v00008086d0000266Dsv*sd*bc*sc*i*<br />
alias: pci:v00008086d000027DDsv*sd*bc*sc*i*<br />
alias: pci:v00008086d00007196sv*sd*bc*sc*i*<br />
alias: pci:v00001022d00007446sv*sd*bc*sc*i*<br />
alias: pci:v00001039d00007013sv*sd*bc*sc*i*<br />
alias: pci:v000010DEd000001C1sv*sd*bc*sc*i*<br />
alias: pci:v000010DEd00000069sv*sd*bc*sc*i*<br />
alias: pci:v000010DEd00000089sv*sd*bc*sc*i*<br />
alias: pci:v000010DEd000000D9sv*sd*bc*sc*i*<br />
<br />
It matches the aliases found by 'grep'ing the alias file. These aliases exported by each module, are gathered by depmod and merged into the modules.alias file dynamically. There is no hand-changing of a lookup table, as it is built on-the-fly. Each module knows exactly what it supports, and therefore depmod can use that information to help load modules.<br />
<br />
==How does hwdetect work?==<br />
hwdetect is the Arch specific tool which loads modules based on these modaliases. All it does is dump all modaliases on the system, and run "modprobe --show-depends <alias>" for each one. That builds a list of all modules your hardware supports. It's that simple. Of course, there are corrections made for certain small things that are not detected right.<br />
<br />
In essence, to does the following:<br />
modprobe -a $(find /sys/devices -name modalias -exec cat {} +)<br />
<br />
Of course, that's not *exact*, as hwdetect loads pnp devices and disk modules as well, which aren't exported via modalias. However, the modalias setup makes all this very simple and straightforward.<br />
<br />
==How does udev work?==<br />
Now, you may be thinking "That makes sense, you just find all the modaliases on the system and load them, but how does this work when I plug a new device in? Do I need to run through the whole system again?"<br />
<br />
Nope. udev is closely tied with sysfs (the filesystem which exposes the modalias in the firstplace). In fact, to load modules based on the modalias when a new device is added, it's insanely simple:<br />
<br />
ACTION=="add", SUBSYSTEM=="pci", MODALIAS=="*", RUN+="/sbin/modprobe $modalias"<br />
ACTION=="add", SUBSYSTEM=="usb", MODALIAS=="*", RUN+="/sbin/modprobe $modalias"<br />
ACTION=="add", SUBSYSTEM=="pcmcia", MODALIAS=="*", RUN+="/sbin/modprobe $modalias"<br />
# so on for ieee1394, scsi, and other devices<br />
<br />
Yep, that's it. It's pretty much a one-liner. These simple lines, which are already part of the default udev rules replace hotplug. Amazing, isn't it?</div>Tey'