在分析usbip驱动前,我们先来学习一下usb总线在linux系统下的表示。
我们知道在linux中,/proc和/sys这个两个文件系统包含了很多有用的信息,所以usb的信息自然也少不了利用它们来展示。
1,我们在《linux usb gadget驱动详解(三)》知道了ls /sys/class/udc 能查看系统注册了的udc驱动。
2,cat /proc/devices能查看当前系统注册了哪些驱动,linux系统为每个已注册的设备驱动分配一个“主设备号”:
Character devices:
1 mem
4 /dev/vc/0
4 tty
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
21 sg
29 fb
89 i2c
90 mtd
128 ptm
136 pts
180 usb
189 usb_device
204 ttyAMA
218 himedia
251 ubi2
252 ubi1
253 ubi0
254 bsg
Block devices:
1 ramdisk
259 blkext
8 sd
...
...
跟usb相关的有这两个:
180 usb
189 usb_device
它们代表的驱动是有区别的。而且并不是所有usb设备驱动(USB接口驱动)都分配一个主设备号,有些是挂接在一些子系统内,如USB HID键鼠设备,就挂接在input子系统内。建议大家把《Linux那些事儿之我是USB》书看烂,里面有详细描述。
3,ls /sys/bus/usb/devices/也包含了很多信息:
1-0:1.0 2-1 2-1.1:1.0 usb1
2-0:1.0 2-1.1 2-1:1.0 usb2
其中usb1、usb2代表系统注册了2条usb总线,即有2个USB主机控制器,1和2用于区分不同总线,是USB的总线号。
每插入一个usb设备,/sys/bus/usb/devices/就有新的文件夹生成。其中“2-1:1.0”代表usb总线号为2,devpath为1,配置号为1,接口号为0,即2号总线的1号端口的设备,使用的是1号配置,接口号为0。而“2-1:1.0”代表的是一个hub设备,可根据下面得知:
/sys/bus/usb/devices # cat 2-1:1.0/bInterfaceClass
09(其中09代表Hub,又如,08代表mass storage class(U盘...)等)
那么当hub的端口上又接入usb设备,那么在linux下又怎么表示呢?我们可以看到还有一个“2-1.1:1.0”,这就是利用了devpath的作用,顶级设备的devpath就是其连在Root Hub上的端口号,而次级的设备就是其父hub的devpath后面加上其端口号,即2-1:1.0是一个Hub,那么它下面的1号端口的设备就是的上面的“2-1.1:1.0”,2号端口的设备就可以是“2-1.2:1.0”等。
OK,现在可以开始讲述usbip了。
usbip驱动提供了linux下USB透传(bypass)的功能,或者说usb over tcp,利用以太网,将usb设备共享到另外一端。usbip刚开始是一个独立的项目(http://usbip.sourceforge.net/),后来合并到linux主分支中,源码在drivers/usb/usbip下,由linux usb子模块的那帮大牛维护。
盗用usbip项目的图:
usbip分为两端:server端和client端,它们分别运行在不同的linux主机中,其中运行server端驱动的PC插入usb设备(如U盘等),用于共享。此时client端PC就可以attach到server端,此时client端的主机PC就能看到u盘,它以为真的有一个u盘插入本机,并为其安装驱动,效果跟在本机上直接插入U盘无异,实现了u盘共享,或者USB延长器的功效。
在分析usbip代码前,我们来玩一下usbip,感受一下:
材料准备:两台装有ubuntu系统的PC,或者虚拟机,两台PC能相互ping通,ubuntu版本为16.04。
因为ubuntu16.04的内核版本为linux4.4以上,所以usbip的用户态工具不能使用apt-get install来安装,用apt安装得到的是配套旧版本的usbip驱动,所以我们需要uname -a查看ubuntu当前使用了什么版本的kernel,然后在https://www.kernel.org/下找到对应版本的kernel版本,下载源码,解压后,进入内核的根目录下tools/usb/usbip,这个是应用程序的,用来配置(控制)usbip驱动的,在编译前ubuntu需要安装依赖:
sudo apt-get install autoconf automake libtool libudev-dev
然后就可以在源码目录运行./autogen.sh,生成configure了。
最后就是经典的“三部曲”:
./configure
make
make install
ok,此时得到了usbip的配置工具了(注意不要使用apt-get install来安装usbip工具,由这种途径得到的工具版本是配套旧版本的usbip驱动(linux3.x以前的版本),在linux4.x版本的usbip驱动上无法正常配置),但usbip工具要求我们在/usr/share/hwdata/下放入usb.ids数据库,usb.ids文件可以到usb.org下载,里面包含了各种厂商的VID和描述信息,可以做实验了:
在server端PC上:
sudo modprobe usbip-host
usbipd -D
加载驱动,运行usbipd程序,该守护进程用于建立TCP socket连接等。
插入一个U盘/鼠标,此时usbip list -l应该能列举出设备,用于查看busid
usbip list -l
- busid 2-1.1 (046d:c077)
Logitech, Inc. : M105 Optical Mouse (046d:c077)
我们找到busid是2-1.1的罗技鼠标为我们将要共享的设备。我们需要绑定它,以便于共享,有complete字眼说明绑定成功:
usbip bind -b 2-1.1
usbip: info: bind device on busid 2-1.1: complete
而usbip unbind -b 2-1.1则是解绑,用于关闭usb的共享。
在client端PC上:
modprobe vhci-hcd
#usbip list –r <server端ip地址>
usbip list -r 192.168.100.191
#usbip attach -r <server端ip地址> -b <busid>
usbip attach -r 192.168.100.191 -b 2-1.1
也需要加载驱动,ubuntu默认是不主动安装usbip驱动的,但它自带了,不需要我们自行编译,所以直接使用modprobe加载即可。其中192.168.100.191是server端PC的ip地址。usbip list -r 192.168.100.191能列举出server端已经导出的usb设备,这里我们导出了2-1.1设备,还能看出是罗技的。运行“usbip attach -r 192.168.100.191 -b 2-1.1” 就能将远程的usb设备attach到本地,如果共享的是U盘就能读写U盘,这里是鼠标,此时就是一个KVM的远程鼠标控制功能了。使用usbip detach -p 0可以断开usb设备。
总的来说usbip在一定程度上实现“usb延长器”功能,但存在一定问题(缺陷):
1,兼容性问题,我测试过usb摄像头支持得不好。
2,稳定性问题,插拔usb或插拔网线后等恢复得不是很好,有待提高。可能需要用卸载驱动再重新加载来规避。
3,缺乏长期测试,没有广泛用于真实产品。
市面上的USB网线延长器(要能过交换机那种)就是利用以太网帧(链路层,不可能是tcp)传输usb数据的,但它是利用硬件实现,兼容性、稳定性会更好,我曾设想过使用"FPGA+ usb phy(UPLI接口)+Ethernet phy(RGMII接口)"来实现usb延长器功能,但迟迟没动手。毕竟usb硬件抓包就是利用FPGA+usb phy来实现抓包的(开源硬件USB抓包及协议分析工具分享),既然能完整抓包,就能把数据原样传输出去,理论上是可行的,但从USB协议规范可以知道,usb对时间要求挺高的,很多状态转移均由时间超时相关,所以要想做得好,FPGA需要处理的东西还是挺多的,否则可能传着传着就提示识别不到usb设备(usb设备挂起)了。
需要说明的是,usbip驱动是用于linux操作系统的。对于windows下,也有类似的开源项目。但我精力有限,没有测试过,有兴趣的朋友可以自行编译+测试。github路径为:https://github.com/cezanne/usbip-win 。windows下的client端我觉得用途更大一点,毕竟很常见的一个情景是,在嵌入式linux设备(server)上插入U盘/加密狗,需要在windows(client)下获取u盘内容/加密狗验证。
最后,不得不说,windows下有好用的、但收费的专用usb共享软件。譬如usb over network (http://www.usb-over-network.com/)和VirtualHere(https://www.virtualhere.com/home),好像均可以免费使用导出一个设备,想要导出多个设备需要花钱购买。功能挺强大的,我测试过能共享 USB 1080p高清摄像头,很稳定,延时也不大。吾爱破解网貌似有大神破解了,有兴趣的可以试下(https://www.52pojie.cn/thread-982233-1-1.html)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)