2017-02-10 169 views
0

拱= x86_64的映射保留高內存通過remap_pfn_range用戶空間

我通過以下這個問題概括的過程中DMA解決方案時, Direct Memory Access in Linux

我對ioremap電話與地址成功返回, PT。

在我致電remap_pfn_range時,我使用virt_to_phys(pt) >> PAGE_SHIFT來指定由ioremap調用生成的區域的pfn。

當執行使用mmap的用戶空間應用程序並調用remap_pfn_range時,機器崩潰。我假設映射關閉,我迫使系統使用已經分配的內存(退出前的屏幕毛刺),但是我不清楚哪裏出現了不匹配。該系統具有4 Gig Ram,並通過使用內核啓動選項mem=2048M預留2Gigs。我使用BUFFER_SIZE=1024u*1024u*1024uBUFFER_OFFSET=2u*1024u*1024u*1024u

把這些放入pt=ioremap(BUFFER_SIZE,BUFFER_OFFSET)我相信pt應該等於虛擬地址到位於2GB邊界的物理內存,直到3GB邊界。這個假設是否準確?

當我執行我的內核模塊,但我更改我的remap_pfn_range使用vma->vm_pgoff>>PAGE_SHIFT作爲目標pfn代碼執行沒有錯誤,我可以讀取和寫入內存。但是,這並未使用我預期的保留物理內存。

既然一切使用vma->vm_pgoff>>PAGE_SHIFT工作時,我相信我的罪魁禍首是我ioremapremap_pfn_range

感謝您的任何建議之間!

使用此內核模塊的動機是需要來自PCI設備的DMA的大量連續緩衝區。在這個應用程序中,重新編譯內核不是一個選項,所以我試圖用模塊+硬件來完成它。

回答

0

我對ioremap的呼叫成功返回,地址爲pt。

在我對remap_pfn_range的調用中,我使用virt_to_phys(pt)>> PAGE_SHIFT, 來指定由ioremap調用生成的區域的pfn。

這是非法的,因爲ioremap保留vmalloc區域中的虛擬區域。 virt_to_phys()只適用於線性映射的內存部分。

把這些成PT = ioremap的(BUFFER_SIZE,BUFFER_OFFSET)相信PT 應該等於一個虛擬地址到位於 2GB的物理存儲器邊界到邊界3GB。這個假設是否準確?

這是不完全正確,例如在我的機器 執行cat/proc/IOMEM

... 
00001000-0009ebff : System RAM 
... 
00100000-1fffffff : System RAM 
... 

可能有幾個存儲庫,而內存不是強制性的將物理地址的地址0x0開始空間。

這可能是有用的,你Dynamic DMA mapping Guide

+0

謝謝,我會考慮這一點,並提出報告。我感謝你的洞察力,簡潔和基調。 – deltatango

相關問題