我有一个基于RTL8153的 USB 以太网适配器,它cdc_ether
默认使用驱动程序。
我想使用r8152
驱动程序,它可以通过创建自定义 udev 规则来加载,如 Realtek 的 linux 驱动程序源中所示。
但这是令人困惑的部分,当我插入适配器时,cdc_ether
和r8152
模块都被加载了。我的问题是,
- 为什么?
- 如何找到负责加载的 udev 规则
cdc_ether
? - 如何停止加载该模块?因为在这种情况下不需要加载两个模块。
Udev规则的一行
ACTION=="add", DRIVER=="r8152", ATTR{idVendor}=="2357", ATTR{idProduct}=="0601", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}"
该DRIVER==
部分不是必需的。
该 udev 规则的含义如下:“当一个
idVendor
值为 2357 和idProduct
值为 0601 的设备(并由驱动程序“r8152”管理)添加到系统时,如果它bConfigurationValue
不是环境变量中定义的任何值REALTEK_NIC_MODE
,则将其设置bConfigurationValue
为那个值。”换句话说,这个 udev 规则不是加载 r8152 驱动程序,而是在必要时将设备切换到该驱动程序的正确模式。
添加新设备时,Linux 内核基本上
modprobe
使用设备的硬件 ID(和其他一些东西)运行,该设备的硬件 ID 编码在它请求的模块的“名称”中。然后将此“名称”与modprobe
作为模块别名嵌入到每个模块中的通配符字符串进行比较。该depmod
命令收集这些别名并将它们存储起来/lib/modules/<kernel version>/modules.alias[.bin]
以便快速搜索。modinfo
您可以使用该命令查看嵌入到内核模块中的别名字符串。对于您的 USB 以太网适配器,“名称”类似于
usb:v2357p0601d...
. 不幸的是,该cdc_ether
模块有一个通配符别名也可以匹配它。中定义的任何别名
/etc/modprobe.d
都将优先于嵌入到模块本身中的别名。因此,您可能会指定一个与您的以太网适配器匹配的别名,并导致r8152
模块被加载。尝试将其添加为
/etc/modprobe.d/usbnic.conf
:然后
depmod -a
以root身份运行,拔下USB以太网适配器,卸载r8152
和cdc_ether
模块,重新插入以太网适配器,看看会发生什么。如果只加载 r8152 模块,很好。如果
cdc_ether
仍然加载,则别名可能需要更具体(即其中的一个或多个星号需要替换为实际值,无论它们可能是),以便该别名是最具体的,因此“最佳”匹配。更新:这里是模块别名格式的描述:http: //people.skolelinux.org/pere/blog/Modalias_strings___a_practical_way_to_map__stuff__to_hardware.html
最近的内核中有一个解决这个问题的补丁:https ://lkml.org/lkml/2017/9/25/711