我有一个char驱动程序,其中我添加的一个接口函数是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
你能帮帮我吗?
答案 0 :(得分:1)
快速回答:您必须使用 do_munmap()取消映射用户进程中的页面。
virt_to_phys()无法完成这项工作。它由内核用于翻译
内核虚拟地址(不是用户虚拟地址)到物理地址。
用户空间记忆由vma区域组织。( struct vm_area_struct * vma )。
它们可以在每个进程的基础上在struct mm_struct下找到。流程
有自己的mm_structs,以便不同进程的相同虚拟地址映射到不同的物理地址。
您需要做的是获取虚拟地址。然后,在内核空间中,您需要 找出这个地址属于哪个vma,然后取消映射地址范围 来自vma并回收页面。(这是 do_munmap()所做的。)。
值得一提的另一点是,因为进程有自己的mm_struct,因此它们自己的vma区域。 do_munmap()
必须在"正确的#34;用户进程conext,否则将得到错误的mm_struct。
总结步骤:
1.已映射区域调用的用户进程
您的界面以释放虚拟地址。
2.系统调用内核空间(这是在用户进程' context下)。你的驱动程序处理程序调用do_munmap()
取消映射虚拟地址
3.你的司机释放了这些页面。
希望这有帮助!