在Linux源代码中,哪里会发生对特定USB设备的识别?

在Linux源代码中,哪里会发生对特定USB设备的识别?

问题描述:

我有一个特定的USB设备,我想检查其Linux驱动程序源代码.我的理解是,USB驱动程序采取的第一步是注册自己,使其能够处理具有特定供应商ID和产品ID的设备.在我的情况下,供应商ID为0BDA,产品ID为8187.有了这些信息,我是否有办法找到能够将自己注册为能够处理此设备的源文件,以期找出其他哪些源文件实际实现了驱动程序的详细信息?

I have a specific USB device whose Linux driver source code I would like to examine. My understanding is that the first step a USB driver takes is to register itself capable of handling a device with a specific vendor ID and product ID. In my case, the vendor ID is 0BDA and the product ID is 8187. Given this information, is there a way I can find the source file that registers itself as capable of handling this device, with a view to then finding out what other source files actual implement the driver details?

作为参考,我在内核3.2.0-26上.我已经尝试过grep -rl 8187 /usr/src,但这会列出一大堆文件,而且我不知道从哪里开始.

For reference, I am on kernel 3.2.0-26. I have tried a grep -rl 8187 /usr/src, but this lists a whole bunch of files, and I don't know where to start.

除供应商和产品ID外,还有许多其他参数会影响选择哪个驱动程序.有版本号,设备类,子类和协议,以及接口类,子类和协议.内核从设备读取所有这些内容,并建立一个包含所有看起来像这样的字符串(示例是我的设备之一,而不是您的设备):

There are a lot of other parameters besides vendor and product ID that can influence which driver is chosen. There's a version number, device class, subclass, and protocol, and interface class, subclass, and protocol. The kernel reads all of those from the device and builds up a string containing all of them that looks like this (example is one of my devices, not yours):

usb:v15A9p0004d0001dc00dsc00dp00icFFiscFFipFF

然后将该字符串传递给modprobe,该字符串与模块本身中找到的字符串(带有通配符)进行匹配.您可以通过在特定模块上运行modinfo来查看匹配规则的列表.与那些规则相对应的源代码构造为MODULE_DEVICE_TABLE.设备表中的各个条目通常是用USB_DEVICE宏构建的,因此grepping USB_DEVICE.*8187而不是仅仅使用8187可以缩小其范围.

That string is then passed to modprobe, which matches it against strings (with wildcards) found in the modules themselves. You can see the list of matching rules for a particular module by running modinfo on it. The source code construct that corresponds to those rules is MODULE_DEVICE_TABLE. The individual entries in the device table are usually built with the USB_DEVICE macro, so grepping USB_DEVICE.*8187 instead of just 8187 should narrow it down.

如果已插入设备并且可以正常工作,则可以通过查看其sysfs条目来找出与之关联的驱动程序:

If you have a device plugged in and working, you can find out which driver is associated with it by looking at its sysfs entry:

ls -l /sys/bus/usb/devices/*/driver

如果您可以构建这些设备描述符字符串之一,则可以要求modprobe为您查找驱动程序而无需实际加载驱动程序(同样以我的设备为例):

If you can build one of those device descriptor strings, you can ask modprobe to look the driver up for you without actually loading it by doing this (again my device as example):

modprobe -v -n 'usb:v15A9p0004d0001dc00dsc00dp00icFFiscFFipFF'

如果可以获取,所有数字都可以在lsusb -v的输出中找到.如果不是,请尝试零,否则您可能会获得通配符匹配.确保您的十六进制数字使用大写字母,其他所有字母均使用小写字母.这仅在/lib/modules中存在驱动程序的情况下才有效,因此不利于查找内核编译中未包含的驱动程序.

All of the numbers are available in the output of lsusb -v if you can get it. If not, try zeros and maybe you'll get a wildcard match. Make sure you use uppercase letters for your hex digits, and lowercase for everything else. This will only work if the driver is present in /lib/modules so it's no good for finding drivers that were left out of your kernel compile.

如果其他所有方法均失败,则采用技术含量较低的方法是从lsusb中提取人类可读的设备名称,然后在Google上加上"Linux"一词.

If all else fails, the low-tech approach is to take the human-readable device name from lsusb, and google it plus the word "Linux".

使用上述某些方法,我发现您设备的驱动程序名为rtl8187,其中的供应商和产品ID是从drivers/net/wireless/rtl818x/rtl8187/dev.c注册的.

Using some of the above methods, I found that your device's driver is called rtl8187, with the vendor and product IDs registered from drivers/net/wireless/rtl818x/rtl8187/dev.c.