USB Raw Gadget¶
USB Raw Gadget 是一種 gadget 驅動程式,它為使用者空間提供了對 gadget 通訊過程的底層控制。
像任何其他 gadget 驅動程式一樣,Raw Gadget 透過 USB gadget API 實現 USB 裝置。 與大多數 gadget 驅動程式不同,Raw Gadget 本身不實現任何具體的 USB 功能,而是需要使用者空間來實現。
Raw Gadget 目前嚴格來說是一種除錯功能,不應在生產環境中使用。請改用 GadgetFS。
使用 CONFIG_USB_RAW_GADGET 啟用。
與 GadgetFS 的比較¶
Raw Gadget 類似於 GadgetFS,但為使用者空間提供對 USB gadget 層的更直接訪問。 主要區別在於
Raw Gadget 將每個 USB 請求傳遞給使用者空間以獲取響應,而 GadgetFS 根據提供的描述符在內部響應某些 USB 請求。 請注意,UDC 驅動程式可能會自行響應某些請求,而永遠不會將其轉發到 gadget 層。
Raw Gadget 允許提供任意資料作為對 USB 請求的響應,而 GadgetFS 對提供的 USB 描述符執行健全性檢查。 這使得 Raw Gadget 適合透過提供格式錯誤的資料作為對 USB 請求的響應來進行模糊測試。
Raw Gadget 提供了一種選擇要繫結到的 UDC 裝置/驅動程式的方法,而 GadgetFS 目前繫結到第一個可用的 UDC。 這允許將多個 Raw Gadget 例項繫結到不同的 UDC。
Raw Gadget 顯式公開有關端點地址和功能的資訊。 這允許使用者編寫與 UDC 無關的 gadgets。
Raw Gadget 具有基於 ioctl 的介面,而不是基於檔案系統的介面。
使用者空間介面¶
使用者可以透過開啟 /dev/raw-gadget 併發出 ioctl 呼叫來與 Raw Gadget 互動;有關詳細資訊,請參閱 include/uapi/linux/usb/raw_gadget.h 中的註釋。 可以同時使用多個 Raw Gadget 例項(繫結到不同的 UDC)。
Raw Gadget 的典型使用場景
透過開啟
/dev/raw-gadget建立一個 Raw Gadget 例項。透過
USB_RAW_IOCTL_INIT初始化例項。使用
USB_RAW_IOCTL_RUN啟動例項。在一個迴圈中,發出
USB_RAW_IOCTL_EVENT_FETCH以從 Raw Gadget 接收事件,並根據必須實現的 USB gadget 的型別對這些事件做出反應。
請注意,某些 UDC 驅動程式具有分配給端點的固定地址,因此不能在描述符中使用任意端點地址。 儘管如此,Raw Gadget 提供了一種與 UDC 無關的方式來編寫 USB gadget。 一旦透過 USB_RAW_IOCTL_EVENT_FETCH 接收到 USB_RAW_EVENT_CONNECT,就可以使用 USB_RAW_IOCTL_EPS_INFO 來查詢有關 UDC 驅動程式具有的端點的資訊。 基於此,使用者空間必須為 gadget 選擇 UDC 端點,並在端點描述符中相應地分配地址。
Raw Gadget 用法示例和一個測試套件
內部細節¶
每個 Raw Gadget 端點讀/寫 ioctl 都提交一個 USB 請求並等待其完成。 這樣做是有意為之,目的是透過讓單個 syscall 完全處理單個 USB 請求來協助覆蓋引導的模糊測試。 此功能必須保留在實現中。
潛在的未來改進¶
支援
O_NONBLOCKI/O。 這將是另一種操作模式,其中 Raw Gadget 不會等到每個 USB 請求完成。支援 USB 3 功能(在啟用端點時接受 SS 端點配套描述符;允許為批次傳輸提供
stream_id)。支援 ISO 傳輸功能(公開已完成請求的
frame_number)。