内存管理API之alloc_vm_area

struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)用于分配一个size字节
大小的内核空间,但是该函数只是保留一个内核地址空间,并分配页表,但是并没有创建真正的映射.
其源码分析如下:
struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
{
	struct vm_struct *area;
	#申请一段虚拟内存
	area = get_vm_area_caller(size, VM_IOREMAP,
				__builtin_return_address(0));
	if (area == NULL)
		return NULL;

	/*
	 * This ensures that page tables are constructed for this region
	 * of kernel virtual address space and mapped into init_mm.
	 */
	 #在init_mm 中建立pgd table,建立pmd和pud,以及pte,但是并没有建立正常的物理内存和虚拟内存的映射
	if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
				size, f, ptes ? &ptes : NULL)) {
		#建立pgd table 失败的话,则释放这段虚拟内存空间
		free_vm_area(area);
		return NULL;
	}

	return area;
}



int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
			unsigned long size, pte_fn_t fn, void *data)
{
	pgd_t *pgd;
	unsigned long next;
	unsigned long end = addr + size;
	int err;

	if (WARN_ON(addr >= end))
		return -EINVAL;
	#通过pgd_offset 得到addr的pgd
	pgd = pgd_offset(mm, addr);
	do {
		#得到下一个pgd
		next = pgd_addr_end(addr, end);
		#依次循环建立pmd/pud/pte table
		err = apply_to_p4d_range(mm, pgd, addr, next, fn, data);
		if (err)
			break;
	#一直循环,知道这段虚拟内存空间的地址完全建立
	} while (pgd++, addr = next, addr != end);

	return err;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值