On Thu, Sep 24, 2009 at 8:30 AM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote: > 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. > >> in case u want to see the VMA chunks: cat /proc/<pid>/maps: 08048000-0808b000 r-xp 00000000 03:46 132253 /usr/sbin/sshd 0808b000-0808d000 rw-p 00042000 03:46 132253 /usr/sbin/sshd 0808d000-080ab000 rwxp 00000000 00:00 0 40000000-40015000 r-xp 00000000 03:47 520194 /lib/ld-2.3.2.so 40015000-40016000 rw-p 00014000 03:47 520194 /lib/ld-2.3.2.so 40016000-40017000 rw-p 00000000 00:00 0 40018000-4001b000 r-xp 00000000 03:47 97563 /lib/security/pam_stack.so 4001b000-4001c000 rw-p 00002000 03:47 97563 /lib/security/pam_stack.so 4001d000-40024000 r-xp 00000000 03:46 66070 /usr/lib/libwrap.so.0.7.6 40024000-40025000 rw-p 00006000 03:46 66070 /usr/lib/libwrap.so.0.7.6 40025000-40026000 rw-p 00000000 00:00 0 for example, all userspace address range. >> 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 > -- 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