get_unmapped_area是mmap实现的一个关键点,它实现
mm-> get_unmapped_area
与
file->f_op->get_unmapped_area
的选择
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);
unsigned long error = arch_mmap_check(addr, len, flags);
if (error)
return error;
/* Careful about overflows.. */
if (len > TASK_SIZE)
return -ENOMEM;
/* 每个进程的mm_struct里面都有一个get_unmapped_area函数
比如arch/x86/mm/mmap.c里面,arch_pick_mmap_layout 函数对
get_unmapped_area赋值。
void arch_pick_mmap_layout(struct mm_struct *mm)
{
...
if (mmap_is_legacy()) {
mm->mmap_base = mm->mmap_legacy_base;
mm->get_unmapped_area = arch_get_unmapped_area;
mm->unmap_area = arch_unmap_area;
} else {
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
mm->unmap_area = arch_unmap_area_topdown;
}
}
*/
get_area = current->mm->get_unmapped_area;
/* 同时如果驱动程序的file_operations定义了get_unmapped_area,则会使用驱动程序定义的方法
file->f_op->get_unmapped_area,但是通常都不会有驱动程序定义这个方法,所以一般都是使用
current->mm->get_unmapped_area 这个方法。目的是在mmap区域找到一块没有被映射过的vm_area_struct对象 */
if (file && file->f_op && file->f_op->get_unmapped_area)
get_area = file->f_op->get_unmapped_area;
addr = get_area(file, addr, len, pgoff, flags);
if (IS_ERR_VALUE(addr))
return addr;
if (addr > TASK_SIZE - len)
return -ENOMEM;
if (addr & ~PAGE_MASK)
return -EINVAL;
return arch_rebalance_pgtables(addr, len);
}
阅读(3404) | 评论(0) | 转发(0) |