USB:通用串行总线,是一种外部总线的标准,用于规范主机与外设之间的连接与通讯,其数据传输速度快,支持热插拔,并具有兼容性和透明性,已成为当今个人电脑和大量智能设
备必配的接口。随着虚拟化技术的盛行和发展,在虚拟化中引入对USB技术的支持,是必须的必然的结果,同时,由于传统桌面使用USB技术和大量的外设进行交互,因而在使用和实现虚拟桌面的时候,必须引入对USB技术的支持,以达到虚拟桌面对外设的兼容和交互,使得虚拟桌面达到和传统桌面一样的用户体验。
USB(Universal Serial Bus通用串行总线)是应用于计算机领域的用于外围设备与计算机进行连接的接口技术。它最初是由Compaq、Intel、NEC、Microsoft等公司共同提出的,其目的是简化PC机和外设的连接过程,使PC接口的扩展变得更加容易。
USB版本的发展到目前为止经历了3代:12Mbps速度的1.0/1.1版本,480bibps速度的2.0版本及目前的5Gbps的USB3.0版本。此外,USB OTG(On-The-Go)的发布使得USB可以脱离主机的限制就进行设备间点对点的数据传输,从而使USB有了更广泛的应用领域。目前几乎所有计算机外设都有USB 接口的设备,包括人机交互设备,存储设备,网络摄像机,媒体播放器,打印机,音响,智能卡,可以毫不夸张地说用户所有的设备都可以支持USB 传输协议。
而且基于大文件和大数据量的传输,出现的USB3.0基本已经和一种被称为火线(FireWire)的接口技术--IEEEl394一样,提供更快的数据传输方法。USB3.0的最大传输带宽高达5Gbps,也就是625MB/S。USB 2.0基于半双工二线制总线,只能提供单向数据流传输,而USB 3.0采用了对偶单纯形四线制差分信号线,故而支持双向并发数据流传输,这也是新规范速度猛增的关键原因。同USB一样,IEEEl394也支持外设热插拔,可为外设提供电源,省去了外设自带的电源,能连接多个不同设备,支持同步和异步数据传输。,IEEEl394的标准速度为3.2Gbps,主要应用于通信和信息家电领域,用于连接高速设备。但是现在USB3.0的速度其实其实已经超过IEEEl394,因此未来这个领域的互联也可以采用USB技术。
在用户看来,USB系统就是外设通过USB接口和PC连接起来。一般的USB系统架构可以分为以下三部分:USB主控制器/根集线器、USB集线器和USB设备。
USB主机控制器/根集线器(hostcontroller/root hub)
USB集线器(USB hubs)
USB设备(USB device)
USB 总线构架如图所示,它也是一个典型的树形结构。连接PCI/PCIe 总线的USB Host 为根,下面连接各种USB 设备或者USB Hub,而USB Hub 又可以连接其它USB Hub 或者USB 设备。每个USB Hub 最多接5 个USB 设备或者子USB Hub。另外,由于USB Host 对挂载的所有USB 设备采用分时共享机制,受响应时间的限制,整个USB 系统最多只能支持7 层。以USB 主控为第一层,包括最底层的USB 设备为第7 层。
简要说明的是,以前我们的CPU/IO桥是典型的南北桥架构,南桥上面放置的是低速USB的主控制器,在北桥上面放置的是高速的USB主控制器。随着技术的发展,现在我们的CPU/IO桥发生了演变,即CPU和内存之间采用的是NUMA互联技术,同时CPU和IO设备之间,IO设备的控制器全部接入到北桥上面,将南桥上面的所以控制器迁移到北桥上面,同时北桥距离CPU和内存更近,访问速度更快。
USB主机控制器/根集线器
USB主控制器是整个USB系统的大脑,负责完成主机和设备间的数据传输。
USB根集线器提供USB连接端口给USB设备或USB集线器使用。
所有在USB系统上沟通都是在软件控制下由PC主机激活的。主机硬件包括USB主机控制器(USBhostcontroller)与USB根集线器两种。在用户计算机上的系统属性的“设各管理器”中所显示的“通用串行总线控制器”内,包含了下列所示的两组项目:
USB主机控制器;
USBRootHub――USB根集线器。
当然,大部分的计算机仅有一组而已。若在操作系统中,未涵盖类似的设各信息画面,则代表此主机并未支持USB接口。用户可能就必须另外购置USB接口的扩充卡来加以使用。而笔记本电脑则须使用PCMCIA接口的扩充卡。相同的方式,若用户须要将原先USB1.1主机控制器的规范升级为USB2.0或着USB3.0,也同样须购置USB2.0h和3.0的扩充卡。
USB根集线器--提供USB连接端口(俗称USBPort)给USB设各或USB集线器来使用。一部计算机可以同时连接127个USB设各,当然不可能由主机控制器去搜寻某个设备的地址,所以USB系统运用类似计算机存储数据的概念,有“根目录”、“子目录”、“次子目录”等分层方式;而主机控制器只要对根集线器下命令,然后再由根集线器传到正确的设各地址即可。
USB集线器
USB集线器主要是提供另外的USB连接端口供用户串接设备。
若仅靠USB根集线器则不可能同时连接上127个USB外围设备,所以除了根集线器外,USB系统还支持额外的集线器。这些集线器的功用主要是提供另外的USB连接端口给用户串接设备,有点像网络的HUB集线器―样;而整个USB连接设备方式,有点像金字塔型的架构。每一个连接器上,呈现了一个USB接口。
USB设备
USB设备指各种类型的USB外设。它们可以与USB主机交互数据和控制信息,并为主机提供额外的功能,但在使用前主机必须对其进行配置。目前的USB设备可大致分为三类:低速设备、全速设备和高速设备。
USB枚举流程
USB通过一个称为USB设备枚举的过程来鉴别和管理设备的连接或者断开。USB设备在连接时,主机通过缺省控制管道来向其发出标准设备请求、获取并分析USB设备的相关描述符,并以此来配置USB设备。USB设备枚举过程的具体步骤如下:
1、USB设备连接至集线器的USB端口后,即就是我们笔记本上面的USB接口,集线器会使用其中断IN管道向主机报告设备的插入事件。这之后还有很多细节,比如主机接收到中断之后是继续向CPU发送中断信息,向CPU报告一个中断事件,等待CPU处理完成其他任务之后再来处理这个中断事件。即在这个过程中,USB主机控制器其实是和CPU通过中断进行通信,CPU指挥USB主机控制器进行一系列动作,主机再来指挥下面更小单位的组件进行以下的流程处理。此时,USB设备处于加电状态,它所连接的端口是无效的。
2、主机知道设备接入集线器后,向集线器发出查询请求以了解更多信息。当确认有设备接入总线,主机发出查询请求复位设备,在这期间集线器会确定设备的传输速率并向主机报告。复位结束后USB设备进入缺省状态,并可使用缺省设各地址对管道0的控制事务做出响应。
3、主机向设备发送USB协议规定的请求描述符命令,读取该描述符的前8个字节,以取得却缺省控制管道所支持的最大数据包长度。
4、主机发送配置地址命令分配一个唯一的地址给设备。设备读取这个请求,返回一个确认,并保存新的地址。从此开始所有通信都使用这个新地址。
5、主机向新地址设备重新发送请求描述符命令,读取其设备描述符,以了解该设备的总体信息。
6、主机向设备循环发送请求配置命令,以读取全部配置信息。获得字符串描述比如厂商、产品描述、型号等。
7、主机根据Device 和应答信息,为设备选择一个合适的USB设备驱动程序。
8、加载USB设备驱动后,主机将发出SetConfiguration(x)请求为该设备选择配置。如果配置成功,USB设备进入设备配置状态,可以和主机进行数据通信。
USB传输流程
当USB设备连接到USB总线之后,USB设备便可以和USB主机进行通信。在通信的过程中,自上而下要涉及4个部分,分别为:
主机软件(应用程序)
USB总线驱动程序(Bus Driver)
USB主控制器驱动程序(Host Driver)
USB功能设备(Device Driver)
其中需要说明的是,这些驱动程序和上面的USB系统架构中的组件是一一对应的,其中USB总线驱动程序(Bus Driver)使用与集线器上,是用来识别USB设备的;USB主控制器驱动程序不用说明,大家看名称就知道;USB功能设备(Device Driver)是用来控制具体的USB设备的驱动程序,即怎么用这个USB设备?
1、主机软件将数据保存在发送数据缓冲区中,向USB总线驱动程序发送数据传输请求,即I/O请求包(IRP)。
2、USB总线驱动程序对主机软件的I/O请求包(IRP)进行响应。将其中的数据转化为USB协议中规定的事务处理格式,并将其向下传递给USB主控制器驱动程序。
3、USB主控制器驱动程序将每个事务处理转化为一系列帧/小帧为单位的事务处理队列。这样处理是为了满足USB传输协议的要求,并保证传输不超过USB的带宽。
4、在USB主控制器中,读取事务处理列表,将其中的事务处理以信息包的形式发送到USB总线上。可以使用块传输、中断传输、同步传输和控制传输4种传输方式,同时也可以选择低速、全速和高速3种传输率进行传输。这些传输方式和传输速率我并不准备进行详细解释。
5、USB功能设备的驱动程序接收信息。USB的SIE引擎自动解码信息包,并将数据保存在指定的端点缓冲区中,供USB进行处理。
虚拟化技术成为计算机领域的热门技术,并且广泛地运用于服务器集群系统和云计算数据中心,是云计算解决方案的基础支撑技术。目前的单个物理平台上可以同时运行多个独立的操作系统实例的虚拟化技术实现主要有VMware、Hpyer-v、Xen、KVM等。其中在这些虚拟化技术中,对于USB设备的虚拟化实现主要有三种技术:QemU模拟实现、USB直通(也叫USB透传)和基于前后端驱动机制的USB虚拟化。
使用软件模拟是非常常见的方法,它通过构造各种软件设备模型,在虚拟机中呈现出和实际总线上一样的I/O 设备。设备模型指虚拟机中对目标设备的模拟,主要是模拟出软件可见的接口和行为。模拟设备操作系统看来和真实设备无异即可,其硬件构架和硬件接口在模拟过程中可适当简化。客户操作系统看到的设备接口,需要设备模型中通过软件接口来实现。设备模型中需要模拟的软件接口包括PCI 配置空间,Port I/O 和MMIO,DMA 及中断。
在虚拟化平台上的QEMU都是经过修改的。其中负责PC 硬件模拟的文件在QEMU 模块加载时会加载这个设备模拟模块,模拟带PCI 总线的PC机。它使用QEMU Machine 结构来描述一台虚拟物理平台,并使用链表连接起来。QEMU Machine 结构中包括名字,类型描述,初始化函数等字段。
QEMU负责硬件平台的模拟。在模拟时,需要完成vCPU 的创建,内存分配,加载并映射虚拟BIOS,加载Linux 代码,模拟并初始化虚拟系统时钟,读取物理PCI 配置空间并虚拟化PCI 总线结构,包括总线上挂载的串口,并口,音频,软盘,IDE 接口,USB 接口等其它总线及设备。其中有专门的USB函数负责模拟USB类型的主机控制接口USB 设备。并将正式的物理设备使用链表连接起来,所以我们在使用虚拟机的时候在虚拟机里面添加USB虚拟控制器即可接入读取到插入物理设备的USB设备。
在Xen 4.0 版本之前,Xen 可以通过两种方式使用USB 设备,但者两种方式都存在效率的问题。其中一种就是通过pass-through 的方式利用Qemu进行模拟实现。同样在其他的虚拟化平台上其使用QEMU来进行模拟USB设备以进行虚拟化的方式和Xen的无任何区别。但是仅支持USB1.1 协议类型,并不支持高速设备。所以这种方式仅能支持有限种类的设备,而且I/O 效率很低。
USB直通是指将USB 设备直接分配给虚拟机,此后,虚拟机中的应用程序可直接访问USB设备,而不需要通过VMM 进行管理。这需要在虚拟机启动前,把设备从VMM 中注销。然后启动虚拟机,在虚拟机的设备驱动中注册该设备。设备直通的方法需要硬件辅助虚拟化技术的支持,比如主板和CPU均支持Intel VT-x,EPT 及VT-d 技术。即需要支持IOMMU。
Xen的USB设备直通是基于IOMMU 的支持通过PCI pass-through 的方式来实现的。每个主机控制由一个虚拟机独占,所以设备不能够被灵活的分配。同样,其他虚拟化平台实现USB直通也是采用IOMMU这种IO设备透传的技术来实现。
为了在虚拟化平台中支持直接分配I/O 设备,需要修修改虚拟化平台,这个一般虚拟化厂家已经加入了支持的代码,去调用IOMMU技术,实现对设备的直接分配。
在VMM中,存在着一个用来描述分配给VM 的I/O 设备的结构体,每个已分配的I/O 设备对应该结构体的一个实例,所有实例构成一个链表,表头记录在VMM结构体的数据元中。VMM模块中分配设备给虚拟机的流程如下。
首先先遍历VMM的数据元,根据待分配设备的设备号查找已分配的设备,确保该设备尚未被分配给任何VM。然后分配一个该设备类型结构体。之后,根据设备号和总线号,查找PCI 总线上的设备,获取I/O 设备的设备信息,写入PCI_DEV 结构体中,并确保该设备没有被VMM 占用,且该设备的I/O 地址空间在VMM 中没有被占用。如果这些条件都满足,则填充分配到对应实例的结构体中,包括总线号、设备号、功能号、访问标志、PCI_DEV 结构体所包含的信息等等。并把该实例插入已分配链表中。最后,调用函数在VM 中为I/O 设备的地址空间做映射,并调用函数分配该设备。
分配USB 设备给VM 后,还需要在该VM 中申请中断号并注册中断处理程序。首先,需要从VMM数据元中开始遍历已分配的设备,确保根据设备号可以在链表中找到该设备的描述信息,然后根据该设备是在宿主操作系统中分配的还是在客户操作系统中分配的,分别调用不同的函数,实现中断处理程序注册。
前后端驱动是非常经典的虚拟化技术,前后端驱动虚拟化是指通过修改客户机操作系统,或者修改VMM 提供给VM 的硬件抽象层,使得VM 和VMM 协同工作,实现系统虚拟化。
前后端驱动模型首先出现在Xen的虚拟化平台上,后来VMware以及Hpyer-v、KVM等虚拟化平台均有采用该模型实现IO虚拟化。
Xen 在4.0 版本中引入了PVUSB(para-virtual USB driver)技术,PVUSB 技术就是采用Xen 虚拟化平台的前后端驱动模型,支持多个半虚拟化虚拟机同时使用USB 设备,支持设备热插拔等功能,使得虚拟化平台中USB 设备使用的性能和灵活性都得到了很大的提高。
因为Xen的特权级虚拟机是基于Linux的,所以我们还要简要说明下,在Linux 内核中,USB 设备驱动包括USB 设备功能驱动,USB 核心驱动和主机控制器驱动。就是我们上面所述的那3层驱动模型,只不过名字叫法不一样。
PVUSB 前端驱动(usbfrontdriver)位于非特权级虚拟域中,是虚拟主机控制器驱动。 PVUSB前端驱动作为PVUSB后端驱动的代理,它会从URB队列(备注:URB 是USB 传输的基本单元)中取出URB,并向后端驱动发送URB。在半虚拟化内核中,USB 功能驱动和USB 核心驱动都没有修改。PVUSB 前端驱动实际上是一个虚拟的驱动程序,它负责和后端驱动通信,并且在虚拟机操作系统中建立一个虚拟的USB 设备树,包括USB 集线器。PVUSB后端驱动(usbback driver)是一种类型的USB 设备驱动,属于USB 驱动架构中的功能驱动,它位于特权域中,负责操作物理主机控制器和设备,并将物理设备分配到客户虚拟机的虚拟USB 设备树中,后端驱动重新创建URB 并将URB 传输给物理设备。客户虚拟机透明地操纵虚拟控制器,与操纵实际的主机控制器一样。用户可以用热插拔的方式将设备连接到虚拟机。在管理域中,管理员可以管理设备与虚拟域的连接。在客户虚拟机中用户可以使用任何设备而不用考虑它们的物理设备总线。
PVUSB 前端驱动作为客户虚拟机USB 主机控制器驱动,属于Linux 系统驱动架构中的USB 主机控制器驱动。它会将URB 队列映射到共享I/O 环,并向后端驱动发出请求。当接收到后端驱动的回应之后,前端驱动更改URB 中的状态标记,然后将URB 返回给USB 核心驱动。PVUSB 后端驱动作为USB 功能驱动,属于Linux 系统驱动架构中的功能驱动程序,在接收到前端驱动的I/O 请求后,会重构URB 请求并将URB 提交给特定的设备。当URB 执行完成之后,后端驱动会将URB 的执行的状态通过共享I/O 环返回给前端驱动。
上述我们所述的USB具有三层驱动中,分别是:
USB总线驱动程序(Bus Driver)
USB主控制器驱动程序(Host Driver)
USB功能设备驱动(Device Driver)
USB总线驱动程序(Bus Driver)使用与USB集线器上,是用来识别USB设备的;USB主控制器驱动程序(Host Driver)用于主机和设备间的数据传输。USB功能设备驱动(Device Driver)主要是提供用来控制USB设备,控制USB设备按照命令进行工作。
如果我们不考虑其他因素的情况下,虚拟桌面虽然是一台虚拟机,但是它仍然拥有这三层驱动,本地客户端同样如此。那么我们如何来考虑对插入本地USB设备进行重定向,目前基于虚拟桌面主流的厂家来说,有两种方法:一种是USB端口重定向,就是虚拟桌面厂家自己写一个虚拟的Host Driver,替换掉USB主控制器驱动;另一种是USB设备重定向,即为某一类设备提供从客户端到远程桌面的映射,并为其提供业务数据传输的专用通道,如摄像头、打印机、扫描类设备、智能卡设备等。说得通俗一点,那就好比是我的本地电脑连接了一台打印机,可以正常打印,同时我做了一个共享,我将这台打印机共享到了网络上,并设置权限让特定的人可以通过网络来访问我的这台连接的本地打印机,并可以进行打印任务。
那不管是何种重定向,其主要分为两部分:虚拟桌面和客户端。
在客户端我们安装一个组件用于监听本地设备的USB设备接入、移除等状态信息,同时实现USB端口或着USB设备的重定向,将USB设备的相应操作通过截获,封装成行相应格式用过网络将其传输到远端的虚拟桌面,同时接收虚拟桌面发送回来的数据,并进行相应处理。
在虚拟桌面我们也需要安装一个组件用于模拟USB设备的接入、移除等状态信息,同时接收来自客户端的USB数据,并进行相应处理。
上面我们说了,Bus Driver的是用来识别U盘的,它主要工作在我们的笔记本那个和我们直接插入USB设备的接口处,我们的计算机直接和USB设备进行物理接触的那个USB接口,是一个类似于集线器的USB接口,在接口后面附带有一个内置的芯片,里面安装了Bus Driver。这个我们无法进行虚拟化,也无法写入虚拟的Bus Driver来代替,因此在这三层驱动中,能够被代替的USB驱动层就是Host Driver和Device Driver,而Device Driver一般都是设备厂商提供的外设驱动,是去操控他们自己的USB设备的。
USB端口重定向方式通过在虚拟桌面和客户端各内置一个虚拟USB主控制器驱动(Host Driver),实现原物理下USB主控制器驱动的拉远。而设备对应的真实USB设备驱动安装并运行在虚拟桌面中,与虚拟桌面虚拟的USB主控制器驱动进行交互,这样对虚拟机中的USB设备驱动来说,并不会感知到所控制的设备实际上在远端,同样应用程序也不会感知到这个差异。因为USB端口重定向与具体的设备和应用无关,直接将USB端口重定向到桌面虚拟桌面中,所以USB端口重定向具有良好的设备兼容性。但同时,也正是因为这个原因,USB端口重定向也有一定的局限性,由于没有经过本地设备驱动层的压缩和预处理,对于某些扫描仪和摄像头等图像类应用,可能会导致带宽过大,网络时延敏感等问题。在这种情况下,需要使用到设备重定向技术。
在Citrix XenDesktop解决方案中,我们在配置HDX策略的时候,在ICA策略当中,其中关于USB的策略实现即属于USB端口重定向技术。
继续书接上文,上文中我们说道USB的三层驱动,可以被虚拟代替的有Host Driver和Device Driver。在USB设备重定向技术中,部分设备就是通过替换Device Driver来实现的USB设备重定向。这里强调部分设备,就是说USB设备重定向技术并不是全部都是通过替换Device Driver来实现,只是针对不同类别的设备,有不同的实现方式和技术。比如在Citrix XenDesktop解决方案中,针对于智能卡的USB设备重定向技术就是通过替换Device Driver来实现的。所以在我们进行智能卡测试的时候,我们发现本地设备识别和使用智能卡没有任何问题,但是在虚拟桌面中就存在问题,这个时候我们只需要在注册表中删除关于Citrix的智能卡Device Driver的文件路径,我们的智能卡就能够正常的识别和使用。其原理就是不使用Citrix自己编写的Device Driver,而是使用微软通用的Device Driver或着厂家自己的Device Driver。
在USB设备重定向的实现方方法上,不同的设备有不同的实现方式,这和设备的通信方式和工作模式存在一定的关系,比如是摄像头的USB重定向,摄像头是会去调用本地的显示和解码,同时视频数据比较大,还会进行一定的针对视频数据格式的压缩。所以对于不同的设备不能使用通用的方法来进行重定向。在Citrix XenDesktop解决中,在HDX策略--ICA策略中,打印机重定向、TWAIN重定向、PC/SC重定向、文件夹重定向等均属于设备重定向技术实现的范畴,只不过说,这些设备如果通过USB来进行互联,那么就是USB设备重定向。
The end!