思虑良久(约一年),终于下定决心买下了一款 USB 转 RJ45 接口的 USB 网卡,我所购买的是裕合联的 USB3.0 有线网卡千兆铝合金,型号 YHL-U5503BK。
把网线、网卡、树莓派、台式电脑都接上,🤔,基本上是工作的……具体情况大概是:
- 在树莓派开机时,把 USB 网卡插上,能正确识别到新的网卡,也可以进行 IP 等的配置。
- 在树莓派关机时,把 USB 网卡插上,再开机,网卡被识别为一个大容量存储设备,网络配置自然也不能进行。
在一系列的尝试过后,发现在网卡被识别为大容量存储设备时,使用 `usbreset 0bda:8151`,可以使其重新被识别为网卡,此时在 journalctl 的系统日志中也可以发现 USB 设备断开连接并且同一个接口中又新添加了一个设备,同时要注意到 Vendor ID 和 Product ID 也发生了改变。
```
$ lsusb -tv
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
ID 1d6b:0003 Linux Foundation 3.0 root hub
|__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
ID 152d:1561 JMicron Technology Corp. / JMicron USA Technology Corp. JMS561U two ports SATA 6Gb/s bridge
|__ Port 2: Dev 3, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
ID 0bda:8151 Realtek Semiconductor Corp. RTL8151 Adapteon Business Mobile Networks BV
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
ID 1d6b:0002 Linux Foundation 2.0 root hub
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
ID 2109:3431 VIA Labs, Inc. Hub
$ sudo usbreset 0bda:8151
Resetting USB 10/100/1000 LAN ... failed [No such device]
$ lsusb -tv
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
ID 1d6b:0003 Linux Foundation 3.0 root hub
|__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
ID 152d:1561 JMicron Technology Corp. / JMicron USA Technology Corp. JMS561U two ports SATA 6Gb/s bridge
|__ Port 2: Dev 4, If 0, Class=Vendor Specific Class, Driver=r8152, 5000M
ID 0bda:8153 Realtek Semiconductor Corp. RTL8153 Gigabit Ethernet Adapter
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
ID 1d6b:0002 Linux Foundation 2.0 root hub
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
不过虽然解决了,依然感觉不是很优雅,询问群友得知,在连接时先被识别为大容量存储设备、然后可以切换为其他工作模式而被识别为另一种设备的行为,是所谓的免驱硬件常见的工作方式,一般在 Windows 下,设备被识别为大容量存储设备后,系统可以从此设备中拿到驱动安装文件,安装以后再切换到实际工作的模式。在 Linux 下 usb_modeswitch 可以触发硬件工作模式的切换。
> Several new USB devices have their proprietary Windows drivers onboard, most of them WAN dongles. When plugged in for the first time, they act like a flash storage and start installing the Windows driver from there. If the driver is already installed, it makes the storage device disappear and a new device, mainly composite with modem ports, shows up.
经过这一大圈的调查,了解到 VID (Vendor ID)是 USB 厂商识别码,每个厂商都会有一个 ID,其唯一性由 [USB-IF](https://www.usb.org) 负责,而 PID (Product ID) 就是厂商自己这一款产品的 ID,其唯一性由厂商自己负责。
所以可以认为对于一个 USB 设备,其 VID:PID 的组合是唯一的,于是 Linux 通过既定格式组合这两个属性并追加其他属性,得到一个长长的字符串,随后到 `/lib/modules/$(uname -r)/modules.alias` 中寻找能够匹配这个字符串的模块,匹配的模块会被加载来操控硬件设备。
在 raspbian 中,`/usr/lib/udev/rules.d/40-usb_modeswitch.rules` 中有大量的自动切换工作模式的规则,如果我所使用的 USB 网卡在这里也有写好的规则的话,这篇文章就不会出现了。
## 参考
1. [switch codes for Realtek USB ethernet adapter - USB_ModeSwitch][0]
2. [[SOLVED] [RTL8151] Ethernet not working via multiport adapter - Support / Network - Manjaro Linux Forum][1]
3. [ubuntu - How does Linux know how and what drivers to install in a new installation - Unix & Linux Stack Exchange][2]
4. [usb_modeswitch(1) - Linux man page][3]
5. [networking - How to automate usb_modeswitch? - Ask Ubuntu][4]
6. [udev(7) - Linux manual page][5]
[0]: https://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=2972 "switch codes for Realtek USB ethernet adapter - USB_ModeSwitch"
[1]: https://forum.manjaro.org/t/solved-rtl8151-ethernet-not-working-via-multiport-adapter/41773/9 "[SOLVED] [RTL8151] Ethernet not working via multiport adapter - Support / Network - Manjaro Linux Forum"
[2]: https://unix.stackexchange.com/questions/499716/how-does-linux-know-how-and-what-drivers-to-install-in-a-new-installation/499771#499771 "ubuntu - How does Linux know how and what drivers to install in a new installation - Unix & Linux Stack Exchange"
[3]: https://linux.die.net/man/1/usb_modeswitch "usb_modeswitch(1) - Linux man page"
[4]: https://askubuntu.com/questions/1247572/how-to-automate-usb-modeswitch "networking - How to automate usb_modeswitch? - Ask Ubuntu"
[5]: https://man7.org/linux/man-pages/man7/udev.7.html "udev(7) - Linux manual page"