如何將 USB 驅動程序分配給設備
這個問題有兩個方面:
首先,您如何手動從 USB 設備中分離驅動程序並連接另一個驅動程序?例如,我有一個設備在連接時會自動使用 usb-storage 驅動程序。
usbview 輸出
Vendor Id: xxxx Product Id: xxxx ... Number of Interfaces: 2 Interface Number: 0 Name: usb-storage Number of Endpoints: 2 ... Interface Number: 1 Name: (none) Number of Endpoints: 2 ...
我不想使用 usb-storage 驅動程序,因此在我的應用程序中,我使用
libusb
庫來分離 usb-storage 驅動程序,然後聲明介面。然後,我可以在我的 USB 設備和我的主機 Linux 系統上執行的應用程序之間發送數據。如何在應用程序之外手動分離驅動程序?
其次,如何自動分配驅動程序以附加到設備外掛上?我目前有一個 udev 規則設置來自動設置設備權限:
SUBSYSTEM=="usb", ATTR{idVendor}=="xxxx", MODE="0666"
我可以使用 udev 規則將驅動程序分配給 USB 設備上的特定介面嗎?例如,如果我希望在介面 0 上自動使用 usbnet 模組而不是 usb-storage,這在 udev 中是否可行?
對於問題的第一部分,我已經看過並且找不到比您已經使用 libusb 做的更好的方法來分離 USB 驅動程序。
至於問題的第二部分,udev 可以對驅動程序載入做出反應,但不能強制將特定驅動程序分配給設備。
Linux 核心中的每個驅動程序都負責一個或多個設備。驅動程序本身選擇它支持的設備。它以程式方式執行此操作,即通過檢查設備的供應商和產品 ID,或者,如果這些不可用(例如舊設備),則執行一些自動檢測啟發式和健全性檢查。一旦驅動程序確信它找到了它支持的設備,它就會將自己連接到它。簡而言之,您通常不能強制特定驅動程序使用特定設備。然而,有時,設備驅動程序對它所接受的東西是慷慨的,並且設備可以在它不知道的情況下工作。您的里程會有所不同!過去,我不得不手動將奇怪的 PCI 設備/供應商 ID 添加到應該支持它們的驅動程序中,結果喜憂參半,還發生了一些有趣的核心崩潰。
現在,在模組的情況下,有一個額外的步驟。當檢測到新設備時,核心會喚醒*模組載入器。*它傳遞了一個 ‘modalias’ 字元串,它標識設備,對於 USB 設備看起來像這樣:
usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00
此字元串包含設備類 (
usb
) 和特定於類的資訊(供應商/設備/序列號、設備類等)。每個核心驅動程序都包含一行,例如:MODULE_ALIAS("usb:...")
其中必須匹配 usbalias(萬用字元用於匹配多個設備)。如果
modalias
與驅動程序支持的匹配,則載入此驅動程序(或通知新設備,如果它已經存在)。您可以通過以下方式查看支持的設備(按模式別名)及其相關模組
less /lib/modules/`uname -r`/modules.alias
如果您使用 grep 獲取 usb-storage 設備驅動程序,您會看到它具有一些由供應商和設備 ID 支持的特定設備,並且還將嘗試支持任何具有正確(儲存)類的設備,無論供應商/設備如何.
您可以使用作業系統上的使用者空間機制來影響這一點(
/etc/modprobe.d/
在 Debian 和朋友上)。您可以將模組列入黑名單,也可以指定要由 modalias 載入的模組,就像modules.alias
文件一樣(並使用相同的語法)。depmod -a
然後將重新生成模組載入器的模式。然而,即使你可以把這匹特殊的馬帶到水邊,但你不能讓他喝水。如果驅動程序不支持您的設備,它應該忽略它。
這是一般情況下的理論。
實際上,在 USB 的情況下,我看到您的設備似乎有兩個介面,其中一個是儲存介面。核心將附加到整個設備的儲存介面。如果另一個介面具有正確的類,
usbnet
驅動程序可以附加到它。是的,您可以將多個驅動程序連接到同一個物理設備,因為 USB 設備導出多個介面(例如,我的 Logitech G15 鍵盤導出兩個,因為它有一個鍵盤設備和一個 LCD 螢幕,每個都由單獨的驅動程序處理) .未檢測到 USB 設備的第二個介面這一事實表明核心缺乏支持。無論如何,您都可以使用 列出設備介面/端點的詳細資訊
lsusb -v | less
,然後向下滾動到您的特定設備(如果您願意,可以通過設備:供應商 ID 或 USB 路徑限制輸出)。請注意:關於 USB 設備的邏輯結構,我在這裡稍微簡化了一點。責怪USB聯盟。:)