linux - 2 关于linux内核内存检查指向的问题(自定义实现)
问题描述
我们有一个项目,我们在其中实现内存检查点(基本只是查看页面并将找到的数据转储到文件中(还检查有关页面的信息(私有,锁定等))和增量,这是我们只查看数据的地方之前更改并将其转储到文件中)。我对此的理解是,我们几乎正在构建一个较小规模的内存保存状态版本(我可能是错的,但这正是我从中得到的)。我们目前正在使用 VMA 方法来解决我们的问题,以通过给定范围(只要它不低于或高于用户空间范围(这意味着没有内核范围或低于用户空间))以报告找到的数据从我们遇到的页面。我知道 vma_area_struct 用于访问 vma(一些函数包括 find_vma())。我的问题是我' 我不确定我们如何使用这个 vma_area_struct 检查这个给定地址范围内的各个页面(用户给我们)。我只知道 struct page(差不多就是这样),但我仍在详细了解内核,所以我一定会错过一些东西。访问页面时,我对 vma_area_sruct 有什么遗漏吗?
第二个问题是,我们用什么来遍历找到的 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_SIZE 中迭代从 VMA 获得的虚拟地址。
请注意,这假定页面实际已映射。如果不是 ( !pte_present(pte_t a)
),您可能需要自己重新映射以访问数据。
如果您的检查在其他上下文中运行(例如 kthread/中断),则必须在访问之前从交换中重新映射页面,这是完全不同的情况。如果您想要简单的方法,我会在这里查找:https ://www.kernel.org/doc/gorman/html/understand/understand014.html以了解如何处理交换查找/检索。
推荐阅读
- python - 在python命令行中输入解析参数作为变量?
- python - 如何读取特定位置的字符串,如果它们匹配,然后在 python 中打印所有行?
- azure-cosmosdb - 如何为 Cosmos db 中的每个文档设置一个字段?
- php - 通过多个外键 INSERT INTO 多个表
- c# - 解析的字节数组在解析成结构后变成垃圾
- sql - 如何在 DB2 where 子句中传递时间戳条件
- c - C:尝试使用 \ 将 fprintf() 格式字符串拆分为多行并在行的开头添加制表符
- python-3.x - 如何从查询集 django 中选择模型的实例?
- android - onitemclick 侦听器在对话框中不起作用
- python - 如何从 jupyter 笔记本中删除停用的 conda 环境名称?