如何在Linux当中判断USB控制器的类型

来源:互联网 发布:淘宝三皇冠 编辑:程序博客网 时间:2024/06/05 09:53
如何在Linux当中判断USB控制器的类型

by Quickmouse (quickmouse@263.net) 2004年10月11日

    一直弄不清楚Linux是如何加载USB控制器的,终于到了非弄清楚不可的时候,不然手头的一个东西通用性就不好了。以RedHat Linux为例吧,我用的7.3的版本。老掉牙了吧,呵呵。
    在启动过程当中的加载是从/etc/rc.sysinit当中完成的,其中有加载usbcore模块和usb控制器模块的脚本。usbcore模块好说,/lib/modules(实际为/lib/modules/内核版本号/下面,省略掉内核版本号,下同)里面本身就有usbcore.o或者usbcore.ko(2.6.x kernel)的模块,但是usb控制器怎么加载呢,这就是今天弄清楚的东西。
      /etc/rc.sysinit当中加载控制器是通过”modprobe usb-controller”命令来完成的,在/lib/modules当中没有usb-controller这个模块,它的定义是通过/etc/modules.conf或者/etc/modprobe.conf(2.6.x kernel)完成的。当中我们可以找到”alias usb-controller usb-uhci”或者”alias usb-controller uhci-hcd”(2.6.x kernel,下不再注明)。于是我们知道了usb控制器的模块实际上是一个别名,其真实模块指向的是uhci。
   当然,uhci只是USB控制器的一种,就如我们知道的还有ohci的USB控制器,源于Intel/VIA/SIS等厂商对USB控制器所在桥控制器的描述不同。如果我们需要构造一个比较通用的USB模块加载的脚本/程序,例如像RedHat发行版这样的,那如何办呢?从我们每个Linux的系统看,这些都是写死了的。让我们想想看modules.conf里面的别名是怎么来的……
   对了,是kudzu写入的。kudzu是Linux下一个类似于windoz当中硬件检测器一样的东东。我们当然不需要关心kudzu是如何从头到尾工作的。只需要关注其检测usb控制器的流程即可。USB控制器是挂接在PCI总线当中的,因此,检测USB控制器的类型实际上就是要通过pci总线上的信息判断USB控制器是属于uhci还是ohci甚至是ehci。
   首先,PCI设备的信息可以通过/proc/bus/pci下的文件得到。文件devices里面表示了系统自动得到的所有pci设备的信息,基本上都是数字,嘿嘿,比较难看懂。不过我们只需要每一行的第一个16位数,例如:
003a    80867112        9       00000000        00000000        00000000       00000000 00001061        00000000        00000000        00000000        0000000000000000        00000000        00000020        00000000        00000000

   这只是其中一行的数据,我们仅仅关心其中的003a。这是16进制表示的,其中高八位表示总线号,中间五位表示设备号,低三位表示功能号。这里我们知道这一行表示总线00上的07号设备的2号功能。这样我们可以打开/proc/bus/pci/00/07.2得到该设备的PCI配置空间(256B)内容。相对于这个256B,我们关心的内容也非常非常的少,把首16B列在下面吧:
      86 80 12 71 05 00 80 02 00 00 03 0c 00 40 00 00
   其中vender是0×8086,16bit;device是0×7112,16bit;04H-07H不关心;08H的0×00是Revision ID;09H-0BH是Class Code,其中Class Code只占用16bit,0×0C03,余下的最高8bit是Programmer Interface,即0×0。Class Code当中的高8位是Base Class,低8位是Sub Class。后面的信息就用不着拉。

   再来看看kudzu如何区分uhci/ohci/ehci,奥秘在/lib/modules下的modules.alias当中,我把它摘录出来:
alias pci:v*d*sv*sd*bc0Csc03i00* uhci_hcd
alias pci:v*d*sv*sd*bc0Csc03i10* ohci_hcd
alias pci:v*d*sv*sd*bc0Csc03i20* ehci_hcd
   嘿嘿,看出什么来了?v表示vendor,d表示device,sv/sd表示subsystem vender/device,bc表示Base Class,sc表示Sub Class,i表示Programmer Interface。于是判断属于uhci/ohci/ehci的标准是Class Code为0×0C03,区分他们的标志即为看Programmer Interface。
   到这里我想大家应该可以写出一个较为通用的加载程序了吧。首先通过/proc/bus/pci/devices得到现在所有的pci设备所在的总线和设备号,依次打开它们的配置空间,读出Class Code和Programmer Interface,如果Class Code是0×0C03即表明是USB控制器,再根据Programmer Interface决定加载uhci还是ohci或者是ehci。
   就这么简单吧 ^_^

参考资料:
1、《如何在LINUX下实现硬件的自动检测(上)》 
    于辰涛 (scu_yct@263.net),http://www-900.ibm.com/developerWorks/cn/linux/hardware/auto-detecting/part1/index.shtml
2、linux 2.6.8.1 src code,~/scripts/mod/file2alias.c

原创粉丝点击