转自:http://blog.csdn.net/lm_tom/article/details/1866189
经常发现,udev中并没有指定许多驱动/设备的加载规则,但udev却能在设备插入系统后
正确的加载其驱动,仔细分析后,发现事情原来是这样的.
1,udev 缺省rule的忽略
fedora 6中的/etc/udev/rules.d/50-udev.rules有如下一个规则:
ACTION=="add", SUBSYSTEM=="?*", ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $env{MODALIAS}".
表示系统发生一个add event,并且产生event的device对应的SUBSYSTEM和MODALIAS key均
包含至少一个字符的字符串时候,执行
/sbin/modprobe $env{MODALIAS}
$env{MODALIAS}就是匹配规则中的key MODALIAS的值. 可以看出这个规则非常容易匹配,可以理解为
一个缺省的规则。
另外,udev规定多个规则都可匹配的话, 每个匹配规则对应的动作都会执行.
2,modules.alias是如何生成的
/lib/modules/
KERNEL_VERSION/modules.alias文件内容格式如下:
...
alias pci:v00001412d00001712sv*sd*bc*sc*i* snd-ice1712
...
alias usb:v*p*d*dc*dsc*dp*ic01isc01ip* snd-usb-audio
alias usb:v*p*d*dc*dsc*dp*ic01isc03ip* snd-usb-audio
...
make modules 的modpost阶段,会调用modpost工具从.ko的elf格式
中找到类似信息,并生成modules.alias文件. module 源码一般通过
MODULE_DEVICE_TABLE (type,table)
定义相应的数据信息,type表示pci/usb/ieee1394/pcmcia/...等
设备类型,table则定义了module所匹配的此种类型的哪些具体设备,
一般不同类型的设备有不同的匹配结构,比如usb的匹配结构为struct
usb_device_id类型,pci设备为 struct pci_device_id,等等.
一般来说,不同类型的设备,定义了不同的匹配结构,因此生成的
module alias的格式也不同. 一个module的MODULE_DEVICE_TABLE (type,table)
中的table有多少个元素,该module就会生成多少个对应的module alias,这些
module alias都对应该module 的名称. 每种类型的module alias的格式一样,
":"前为类型名称(usb/pci/...),":"后和具体类型相关,但格式均为:
key_namekey_value|key_namekey_value|key_namekey_value|...
key_name为某个id的名称,key_value为匹配的值(*表示任意值).
3,sysfs中的modalias信息
sysfs中的modalias属性一般由设备所在的bus驱动来提供接口并生成.
比如:
[root@localhost /]# find /sys/devices -name modalias
/sys/devices/pci0000:00/0000:00:12.0/modalias
/sys/devices/pci0000:00/0000:00:11.0/modalias
/sys/devices/pci0000:00/0000:00:10.0/modalias
/sys/devices/pci0000:00/0000:00:0f.0/modalias
/sys/devices/pci0000:00/0000:00:07.3/modalias
/sys/devices/pci0000:00/0000:00:07.2/usb1/1-1/1-1:1.1/modalias
/sys/devices/pci0000:00/0000:00:07.2/usb1/1-1/1-1:1.0/modalias
/sys/devices/pci0000:00/0000:00:07.2/usb1/1-0:1.0/modalias
/sys/devices/pci0000:00/0000:00:07.2/modalias
/sys/devices/pci0000:00/0000:00:07.1/ide1/1.0/modalias
/sys/devices/pci0000:00/0000:00:07.1/modalias
/sys/devices/pci0000:00/0000:00:07.0/modalias
/sys/devices/pci0000:00/0000:00:01.0/modalias
/sys/devices/pci0000:00/0000:00:00.0/modalias
/sys/devices/platform/bluetooth/modalias
/sys/devices/platform/floppy.0/modalias
/sys/devices/platform/i8042/serio1/modalias
/sys/devices/platform/i8042/serio0/modalias
/sys/devices/platform/i8042/modalias
/sys/devices/platform/serial8250/modalias
/sys/devices/platform/vesafb.0/modalias
/sys/devices/platform/pcspkr/modalias
4,驱动加载的完整过程
1),设备插入系统,设备所在的bus调用device driver model接口生成
netlink event,event包含了modalias key以及对应的值;
2),udevd接收到内核发来的netlink event,根据默认的匹配规则发现有
匹配的项,于是就执行对应的动作:
/sbin/modprobe $env{MODALIAS}
$env{MODALIAS}和/lib/modules/
KERNEL_VERSION/modules.alias中的某行
所匹配,于是就相当于modprobe module_name,加载了对应的模块.
5,reference
[1], linux kernel 2.6.15 source code
[2], udev man 帮助;