Linux那些事儿之我是USB
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
 9.不一样的Core

9.不一样的Core

我们来看Core目录。关于USB,有一个很重要的模块,它的名字耐人寻味——usbcore。如果你的电脑安装了Linux操作系统,那么你用lsmod命令查看,有一个模块叫做usbcore。当然,你要是玩嵌入式系统的高手,那么也许你的电脑里没有USB模块。不过听说如今玩嵌入式的人也喜欢玩USB,因为USB设备很符合嵌入式的口味。查看lsmod命令的输出吧。

localhost:/usr/src/linux-2.6.22.1/drivers/usb/core # lsmod
Module           Size Used by
af_packet        55820 2
raw              89504 0
nfs             230840 2
lockd            87536 2 nfs
nfs_acl          20352 1 nfs
sunrpc          172360 4 nfs,lockd,nfs_acl
ipv6            329728 36
button           24224 0
battery          27272 0
ac               22152 0
apparmor         73760 0
aamatch_pcre     30720 1 apparmor
loop             32784 0
usbhid           60832 0
dm_mod           77232 0
ide_cd           57120 0
hw_random        22440 0
ehci_hcd         47624 0
cdrom            52392 1 ide_cd
uhci_hcd         48544 0
shpchp           61984 0
bnx2            157296 0
usbcore         149288 4 usbhid,ehci_hcd,uhci_hcd
e1000           130872 0
pci_hotplug      44800 1 shpchp
reiserfs        239616 2
edd              26760 0
fan              21896 0
thermal          32272 0
processor        50280 1 thermal
qla2xxx         149484 0
firmware_class   27904 1 qla2xxx
scsi_transport_fc  51460 1 qla2xxx
sg                 52136 0
megaraid_sas       47928 3
piix               27652 0 [permanent]
sd_mod             34176 4
scsi_mod          163760 5 qla2xxx,scsi_transport_fc,sg,megaraid_sas,sd_mod
ide_disk           32768 0
ide_core          164996 3 ide_cd,piix,ide_disk

找到usbcore那一行了吗?它就是这里要说的USB子系统的核心,如果要在Linux里使用USB,这个模块是必不可少的,另外,你应该会在usbcore的最后一行看到ehci_hcd或uhci_hcd,它们就是前面说的USB主机控制器的驱动模块,你的USB设备要工作,合适的USB主机控制器模块也是必不可少的。

USB Core负责实现一些核心的功能,为别的设备驱动程序提供服务,提供一个用于访问和控制USB硬件的接口,而不用去考虑系统当前存在哪种主机控制器。至于USB Core、USB主机控制器和USB设备驱动三者之间的关系,如图1.9.1所示。

图1.9.1 内核中USB子系统的结构

驱动和主机控制器像不像Core的两个保镖?没办法,这可是Core啊!协议中也说了,主机控制器的驱动(HCD)必须位于USB软件的最下一层。HCD提供主机控制器硬件的抽象,隐藏硬件的细节,在主机控制器之下是物理的USB及所有与之连接的USB设备。而HCD只有一个客户,对一个人负责,就是咱们的USB Core,USB Core将用户的请求映射到相关的HCD,用户不能直接访问HCD。

在写USB驱动时,只能调用Core的接口,Core会将咱们的请求发送给相应的HCD,Core为咱们完成了大部分的工作,Linux的哲学是不是和咱们生活中不太一样?

到drivers/usb/core目录里,使用ls命令看一看。

Kconfig Makefile buffer.c config.c devices.c devio.c driver.c
endpoint.c file.c generic.c hcd-pci.c hcd.c hcd.h hub.c hub.h
inode.c message.c notify.c otg_whitelist.h quirks.c sysfs.c urb.c
usb.c usb.h

再使用wc命令统计,将近两万行的代码,Core不愧是Core,为大家默默地做这么多事,我们要用感恩的心去深刻理解你的内心,回报你的付出。

不过这么多文件中不一定都是我们所要关注的,先拿咱们的地图来看一看接下来该怎么走。先看一看Kconfig文件。

4 config USB_DEBUG
5   bool "USB verbose debug messages"
6   depends on USB
7   help
8     Say Y here if you want the USB core & hub drivers to produce a bunch
9     of debug messages to the system log. Select this if you are having a
10    problem with USB support and want to see more of what is going on.

这是USB的调试tag,如果你在写USB设备驱动的话,最好还是打开它吧,不过这里它就不是我们关注的重点了。

15 config USB_DEVICEFS
16     bool "USB device filesystem"
17     depends on USB
18     ---help---
19       If you say Y here (and to "/proc file system support" in the "File
20       syste ms" section, above), you will get a file /proc/bus/usb/devices
21       which lists the devices currently connected to your USB bus or
22       busses, and for every connected device a file named
23       "/proc/bus/usb/xxx/yyy", where xxx is the bus number and yyy the
24       device number; the latter files can be used by user space progra ms
25       to talk directly to the device. These files are "virtual", meaning
26       they are generated on the fly and not stored on the hard drive.
27
28       You may need to mount the usbfs file system to see the files, use
29       mount -t usbfs none /proc/bus/usb
30
31       For the format of the various /proc/bus/usb/ files, please read
32       <file:Documentation/usb/proc_usb_info.txt>.
33
34       Usbfs files can't handle Access Control Lists (ACL), which are the
35       default way to grant access to USB devices for untrusted users of a
36       desktop system. The usbfs functionality is replaced by real
37       device-nodes managed by udev. These nodes live in /dev/bus/usb and
38       are used by libusb.

这个选项是关于usbfs文件系统的。usbfs文件系统挂载在/proc/bus/usb上(mount -t usbfs none /proc/bus/usb),显示了当前连接的USB设备及总线的各种信息,每个连接的USB设备在其中都会有一个文件进行描述。比如文件/proc/bus/usb/xxx/yyy,xxx表示总线的序号,yyy表示设备在总线的地址,不过不能够依赖它们来稳定地访问设备,因为同一个设备两次连接对应的描述文件可能会不同。比如,第一次连接一个设备时,它可能是002/027,一段时间后再次连接,它可能就已经改变为002/048。

usbfs与咱们探讨的主题关系不大,况且也已经足可以开个专题来讨论了,所以以后不会过多地提及它。

74 config USB_SUSPEND
75      bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)"
76      depends on USB && PM && EXPERIMENTAL
77      help
78        If you say Y here, you can use driver calls or the sysfs
79        "power/state" file to suspend or resume individual USB
80        peripherals.
81
82        Also, USB "remote wakeup" signaling is supported, whereby some
83        USB devices (like keyboards and network adapters) can wake up
84        their parent hub. That wakeup cascades up the USB tree, and
85        could wake the system from states like suspend-to-RAM.
86
87        If you are unsure about this, say N here.

这一项有关USB设备的挂起和恢复。开发USB的人都是节电节能的好孩子,所以协议中就规定了:所有设备都必须支持挂起状态,也就是说,为了达到节电的目的,当设备在指定的时间内(3ms),如果没有发生总线传输,就要进入挂起状态。当它收到一个non-idle的信号时,就会被唤醒,节约用电从USB做起。不过目前来说,内核对挂起休眠的支持普遍都不太好,而且许多USB设备也没有支持它,还是暂且不提了。

剩下的还有几项,不过似乎与咱们关系也不大,还是去看一看Makefile。

5 usbcore-objs  := usb.o hub.o hcd.o urb.o message.o driver.o \
6         config.o file.o buffer.o sysfs.o endpoint.o \
7         devio.o notify.o generic.o quirks.o
8
9 ifeq ($(CONFIG_PCI),y)
10   usbcore-objs  += hcd-pci.o
11 endif
12
13 ifeq ($(CONFIG_USB_DEVICEFS),y)
14   usbcore-objs  += inode.o devices.o
15 endif
16
17 obj-$(CONFIG_USB)   += usbcore.o
18
19 ifeq ($(CONFIG_USB_DEBUG),y)
20 EXTRA_CFLAGS += -DDEBUG
21 endif

Makefile可比Kconfig简略多了,所以看起来也更亲切,咱们总是拿的钱越多越好,看的代码越少越好。这里之所以会出现CONFIG_PCI,是因为USB的Root Hub通常包含在一个PCI设备中,前面也已经聊过了。hcd-pci和hcd顾名思义就是主机控制器,它们实现了主机控制器公共部分,按协议中的说法,它们就是HCDI(HCD的公共接口),host目录下则实现了各种不同的主机控制器。CONFIG_USB_DEVICEFS在前面的Kconfig文件中也见到了,关于usbfs,与咱们的主题无关,inode.c和devices.c两个文件也可以不用管了。