哪一個正確的方式在用戶空間進程中映射一個用kmalloc分配的緩衝區?也許我不明白內存映射呢......我寫了一個內核模塊來分配這個緩衝區(例如120字節),我會在用戶空間進程中讀寫它。顯然,我創建了一個char設備,並在file_operations
結構中實現了mmap
方法。我的方法是:mmap:在用戶空間映射一個用kmalloc分配的內核緩衝區
static int my_mmap(struct file *filp, struct vm_area_struct *vma)
{
//printk(KERN_INFO "Allocated virtual memory length = %d", vma->vm_end - vma->vm_start);
long unsigned int size = vma->vm_end - vma->vm_start;
if (remap_pfn_range(vma, vma->vm_start,
__pa(mem_area) >> PAGE_SHIFT, //what about vma->vm_pgoff?
size,
vma->vm_page_prot) < 0)
return -EAGAIN;
vma->vm_flags |= VM_LOCKED;
vma->vm_ops = &vmops;
vma->vm_flags |= VM_RESERVED;
my_vm_open(vma);
return 0;
}
其中mem_area
點在存儲器領域模塊初始化與kmalloc
分配。該區域填充相同的值(例如0x10)。所有的作品,但我覺得有什麼不對在此代碼:
kmalloc
可以返回未對齊頁的指針,在這種情況下,我不認爲這是正確的第三個參數的值remap_pfn_range
其實在用戶空間我讀錯誤的值。如果我使用__get_free_page
(因爲該函數總是返回一個頁面對齊的指針),或者當kmalloc
返回一個頁面對齊的指針,所有工作。內存映射適用於多個PAGE_SIZE
的內存區域,因此,我應該分配整個頁面而不是使用kmalloc
?當調用
my_mmap
時,內核已經分配了一些頁面呢?我問這個,因爲我發現一些自定義mmap
方法的實現,調用remap_pfn_range
與vma->vm_pgoff
作爲第三個參數......這可能有用嗎?這是第一個新分配頁面的頁框嗎?如果我作爲第三個參數傳遞頁面框架,就像我在my_mmap
中做的那樣,我應該從vma->vm_pgoff
頁面開始免費頁面?但是,我發現一個
mmap
方法的實現映射了一個緩衝區分配kmalloc
。爲了正確映射緩衝區,在remap_pfn_range
之前執行一個操作(我現在不打算)。假設mem
是kmalloc
返回的指針,mem_area
以這種方式初始化:mem_area=(int *)(((unsigned long)mem + PAGE_SIZE - 1) & PAGE_MASK);
所以mem_area
包含mem
只有mem
是頁對齊,否則是相同的值應包含指針開頭的下一頁。但是,如果我作爲remap_pfn_range
的第三參數傳遞,則此操作的值__pa(mem_area) >> PAGE_SHIFT
映射效果良好。爲什麼?
謝謝大家!
我有一個類似的問題,但使用啓動參數'mmap':http://stackoverflow.com/q/12790382/143897?你能提供一些你的發現嗎?謝謝。 –
您不需要爲vm_operations_struct.fault設置頁面錯誤處理程序嗎? –
最小的可運行示例:https://stackoverflow.com/questions/10760479/how-to-mmap-a-linux-kernel-buffer-to-user-space/45645732#45645732 –