USBIP解读及源码分析
+ -

USB学习之USBIP之路

2024-01-02 435 1

学习本身就是一门避轻就重之路。
本人从开始搞USB开始,大概已经3年了。其当时的切入点就是USB驱动的开发,其实到目前为止,也是以USB驱动开发为主要任务。但在实际的开发过程中,总会遇到很多的USB技术问题,为了解决这些问题,也不得不去涉及到USB软件层之外的问题。
例如USB硬件知识,链路层,事务及令牌,更有甚不得不看一些USB集线器、控制器相关的知识,当然这些对我为说,都是一些边边角角的东西,因为本身并非从事这些方面的东西,只是洽巧因问题需要翻这些东西。
当然,要解决上述的问题,就需要强大的综合知识,也洽好本人硬件出身,模电还是有一定的功底的,所以对这些东西来说,也不会无从下手,下有下手的动作,但效率上来说,就很低了,毕竟不从事这方面的工作。
为了更深入地了解USB底层,也为了提高本人的综合水平。也不得不去学习一些相关的东西。所以就有了以下各种诡异的操作。
研究了STM32F407,开始研究FPGA,学习音视频开发,看USBIP源代码,也在开始学习LINUX相关的知识。

  • 学习STM32,也只是为了满足自己当前嵌入式的一个小的心愿。
  • 学习FPGA,最终也只是为了ZYNQ到最终的LINUX。
  • 学习LINUX,也是为了驱动以及内核的东西,也为是了ZYNQ服务的。
  • 学习USBIP源代码,也是自己的一个小心愿。只是为了从系统层了解USB相关的知识。

搞这些东西,也只是满足心愿。当然也会有一些附带的产出。这些产出说来也奇怪,有时竟成为某些同学的需求。

USBIP之路

搞USBIP,纯属是为了提高自己的Windows内核的知识。因为看别人的代码来学习,是一件很开心的事。我们去学习中小型软件的设计架构,了解一些系统层的知识。总比漫无目的在REACTOS中乱看有效的多。所以学习USBIP是一个心愿。
当自己许了愿,就要想办法把它实现。所以就开始看USBIP的源代码,做笔记来学习。
另外,自己以前虚拟的USB各类设备,都是比较暴力的虚拟。但在本人看来,都是无源之水,无根之萍。USB设备总得从USB集线器USB控制器开始。另外我们在搞USB的时候,经常用的一个工具是USBTreeViewer,这是在微软开源USBViewer的基础上二次开发的。这个工具有很多实用的功能,所以为了熟悉这些功能的实现以及与系统层相关的接口,无论是IOCTL还是SETUPAPI,都是很有必要的。
当然,看了别人的代码。为了将这些代码真实的变为自己的,自己就得自己重写一遍。只有自己重写一遍,才能更加深刻地理解和了解一些关键性的东西。所以本人也就有了VUSB这个工程。

2023/12/26  15:27             5,595 add_device.cpp
2023/12/15  16:04               572 add_device.h
2023/12/05  19:45               313 create_close.cpp
2023/11/27  16:22                96 create_close.h
2023/12/27  15:07             4,846 device.h
2023/12/29  16:29               661 device_fhci.cpp
2023/12/12  11:15               212 device_fhci.h
2024/01/02  11:22             6,886 device_hub.cpp
2023/12/26  16:56               374 device_hub.h
2023/12/26  11:35             4,016 device_pusb.cpp
2023/12/12  17:53               739 device_pusb.h
2023/12/29  11:30            10,824 internal_ioctrl.cpp
2023/12/15  10:59               838 internal_ioctrl.h
2023/12/26  09:59             1,126 ioctrl.cpp
2023/12/12  16:58                87 ioctrl.h
2023/12/29  16:29             3,208 ioctrl_fhci.cpp
2023/12/12  10:38               242 ioctrl_fhci.h
2024/01/02  11:12            11,090 ioctrl_fhub.cpp
2023/12/13  11:21             1,062 ioctrl_fhub.h
2023/11/29  12:17             1,548 irp.cpp
2023/11/29  12:17               387 irp.h
2023/12/15  16:42             1,882 main.cpp
2023/11/27  10:13               133 main.h
2023/12/29  11:30            13,770 pnp.cpp
2023/11/29  15:04             1,534 pnp.h
2023/12/29  11:30             4,725 pnp_device_status.cpp
2023/11/30  10:08               998 pnp_device_status.h
2023/12/29  11:30             6,501 pnp_query_cap.cpp
2023/12/05  15:58               240 pnp_query_cap.h
2023/12/29  15:40             5,254 pnp_query_id_text.cpp
2023/12/25  11:26               514 pnp_query_id_text.h
2023/12/28  14:11             5,948 pnp_query_interface.cpp
2023/11/30  15:29               256 pnp_query_interface.h
2023/12/27  15:05             5,332 pnp_query_relation.cpp
2023/12/05  17:39               409 pnp_query_relation.h
2023/12/05  16:10               811 pnp_query_resource.cpp
2023/12/05  15:53               143 pnp_query_resource.h
2023/11/28  16:36             3,080 power.cpp
2023/11/27  16:38                83 power.h
2023/12/12  10:26               475 stdafx.h
2023/11/02  23:59             7,582 usb.cpp
2023/07/25  14:34             2,556 usb.h
2023/12/26  15:28            10,229 USBZH.vcxproj
2023/11/27  15:57               168 USBZH.vcxproj.user
2023/12/25  11:00             1,376 VHUB.inf
2023/12/29  11:29             1,444 VUSB.inf

VUSB是一个简化了的USBIP,本人只做设备虚拟层了,舍弃了应用层及相关的网络通讯,因为本人并不需要USB远程映射,只需要本地电脑实现虚拟USB设备即可。
一个测试的例子,就是本人在USB控制器下虚拟了一个USB集线器,USB集线器挂了16个端口,本人为展示,也对这16个端口挂了16个HID设备,用于测试。
在设备管理器中是这样的:
VUSB设备管理器
在USBTREEViewer中是这样的:
USBTREEViewer

当然,这是一个半拉子工程。本人还没有挂音视频或者其它USB设备来测试,HID的也是一个自定义设备。功能这里也并没有完成。
还有就是为什么获取字符串描述符它说没找到,但我确实有返回了的。

   ---------------------- Device Descriptor ----------------------
bLength                  : 0x12 (18 bytes)
bDescriptorType          : 0x01 (Device Descriptor)
bcdUSB                   : 0x200 (USB Version 2.0)
bDeviceClass             : 0x03 (HID - Human Interface Device)
bDeviceSubClass          : 0x01
bDeviceProtocol          : 0x02 (Mouse)
bMaxPacketSize0          : 0x40 (64 bytes)
idVendor                 : 0xFF00 (Unknown Vendor)
idProduct                : 0x0108
bcdDevice                : 0x0100
iManufacturer            : 0x01 (String Descriptor 1)
 *!*ERROR  String descriptor not found
iProduct                 : 0x02 (String Descriptor 2)
 *!*ERROR  String descriptor not found
iSerialNumber            : 0x03 (String Descriptor 3)
 *!*ERROR  String descriptor not found
bNumConfigurations       : 0x01 (1 Configuration)
Data (HexDump)           : 12 01 00 02 03 01 02 40 00 FF 08 01 00 01 01 02   .......@........
                           03 01                                             ..

另外,关于USBTreeViewer对设备,对集线器及端口的操作,本人也并没有测试。
所以这时,需要反向需要研究USBViewer的实现原理并配合本人的VUSB工程来调试了。感觉这又是一个无边的天际线大坑。
路漫漫其修远兮,吾想一逃了之~
原因也比较简单:时间成本太高,本人也是一个无利不起灶的人。

HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936   

0 篇笔记 写笔记

USBIP整体架构
在普通的电脑上,想使用USB设备,必须将插入到主机。USBIP却可以通过网络,让主机访问其他主机上的外部设备,而用户程序完全感知不到区别。usbip的文章在这里:https://pdfs.semanticscholar.org/c7c4/cb054d75810fdb0a2affa11c288b76......
USBIP虚拟控制器和根集线器HUB的设备信息分析
USBIP是一套可以实现USB远程设备的本机映射,这样就像在本地操作目标USB设备一样。其原理是在本地端通过安装一个虚拟的USB根控制器,根集线器,同时虚拟出4个USB端口,当远程USB设备连接到远程机器时,可以把远程设备的USB信息通过网络传输到本地,在本地的虚拟USB端口虚拟一个相同的设备,这样......
USBIP虚拟控制器安装命令过程分析
USBIP虚拟控制器其自带的安装命令为:usbip.exe install -w可以看到,这是一个明显的自定义命令。这里一个比较有意思的是对命令行进行解析,使用的函数是getopt_long。在介绍这个命令之前,我们先介绍几个命令行参数的函数。命令行的长短项之分命令行分为长项和短项,我们一般使......
USBIP 设备树层次分析
通过前面知道,usbip_vhci工程实现的是pnp管理器虚拟出来的PDO的FDO,但同样也是这个FDO创建的PDO虚拟根USB控制器和其子设备HUB的驱动程序。USBIP设备硬件ID名称sys文件inf文件硬件IDusbip-win VHIC Rootusbip_vhic......
USBIP 驱动入口DriverEntry和vhci_driverUnload函数
无论该驱动被安装几次,DriverEntry和卸载函数只执行一次。DriverEntryWindows驱动和应用层一样,也有个入口函数,只是这个名字叫做DriverEntry。在DriverEntry中应实现的是该驱动各个IRP类类型的回调函数。PAGEABLE NTSTATUSDriverE......
USBIP 创建设备AddDevice
USBIP的AdDevice函数为vhci_add_device。DriverEntry(__in PDRIVER_OBJECT drvobj, __in PUNICODE_STRING RegistryPath){... drvobj->DriverExtension->......
USBIP 创建FDO设备和子设备PDO
设备创建由add_vdev函数实现,具体过程为:使用vdev_create创建FDO设备建立自己的设备链表将创建的FDO和PDO使用IoAttachDeviceToDeviceStack函数关联最后根据设备类型进行初始化设备层级及设备成员指针链表如下:static PAGEABLE NTST......
USBIP FDO和PDO设备类型及结构体大小
设备类型typedef enum { VDEV_ROOT,//虚拟根设备FDO VDEV_CPDO,//虚拟USB控制器PDO VDEV_VHCI,//USB控制器FDO VDEV_HPDO,//USB根HUB PDO VDEV_VHUB, //USB根HUB......
USBIP设备启动IRP_MN_START_DEVICE
在主功能号为IRP_MJ_PNP的子功能号里,使用IRP_MN_START_DEVICE执行设备的启动。DriverEntry函数中为:drvobj->MajorFunction[IRP_MJ_PNP] = vhci_pnp;vhci_pnp(__in PDEVICE_OBJECT de......
USBIP 虚拟根设备(VDEV_ROOT)FDO的初始化过程
AddDeviceUSBIP使用devcon安装根设备驱动后,会创建其对应的PDO,这时系统会加载我们的驱动调用AddDevice函数创建PDO,进入进行堆栈。devcon.exe install vaudio.inf "USBIPWIN oot"我们在之前的创建设备Add......
USBIP 虚拟控制器设备(VDEV_CPDO)PDO的初始化过程
IRP_MN_QUERY_ID/BusQueryDeviceIDPAGEABLE NTSTATUSpnp_query_id(pvdev_t vdev, PIRP irp, PIO_STACK_LOCATION irpstack){ NTSTATUS status = STATUS_......
USBIP 虚拟控制器设备(VDEV_VHCI)FDO的初始化过程
虚拟ROOT总线FDO创建了虚拟USB控制器PDO之后,系统通过各种IRP_MJ_PNP收集完物理设备的信息之后,开始根据其硬件ID进行设备驱动批配,批配成功后,装载驱动并调用其AddDevice之后,开始FDO的创建过程。通过前面的可知,USBIP实现的根驱动,USB控制器、HUB和设备PDO的S......
USBIP 集线器PDO(VDEV_HPDO)的初始化过程
USB集线器其实也是USB设备的一类,其设备分类分类为0x09。和USBIP虚拟的控制器(VDEV_CPDO)类似,USB控制器创建了其PDO之后,会通过IRP_MN_QUERY_DEVICE_RELATIONS返回USB集线器HUB的PDO设备列表。PNP管理器收到有新的设备之后,会开始收集这个P......
USBIP 虚拟集线器FDO子设备的管理
IRP_MN_QUERY_DEVICE_RELATIONS这得从IRP_MN_QUERY_DEVICE_RELATIONS来谈起,好像有点看的不是很明白。先把上一节的代码复制过来,看一下:static PAGEABLE NTSTATUSget_bus_relations_vhub(pvhub_d......
USBIP 虚拟集线器FDO(VDEV_VHUB )的初始化
AddDevice执行vhci_add_device,返回的设备类型为VDEV_VHUB,集线器HUB的FDO类型。然后初始化HUB的FDO,使用init_dev_vhub(vdev);函数实现static PAGEABLE voidinit_dev_vhub(pvdev_t vdev){ ......
关注公众号
  • HID人机交互
  • Linux&USB
  • UAC音频
  • TYPE-C
  • USB规范
  • USB大容量存储
  • USB百科
  • USB周边
  • UVC摄像头
  • Windows系统USB
  • 音视频博客
  • 取消
    感谢您的支持,我会继续努力的!
    扫码支持
    扫码打赏,你说多少就多少

    打开支付宝扫一扫,即可进行扫码打赏哦

    您的支持,是我们前进的动力!