Hi,

I use remap_pfn_range to do mmap, and it can work.

Best Regards,
Peter Chen


On Thu, 2009-03-26 at 14:03 +0800, yihect wrote:
> It seems the mux_vma_nopage() operation hadn't been called.
>         ----- Original Message ----- 
>         From: yihect 
>         To: kernelnewbie 
>         Cc: [email protected] 
>         Sent: Thursday, March 26, 2009 1:48 PM
>         Subject: question about mapping RAM into user space.
>         
>         
>         Hi, all:
>             I'm a newbie of kernel. I'm working on my mux driver in
>         hand, and want to map some RAM(say, 1024*1024*2 bytes
>         totally)into user space. 
>          
>             Accroding the LDD3 book, I'm using __get_free_pages()
>         which be called in nopage() operation of struct
>         vm_operations_struct like follow:
>          
>             /* get page from mux dev, and return it to the user. */
>          struct page *mux_vma_nopage(struct vm_area_struct *vma,
>          unsigned long address, int *type)
>         {
>             unsigned long offset;
>             struct mux_dev *dev = vma->vm_private_data;
>             struct page *page = NOPAGE_SIGBUS;
>             void *pageptr = NULL; /* default to "missing" */
>          
>         
>             printk("In mux_vma_nopage
>         ############################################\n" );
>          
>             down(&dev->sem);
>             offset = (address - vma->vm_start) + (vma->vm_pgoff <<
>         PAGE_SHIFT);
>             if (offset >= dev->size) goto out; /* out of range */
>          
>             /* get page from our dev, get free page if inavialable */
>             offset >>= PAGE_SHIFT; /* offset is a number of pages */
>             if (!dev->data[offset])
>             {
>              dev->data[offset] = (void *)__get_free_pages(GFP_KERNEL,
>         0); /* order must be 0 */
>              if (!dev->data[offset]) 
>                  goto out;
>              memset(dev->data[offset], 0, PAGE_SIZE); 
>             } 
>             pageptr = dev->data[offset];
>             page = virt_to_page(pageptr);
>          
>             /* now increment the count */
>             get_page(page);
>             if (type)
>                  *type = VM_FAULT_MINOR;
>         
>         out:
>             up(&dev->sem);
>             return page;
>         }
>          
>          
>             The mmap() operation of fops is like:
>          
>         int nc_mux_mmap(struct file *filp, struct vm_area_struct *vma)
>         {
>             /* don't do anything here: "nopage" will set up page table
>         entries */
>             vma->vm_ops = &mux_vm_ops;
>             vma->vm_flags |= VM_RESERVED;
>             vma->vm_private_data = filp->private_data;
>             mux_vma_open(vma);
>             return 0;
>         }
>          
>              When I test useing code :
>         address=mmap(0, len, PROT_READ, MAP_FILE | MAP_PRIVATE, fd,
>         offset);
>          
>             if (address == (void *)-1) {
>                 fprintf(stderr,"%s: mmap(): %s
>         \n",argv[0],strerror(errno));
>                 exit(1);
>             }
>             strcpy((char *)address, "hello, world.");
>         
>         It gives me msg of "segmen fault":
>          
>         /mnt/nfs $ ./mapper /dev/mux_dev 0x0 0x400
>         SDVR22xxMX MUX Device Driver Open...
>         pgd = c01a4000
>         [40018000] *pgd=001e8031, *pte=00000000, *ppte=00000000
>          
>         Pid: 151, comm:               mapper
>         CPU: 0
>         PC is at 0x4008b9f8
>         LR is at 0x8960
>         pc : [<4008b9f8>]    lr : [<00008960>]    Tainted: P     
>         sp : bec9a64c  ip : 4008b9ec  fp : bec9ae88
>         r10: 40133000  r9 : 00000000  r8 : 00008738
>         r7 : 00000004  r6 : 00008b3c  r5 : 00008ad8  r4 : bec9aeb4
>         r3 : 00000068  r2 : 4000f3c3  r1 : 00008c3d  r0 : 40018000
>         Flags: nZCv  IRQs on  FIQs on  Mode USER_32  Segment user
>         Control: 397F  Table: 001A4000  DAC: 00000015
>         [<c052e7d8>] (show_regs+0x0/0x4c) from [<c0533bcc>]
>         (__do_user_fault+0x5c/0xa4)
>          r4 = C0039820 
>         [<c0533b70>] (__do_user_fault+0x0/0xa4) from [<c0533e98>]
>         (do_page_fault+0x218/0x250)
>          r7 = C05240CC  r6 = C0047FB0  r5 = C0039820  r4 = FFFFFFEB
>         [<c0533c80>] (do_page_fault+0x0/0x250) from [<c053401c>]
>         (do_DataAbort+0x3c/0xa0)
>         [<c0533fe0>] (do_DataAbort+0x0/0xa0) from [<c052c908>]
>         (ret_from_exception+0x0/0x10)
>          r8 = 00008738  r7 = 00000004  r6 = 00008B3C  r5 = 00008AD8
>          r4 = FFFFFFFF
>          SDVR22xxMX MUX Device Driver Release...
>         Segmentation fault
>          
>         Platform is arm and kernel version is 2.6.14, I don'e know how
>         to do nextly, is somebody have any suggestion? thanks.

Reply via email to