首页 > 解决方案 > 关于 remap_page_range 的第二个参数的困惑

问题描述

在通过 remap_page_range() 时,对第二个参数的使用感到困惑,正如在下面的线程中所指出的,它期望这个参数是一个物理地址。

https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch13s02.html

但在实施中:

 int simple_mmap(struct file *filp, struct vm_area_struct *vma)
 {
     unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
    
     if (offset >= _&thinsp;_pa(high_memory) || (filp->f_flags & O_SYNC))
         vma->vm_flags |= VM_IO;
     vma->vm_flags |= VM_RESERVED;

     if (remap_page_range(vma->vm_start, offset, 
            vma->vm_end-vma->vm_start, vma->vm_page_prot))
         return -EAGAIN;
     return 0;
 }

它源自 vma->vm_pgoff 似乎是虚拟地址(与当前用户空间 VMA 相关),那么偏移值如何与物理地址相关?

编辑: 我看到 remap_page_range() 不再是最新内核源的一部分,而是转换为 remap_pfn_range ,其中第三个参数似乎是页帧号(从物理地址派生),但我仍然看到 vm_pgoff 用于它。

https://elixir.bootlin.com/linux/latest/source/drivers/infiniband/hw/bnxt_re/ib_verbs.c#L3936

那么,vm_pgoff 与 Physical address 有什么关系呢?

标签: cmemory-managementlinux-kernellinux-device-driver

解决方案


推荐阅读