On Mon, Sep 21, 2009 at 10:15 PM, Andrea Gasparini <gaspa@xxxxxxxxxxx> 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 ecartis@xxxxxxxxxxxx > Please read the FAQ at http://kernelnewbies.org/FAQ > > -- Regards, Peter Teoh -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ