mmap内核源码分析,基于内核版本3.10(三)

之前写了(一)(二)其实就梳理到了get_unmapped_area的内容,而且有一点混乱,这里进行第三篇的讲解,讲解在do_mmap_pgoff中除了get_unmapped_area的内容,来了解mmap的具体实现。通过(一)(二)(三)来将mmap内核源码进行一次梳理。可能过程有一点乱,所以最后准备写一篇总结来总结mmap这样一个流程。

(一)https://blog.csdn.net/SweeNeil/article/details/83685812

(二)https://blog.csdn.net/SweeNeil/article/details/83897094

在(三)中我准备从do_mmap_pgoff中的内容出发,分析(一)、(二)中没有分析的内容。

直接上do_mmap_pgoff函数的内容,/mm/mmap.c文件中的do_mmap_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)
{
	struct mm_struct * mm = current->mm;
	struct inode *inode;
	vm_flags_t vm_flags;

	*populate = 0;

	/*
	 * Does the application expect PROT_READ to imply PROT_EXEC?
	 *
	 * (the exception is when the underlying filesystem is noexec
	 *  mounted, in which case we dont add PROT_EXEC.)
	 应用程序是否期望PROT_READ影射PROT_EXEC? 
	 (例外情况是底层文件系统是noexec挂载的,
	 在这种情况下我们不添加PROT_EXEC)
	 */
	if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
		if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
			prot |= PROT_EXEC;

	if (!len)
		return -EINVAL;

	if (!(flags & MAP_FIXED))
		addr = round_hint_to_min(addr);

	/* 小心溢出 */
	len = PAGE_ALIGN(len);
	if (!len)
		return -ENOMEM;

	/* 溢出偏移? */
	if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
               return -EOVERFLOW;

	/* 影射是否过多? */
	if (mm->map_count > sysctl_max_map_count)
		return -ENOMEM;

	/* Obtain the address to map to. we verify (or select) it and ensure
	 * that it represents a valid section of the address space.
	 获取要映射到的地址。 我们验证(或选择)它并确保它代表有效的地址空间。
	 */
	addr = get_unmapped_area(file, addr, len, pgoff, flags);

	//如果现在都不是页对齐的,那么返回的肯定是错误码,返回之return addr
	if (addr & ~PAGE_MASK)
		return addr;

	/* Do simple checking here so the lower-level routines won't have
	 * to. we assume access permissions have been handled by the open
	 * of the memory object, so we don't do any here.
	 在这里进行简单的检查,以便下级例程不必。 
	 我们假设访问权限已由内存对象的打开处理,
	 因此我们不在此处执行任何操作。
	 */
	 //calc_vm_prot_bits 将mmap“prot”参数合并到内部使用的“vm_flags”中。
	vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
			mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;

	if (flags & MAP_LOCKED)
		if (!can_do_mlock())
			return -EPERM;

	/* mlock MCL_FUTURE? */
	if (vm_flags & VM_LOCKED) {
		unsigned long locked, lock_limit;
		locked = len >> PAGE_SHIFT;
		locked += mm->locked_vm;
		lock_limit = rlimit(RLIMIT_MEMLOCK);
		lock_limit >>= PAGE_SHIFT;
		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
			return -EAGAIN;
	}

	inode = file ? file_inode(file) : NULL;

	if (file) {
		switch (flags & MAP_TYPE) {
		case MAP_SHARED:
			if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE))
				return -EACCES;

			/*
			 * M
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值