On Mon, Sep 21, 2009 at 10:15 PM, Andrea Gasparini <[email protected]> wrote:
> Hi,
> I'm just writing some code that wants to implement a stupid mmap on a
> device.
> What I did is the following:
> 1 - allocating a buffer with kmalloc:
> kmalloc_ptr = kmalloc(LEN + 2 * PAGE_SIZE, GFP_KERNEL);
> 2 - make sure that it's page aligned:
> kmalloc_area = (kmalloc_ptr + PAGE_SIZE -1) & PAGE_MASK;
> ( _area and _ptr point to the same address, though )
> 3 - fill it with some dumb numbers and print them to check:
> for( i = 0; i < LEN; i++) {
> ((unsigned char*)kmalloc_area)[i] = (unsigned char)i;
> }
> for( i = 0; i < 20; i++) {
> printk(" %d ",( (unsigned char*)kmalloc_area)[i]);
> }
> 4 - in properly registered mmap, driver side, i wrote simply:
> ret = remap_pfn_range(vma, vma->vm_start,
> virt_to_phys(kmalloc_area) >> PAGE_SHIFT,
> vma->vm_end-vma->vm_start, vma->vm_page_prot);
this is wrong. read the comment for the function:
1688 /**
1689 * remap_pfn_range - remap kernel memory to userspace
1690 * @vma: user vma to map to
1691 * @addr: target user address to start at
1692 * @pfn: physical address of kernel memory
1693 * @size: size of map area
1694 * @prot: page protection flags for this mapping
1695 *
1696 * Note: this is only safe if the mm semaphore is held when called.
1697 */
1698 int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
1699 unsigned long pfn, unsigned long size, pgprot_t prot
)
so addr is a user virtual address, not physical, and must be allocated
from userspace. (get_user_pages() or something like that).
another code to confirm your understanding is inside the above function:
1724 */
1725 if (addr == vma->vm_start && end == vma->vm_end) {
1726 vma->vm_pgoff = pfn;
1727 vma->vm_flags |= VM_PFN_AT_MMAP;
1728 } else if (is_cow_mapping(vma->vm_flags))
1729 return -EINVAL;
1730
1731 vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
remember, vma's start and end is the limits bounding the userspace
address, in terms of VMA chunks. so addr must be withing this range,
ie, must be allocated and added to the VMA linked list as well.
>
> Ok, what's wrong with that? From a userspace test program, I got only
> zeroes:
> fd = open("/dev/mmaptest",O_RDWR);
> mmapped_ptr = mmap(NULL,SIZE,PROT_READ | PROT_WRITE, MAP_FILE |
> MAP_SHARED ,fd,0);
> for( i=0; i < SIZE; i++){
> printf(" i=%d, mmap[%d]=%d\n",i,i,mmapped_ptr[i]);
> }
> and that's the output:
> i=0, mmap[0]=0
> i=1, mmap[1]=0
> i=2, mmap[2]=0
> ...
>
> I'm clearly missing something trivial, and probably need more coffe... ;)
> Ideas?
> Thanks in advance.
> --
> -gaspa-
> -----------------------------------------------
> -------- https://launchpad.net/~gaspa ---------
> ------ HomePage: iogaspa.altervista.org -------
> -Il lunedi'dell'arrampicatore: www.lunedi.org -
>
> --
> To unsubscribe from this list: send an email with
> "unsubscribe kernelnewbies" to [email protected]
> Please read the FAQ at http://kernelnewbies.org/FAQ
>
>
--
Regards,
Peter Teoh
--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [email protected]
Please read the FAQ at http://kernelnewbies.org/FAQ