- Linux那些事儿之我是USB
- 肖林甫 肖季东 任桥伟
- 1883字
- 2020-08-27 00:52:23
8.好戏开始了
首先要去drivers/usb目录下走一走、看一看。
atm/ class/ core/ gadget/ host/ image/ misc/ mon/ serial/ storage/ Kconfig Makefile README usb-skeleton.c
ls命令的结果就是上面的10个目录和4个文件。usb-skeleton.c是一个简单的USB driver的框架。那么首先应该关注什么?那就是Kconfig、Makefile、README。
README里有关于这个目录下内容的一般性描述。再说了,面对“读我吧!读我吧!”这么热情奔放的呼唤,善良的我们是不可能无动于衷的,所以先来看一看README里面都有些什么内容。
Here is a list of what each subdirectory here is, and what is contained in them. core/ - This is for the core USB host code, including the usbfs files and the hub class driver ("khubd"). host/ - This is for USB host controller drivers. This includes UHCI, OHCI, EHCI, and others that might be used with more specialized "embedded" syste ms. gadget/ - This is for USB peripheral controller drivers and the various gadget drivers which talk to them. Individual USB driver directories. A new driver should be added to the first subdirectory in the list below that it fits into. image/ - This is for still image drivers, like scanners or digital cameras. input/ - This is for any driver that uses the input subsystem, like keyboard, mice, touchscreens, tablets, etc. media/ - This is for multimedia drivers, like video cameras, radios, and any other drivers that talk to the v4l subsystem. net/ - This is for network drivers. serial/ - This is for USB to serial drivers. storage/ - This is for USB mass-storage drivers. class/ - This is for all USB device drivers that do not fit into any of the above categories, and work for a range of USB Class specified devices. misc/ - This is for all USB device drivers that do not fit into any of the above categories.
drivers/usb/README文件描述了前面使用ls命令列出的那10个文件夹的用途。那么什么是USB Core?Linux内核开发人员们专门写了一些代码,负责实现一些核心的功能,为别的设备驱动程序提供服务,比如申请内存,实现一些所有的设备都会需要的公共函数,并美其名曰为“USB Core”。
时代总在发展,早期的Linux内核,其结构并不是如今天这般有层次感,远不像今天这般错落有致,那时候drivers/usb/目录下放了很多文件,USB Core与其他各种设备驱动程序代码都堆砌在这里,后来,在drivers/usb/目录下面出来了一个core目录,就专门放一些核心的代码,比如初始化整个USB系统,初始化Root Hub,初始化主机控制器的代码,再后来甚至把主机控制器相关的代码也单独建了一个目录,叫host目录。这是因为USB主机控制器随着时代的发展,也开始有了好几种,不再像刚开始那样只有一种。所以,设计者们把一些主机控制器公共的代码仍然留在core目录下,而一些各主机控制器单独的代码则移到host目录下面负责各种主机控制器的人去维护。
那么USB gadget呢?gadget说白了就是配件的意思,主要就是一些内部运行Linux的嵌入式设备,比如PDA,设备本身有USB设备控制器(USB Device Controller),可以将PC,也就是我们的主机作为master端,将这样的设备作为slave端和主机通过USB进行通信。从主机的观点来看,主机系统的USB驱动程序控制插入其中的USB设备,而USB gadget的驱动程序控制外围设备作为一个USB设备和主机通信。比如,我们的嵌入式主板上支持SD卡,如果我们希望将主板通过USB连接到PC之后,这个SD卡被模拟成U盘,那么就要通过USB gadget架构的驱动。
gadget目录下大概可以分为两个模块:一个是udc驱动,这个驱动是针对具体CPU平台的,如果找不到现成的,就要自己实现;另外一个就是gadget驱动,主要有file_storage、ether、serial等。另外还提供了USB gadget API,即USB设备控制器硬件和gadget驱动通信的接口。PC及服务器只有USB主机控制器硬件,它们并不能作为USB gadget存在,而对于嵌入式设备,USB设备控制器常被集成到处理器中,设备的各种功能,如U盘、网卡等常依赖这种USB设备控制器来与主机连接,并且设备的各种功能之间可以切换,比如可以选择作为U盘或网卡等。
剩下的几个目录分门别类地放了各种USB设备的驱动,U盘的驱动在storage目录下,触摸屏和USB键盘鼠标的驱动在input目录下等。另外,在USB协议中,除了通用的软硬件电气接口规范等,还包含各种各样的Class协议,用来为不同的功能定义各自的标准接口和具体的总线上的数据交互格式和内容。这些Class协议的数量非常多,比如最常见的支持U盘功能的Mass Storage Class,以及通用的数据交换协议CDC Class。此外,还包括Audio Class、Print Class等。理论上讲,即使没有这些Class,通过专用驱动也能够实现各种各样的应用功能。但是,正是Mass Storage Class的使用,使得各个厂商生产的U盘都能通过操作系统自带的统一驱动程序来使用,对U盘的普及起了极大的推动作用,制定其他的Class也是同样的目的。
我们响应了README的呼唤,它给予了我们想要的,通过它,我们了解了USB目录里的那些文件夹都有着什么样的角色。到现在为止,就只剩下Kconfig和Makefile两个文件了,它们又扮演着什么样的角色?就好像我吃东西时总是喜欢把好吃的留在最后享受一样,我也习惯于将重要的内容留在最后去描述。对于一个希望能够在Linux内核的汪洋代码里看到一丝曙光的人来说,将它们放在多么重要的地位都不过分。我们在去香港通过海关时,总会有免费的地图,有了它们,我们才不至于像无头苍蝇般迷惘地行走在陌生的街道上。即使在出去旅游时,一般也总是会先找一份地图,当然了,这时就是要去买了,拿是拿不到的。不同的地方有不同的特色,别人的特色是服务,咱们的特色是索取。Kconfig、Makefile就是Linux kernel迷宫里的地图,我们每次浏览kernel寻找属于自己的那一段代码时,都应该先看一看目录下的这两个文件。
不过,这里很明显,要想了解USB协议在内核中的实现,USB Core就是我们需要关注的对象。