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

时间:2012-07-13 18:11:54

标签: linux linux-kernel linux-device-driver

如何确定设备内存的页面帧号?来自LDD3 / Ch。 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;
...
}

1 个答案:

答案 0 :(得分:5)

venk,我只是个新手。 我对你的问题非常好奇,而且我已经阅读了你在Linux设备驱动程序中指出的部分。

我应该推荐另一本书,专业Linux内核架构。 有关mmap的一些细节在那里描述。

从上面的书中可以看出,在调用函数simple_remap_mmap()之前,有一些转换为vm-> vm_pgoff,这在Linux内核源代码中是不存在的。

所以,即使vm_pgoff为0,在对它进行一些转换之后,该成员变量vm_pgoff中可能存在正确的值。

以下代码存在于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