【问题标题】:Find page in memory for Process (linux-kernel)在内存中查找进程的页面(linux-kernel)
【发布时间】:2024-04-30 11:40:02
【问题描述】:

基本上我有一个程序可以找到一个进程的所有 VMA,但我也想查看该进程的页表中的页面。我难住了。我知道进程的 task_struct 有一个字段

pgd_t                  *pgd;                /* page global directory */

这只是所有页面的索引数组吗?

我在“/mm/memory.c”中找到了这个函数

/*
* Do a quick page-table lookup for a single page.
*/
struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
                    unsigned int flags)

我可以将 VMA 传递给它,但我不确定地址和标志应该是什么。或者这不是我想要的?有什么建议吗?

【问题讨论】:

    标签: c memory linux-kernel operating-system


    【解决方案1】:

    听起来你想做一个基本的页面遍历。

    给定pgd,您可以遍历条目以寻找有效的pud,然后遍历pud,依此类推。

    一种方法是使用以下方法:

    // iterate through your address space
    for (i = 0; i < PAGE_SIZE / sizeof(*pud); i++) {
        pud = pud_offset(pgd, PUD_SIZE * i);
        // Check if the pud is valid
        if (pud_none(*pud) || pud_bad(*pud))
            continue;
        // And so on
    }
    

    【讨论】:

    • 那么系统上所有东西的 pgd 是什么?还是只是发现它的 task_struct 中的进程?为了确保我了解多级页表,实际包含信息(即标志)的页面在 pmd 中?
    • pgd 是页表的根。我不确定当前状态,但通常内核被映射到每个进程中的前 1GB 内存。
    • 试图理解你的例子。 pud_offset 不期望一个虚拟地址(你传递PUD_SIZE * i 的地方)吗?
    • 目标是遍历所有虚拟内存,因此它只是组成虚拟地址。之后的检查是为了确保你没有遵循错误的指针。