linux-kernel - 如何从 Linux 内核中的任何地址获取结构页面

标签 linux-kernel virtual-memory

我现有的代码需要一个列表 struct page *并建立一个描述符表与设备共享内存。该代码的上层当前期望分配有 vmalloc 的缓冲区。或来自用户空间,并使用 vmalloc_to_page 获取对应的struct page * .

现在上层需要处理各种内存,不仅仅是通过vmalloc获得的内存.这可能是使用 kmalloc 获得的缓冲区,内核线程堆栈内的指针,或我不知道的其他情况。我唯一的保证是这个上层的调用者必须确保有问题的内存缓冲区在那一点被映射到内核空间中(即在这一点上访问 buffer[i] 对所有 0<=i<size 都是有效的)。 我如何获得 struct page*对应于任意指针?

把它放在伪代码中,我有这个:

lower_layer(struct page*);
upper_layer(void *buffer, size_t size) {
    for (addr = buffer & PAGE_MASK; addr <= buffer + size; addr += PAGE_SIZE) {
        struct page *pg = vmalloc_to_page(addr);
        lower_layer(pg);
    }
}

我现在需要改变 upper_layer处理任何有效的缓冲区(不改变 lower_layer )。

我找到了 virt_to_page , 其中 Linux Device Drivers表示对“逻辑地址,[不是]来自 vmalloc 的内存进行操作”或高内存”。此外, is_vmalloc_addr 测试地址是否来自 vmalloc , 和 virt_addr_valid 测试地址是否是有效的虚拟地址( virt_to_page 的素材;这包括 kmalloc(GFP_KERNEL) 和内核堆栈)。其他情况如何:全局缓冲区、高内存(总有一天会到来,但我现在可以忽略它),可能还有我不知道的其他类型?所以我可以将我的问题重新表述为:
  • 内核中有哪些类型的内存区域?
  • 我如何区分它们?
  • 如何获取每个页面的映射信息?

  • 如果重要,代码运行在 ARM(带有 MMU)上,内核版本至少为 2.6.26。

    最佳答案

    我想您想要的是页表遍历,例如(警告,不是实际代码,锁定丢失等):

    struct mm_struct *mm = current->mm;
    pgd = pgd_offset(mm, address);
    pmd = pmd_offset(pgd, address);  
    pte = *pte_offset_map(pmd, address);  
    page = pte_page(pte);
    

    但是你应该非常非常小心。例如,您获得的 kmalloc 地址很可能不是页面对齐的。这对我来说听起来像是一个非常危险的 API。

    关于linux-kernel - 如何从 Linux 内核中的任何地址获取结构页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5982125/

    相关文章:

    linux-kernel - ARM Linux 页表条目格式——未使用的位?

    memory-management - 当进程访问刚用 brk/sbrk 分配的地址时,内核会发生什么?

    linux - 内核虚拟地址空间中的高内存映射

    Linux:在我的进程中管理虚拟内存映射以进行快速仿真

    文件中的linux内核输出

    linux - 如何在 virtualbox 中调试内核加载和 intrd 加载

    linux-kernel - .config 和 kconfig 之间的区别

    Linux 模块每秒检查电池状态,更好的检查方式,当前方式 rmmod 不起作用

    c - Emacs 中的 Linux 内核标记

    linux - 遗留的 gcc 编译器问题