Re: implementing mmap

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux