歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux Kernel 及 binder mmap實現

Linux Kernel 及 binder mmap實現

日期:2017/2/28 15:55:13   编辑:Linux教程

1. 簡介

對於mmap在用戶態通過函數以下函數進行調用:

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

然後進入系統調用。

2. Kernel mmap實現

1)然後進入系統調用,其系統調用號為:

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

#define __NR_mmap2 (__NR_SYSCALL_BASE+192)

2)觸發軟中斷

其ISR 代碼位於kernel/arch/arm/kernel/entry-common.S的ENTRY(vector_swi), __NR_mmap2對應的函數為:sys_mmap2(位於linux/arch/arm/kernel/calls.S)

3)sys_mmap2的實現

位於kernel/arch/arm/kernel/entry-common.S,實現代碼如下:

  1. /*
  2. * Note: off_4k (r5) is always units of 4K. If we can't do the requested
  3. * offset, we return EINVAL.
  4. */
  5. sys_mmap2:
  6. #if PAGE_SHIFT > 12
  7. tst r5, #PGOFF_MASK
  8. moveq r5, r5, lsr #PAGE_SHIFT - 12
  9. streq r5, [sp, #4]
  10. beq sys_mmap_pgoff
  11. mov r0, #-EINVAL
  12. mov pc, lr
  13. #else
  14. str r5, [sp, #4]
  15. b sys_mmap_pgoff
  16. #endif

4) 調用sys_mmap_pgoff

在kernel/include/linux/syscalls.h中定義如下:

  1. asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len,
  2. unsigned long prot, unsigned long flags,
  3. unsigned long fd, unsigned long pgoff);

6)sys_mmap_pgoff實現
在kernel/mm/mmap.c中實現如下:

  1. SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
  2. unsigned long, prot, unsigned long, flags,
  3. unsigned long, fd, unsigned long, pgoff)
  4. {
  5. struct file *file = NULL;
  6. unsigned long retval = -EBADF;
  7. if (!(flags & MAP_ANONYMOUS)) {
  8. audit_mmap_fd(fd, flags);
  9. if (unlikely(flags & MAP_HUGETLB))
  10. return -EINVAL;
  11. file = fget(fd);
  12. if (!file)
  13. goto out;
  14. } else if (flags & MAP_HUGETLB) {
  15. struct user_struct *user = NULL;
  16. /*
  17. * VM_NORESERVE is used because the reservations will be
  18. * taken when vm_ops->mmap() is called
  19. * A dummy user value is used because we are not locking
  20. * memory so no accounting is necessary
  21. */
  22. len = ALIGN(len, huge_page_size(&default_hstate));
  23. file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE,
  24. &user, HUGETLB_ANONHUGE_INODE);
  25. if (IS_ERR(file))
  26. return PTR_ERR(file);
  27. }
  28. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  29. down_write(¤t->mm->mmap_sem);
  30. retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  31. up_write(¤t->mm->mmap_sem);
  32. if (file)
  33. fput(file);
  34. out:
  35. return retval;
  36. }

其功能為:從當前進程中獲取用戶態可用的虛擬地址空間(vm_area_struct *vma),在mmap_region中真正獲取vma,然後調用file->f_op->mmap(file, vma),調用具體的支持mmap的驅動來處理。

下面以binder驅動為例。

Copyright © Linux教程網 All Rights Reserved