内存管理API之get_unmapped_area

unsigned long
get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
		unsigned long pgoff, unsigned long flags)
在当前进程的用户空间中获得一个未映射的起始地址.
其在do_mmap中有使用这个函数。
其源码分析如下:
unsigned long
get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
		unsigned long pgoff, unsigned long flags)
{
	unsigned long (*get_area)(struct file *, unsigned long,
				  unsigned long, unsigned long, unsigned long);

	#针对特定平台的检查,目前arm64中arch_mmap_check 是一个空函数
	unsigned long error = arch_mmap_check(addr, len, flags);
	if (error)
		return error;
	#申请虚拟空间的地址不能超过最大值。这里可以知道虚拟空间size 的最大值就是TASK_SIZE
	/* Careful about overflows.. */
	if (len > TASK_SIZE)
		return -ENOMEM;
	#指向当前进程的unmap 空间的分配函数
	get_area = current->mm->get_unmapped_area;
	#file 不为空的话,则unmap 空间的分配函数执行file中指定的函数
	if (file) {
		if (file->f_op->get_unmapped_area)
			get_area = file->f_op->get_unmapped_area;
	} else if (flags & MAP_SHARED) {
	#如果file为空,说明可能申请的是匿名空间,这里检查如果是共享内存的话,则分配函数执行共享内存的分配函数
		/*
		 * mmap_region() will call shmem_zero_setup() to create a file,
		 * so use shmem's get_unmapped_area in case it can be huge.
		 * do_mmap_pgoff() will clear pgoff, so match alignment.
		 */
		pgoff = 0;
		get_area = shmem_get_unmapped_area;
	}
	#使用前面已经指定的分配函数来在未映射的虚拟空间中映射的空间中申请.
	addr = get_area(file, addr, len, pgoff, flags);
	if (IS_ERR_VALUE(addr))
		return addr;
	#addr +len 不能大于TASK_SIZE
	if (addr > TASK_SIZE - len)
		return -ENOMEM;
	#检查分配到的地址是否已经被映射,如果已经被映射则返回error,毕竟我们这里要分配的是进程未映射的空间。
	if (offset_in_page(addr))
		return -EINVAL;
	#secure检查
	error = security_mmap_addr(addr);
	return error ? error : addr;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值