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;
}
内存管理API之alloc_vm_area
最新推荐文章于 2022-06-08 16:20:22 发布