設備驅動能夠運行在內核態,也能夠運行在用戶態,用戶態驅動的利弊網上有不少的討論,並且有些還上升到政治性上,這裏再也不多作討論。無論用戶態驅動仍是內核態驅動,他們都有各自的缺點。內核態驅動的問題是:系統調用開銷大;學習曲線陡峭;接口穩定性差;調試困難;bug致命;編程語言選擇受限;而用戶態驅動面臨的挑戰是:如何中斷處理;如何DMA;如何管理設備的依賴關係;沒法使用內核服務等。對此,《User-Space Device Drivers in Linux: A First Look》 一文有較詳細描述。linux
多是爲了性能優化,或者爲了故障隔離,或者爲了逃避開源許可證的約束,無論是基於何種目的,linux已有多種用戶態驅動的實現,如UIO,VFIO、USB用戶態驅動等。它們在處理中斷、DMA、設備依賴管理等方面的設計方案和實現細節上各有千秋,這是《User-Space Device Drivers in Linux: A First Look》 沒有提到的,也是本文的重點。git
UIO 框架導出sysfs和/dev/uioX 2套用戶態接口,用戶對設備節點/dev/uioX進行設備控制,mmap()接口用於映射設備寄存器空間,write()接口用於控制中斷關閉/打開,read()接口用於等待一個設備中斷。編程
由於對於設備中斷的應答必須在內核空間進行,因此在內核空間有一小部分代碼用來應答中斷和禁止中斷,其他的工做所有留給用戶空間處理。若是用戶空間要等待一個設備中斷,它只須要簡單的阻塞在對 /dev/uioX的read()操做上。 當設備產生中斷時,read()操做當即返回。UIO 也實現了poll()系統調用,你可使用 select()來等待中斷的發生。select()有一個超時參數能夠用來實現有限時間內等待中斷。安全
UIO的幾個特色:性能優化
總的來講,UIO框架適用於簡單設備的驅動,由於它不支持DMA,不能支持多箇中斷線,缺少邏輯設備抽象能力。數據結構
上文提到,UIO不支持DMA,因此經過DMA傳輸大流量數據的IO設備,如網卡、顯卡等設備,沒法使用UIO框架,VFIO作爲UIO的升級版,主要就是解決了這個問題。經過用戶態配置IOMMU接口,能夠將DMA地址空間映射限制在進程虛擬空間中。這對高性能驅動和虛擬化場景device passthrough尤爲重要。併發
在VFIO框架中,有幾個核心概念或對象:IOMMU、/dev/vfio、container、iommu_group。框架
VFIO的幾個特色:異步
usbfs(USB file system)提供了一些在用戶空間下操做USB設備的函數接口和數據結構, 在開發用戶態驅動時, 能夠直接利用這些函數接口來實現對 USB 設備的控制和數據傳輸。
libusb對usb file system提供的函數接口和數據結構進行了封裝, 能夠有效減小程序中函數和數據結構使用不當形成的錯誤。Libusb 對 USB 設備的訪問提供了兩種機制, 同步訪問和異步訪問。
khubd是內核後臺線程,用來管理監視USB HUB的狀態, 一旦發生熱插拔就會喚醒這個線程, 進而添加或者移除設備,併發送netlink消息傳遞給用戶態空間。編程語言
USB 用戶態驅動框架的幾個特色: