Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine the Page Frame Number for device memory? [duplicate]

How does one determine the page frame number for device memory? From LDD3/ Ch. 15/ sections "Using remap_pfn_range" and "A Simple Implementation", pfn has been equated to the vm_pgoff field. I am confused by this. How can that be so?

Note that vm_pgoff is described as:

The offset of the area in the file, in pages. When a file or device is mapped, this is the file position of the first page mapped in this area.

Thus if the first page mapped corresponds to the first page of the file as well (which, I think would be quite common), vm_pgoff would be 0. correct? If so, this doesn't seem to be the correct value for the pfn parameter of remap_pfn_range( ). What am I missing here? What is the correct value? For ease of reference, I am reproducing the relevant code from LDD3 below (Page no. 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;
...
}
like image 448
venk Avatar asked Jul 13 '12 18:07

venk


1 Answers

venk, I am just a newbie. I am very curious about your question, and also I have read the part that you pointed in Linux device driver.

There is another book I should recommend, Professional Linux kernel architecture. some details on mmap are described there.

from within the book above, it seems there are some transformations to vm->vm_pgoff before calling the function simple_remap_mmap() as a example here, which does not exist in Linux kernel source code.

so, even if vm_pgoff is 0, after some transformation to it, there may be a correct value in that member variable vm_pgoff.

the codes below are present in Linux kernel source code 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
like image 186
shawn xy bai Avatar answered Sep 22 '22 18:09

shawn xy bai