sorry again....now I understood why the old program worked (http://www.scs.ch/~frey/linux/memorymap.html) - because the function declaration for remap_page_range() is different!!! >From 2.4.17 kernel source: /* Note: this is only safe if the mm semaphore is held when called. */ int remap_page_range(unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot) { so phys_addr is a true physical address. and as i read a particular instance in drivers/usb/usbvideo.c, the address is a kernel-allocated address, which is why u don't see any vma stuff here. 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. > >> >> 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