在之前写了一篇mmap内核源码分析,基于内核版本3.10,经过几天再来回顾发现还是没能学习透彻,所以再写一篇(二)
mmap内核源码分析,基于内核版本3.10(一)博客地址:
https://blog.csdn.net/SweeNeil/article/details/83685812
我们接着从一中的get_unmapped_area函数讲起,get_unmaped_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;
get_area = current->mm->get_unmapped_area;
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;
addr = arch_rebalance_pgtables(addr, len);
error = security_mmap_addr(addr);
return error ? error : addr;
}
在(一)中我们知道了函数get_unmaped_area()调用文件对象的get_unmaped_area方法,如果已定义,就为文件的内存映射分配一个合适的线性地址区间。磁盘文件系统不会定义这么一个方法,那么get_unmaped_area就会调用内存描述符的get_unmaped_area方法。
接下来我们在(一)讲解了如何找到get_unmaped_area,在(二)中接着这一步进行详细讲解,使用Search Project找到内核源码中所有的get_unmaped_area,我们就对这些所有找到的内容进行讲解以及对后续调用代码进行更加深入的学习。
最后我们找到了:---- get_unmapped_area Matches (78 in 55 files) ----
这里按文件进行分析:
1 、fs/bad_inode.c
.get_unmapped_area = bad_file_get_unmapped_area
bad_inode.c (fs) line 167 :
.sendpage = bad_file_sendpage,
.get_unmapped_area = bad_file_get_unmapped_area,
.check_flags = bad_file_check_flags,
.flock = bad_file_flock,
.splice_write = bad_file_splice_write,
bfin_capture.c (drivers\media\platform\blackfin) line 946 :
#ifndef CONFIG_MMU
.get_unmapped_area = bcap_get_unmapped_area,
#endif
.poll = bcap_poll
};
2、drivers/video/fbmem.c
.get_unmapped_area = ramfs_nommu_get_unmapped_area
fbmem.c (drivers\video) line 1486 :
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
.get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO
.fsync = fb_deferred_io_fsync,
file-nommu.c (fs\ramfs) line 39 :
.mmap = ramfs_nommu_mmap,
.get_unmapped_area = ramfs_nommu_get_unmapped_area,
.read = do_sync_read,
.aio_read = generic_file_aio_read,
.write = do_sync_write,
spufs_get_unmapped_area in file.c (arch\powerpc\platforms\cell\spufs) :
if (!csa->use_big_pages)
return current->mm->get_unmapped_area(file, addr, len,
pgoff, flags