mmap是kernel提供的一个系统调用,其功能是将一个文件或者其它对象映射进内存。mmap在kernel中的对应的服务例程为do_mmap,下面来简单的说一说do_mmap的实现。
do_mmap的代码如下:
static inline unsigned long do_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long offset)
{
unsigned long ret = -EINVAL;
if ((offset + PAGE_ALIGN(len)) < offset)
goto out;
if (!(offset & ~PAGE_MASK))//映射在文件中的偏移量offset必须是以PAGE_SIZE对齐的,否则,函数直接退出,返回Invalid argument</span>
ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
out:
return ret;
}
可以看到do_mmap主要功能是通过函数do_mmap_pgoff来实现的,do_mmap_pgoff,其主要代码如下:
unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flags, unsigned long pgoff)
{
struct mm_struct * mm = current->mm;
......
......
if (!len)
return -EINVAL;
/* Careful about overflows.. */
len = PAGE_ALIGN(len);//将映射长度进行以PAGE_SIZE对齐</span>
if (!len)
return -ENOMEM;
/* offset overflow? */
if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
return -EOVERFLOW;
/* Too many mappings? */
if (mm->map_count > sysctl_max_map_count)
return -ENOMEM;
/* Obtain the address to map to. we verify (or select) it and ensure
* that it represents a valid section of the address space.
*/
addr = get_unmapped_area(file, addr, len, pgoff, flags);//该函数用来获取合适的映射区域,该函数在不同的体系结构上调用的函数不同。
if (addr & ~PAGE_MASK)
return addr;