回覆列表
  • 1 # 程式設計頌

    在《深入理解Linux核心》中的第545頁介紹了DMA的相關操作。說道DMA,那就不得不提到Cache(快取記憶體)的問題。書中引用瞭如下一段例子來描述了Cache一致性問題:

    逗假設裝置驅動程式把一些資料填充到記憶體緩衝區中,然後立刻命令硬體裝置利用DMA傳送方式讀取該資料。如果DMA訪問這些物理RAM記憶體單元,而相應的硬體快取記憶體行的內容還沒有寫入RAM中,那麼硬體裝置所讀取的至就是記憶體緩衝區中的舊值。地

    現在有兩種方法來處理DMA緩衝區:

    一致性DMA對映:

    書上講的比較抽象,通俗地所就是任何對DMA緩衝區的改寫都會直接更新到記憶體中,也稱之為逗同步的地或者逗一致的地。

    流式DMA對映:

    根據個人的理解,這裡的流即輸入輸出流,我們需要事先指定DMA緩衝區的方向,比如是地讀緩衝區地還是逗寫緩衝區地。也稱之為逗非同步的地或逗非一致性的地,詳細的內容請看下文。

    由於x86體系結構中,硬體裝置驅動程式本身會逗窺探地所訪問的硬體告訴快取,因此x86體系結構中不存在DMA一致性問題。而對於其他一些架構如MIPS,SPARC以及POWERPC(包括ARM在內)需要在軟體上保證其DMA一致性。

    對於以上兩者如何選擇,書中有一個合適的建議,如果CPU和DMA處理器以不可預知的方式去訪問一個緩衝區,那麼必須強制使用一致性DMA對映方式(這裡我對不可預知的理解是,不能確定在何時它們訪問緩衝區),其他情形下,流式DMA對映方式更可取,因為在一些體系結構中處理一致性DMA對映是很麻煩的,並且可能導致更低的系統性能。

    這裡詳細介紹流式DMA:

    需要訪問的緩衝區需要在資料傳送之前被對映(這裡的對映也就是需要呼叫一些函式告知核心,該緩衝區進行流式對映),在傳送之後被取消對映。

    啟動一次流式DMA資料傳輸分為如下步驟:

    1. 分配DMA緩衝區。

    在DMA裝置不採用S/G(分散/聚集)模式的情況下,必須保證緩衝區是物理上連續的,linux核心有兩個函式用來分配連續的記憶體:kmalloc()和__get_free_pages()。這兩個函式都有分配連續記憶體的最大值,kmalloc以分配位元組為單位,最大約為64KB,__get_free_pages()以分配頁為單位,最大能分配2^order數目的頁,order引數的最大值由include/linux/Mmzone.h檔案中的MAX_ORDER宏決定(在預設的2.6.18核心版本中,該宏定義為10。也就是說在理論上__get_free_pages函式一次最多能申請1

    2. 建立流式對映。

    在對DMA衝區進行讀寫訪問之後,且在啟動DMA裝置傳輸之前,啟用dma_map_single()函式建立流式DMA對映,這兩個函式接受緩衝區的線性地址作為其引數並返回相應的匯流排地址。

    3. 釋放流式對映。

    當DMA傳輸結束之後我們需要釋放該對映,這時呼叫dma_unmap_single()函式。

    注意:

    (1). 為了避免快取記憶體一致性問題,驅動程式在開始從RAM到裝置的DMA資料傳輸之前,如果有必要,應該呼叫dma_sync_single_for_device()函式重新整理與DMA緩衝區對應的快取記憶體行。

    (2). 從裝置到RAM的一次DMA資料傳送完成之前裝置驅動程式是不可以訪問記憶體緩衝區的,但如果有必要的話,驅動程式在讀緩衝區之前,應該呼叫dma_sync_single_for_cpu()函式使相應的硬體快取記憶體行無效。

    (3). 雖然kmalloc底層也是用__get_free_pages實現的,不過kmalloc對應的釋放緩衝區函式為kfree,而__get_free_pages對應的釋放緩衝區函式為free_pages。具體與__get_free_pages有關係的幾個申請與釋放函式如下:

    申請函式:

    alloc_pages(gfp_mask,order)返回第一個所分配頁框描述符的地址,或者如果分配失敗則返回NULL。__get_free_pages(gfp_mask,order)類似於alloc_pages(),但它返回第一個所分配頁的線性地址。如果需要獲得線性地址對應的頁框號,那麼需要呼叫virt_to_page(addr)宏產生線性地址。釋放函式:__free_pages(page,order)這裡主要強調page是要釋放緩衝區的線性首地址所在的頁框號free_pages(page,order)這個函式類似於__free_pages(page,order),但是它接收的引數為要釋放的第一個頁框的線性地址addr

  • 中秋節和大豐收的關聯?
  • 葡萄秧發芽後不愛長怎麼回事?