1. 简介
对于mmap在用户态通过函数以下函数进行调用:
- 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,实现代码如下:
- /*
- * Note: off_4k (r5) is always units of 4K. 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
4) 调用sys_mmap_pgoff在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);
6)sys_mmap_pgoff实现
在kernel/mm/mmap.c中实现如下:
- SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
- unsigned long, prot, unsigned long, flags,
- unsigned long, fd, unsigned long, pgoff)
- {
- struct file *file = NULL;
- unsigned long retval = -EBADF;
-
- if (!(flags & MAP_ANONYMOUS)) {
- audit_mmap_fd(fd, flags);
- if (unlikely(flags & MAP_HUGETLB))
- return -EINVAL;
- file = fget(fd);
- if (!file)
- goto out;
- } else if (flags & MAP_HUGETLB) {
- struct user_struct *user = NULL;
- /*
- * VM_NORESERVE is used because the reservations will be
- * taken when vm_ops->mmap() is called
- * A dummy user value is used because we are not locking
- * memory so no accounting is necessary
- */
- len = ALIGN(len, huge_page_size(&default_hstate));
- file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE,
- &user, HUGETLB_ANONHUGE_INODE);
- if (IS_ERR(file))
- return PTR_ERR(file);
- }
-
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
- down_write(¤t->mm->mmap_sem);
- retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up_write(¤t->mm->mmap_sem);
-
- if (file)
- fput(file);
- out:
- return retval;
- }
其功能为:从当前进程中获取用户态可用的虚拟地址空间(vm_area_struct *vma),在mmap_region中真正获取vma,然后调用file->f_op->mmap(file, vma),调用具体的支持mmap的驱动来处理。 下面以binder驱动为例。
Linux Kernel中如何使用高精度timer(hrtimer)Ubuntu 11.10配置Modlesim6.5相关资讯 Linux Kernel
- Linux Kernel 3.14系列结束支持 (今 14:24)
- Linux kernel 2.6.32 LTS 将于下个 (01月31日)
- 怎样在 CentOS 7 上安装 Kernel 4. (05/15/2015 11:28:39)
| - Linux Kernel 开发报告 25 周年版 (09月10日)
- Linux Kernel 4.1.15发布 (12/15/2015 20:54:13)
- Linux Kernel stable 3.19.7/4.0.2 (05/07/2015 08:50:31)
|
本文评论 查看全部评论 (0)