vmalloc.c1.功能与原理:slab分配器分配内存,用这些方法得到的内存在物理地址上都是连续的,然而,有些时候,每次请求内存时,系统都分配物理地址连续的内存块是不合适的,可以利用小块内存“连接”成大块可使用的内存.这在操作系统设计中也被称为“内存拼接”,显然,内存拼接在需要较大内存,而内存访问相比之下不是很频繁的情况下是比较有效的.在linux内核中用来管理内存拼接的接口是vmalloc/vfree.用vmalloc分配得到的内存在线性地址是平滑的,但是物理地址上是非连续的.2.主要函数,功能及流程图:(1)__vmalloc()函数【1】函数功能:分配虚拟内存连续的页面【2】流程图:(2)get_vm_area()函数【1】函数功能:该函数负责分配一个合适的vm结构并将其链入到vmlist中【2】流程图:(3)vfree()函数【1】函数功能:从vmlist中释放vm使其的空间可用。【2】流程图:(4)vmalloc_area_pages()函数【1】函数功能:该函数实际建立起了非连续内存区到物理页面的映射,即分配一个个单独的页,并把这些单独的页放到相应的页目录项中【2】流程图:(5)free_area_pte()函数【1】函数功能:释放页表中的表项pte分配所有页框(6)free_area_pmd()函数【1】函数功能:释放页中间目录(pmd映射)(7)alloc_area_pte()函数【1】函数功能:为页表中的表项pte分配所有页框(页表页建立映射)(8)alloc_area_pmd()函数【1】函数功能:创建页中间目录映射(9)vmfree_area_pages()函数【1】函数功能:用来断开vm所在线性地址所对应的映射关系(10)vread(),vwrite()函数【1】函数功能:读写调换页面3.函数之间内部关系vfree、vmfree_area_pages、free_area_pte、free_area_pmd之间的关系流程图:vmalloc_area_pages()、alloc_area_pmd()、alloc_area_pte()之间的关系流程图:memory.c1.功能与原理:提供了对虚拟内存操作的若干函数,其中包括对虚拟页的复制、新建页表、清除页表、处理缺页中断等等。2.主要函数、功能及流程图:(1)copy_cow_page()函数【1】函数功能:提供复制页面数据功能的函数(2)__free_pte()函数【1】函数功能:提供将页面数据释放功能的函数(3)free_one_pgd()函数、free_one_pmd()函数、free_pte()函数【1】函数功能:释放虚拟中内存所对应的页映射关系【2】流程图:(4)check_pgt_cache()函数【1】函数功能:清理页表的缓存(5)clear_page_tables()函数【1】函数功能:释放一个进程指定范围内的页表,以及关联的pmd,对应的pgdentry被清空,pgd本身没有被释放.至于页表中是否还有未断开影射的物理页面,此函数未做检查【2】流程图:(6)copy_page_range()函数【1】函数功能:该函数的主要功能是将某个任务或进程的vma块复制给另一个任务或进程。其工作机制是循环调用copy_pmd_range将vma块中的所有虚拟空间复制到对应的虚拟空间中。在做复制之前必须确保新任务对应的被复制的虚拟空间中必须都为零。copy_page_range按dup_mmap()-copy_mm()-do_fork()的顺序被调用以上三个函数均kernel/fork.c中。当进程被创建的时候需要从父进程处复制所有的虚拟空间copy_page_range完成的就是这个任务。【2】流程图:(7)forget_pte()函数【1】函数功能:判断页面是否为空。(8)zap_pte_range()函数【1】函数功能:该函数的作用是将在pmd中从虚拟地址address开始长度为size的内存块通过循环调用pte_clear将其页表项清零调用free_pte将所含空间中的物理内存或交换空间中的虚存页释放掉。(9)zap_pmd_range()函数【1】函数功能:函数结构与zap_pte_range类似通过调用zap_pte_range完成对所有落在address到address+size区间中的所有pte的清零工作。zap_pmd_range至多清除4M空间的物理内存。(10)zap_page_range()函数【1】函数功能:清除指定范围的用户页面函数结构与前两个函数类似。将任务从address开始到address+size长度内的所有对应的pmd都清零。zap_page_range的主要功能是在进行内存收缩、释放内存、退出虚存映射或移动页表的过程中将不在使用的物理内存从进程的三级页表中清除。在讨论clear_page_tables时就提到过当进程退出时释放页表之前先保证将页表对应项清零保证在处于退出状态时进程不占用0~3G的空间。【2】流程图:(11)follow_page()函数【1】函数功能:在页表中快速查找一个页面(12)get_page_map()函数【1】函数功能:如果页面有效该函数就返回指定物理页面的地址否则返回0(13)get_user_pages()函数【1】函数功能:取得用户页面(14)map_user_kiobuf()函数【1】函数功能:从内核读取数据直接映射到用户空间【2】流程图:(15)mark_dirty_kiobuf()函数【1】函数功能:把所有的在kiobuf中的页面都置为“脏”(16)unmap_kiobuf()函数【1】函数功能:撤销映射(17)lock_kiovec()函数【1】函数功能:该函数试图锁住kiovec中的每一个页面但若其中的某一个页面不能被锁住操作就失败(18)unlock_kiovec()函数【1】函数功能:释放内存中的kiovec(19)zeromap_pte_range()函数、zeromap_pmd_range()函数、zeromap_page_range()函数【1】函数功能:zeromap_pte_range、zeromap_pmd_range、zeromap_page_range这三个函数与前面的三个函数从结构上看很相似,他们的功能是将虚拟空间中从地址address开始长度为size的内存块所对应的物理内存都释放掉,同时将指向这些区域的pte都指向系统中专门开出的长度为4K全为0的物理页。zeromap_page_range在kernel代码中没有被引用这个函数是旧版本的Linux遗留下来的,在新版本中已经被zap_page_range所替代。【2】流程图:(20)remap_pte_range()函数【1】函数功能:在remap_pte_range中通过set_pte将物理页映射到新的虚拟内存页表项pte上