[英]Map physical memory to userspace as normal, struct page backed mapping
我有一個自定義設備驅動程序,它實現了一個mmap
操作,將共享RAM緩沖區(在操作系統之外)映射到用戶空間。 通過傳遞mem=32M
作為OS的引導參數來保留緩沖區,剩下的512MB可用作緩沖區。 我想從映射內存執行零復制操作,如果vm_flags
包含VM_PFNMAP
和VM_IO
,則無法執行此操作。
我的驅動程序當前通過調用vm_iomap_memory(vma, start, size)
執行映射, vm_iomap_memory(vma, start, size)
又調用io_remap_pfn_range
和remap_pfn_range
,后者使用VM_PFNMAP
和VM_IO
設置來設置VM_IO
。 這適用於將內存映射到用戶空間,但由於設置了VM_PFNMAP
標記或缺少結構頁,因此零拷貝套接字操作在get_user_pages
失敗。 remap_pfn_range
的注釋顯示這是預期的行為,因為remap_pfn_range
映射的內存不應被視為“正常”。 但是,對於我的情況,它只是一塊保留的RAM,所以我不明白為什么它不應該被視為正常。 我已設置緩存失效/刷新以手動管理內存。
我已嘗試在映射期間和之后VM_IO
設置vm_area_struct
上的VM_PFNMAP
和VM_IO
標志,但get_user_pages
仍然失敗。 我也查看了dma庫,但看起來它們依賴於在幕后調用remap_pfn_range
。
我的問題是如何將物理內存映射為普通的非pfn結構頁面支持的用戶空間地址? 還是有其他方式我應該看看它? 謝謝!
我已經找到了將內存緩沖區映射到內核之外的解決方案,這需要對上面提到的幾個錯誤的起點進行修正。 這里不可能發布完整的源代碼,但是讓它運行的步驟是:
memremap
而不是ioremap
,因為它是我們正在映射的實際內存。 remap_pfn_range
任何變體來設置用戶空間的vma,而是將自定義fault
nopage例程分配給vma->vm_ops.fault
以便在使用用戶空間虛擬地址時查找頁面。 這種方法在lddv3 ch15中描述。 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.