如何确定设备内存的页面帧号?

5
如何确定设备内存的页面框号?从LDD3/第15章/“使用remap_pfn_range”和“一个简单的实现”部分中,pfn被等同于vm_pgoff字段。我感到困惑。这怎么可能呢?
请注意,vm_pgoff被描述为:
文件中区域的偏移量,以页为单位。当文件或设备映射时,这是第一个映射在此区域中的页面的文件位置。
因此,如果第一个映射的页面与文件的第一页对应(我认为这很常见),那么vm_pgoff将为0。如果是这样,似乎这不是remap_pfn_range()函数的pfn参数的正确值。我错过了什么?正确的价值是多少?为了方便参考,我在下面重复了来自LDD3的相关代码(第426页)。
static int simple_remap_mmap(struct file *filp, struct vm_area_struct *vma)
{
if (remap_pfn_range(vma, vma->vm_start, vm->vm_pgoff,
                    vma->vm_end - vma->vm_start,
                    vma->vm_page_prot))
    return -EAGAIN;
...
}

https://dev59.com/XGbWa4cB1Zd3GeqPTiX0 - venk
1个回答

5

你好,我是一位有用的助手。

venk,我是一个新手。我对你的问题非常好奇,我也阅读了你在Linux设备驱动程序中指出的部分内容。

还有一本书我应该推荐,《Professional Linux kernel architecture》。其中描述了一些关于mmap的细节。

从上面的那本书中看起来,在调用函数simple_remap_mmap()之前,会对vm->vm_pgoff进行一些变换,这在Linux内核源代码中不存在。所以,即使vm_pgoff为0,在对它进行一些转换后,该成员变量中可能会有一个正确的值。

下面的代码存在于Linux内核源代码3.3.5中。

#ifdef CONFIG_DEVKMEM

static int mmap_kmem(struct file *file, struct vm_area_struct *vma)
{

    unsigned long pfn;

    /* Turn a kernel-virtual address into a physical page frame */

    pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;   <----- Here

    /*
     * RED-PEN: on some architectures there is more mapped memory than
     * available in mem_map which pfn_valid checks for. Perhaps should add a
     * new macro here.
     *
     * RED-PEN: vmalloc is not supported right now.
     */
    if (!pfn_valid(pfn))
        return -EIO;

    vma->vm_pgoff = pfn;
    return mmap_mem(file, vma);
}
#endif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接