mmap()内存分配函数

读书笔记——Linux内核源代码情景分析——2.13  系统调用mmap()

  (2009-03-09 22:02:29)
标签: 

杂谈

分类: 读书笔记

一个进程可以通过系统调用mmap(),将一个已打开的文件的内容映射到它的用户空间,其用户界面为:
mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset)
参数fd代表一个已打开的文件,offset为文件中的起点,而start为映射到用户空间的起始地址,length则为长度,prot用于对所映射区间的访问模式,如可写、可执行等等;flags用于其他控制目的。

在2.4.0版的内核中实现这个调用的函数为sys_mmap2(),但是在老一些的版本中另有一个函数old_mmap(),这两个函数对应着不用的系统调用号。
由不同版本的C语言库程序决定采用那一个系统调用号。二者的代码都在arch/i386/kernel/sys_i386.c中。
二者的区别仅在与传递参数的方式,它们的主体都是do_mmap2()函数,同在arch/i386/kernel/sys_i386.c中。

一般而言,系统调用mmap()将已打开的文件映射都用户空间。但是有个例外,那就是可以在调用参数flags中把标志位MAP_ANONYMOUS设成1,表示没有文件,实际上只是用来在指定的位置上分配空间。(“圈地”)
除此之外,剩下的主体就是do_mmap_pgoff()

内核中还有一个inline函数do_mmap(),是供内核自己用的,在include/linux/mm.h中定义的。它也是将已打开的文件映射到当前用户空间。在系统调用sys_execve()代码中,将通过do_mmap()将可执行程序映射到当前进程的用户空间,此外do_mmap()还用来创建进程间通信手段的“共享内存区”。这个函数同样是通过do_mmap_pgoff()完成操作。

do_mmap_pgoff()在mm/mmap.c中:
get_unmapped_area()在当前进程的用户空间中分配一个起始地址。
kmem_cache_alloc()为待映射的区间分配一个vm_area_struct数据结构。属性不同的区间段不能共存于一个逻辑区间中,由于映射到特定的文件也是一种属性,所以总要为之单独建立一个逻辑区间。
do_munmap()检查目的地址在当前进程的虚存空间是否已经在使用。在前面的get_unmapped_area()中,如果flags中的MAP_FIXED被设1,则直接返回,并未对此加以检查。


内核中常常可以看到先分配某项资源,然后检查条件,如果条件不符再释放资源(而不是先检查条件再分配资源)的情况。关键在于分配资源的过程中是否有可能发生调度,以及其他进程或线程的运行有否可能改变这些条件。


每种文件系统都有个一file_operations数据结构,其中的函数指针mmap提供了用来建立从该类文件到虚存区间的映射的操作。对于Linux的Ext2文件系统,在fs/ext2/file.c中:
struct file_operations ext2_file_operations = {
... ...
 mmap:  generic_file_mmap,
... ...
};
generic_file_mmap()这个函数在mm/filemap.c中,

Ext2文件系统的address_space_operations数据结构在fs/ext2/inode.c中:
struct address_space_operations ext2_aops = {
 readpage: ext2_readpage,
 writepage: ext2_writepage,
 sync_page: block_sync_page,
 prepare_write: ext2_prepare_write,
 commit_write: generic_commit_write,
 bmap: ext2_bmap
};

 

由于计算机技术中一个称为lazy computation的概念,就是说将有些为将来作某种准备而进行的操作可能并无必要,应该推迟到真正需要是才进行。
1。当一个区间中的一个页面首次受到访问,会由于页面无映射而发生页面异常,相应的异常处理程序为
do_no_page(),对于Ext2文件系统,do_no_page()会通过ext2_readpage()分配到一个空闲内存页面并从文件读入相应的页面,然后建立映射。
2。当页面因为写操作也变脏时,由内科线程bdflush()周期型运行通过page_lander()间接调用ext2_writepage()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值