為什麼 Udev 為單個 USB 設備載入兩個核心模組?
我有一個基於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==
部分不是必需的。
ACTION=="add", DRIVER=="r8152", ATTR{idVendor}=="2357", ATTR{idProduct}=="0601", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}"
該 udev 規則的含義如下:“當一個
idVendor
值為 2357 和idProduct
值為 0601 的設備(並由驅動程序“r8152”管理)添加到系統時,如果它bConfigurationValue
不是環境變數中定義的任何值REALTEK_NIC_MODE
,則將其設置bConfigurationValue
為那個值。”換句話說,這個 udev 規則不是載入 r8152 驅動程序,而是在必要時將設備切換到該驅動程序的正確模式。
添加新設備時,Linux 核心基本上
modprobe
使用設備的硬體 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
:alias usb:v2357p0601d*dc*dsc*dp*ic*isc*ip*in* r8152
然後
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