2个问题,有关使用Linux内核指向内存的检查(自定义实现)

时间:2018-10-31 17:25:38

标签: linux linux-kernel c

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

第二个问题是,我们要使用什么来遍历找到的vma中的每个页面(从给定的起始地址和结束地址开始)?

1 个答案:

答案 0 :(得分:0)

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),因为这仅适用于内核地址)。

就迭代而言,您只需要对从VMA获得的虚拟地址进行PAGE_SIZE迭代即可。

请注意,这假定页面实际上已映射。如果不是(!pte_present(pte_t a),则可能需要自己重新映射才能访问数据。

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