2016-06-27 94 views
2

我有一個字符驅動程序,其中我添加的接口函數之一是alloc_contig(int order),其中order是所需數量的4K頁的log2。 該函數分配連續的物理內存並使用remap_pfn_range函數將其映射到用戶空間使用情況。 我試圖寫的功能,它釋放內存dealloc_contig(va) 現在在內核我有虛擬地址用戶給予免費,我需要獲得底層的物理地址,所以我試圖使用virt_to_phys,但它並沒有給我期望的地址。 日誌:虛擬內核邏輯地址

//allocating 
page address is ffff880868764000 //allocated using alloc_pages 
//deallocating 
virtual address from user 7f4c7e095000 
when converted to PA using virt_to_phys got f74c7e095000 instead of ffff880868764000 

你能幫我嗎?

回答

1

快速回答:您必須使用do_munmap()從用戶進程中取消映射頁面。
virt_to_phys()不能完成這項工作。它被內核用來將 內核虛擬地址(不是用戶虛擬地址)轉換爲物理地址。

用戶空間存儲器由vma區域組織(struct vm_area_struct * vma)。 可以在每個進程的基礎上在struct mm_struct下找到它們。進程 有它們自己的mm_structs,以便不同進程的相同虛擬地址映射到不同的物理地址。

你需要做的是獲得虛擬地址。然後,在內核空間中,您需要 找出該地址屬於哪個vma,然後從vma中取消映射地址範圍 並回收頁面(這就是do307)。

另一點值得一提的是,因爲進程有它們自己的mm_struct,因此它們自己的vma區域。必須在「正確的」用戶進程conext下調用do_munmap() ,否則會得到錯誤的mm_struct。

總結步驟:
已映射區域呼叫 界面以釋放虛擬地址 1.用戶進程。 2.系統調用內核空間(這是在你的用戶進程的上下文中)。您的驅動程序處理程序調用do_munmap()至 取消映射虛擬地址。
3.您的驅動程序釋放頁面。

希望這有助於!

+0

謝謝你的幫助。你可以請,如果可能的話,指導我如何找到適當的VMA結構?正如我所看到的,在mm_strct中有一個名爲mm_rb的紅黑樹,其中包含vma結構。那麼如何訪問進程的mm_struct,以及如何在此樹中搜索? –

+0

嗨,這是通過do_munmap() - > find_vma()完成的,你可以看看這個鏈接的源代碼。 http://lxr.free-electrons.com/source/mm/mmap.c#L2411 – Lin