linux usb usbip驱动详解(一)

2023-05-16

在分析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(使用前将#替换为@)

linux usb usbip驱动详解(一) 的相关文章

  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • GCC 和 ld 找不到导出的符号...但它们在那里

    我有一个 C 库和一个 C 应用程序 尝试使用从该库导出的函数和类 该库构建良好 应用程序可以编译 但无法链接 我得到的错误遵循以下形式 app source file cpp text 0x2fdb 对 lib namespace Get
  • diff 文件仅比较每行的前 n 个字符

    我有2个文件 我们将它们称为 md5s1 txt 和 md5s2 txt 两者都包含a的输出 find type f print0 xargs 0 md5sum sort gt md5s txt 不同目录下的命令 许多文件被重命名 但内容保
  • 在 Linux 上的 Python 中使用受密码保护的 Excel 工作表

    问题很简单 我每周都会收到一堆受密码保护的 Excel 文件 我必须解析它们并使用 Python 将某些部分写入新文件 我得到了文件的密码 当在 Windows 上完成此操作时 处理起来很简单 我只需导入 win32com 并使用 clie
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 在Linux上编译C# + WPF以便在Windows上运行

    我有一个 C 应用程序 其中某些部分是使用 WPF 编写的 Mono 不支持 可以在 Linux 上编译这个应用程序吗 最终 该应用程序将在 Windows 上运行 但它是更大框架的一部分 并且我们的整个构建过程在 Linux 上运行 因此
  • 在 Mac OS X 上构建 Linux 内核

    我正在做一个修改Linux内核的项目 我有一台桌面 Linux 机器 在上面构建内核没有问题 不过 我要去旅行 我想在途中工作 我只有一台 MacBook 当我尝试构建 Linux 内核时 它抱怨说elf h was not found 我
  • 为什么我收到“无法进行二进制日志记录”的信息。在我的 MySQL 服务器上?

    当我今天启动 MySQL 服务器并尝试使用以下命令进行一些更改时用于 MySQL 的 Toad http www quest com toad for mysql 我收到此消息 MySQL 数据库错误 无法进行二进制日志记录 消息 交易级别
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 创建 jar 文件 - 保留文件权限

    我想知道如何创建一个保留其内容的文件权限的 jar 文件 我将源代码和可执行文件打包在一个 jar 文件中 该文件将在使用前提取 人们应该能够通过运行批处理 shell 脚本文件立即运行示例和演示 然后他们应该能够修改源代码并重新编译所有内
  • 如何使用 bash 锁定文件

    我有一个任务从远程服务器同步目录 rsync av email protected cdn cgi l email protection srv data srv data 为了使其定期运行并避免脚本 reEnter 问题 我使用 rsyn
  • 如何在bash中使用jq从变量中包含的json中提取值

    我正在编写一个 bash 脚本 其中存储了一个 json 值 现在我想使用 Jq 提取该 json 中的值 使用的代码是 json val code lyz1To6ZTWClDHSiaeXyxg redirect to http examp
  • Linux中的CONFIG_OF是什么?

    我看到它在很多地方被广泛使用 但不明白在什么场景下我需要使用它 What is 配置 OF OF 的全名是什么 打开固件 这是很久以前发明的 当时苹果公司正在生产基于 PowerPC CPU 的笔记本电脑 而 Sun Microsystem
  • 如何在 ADB 连接期间禁用电池充电?

    问题描述 每次我在电脑和手机之间连接 USB 线时 电池都会自动充电 我想使用 ADB 协议 但我不想在 ADB 连接期间为电池充电 是否可以关闭此充电功能 当然 我该怎么做呢 环境 Android 操作系统 4 及更高版本的手机 我只需要
  • 我可以从命令行打印 html 文件(带有图像、css)吗?

    我想从脚本中打印带有图像的样式化 html 页面 谁能建议一个开源解决方案 我使用的是 Linux Ubuntu 8 04 但也对其他操作系统的解决方案感兴趣 你可以给html2ps http user it uu se jan html2
  • Linux中的定时器类

    我需要一个计时器来以相对较低的分辨率执行回调 在 Linux 中实现此类 C 计时器类的最佳方法是什么 有我可以使用的库吗 如果您在框架 Glib Qt Wx 内编写 那么您已经拥有一个具有定时回调功能的事件循环 我认为情况并非如此 如果您
  • fopen 不返回

    我在 C 程序中使用 fopen 以只读模式 r 打开文件 但就我而言 我观察到 fopen 调用没有返回 它不返回 NULL 或有效指针 执行在 fopen 调用时被阻止 文件补丁绝对正确 我已经验证过 并且不存在与权限相关的问题 任何人
  • Android 时钟滴答数 [赫兹]

    关于 proc pid stat 中应用程序的总 CPU 使用率 https stackoverflow com questions 16726779 total cpu usage of an application from proc
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include

随机推荐