Linux下PCIe驅動以及DMA機制

2021-08-14 11:56:53 字數 3992 閱讀 3776

1. 

驅動程式作用:

·        

裝置驅動程式向應用程式遮蔽了硬體在實現上的細節,使得應用程式可以像操作普通檔案一樣操作外部裝置。

linux

作業系統抽象了對硬體的處理,可以使用和操作檔案相同的,標準的系統呼叫介面來完成開啟,關閉,讀寫喝

i/o控制操作,而驅動程式主要任務也就是實現這些系統呼叫函式。

·        

每個裝置檔案對應兩個裝置號,其中主裝置號標識裝置種類,也標識了裝置所使用的驅動程式;次裝置號標識使用同一裝置驅動程式的不同硬體裝置。裝置檔案的主裝置號必須與裝置驅動程式在登陸該裝置時申請的主裝置號一致,否則使用者程序無法訪問到裝置驅動程式。

2. 

塊裝置與字元裝置的區別:

·        

二者之間區別僅僅在於核心與驅動程式之間的軟體介面上,塊裝置利用一塊系統記憶體作為緩衝區,當使用者程序對裝置進行讀寫請求時,驅動程式先檢視緩衝區的內容,如果能滿足使用者要求,則返回相應資料,否則呼叫相應請求函式進行實際

i/o操作。

3. dma

迴圈緩衝區的分配與實現:

·        

對於高速資料訊號的採集處理,需要在驅動程式的初始化模組(

probe

)中申請大量的

dma迴圈緩衝區,申請的大小直接關係著能否實時對高速資料處理的成敗。直接記憶體訪問(

dma)是一種硬體機制,允許外圍裝置和主記憶體直接直接傳輸

i/o資料,避免了大量的計算開銷。

4. linux

核心的記憶體分割槽段:

·        

三個區段,可用於

dma的記憶體,常規記憶體以及高階記憶體。

·        

通常的記憶體分配發生在常規記憶體區,但是通過設定記憶體標識也可以請求在其他區段中分配。可用於

dma的記憶體指存在於特別位址範圍內的記憶體,外設可以利用這些記憶體執行

dma訪問,進行資料通訊傳輸。

·        

dma迴圈緩衝區的分配要求:物理連續,

dma可以訪問,足夠大。

5. linux

記憶體分配函式:

·        

linux

系統使用虛擬位址,記憶體分配函式提供的都是虛擬位址,通過

virt_to_bus

轉換才能得到實體地址。

·        

分配核心記憶體空間的函式:

kmalloc

實現小於

128kb

的核心記憶體申請,申請空間物理連續;

__get_free_pages

實現最大

4mb的記憶體申請,以頁為單位,所申請空間物理連續;

vmalloc

分配的虛擬位址空間連續,但在物理上可能不連續。

·        

linux

核心中專門提供了用於

pci裝置申請核心記憶體的函式

pci_alloc_consistent

,支援按位元組長度申請,該函式呼叫

__get_free_pages

,故一次最大為

4mb。

6. dma

資料傳輸的方式:

·        

一種是軟體發起的資料請求(例如通過

read

函式呼叫),另一種是硬體非同步將資料傳給系統。對於資料採集裝置,即便沒有程序去讀取資料,也要不斷寫入,隨時等待程序呼叫,因此驅動程式應該維護乙個環形緩衝區,當

read

呼叫時可以隨時返回給使用者空間需要的資料。

7. pcie

中向cpu

發起中斷請求的方式:

·        

訊息訊號中斷(

msi),

intx

中斷。

·        

在msi

中斷方式下,裝置通過向

os預先分配的主存空間寫入特定資料的方式請求

cpu的中斷服務,為

pcie

系統首選的中斷訊號機制,對於

pcie

到pci/pci-x

的橋接裝置和不能使用

msi機制的傳統端點裝置,採用

intx

虛擬中斷機制。

·        

pcie

裝置註冊中斷時使用共享中斷方式,

linux

系統通過

request_irq

實現中斷處理程式的註冊,呼叫位置在裝置第一次開啟,硬體產生中斷之前;同樣,

free_irq

時機在最後一次關閉裝置,硬體不用中斷處理器之後。

·        

中斷處理函式的功能是將有關中斷接收的資訊反饋給裝置,並對資料進行相應讀寫。中斷訊號到來,系統呼叫相應的中斷處理函式,函式判斷中斷號是否匹配,若是,則清除中斷暫存器相應的位,即在驅動程式發起新的

dma之前裝置不會產生其他中斷,然後進行相應處理。

8. 

資料讀寫和

ioctl

控制:

·        

資料讀寫:應用程序不需要資料時,驅動程式動態維護

dma環形緩衝區,當應用程序請求資料,驅動程式通過

linux

核心提供

copy_from_user()/copy_to_user()

實現核心態和使用者態之間的資料拷貝。

·        

硬體控制:使用者空間經常回去請求裝置鎖門,報告錯誤資訊,設定暫存器等,這些操作都通過

ioctl

支援,可以對

pcie

卡給定的暫存器空間進行配置。

9. 

中斷處理程式的註冊:

·        

中斷號在

bios

初始化階段分配並寫入裝置配置空間,然後

linux

在建立pci_dev

時從配置空間中讀出該中斷號並寫入

pci_dev

的irq

成員中,所以註冊中斷程式時直接從

pci_dev

中讀取就行。

·        

當裝置發生中斷,

8259a

將中斷號發給

cpu,

cpu根據中斷號找到中斷處理程式,執行。

10. dma

資料傳輸機制的產生:

·        

傳統經典過程:資料到達網絡卡

-> 

網絡卡產生乙個中斷給核心

-> 

核心使用

i/o 

指令,從網絡卡

i/o區域中去讀取資料。這種方式,當大流量資料到來時,網絡卡會產生大量中斷,核心在中斷上下文中,會浪費大量資源處理中斷本身。

·        

改進:napi

,即輪詢,即核心遮蔽中斷,隔一定時間去問網絡卡,是否有資料。則在資料量小的情況下,這種方式會浪費大量資源。

·        

另乙個問題,

cpu到網絡卡的

i/o區域,包括

i/o暫存器和

i/o記憶體中讀取,再放到系統物理記憶體,都占用大量

cpu資源,做改進,即有了

dma,讓網絡卡直接從主記憶體之間讀寫自己的

i/o資料。

·        

首先,核心在主記憶體中為收發資料建立乙個環形的緩衝佇列(

dma環形緩衝區),核心將這個緩衝區通過

dma對映,將這個佇列交給網絡卡;網絡卡收到資料,直接放進環形緩衝區,即直接放到主記憶體,然後向系統產生中斷;

·        

核心收到中斷,取消

dma對映,可以直接從主記憶體中讀取資料。

linux下pcie裝置驅動

pcie裝置驅動與platform裝置驅動的對比學習 1 驅動模組結構 1 pcie裝置註冊 module pci driver x driver 展開之後對應於 module init x driver pci register drive x driver module exit x drive...

Linux平台PCIe驅動編寫

以前文章分析了pcie整個系統知識,包括如何掃瞄pcie樹,這篇文章講解一下當拿到乙個pcie裝置時如何編寫驅動程式。編寫驅動程式在應用程式中編寫,同樣可以在核心層編寫驅動。從應用層編寫驅動主要是使用pcilib庫和 dev mem介面,下面開始分析 根據pcie裝置的廠家id和裝置id初始化裝置,...

linux裝置驅動之PCIE驅動開發

pcie pci express 是intel提出的新一代的匯流排介面,目前普及的pcie 3.0的傳輸速率為8gt s,下一代pcie 4.0將翻番為16gt s,因為傳輸速率快廣泛應用於資料中心 雲計算 人工智慧 機器學習 視覺計算 顯示卡 儲存和網路等領域。pcie插槽是可以向下相容的,比如p...