簡體   English   中英

像往常一樣將物理內存映射到用戶空間,結構頁支持映射

[英]Map physical memory to userspace as normal, struct page backed mapping

我有一個自定義設備驅動程序,它實現了一個mmap操作,將共享RAM緩沖區(在操作系統之外)映射到用戶空間。 通過傳遞mem=32M作為OS的引導參數來保留緩沖區,剩下的512MB可用作緩沖區。 我想從映射內存執行零復制操作,如果vm_flags包含VM_PFNMAPVM_IO ,則無法執行此操作。

我的驅動程序當前通過調用vm_iomap_memory(vma, start, size)執行映射, vm_iomap_memory(vma, start, size)又調用io_remap_pfn_rangeremap_pfn_range ,后者使用VM_PFNMAPVM_IO設置來設置VM_IO 這適用於將內存映射到用戶空間,但由於設置了VM_PFNMAP標記或缺少結構頁,因此零拷貝套接字操作在get_user_pages失敗。 remap_pfn_range的注釋顯示這是預期的行為,因為remap_pfn_range映射的內存不應被視為“正常”。 但是,對於我的情況,它只是一塊保留的RAM,所以我不明白為什么它不應該被視為正常。 我已設置緩存失效/刷新以手動管理內存。

我已嘗試在映射期間和之后VM_IO設置vm_area_struct上的VM_PFNMAPVM_IO標志,但get_user_pages仍然失敗。 我也查看了dma庫,但看起來它們依賴於在幕后調用remap_pfn_range

我的問題是如何將物理內存映射為普通的非pfn結構頁面支持的用戶空間地址? 還是有其他方式我應該看看它? 謝謝!

我已經找到了將內存緩沖區映射到內核之外的解決方案,這需要對上面提到的幾個錯誤的起點進行修正。 這里不可能發布完整的源代碼,但是讓它運行的步驟是:

  1. 設備樹:為沒有關聯驅動程序的緩沖區定義保留的內存區域。 不要使用mem或memmap bootargs。 內核將僅限於在自己的保留空間之外使用內存,但現在可以為保留內存創建結構頁面。
  2. 在設備驅動程序(在我的情況下是LKM)中,將物理地址映射到內核虛擬地址需要使用memremap而不是ioremap ,因為它是我們正在映射的實際內存。
  3. 在設備驅動程序mmap例程中,不要使用remap_pfn_range任何變體來設置用戶空間的vma,而是將自定義fault nopage例程分配給vma->vm_ops.fault以便在使用用戶空間虛擬地址時查找頁面。 這種方法在lddv3 ch15中描述。
  4. 驅動程序中的nopage函數應使用傳遞給它的vm_fault結構參數來計算需要頁面的地址的vma偏移量。 然后使用該偏移量計算內核虛擬地址(針對memremap的地址),並通過調用page = virt_to_page(pageptr);獲取頁面page = virt_to_page(pageptr); ,然后調用get_page(page); ,並使用vmf->page = page;將其分配給vm_fault結構vmf->page = page; 后一部分也在lddv3第15章中說明。

就我所知,使用mmap針對自定義設備驅動程序以這種方式映射的內存可以像普通的malloc內存一樣使用。 有可能用DMA庫實現類似的結果,但是我有限制阻止該路由,或者將設備樹節點與驅動程序相關聯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM