Binder mmap

来源:互联网 发布:域名分析站长 编辑:程序博客网 时间:2024/05/21 15:39

Binder mmap

By yacoo

 

这篇小文,只说明一件事情,如何从应用层的binder mmap调用到binder驱动mmap。

 

1.       先给出两个打开binder设备的场景,我们可以看到,mmap 空间的size并不一样。

l  service_manager.c

intmain(int argc, char **argv)

bs = binder_open(128*1024);

 

structbinder_state *binder_open(unsigned mapsize)

bs->fd = open("/dev/binder", O_RDWR);

bs->mapsize = mapsize;

bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE,bs->fd, 0);

 

b6ea8000-b6ec8000r--p 00000000 00:0c 8237       /dev/binder--- size = 128K

 

l  ProcessState.cpp

ProcessState::ProcessState()

    : mDriverFD(open_driver())

 

staticint open_driver()

    int fd = open("/dev/binder",O_RDWR);

  

 if(mDriverFD >= 0) {

        mVMStart = mmap(0,BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);

 

74c55000-74d53000r--p 00000000 00:0c 8237      /dev/binder --- size  = BINDER_VM_SIZE

#defineBINDER_VM_SIZE ((1*1024*1024) - (4096 *2))

 

2.       下来,分析下应用层的binder mmap是怎么走到binder驱动里面的。

对于mmap在用户态通过函数以下函数进行调用:

void*   mmap( void*  addr,  size_t  size, int  prot, int  flags, int  fd,  long  offset )  

 

然后进入系统调用,其系统调用号为: 

kernel/arch/arm/include/asm/unistd.h

#define__NR_mmap2   (__NR_SYSCALL_BASE+192)

unistd32.h:

__SYSCALL(192,sys_mmap_pgoff)

kernel/arch/arm/kernel/entry-common.S:

/*

 * Note: off_4k (r5) is always units of4K.  If we can't do the requested

 * offset, we return EINVAL.

 */

sys_mmap2:

#if PAGE_SHIFT> 12

                   tst    r5, #PGOFF_MASK

                   moveq      r5, r5, lsr #PAGE_SHIFT - 12

                   streq         r5, [sp, #4]

                   beq  sys_mmap_pgoff

                   mov r0, #-EINVAL

                   mov pc, lr

#else

                   str    r5, [sp, #4]

                   b       sys_mmap_pgoff

#endif

 

kernel/include/linux/syscalls.h:

asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len,

                            unsigned long prot,unsigned long flags,

                            unsigned long fd,unsigned long pgoff);

 

kernel/mm/mmap.c:

SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,

                   unsigned long, prot, unsignedlong, flags,

                   unsigned long, fd, unsignedlong, pgoff)

{

         retval = do_mmap_pgoff(file, addr, len,prot, flags, pgoff);

 

unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,

                            unsigned long len,unsigned long prot,

                            unsigned long flags,unsigned long pgoff,

                            unsigned long*populate)

{

         /* Obtain the address to map to. weverify (or select) it and ensure

          * that it represents a valid section of theaddress space.

          */

         addr= get_unmapped_area(file, addr, len, pgoff, flags); ---注意,此处,kernel已经提供了虚拟地址供该map空间使用。

         addr = mmap_region(file, addr, len,vm_flags, pgoff);

 

unsigned longmmap_region(struct file *file, unsigned long addr,

                   unsigned long len, vm_flags_tvm_flags, unsigned long pgoff)

{

 

         /*

          * Can we just expand an old mapping?

          */

         vma = vma_merge(mm, prev, addr, addr +len, vm_flags, NULL, file, pgoff, NULL);

 

         /*

          * Determine the object being mapped and callthe appropriate

          * specific mapper. the address has alreadybeen validated, but

          * not unmapped, but the maps are removed fromthe list.

          */

         vma = kmem_cache_zalloc(vm_area_cachep,GFP_KERNEL);

 

                   vma->vm_file =get_file(file);

                   error= file->f_op->mmap(file, vma); ---至此,终于调用到了binder驱动自身的mmap

 

binder.c

static int binder_mmap(struct file *filp, struct vm_area_struct*vma)

{

 

参考链接:http://blog.csdn.net/myarrow/article/details/7207628

0 0
原创粉丝点击