2关于linux内核内存检查点的问题(自定义实现)



我们得到了一个项目,在这个项目中,我们实现了内存检查点(基本的是查看页面并将找到的数据转储到文件中(还检查页面的信息(私有、锁定等((和增量的,这是我们只查看数据以前是否更改并将其转储到文件的地方(。我对此的理解是,我们正在构建一个较小规模的内存保存状态版本(我可能错了,但这正是我从中得到的(。我们目前正在使用VMA方法来解决我们的问题,通过给定的范围(只要它不低于或高于用户空间范围(这意味着没有内核范围或低于用户空间((,以报告从我们遇到的页面中找到的数据。我知道vma_area_struct用于访问vma(一些函数包括find_vma(((。我的问题是,我不确定我们如何通过使用此vma_area_struct来检查给定地址范围(用户给我们的(内的各个页面。我只知道structpage(差不多就是这样(,但我仍在详细学习内核,所以我一定会错过一些东西。在访问页面时,vma_are_struct是否缺少某些内容?

第二个问题是,我们用什么来迭代找到的vma中的每个单独的页面(从给定的开始和结束地址(?

VMA包含其第一个字节和最后一个字节的虚拟地址:

struct vm_area_struct {
/* The first cache line has the info for VMA tree walking. */
unsigned long vm_start;         /* Our start address within vm_mm. */
unsigned long vm_end;           /* The first byte after our end address
within vm_mm. */
...

这意味着,为了获得页面的数据,您需要首先弄清楚代码是在什么上下文中运行的?

如果它在流程上下文中,那么一个简单的copy_from_user方法可能足以获得实际数据和页面遍历(通过整个PGD/PUD/PMD/PTE(来获得PFN,然后将其转换为struct page。(注意不要使用诱人的virt_to_page(addr),因为这只适用于内核地址(。

在迭代方面,您只需要在PAGE_SIZEs中迭代,即从VMA获得的虚拟地址。

请注意,此假设实际映射了页面。如果不是(!pte_present(pte_t a)(,您可能需要自己重新映射它来访问数据。

如果您的检查是在其他上下文中运行的(如kthread/中断(,则在访问页面之前,必须从交换中重新映射页面,这是完全不同的情况。如果你想要简单的方法,我会在这里查找:https://www.kernel.org/doc/gorman/html/understand/understand014.html了解如何处理交换查找/检索。

最新更新