2008-12-15 04:52:44     mmap and __get_free_page

Document created by Aaronwu Employee on Aug 9, 2013
Version 1Show Document
  • View in full screen mode

2008-12-15 04:52:44     mmap and __get_free_page

Daniele Pagani (ITALY)

Message: 66709   

 

Dear sirs,

 

I'm adding the mmap feature to a driver.

 

I start from:

 

http://docs.blackfin.uclinux.org/doku.php?id=mmap

 

but I need some suggestions about a problem.

 

My idea is to allocate a page of memory and then mmap this page in user space.

 

In simple_open I add:

 

// global

 

char *kbuf;

 

// in simple_open

 

kbuf=(char*)__get_free_page(GFP_DMA); // does __get_free_page return physical or virtual address?

 

if(!kbuf) return -ENOMEM;

 

printk("kbuf %p page_size %d\n",kbuf,(int)PAGE_SIZE);

 

 

 

Then, in simple_release

 

__free_page((unsigned long)kbuf

 

 

 

When I run the user space application I can see:

 

kbuf 0378b000 page_size 4096 // Ezkit BF537

 

 

 

Now, in simple_remap_mmap

 

static int simple_remap_mmap(struct file *filp,struct vm_area_struct *vma){

 

unsigned long simple_region_start;

 

unsigned long simple_regions_size;

 

unsigned long off;

 

unsigned long physical;

 

unsigned long vsize;

 

unsigned long psize;

 

int ret;

 

simple_region_size=PAGE_SIZE; // 4k

 

simple_region_start=(unsigned long)kbuf; // physical address?

 

off=vma->vm_pgoff<<PAGE_SHIFT;

 

physical=simple_region_start+off;

 

vsize=vma->vm_end-vma->vm_start;

 

psize=simple_region_size-off;

 

if(vsize>psize)return -EINVAL;

 

vma->vm_flags|=VM_MAYSHARE;

 

printk("remap_pfn_range(%p,0x%lx,0x%lx,0x%lx,0x%lx)\n",vma,vma->vm_start,vma->vm_pgoff,vsize,vma->vm_page_prot);

 

vma->vm_start=__va(simple_region_start); // this is for debug, because I don't understand exactly the matter

 

vma->vm_end=vma->vm_start+simple_region_size;

 

printk("remap_pfn_range(%p,0x%lx,0x%lx,0x%lx,0x%lx)\n",vma,vma->vm_start,vma->vm_pgoff,vsize,vma->vm_page_prot);

 

ret=remap_pfn_range(vma,vma->vm_start,physical,vsize,vma->vm_page_prot);

 

vma->vm_ops=&simple_remap_vm_ops;

 

simple_vma_open(vma);

 

return 0;

 

}

 

 

 

Then, in user space:

 

...

 

p=mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);

 

if(p==MAP_FAILED)...

 

printf("mmap device ok p=%p\n",p);

 

 

 

I have as result:

 

kbuf 0378f000 page_size 4096

 

remap_pfn_range(037a4ea0,0x0,0x0,0x1000,0x0)

 

remap_pfn_range(037a4ea0,0x378f000,0x0,0x1000,0x0)

 

Simple VMA open, virt 0 , phys 0

 

mmap device ok p = (nil)

 

Simple VMA close

 

So, I don't understand exactly why I have p as null pointer.

 

Thank you in advanced for your cooperation.

 

Regards,

 

Daniele.

Attachments

    Outcomes