Java NIO-09-零拷貝之 DMA


DMA 的好處

在介紹DMA之前我想問大家:我們為什么要引入DMA,DMA對我們有什么好處那?

計算機系統中各種常用的數據輸入/輸出方法有查詢方式(包括無條件及條件傳送方式)和中斷方式,這些方式適用於CPU與慢速及中速外設之間的數據交換。

但當高速外設要與系統內存或者要在系統內存的不同區域之間進行大量數據的快速傳送時,就在一定程度上限制了數據傳送的速率。

直接存儲器存取(DMA)就是為解決這個問題提出的,采用DMA方式,在一定時間段內,由DMA控制器取代CPU,獲得總線控制權,來實現內存與外設或者內存的不同區域之間大量數據的快速傳送。

同時很重要的一點是當DMA傳輸數據時,並不占用CPU資源,在這個時候CPU可以空出手來做其他的事情。

這樣我們既可以做大量數據的高速傳輸又可以讓CPU有時間和資源去做其他的事情。

DMA 芯片的實現

上面介紹了什么是DMA,也介紹了DMA的重要性。那么我們就要看看我們芯片中的DMA了。

在S3C2440A中,我們集成了DMA模塊,可以用來傳遞高速傳輸數據。既然是數據傳輸那么我又要問了,我們知道數據傳輸三要素:源,目的,長度。這是我們數據傳輸時要知道的。那么在S3C2440A中,源,目的,長度是怎么表示的那?

ps: 硬件知識,暫時不做研究。

DMA映射

基本原理

DMA映射主要為在設備與主存之間建立DMA數據傳輸通道時,在主存中為該DMA通道分配內存空間的行為,該內存空間也稱為DMA緩沖區。

這個任務原本可以很簡單,但是由於現代處理器cache的存在,使得事情變得復雜。

RAM與cache內容的一致性問題

出現問題原因

現代處理器為了提升系統性能,在CPU與RAM之間加入了高速緩存cache,所以當在RAM中為一個DMA通道建立一段緩沖區時,必須仔細考慮RAM與cache內容的一致性問題。

具體分析

如果RAM與Device之間的一次數據交換改變了RAM中DMA緩沖區的內容,而cache中緩存了DMA緩沖區對應的RAM中一段內存塊。

如果沒有機制保護cache中的內容被新的DMA緩沖區數據更新(或者無效),那么cache和他對應的RAM中的一段內存塊在內容上出現了不一致,此時如果CPU去讀取device傳到RAM的DMA緩沖區中的數據,它將直接從cache獲得數據,這些數據顯然不是它所期望的,因為cache對應的RAM中的數據已經更新了。

解決問題

就cache一致性問題,不同的體系架構有不同的策略,有些是在硬件層面予以保證(x86平台)有些沒有硬件支持而需要軟件的參與(ARM品台)。

Linux內核中的通用DMA盡力為設備驅動程序提供統一的接口來處理cache緩存一致性的問題,

而將大量品台相關的代碼對設備驅動程序隱藏起來。

DMA 的映射方式

1. 一致性DMA映射

linux內核DMA層為一致性DMA映射提供的接口函數為dma_alloc_coherent()

一致性所獲得的DMA緩沖區的大小都是頁面的整數倍,如果驅動程序需要更小的DMA一致性的DMA緩沖區,則應該使用內核提供的DMA池(pool)機制

對於一致性DMA映射,在分配DMA緩沖區時各平台相關代碼已經從根本上解決了cache一致性問題.

但是,一致性映射也會遇到無法克服的困難,主要是指驅動程序中使用的DMA緩沖區並非由驅動程序分配,

大專欄  Java NIO-09-零拷貝之 DMA是來自其他模塊(如網絡設備驅動程序中用於數據包傳輸的skb->data所指向的緩沖區),此時需要流式DMA映射。

2. 流式DMA映射

流式DMA映射的特點是DMA傳輸通道使用的緩沖區不是由當前驅動程序自身分配的,而且往往對每次DMA傳輸都會重新建立一個流式映射的緩沖區,所以使用流式DMA映射時, 設備驅動程序必須小心負責處理可能出現的cache一致性。

linux內核DMA層為設備驅動提供的建立流式DMA映射的函數—dma_map_single

3. 分散/聚集DMA映射

分散/聚集DMA映射通過將虛擬地址上分散的DMA緩沖區通過一個struct scatterlist的數組或鏈表組織起來,然后通過一次的DMA傳輸操作在主存RAM與設備之間傳輸數據。

分散/聚集DMA映射本質上是通過一次DMA操作把內存中分散的數據塊在主存與設備之間進行傳輸,對於其中的每個數據塊內核都會建立對應的一個流式DMA映射。

需要設備的支持。

回彈緩沖區

如果CPU側虛擬地址對應的物理地址不適合設備的DMA操作,那么需要建立回彈緩沖區,相當於一個 中轉站,把數據往設備傳輸時,驅動程序需要把CPU給的數據拷貝到回彈緩沖區,然后再啟動DMA操作。

DMA池

由於DMA映射所建立的緩沖區是單個頁面的整數倍,如果驅動程序需要更小的一致性映射的DMA緩沖區,可以使用內核提供的DMA池機制(非常類似於Linux內存管理中的slab機制).

個人收獲

參考資料

嵌入式Linux——DMA:在內核中簡單使用DMA實現內存中數據傳遞

Linux內核中DMA分析

Linux DMA驅動構架分析

https://www.xuebuyuan.com/3235513.html

https://www.cnblogs.com/lihuidashen/p/4470678.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM