- 1、本文档共24页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Virtual Memory Areas 与进程地址空间相关的数据结构 mm_struct * 触发进程空间的内存动态分配的操作 进程创建:fork,execv,clone 扩充/紧缩堆内存:brk, sbrk 创建文件内存映射或匿名映射:mmap, mremap, munmap 创建进程间共享内存:shmat, shmdt 当用户堆栈不够用的时候,需要扩展堆栈 上述操作都可能引起线性区数据结构的创建和删除。 * 如何实现进程地址空间动态内存分配 查找进程虚拟地址空间是否存在大小合适的空闲区域。 如果有,则创建相应的线性区描述符vm_area_struct,并将其插入链表mmap 线性区创建成功后,立即返回(注意,没有分配相应的物理页框,也没有修改页表!) 当用户程序访问刚刚动态分配的内存时,会触发缺页异常。 在缺页异常的中断服务程序中按“一次一页”的方式分配物理页框,并修改页表。 * Linux OS analysis */24 增加或删除一个线性区 处理线性区的函数 内核进程需要对一个线性区进行处理,比如确定一个给定线性地址是否存在于一个线性地址空间中 find_vma(),查找一个线性地址所属的线性区 两个参数:进程内存描述符的地址mm和线性地址addr find_vma_intersection(),查找一个与给定地址区间重叠的线性区 get_unmapped_area(),查找一个空闲的地址区间 insert_vm_struct(),向内存描述符链表中插入一个线性区 split_vma(),拆分线性区 创建一个线性区间 mmap()和do_mmap(),创建一个线性区 根据file参数映射指定的文件中偏移量为offset,长度为len的一段内容 addr参数指明从何处开始查找一段可用的空闲线性地址区间 Prot参数指定这个区间所包含的页的存取权限 flags参数指定这个创建的线性区本身的一些标志 static inline unsigned long do_mmap (struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flag, unsigned long offset) include/linux/mm.h 删除一个线性区间 munmap()和do_munmap() do_munmap()函数从进程地址空间中删除一段线性空间 mm参数指向了当前进程的内存描述符 addr参数为线性区的起始地址 len参数指明要删除的区间大小 int do_munmap (struct mm_struct *mm, unsigned long addr, size_t len) mm/mmap.c * mmap内存映射 利用mmap函数可以将一个磁盘文件或者其它设备对象映射到虚拟内存空间。文件被映射到多个页上,所有页的大小之和大于等于文件大小。 * mmap内存映射 void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset) start:要映射到的虚拟内存区域的起始地址,通常都是用NULL,NULL表示由内核来指定该内存地址 length:要映射的内存区域的大小 prot:期望的内存保护标志,是以下的某个值,可以通过or运算符组合到一起 1. PROT_EXEC 可执行;2. PROT_READ可读;3. PROT_WRITE可执 flags:指定映射对象的类型,映射选项和映射页是否可以共享。 MAP_SHARED /MAP_PRIVATE/MAP_LOCKED/ MAP_ANONYMOUS fd:文件描述符(由open函数返回) offset:表示被映射对象(即文件)从那里开始对映,通常都是用0。 该值应该为大小应为PAGE_SIZE的整数倍 返回值:成功则返回被映射虚拟内存区的指针,失败返回-1。 * mmap内存映射 int?munmap(void?*start,?size_t?length) 取消映射关系? int?msync(const?void?*start,?size_t?length,?int?flags) 将内存中的内容同步到文件? 思考: mmap函数执行时会一次性将整个被映射文件读入内存吗? 即用mmap函数映射一个大文件时会很耗时吗? * mmap的应用 快速读写大文件,简化程序逻辑。 快速读写I/O设备(如V4L库) 创建进程间共享内存(可利用/dev/zero文件) 在用户态的应用程序中
文档评论(0)