USB设备通过网络共享

 

参考教程及其它

WSL2连接USB设备 | 旧版本源码usbip的移植 | Arch Wiki

1
2
3
4
5
6
7
8
9
10
# 注意:使用 usbipd bind 共享USB设备前,USB设备不能处于使用或占用状态,否则 usbip attach 时会报如下错误
usbip: error: Attach Request for 6-1 failed - Device busy (exported)

# 在WSL2中 官方内核 ≥ 5.15 才支持 USBIP 功能,以前的内核版本只能自行编译才能支持USBIP功能

# 解决关于 usbipd 默认监听所有网卡且不能使用身份验证来连接设备的问题
服务端监听 127.0.0.1 3240 (3240是默认端口)
客户端SSH转发服务端 127.0.0.1 3240 到 客户端: 127.0.0.1 3240
然后把客服务端IP替换为 127.0.0.1

内核启用USBIP功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 服务端是插入USB设备的一端,需要的模块是usbip-core.ko和usbip-host.ko
# 客户端是获取USB设备的一端,需要的模块是usbip-core.ko和vhci-hcd.ko
> Device Drivers -> USB support -> <*> USB/IP support
> Device Drivers -> USB support -> USB/IP support -> <*> VHCI hcd
> Device Drivers -> USB support -> USB/IP support -> <*> Host driver
> Device Drivers -> USB support -> USB/IP support -> <*> VUDC driver
> Device Drivers -> USB support -> [*] Debug messages for USB/IP

# 对应的内核配置内容如下:
CONFIG_USBIP_CORE=m
CONFIG_USBIP_VHCI_HCD=m
CONFIG_USBIP_VHCI_HC_PORTS=8
CONFIG_USBIP_VHCI_NR_HCS=1
CONFIG_USBIP_HOST=m
CONFIG_USBIP_VUDC=m
CONFIG_USBIP_DEBUG=y

静态编译USBIP软件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 在Linux 3.16.85之前 linux-source-3.16.85/drivers/staging/usbip/userspace	下有usbip的源码
# 在Linux 3.16.85之后 linux-source-***/tools/usb/usbip/ 下有usbip的源码

# 这里使用Alpine系统来编译,先安装编译所需的工具及库
apk add build-base autoconf automake libtool eudev-dev linux-headers

# 下载解压源码
wget https://www.kernel.org/pub/linux/kernel/v6.x/linux-6.12.17.tar.gz
tar -xzvf linux-6.12.17.tar.gz
cp -r linux-6.12.17/tools/usb/usbip/ ~ && cd ~/usbip

# 去除报错及生成 configure 脚本
sed -i 's,-Wall -Werror -Wextra,,' configure.ac
./autogen.sh

# 开启静态和开启动态必须同时设置为静开动关才能静态编译
./configure --prefix=$HOME/usbip_build \
--enable-static=yes --enable-shared=no --with-usbids-dir="." \
CFLAGS="-static -no-pie" LDFLAGS="-L/usr/lib" LIBS="-l:libudev.a -l:libc.a"

# 详细显示编译信息及安装到指定位置
make V=s && make install

# 使用strip给两个程序减肥
strip src/usbip src/usbipd

# 将生成的程序拷贝到指定位置后,获取 usb.ids 到 usbip 程序所在目录(上面with-usbids-dir中指定)
wget https://github.com/vcrhonek/hwdata/raw/refs/heads/master/usb.ids

# 如果生成的程序虽然不依赖动态库,但它指定了动态链接器(例如:/lib/ld-musl-x86_64.so.1)
# 如果仅 CFLAGS="-static" 无效,可再添加参数 CFLAGS="-no-pie" 使其不依赖依赖动态链接器
/root/usbip # ldd src/usbipd
/lib/ld-musl-x86_64.so.1 (0x7fb5ea957000)
/root/usbip # file src/usbipd
/mnt/d/usbipd: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, stripped

# PIE依赖动态链接器(如ld-*.so)完成运行时重定位,与传统可执行文件的区别:PIE需通过动态链接器加载,而传统文件可能直接使用固定地址‌
/root/usbip # ldd src/usbipd
/lib/ld-musl-x86_64.so.1: src/usbipd: Not a valid dynamic program
/root/usbip # file src/usbipd
src/usbipd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped

以Linux为服务端来共享USB设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 在Debian 12上安装相关程序
sudo apt install usbip hwdata

# 在Ubunt 22.04上安装(需要与官方内核版本对应)
sudo apt install linux-tools-common

# 服务端是插入Usb设备的一端,需要载入的模块是usbip-core.ko和usbip-host.ko,最后执行 usbipd
leux@h88k:~$ sudo modprobe -a usbip-core usbip-host

# 首先列出所有本地的USB设备
leux@h88k:~$ usbip list -l
- busid 2-1.1 (2c7c:0800)
Quectel Wireless Solutions Co., Ltd. : unknown product (2c7c:0800)

- busid 2-1.3 (0951:1666)
Kingston Technology : DataTraveler 100 G3/G4/SE9 G2/50 Kyson (0951:1666)

# 以root权限来共享USB设备,以 2-1.3 金士顿U盘为例
leux@h88k:~$ sudo usbip bind --busid=2-1.3
usbip: info: bind device on busid 2-1.3: complete

# 后台运行守护进程,USB/IP默认的端口号为3240,也可手动指定端口:sudo usbipd -D [--tcp-port PORT]
leux@h88k:~$ sudo usbipd -D

# 如果不想分享该USB设备了,可解绑共享的USB设备
leux@h88k:~$ sudo usbip unbind --busid=2-1.3
usbip: info: unbind device on busid 2-1.3: complete

以Win32为服务端来共享USB设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
https://github.com/dorssel/usbipd-win/releases/latest
winget install usbipd
winget uninstall usbipd

# 首先列出所有连接到Windows的USB设备
PS C:\Users\leux> usbipd list
Connected:
BUSID VID:PID DEVICE STATE
1-11 0e8d:0616 RZ616 Bluetooth(R) Adapter Not shared
1-12 048d:5702 USB 输入设备 Not shared
2-2 0414:a014 Realtek USB2.0 Audio, USB 输入设备 Not shared
9-1 046d:0acb G435 Wireless Gaming Headset, USB 输入设备 Not shared
9-2 046d:c539 PRO WIRELESS, USB 输入设备, LIGHTSPEED Receiver, 虚拟 HID... Not shared
9-4 046d:c545 G913 TKL, USB 输入设备, LIGHTSPEED Receiver, 虚拟 HID 框 ... Not shared

Persisted:
GUID DEVICE

# Win下以管理员身份来共享USB设备,以共享 1-11 的 RZ616 Bluetooth(R) Adapter 蓝牙为例
PS C:\Users\leux> usbipd bind --busid 1-11


# 如果不想分享该USB设备了,可执行如下取消共享USB设备
PS C:\Users\leux> usbipd unbind --busid=1-11

# 共享完成后,既可物理断开USB设备,或者运行此命令分离
PS C:\Users\leux> usbipd detach --busid 1-11

以Linux为客户端来获取USB设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 而客户端是获取usb设备信息的一端,需要载入的模块是usbip-core.ko和vhci-hcd.ko,执行 usbip
# /lib/modules/6.1.84-xxx/kernel/drivers/usb/usbip/usbip-core.ko vhci-hcd.ko
leux@h88k:~$ sudo modprobe -a usbip-core vhci-hcd

# 查看指定IP主机共享的USB设备
leux@h88k:~$ usbip list -r 192.168.1.214
Exportable USB devices
======================
- 192.168.1.214
1-11: MediaTek Inc. : unknown product (0e8d:0616)
: USB\VID_0E8D&PID_0616\000000000
: Miscellaneous Device / ? / Interface Association (ef/02/01)
: 0 - Wireless / Radio Frequency / Bluetooth (e0/01/01)
: 1 - Wireless / Radio Frequency / Bluetooth (e0/01/01)
: 2 - Wireless / Radio Frequency / Bluetooth (e0/01/01)

# 将指定IP主机共享的USB设备【插入】到本地主机上就可以使用了
leux@h88k:~$ sudo usbip attach -r 192.168.1.214 -b 1-11
leux@h88k:~$ lsusb
Bus 007 Device 006: ID 0e8d:0616 MediaTek Inc. Wireless_Device


# 要【拔出已插入的】USB设备,可先查看所有已【插入】的设备
leux@h88k:~$ sudo usbip port
Imported USB devices
====================
Port 00: <Port in Use> at High Speed(480Mbps)
MediaTek Inc. : unknown product (0e8d:0616)
7-1 -> usbip://192.168.1.214:3240/1-11
-> remote bus/dev 001/011

# 然后指定想要【拔出】的USB设备的端口
leux@h88k:~$ sudo usbip detach -p 00
usbip: info: Port 0 is now detached!

以Win32为客户端来获取USB设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 安装时切记要安装【USBIP-WIN2 通用串行总线控制器】驱动,否则后面附加时会【error: VHCI device not found, driver not loaded?】
https://github.com/vadimgrn/usbip-win2/releases

# 安装使用该软件需要在Windows测试模式下,正常模式安装后将无法使用任何USB设备:https://github.com/vadimgrn/usbip-win2/issues/86
bcdedit.exe /set testsigning on

# 默认安装后程序所在的位置:C:\Program Files\USBip\usbip.exe
PS C:\Users\leux> cd "C:\Program Files\USBip\"

# 查看指定IP主机共享的USB设备
PS C:\Program Files\USBip> .\usbip.exe list -r 192.168.1.1
Exportable USB devices
======================
2-1.3 : Kingston Technology : DataTraveler 100 G3/G4/SE9 G2/50 Kyson (0951:1666)
: /sys/devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.11.auto/usb2/2-1/2-1.3
: (Defined at Interface level) (00/00/00)

# 将指定IP主机共享的USB设备附加到本地主机上
PS C:\Program Files\USBip> .\usbip.exe attach -r 192.168.1.1 -b 2-1.3
succesfully attached to port 31

# 查看所有已【插入】的设备
PS C:\Program Files\USBip> .\usbip.exe port

# 然后指定想要【拔出】的USB设备的端口
PS C:\Program Files\USBip> .\usbip.exe detach -p 31
port 31 is successfully detached