关于USB重定向和读写控制

前提

使用的是qemu+spice_gtk+virt_viewer来做这个事情的,不过走了一些弯路,之前由于拿到这一块是用的是spicec的代码,在其上加入usb重定向的东西,不过这个spicec目前是不推荐使用的,官方早就推荐了用remote-viewer,故走了两个版本,一个版本是使用spicec加上重定向代码,还有一个是用spice-gtk上用其代码,但是要加入管控,两个版本都做了,觉得spice-gtk加上禁止,只读控制还是好一点。最后发现坐在qemu上最好

Mass Storage协议

U盘是属于大容量存取介质,USB一般是使用Mass Storage协议来进行通信的。使用Mass Storage协议通信之前主机需先获取设备的相关信息,并进行设置。 首先是control协议,然后是bulk的批量协议。 qemu对usb存储使用大容量存储传输协议,这种传输方式是大部分usb设备所使用的,官方原话:

QEMU has two emulations for usb storage devices.Number one emulates the classic bulk-only transport protocol which is used by 99% of the usb sticks on the marked today and is called “usb-storage”. Usage (hooking up to xhci, other host controllers work too):

qemu ${other_vm_args}
   -drive if=none,id=stick,file=/path/to/file.img  \
   -device nec-usb-xhci,id=xhci                    \
   -device usb-storage,bus=xhci.0,drive=stick

检查了下启动参数,确实有点问题,这一块还有很多不是很明白。官方还有一种支持多分区的办法。

抓包Bulk Only传输协议

用抓包去分析这个问题,将usb通信协议都抓出来了,发现usb协议属于对话协议,即一问一答协议,先control后批量传输,前面一直觉得握手协议中控制协议一定标记了设备的属性等,最后发现不是这里,具体在bulk里面。 type 0x80 req 0x6 这里应该是标记usb协议的大容量协议吧,具体没去查文档。 传输方向是:CBW(Command Block Wrapper)->[DATA]->CSW(Command Status Wrapper)

CBW是以0x55534243(Little Endian)开始

CBW是以0x55534253(Little Endian)开始

这里写图片描述

dCBWSignature:

    CBW的标识,固定值:43425355h (little endian)。

dCBWTag:

    主机发送的一个命令块标识,设备需要原样作为dCSWTag(CSW中的一部分)再发送给Host;主要用于关联CSW到对应的CBW。  dCBWDataTransferLength: 

    本次CBW命令要求在命令与回应之间传输的字节数。如果为0,则不传输数据。 bmCBWFlags: 

    反映数据传输的方向,0 表示来自Host,1 表示发至Host;      bCBWLUN: 

    对于有多个LUN逻辑单元的设备,用来选择具体目标。如果没有多个LUN,则写0。 bCBWCBLength: 

    命令的长度,范围在0~16. CBWCB: 

    传输的具体命令,符合bInterfaceSubClass.中定义的命令规范,此处是SCSI

下面是协议:

out: 55 53 42 43 60 6C 0E 02]

out: 24 00 00 00 80 00 06 12]

out: 00 00 00 24 00 00 00 00]

out: 00 00 00 00 00 00 00]

log end

log start len = 36

in: 00 80 04 02 1F 00 00 00]

in: 4E 65 74 61 63 20 20 20]

in: 4F 6E 6C 79 44 69 73 6B]

in: 20 20 20 20 20 20 20 20]

in: 50 4D 41 50]

log start

in: 55 53 42 53 60 6C 0E 02]

in: 00 00 00 00 00]

60 6C 0E 02是校验码,00 00 00 00 00是表示执行正常。中间的是数据块,这里表示什么要根据这个: 这里写图片描述

SCSI命令http://en.wikipedia.org/wiki/SCSI_command 这里0x1E是写保护,qemu也有这个代码 Prevent/Allow Medium Removal 。根据SCSI命令就完成了功能。

实现功能如下:

这里可以看到右键没有新建等选项

这里写图片描述

这里写图片描述 这里写图片描述

最近的文章

我为什么写博客?

注我讲注解放到最上面来就是想告诉你们这群乱入的年轻人,以下全是一个大龄九零后傲娇言辞,建议你们速速离去,我只想说,没有被这篇文章而耽误生命的人真的是太好了。.第一篇Blog写博客的主要目的是什么,这往往是我一开始就想要说的。Github是一个开源技术社区,在这上面写博客往往是被贴上技术的标签,所以在这一层上看,将来的博客可能都将是关于技术,但也可能不是。不管怎样,我今天至少尝试在继续写博客而且跨出了一大步,至少这样看到还是挺好的。我是谁我是一个大龄九零后,目前在深圳从事桌面云相关开发,主要...…

为什么要在Github上写博客继续阅读