虚拟内存结构描述_第1页
虚拟内存结构描述_第2页
虚拟内存结构描述_第3页
虚拟内存结构描述_第4页
虚拟内存结构描述_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、操作系统结构虚拟内存管理结构描述李 煜摘要:本文。本文通过介绍虚拟内存的概念,主要数据结构,Linux虚拟内存重建和拷贝等过程进行了详细的介绍和总结概括。首先介绍了Linux虚拟内存主要的数据结构如虚拟内存区域vm_area_struct,虚拟内存管理mm_struct等。然后对Linux虚拟内存重建和拷贝的过程进行了详细的介绍。目地是为了让读者了解Linux虚拟内存的重建过程,虚拟内存的拷贝以及重要数据结构有一个初步的了解。关 键 词:虚拟内存;Linux;数据结构1 引言我们知道程序代码和数据必须驻留在内存中才能得以运行,然而系统内存数量很有限,往往不能容纳一个完整程序的所有代码和数据,更

2、何况在多任务系统中,可能需要同时打开子处理程序,画图程序,浏览器等很多任务,想让内存驻留所有这些程序显然不太可能。因此首先能想到的就是将程序分割成小份,只让当前系统运行它所有需要的那部分留在内存,其它部分都留在硬盘。当系统处理完当前任务片段后,再从外存中调入下一个待运行的任务片段。的确,老式系统就是这样处理大任务的,而且这个工作是由程序员自行完成。但是随着程序语言越来越高级,程序员对系统体系的依赖程度降低了,很少有程序员能非常清楚的驾驭系统体系,因此放手让程序员负责将程序片段化和按需调入轻则降低效率,重则使得机器崩溃。系统必须采取一种能按需分配而不需要程序员干预的新技术。 虚拟内存(

3、之所以称为虚拟内存,是和系统中的逻辑内存和物理内存相对而言的,逻辑内存是站在进程角度看到的内存,因此是程序员关心的内容。而物理内存是站在处理器角度看到的内存,由操作系统负责管理。虚拟内存可以说是映射到这两种不同视角内存的一个技术手段。)技术就是一种由操作系统接管的按需动态内存分配的方法,它允许程序不知不觉中使用大于实际物理空间大小的存储空间(其实是将程序需要的存储空间以页的形式分散存储在物理内存和磁盘上),所以说虚拟内存彻底解放了程序员,从此程序员不用过分关心程序的大小和载入,可以自由编写程序了,繁琐的事情都交给操作系统去做吧。  2 虚拟内存的概念极其优缺点2.1 虚拟内存的概念在

4、分页系统中,由于在程序地址空间和物理地址空间引入了页表,隔离了两个地址空间,一个程序可以在物理内存中不连续。操作系统负责在内外存之间交换页面,造成每个进程都认为自己是系统中唯一一个程序,独占系统全部地址空间的假象。虚拟地址是一块地址空间,它的特点主要是:(1)从0开始编址并且连续(2)不受系统物理内存大小限制(3)在功能上等价于物理内存,但实际上并不存在(4)虚拟地址空间是相互隔离的2.2 虚拟内存的优缺点在分页系统中,由Linux虚拟内存的优点主要有以下几个:(1)大地址空间:运行在I386平台的每个Linux进程,都可以使用4GB的地址空间。(2)进程保护:系统的每一个进程都有自己的虚拟地

5、址空间,不同进程的虚拟空间所对应的物理地址是完全隔离的。(3)内存映射:利用内存映射可以将数据文件映射到虚拟地址空间,从而使得对文件的访问和对内存单元的访问一样。(4)虚存共享:多个进程的虚拟地址映射到同一个物理地址空间,则可以在不同的进程之间实现虚存共享。(5)多程序同时驻留内存:由于进程只有一部分驻留在内存,因此内存中可以驻留多个进程,提高cpu效率。(6)允许运行重定位程序:程序可以放在物理内存的任意位置,并且在执行过程中也可以移动。(7)代价小:换入换出单个页面的代价比交换这个进程小。但是,虚拟内存也是有代价的,虚拟内存管理需要建立很多的数据结构,它们要占额外的内存;虚拟地址到物理地址

6、的转化增加了每条指令的执行时间;页面的换入换出也增加了磁盘的I/O操作。3 虚拟内存管理结构3.1 虚拟内存管理实现思路在分页系统中,由Linux虚拟内存的优点主要有以下几个:(1)大地址空间:运行在I386平台的每个Linux进程,都可以使用4虚拟内个管理的基本思路是虚拟或者制造假象,它使得每个进程都认为系统中有足够大的内存并且内存中只有自己一个进程,实现的基本思路是如下,具体如图1所示:(1)将系统的物理地址和进程的虚拟地址分成固定大小的页,为每个进程重建一个页表,从而实现两个地址空间的隔离。(2)由虚拟内存管理器管理和维护进程的页表,建立虚拟内存页和物理页的对应关系,利用硬件实现地址的转

7、换。(3)由内存管理器负责内外存之间的页面交换,将进程使用的虚拟页面换入物理内存,不用的换出内存,提高物理内存的使用率,造成几乎无限大小的虚拟内存的假象。图1. Linux虚拟内存管理器的实现思路3.2 页表的介绍在分页系页表是虚拟内存管理中最基础的数据结构,在Intel的32位处理器中分为两级,分别称为页目录和页表。其特点主要有:(1)页目录和页表只能由虚拟内存管理,对进程是透明的。(2)虚拟页在内存时,页表项记录这对应关系,虚拟页不在内存时,虚拟项记录这页面在外存的位置。(3)页表项和页表都是动态重建和动态删除的。(4)虚拟页和物理页的映射关系不要求连续,也不要求有序,多个虚拟页可以对应一

8、个物理页。它的每一个元素称为一个页表项(PTE),在Intel系统上,页表项长度为32位,4个字节,包含以下信息:(1) 有效标志:表示页表本项是否有效(2)映射关系:本页表项所对应的物理页编号(3)访问控制信息:描述本页是否可写?是否包含执行代码。3.3 虚拟内存区域的代码实现的每个进程都有自己的页目录和页表,通过页目录和页表,每个进程有拥有4GB的虚拟地址空间。进程的所有信息比如代码、数据、堆栈、共享区等。Linux使用结构vm_area_struct(vma)结构来描述一个虚拟内存区域,其定义如下,具体如图2所示:struct vm_area_struct struct mm_struc

9、t * vm_mm; /* 指向虚拟区所在的mm_struct结构的指针*/ unsigned long vm_start; /* 在vm_mm中的起始地址*/ unsigned long vm_end; /*在vm_mm中的结束地址 */ struct vm_area_struct *vm_next; pgprot_t vm_page_prot; /* 对这个虚拟区间的存取保护权限(只读、只写、执行) */ unsigned long vm_flags; /* 虚拟区间的标志.(读、写、共享) */ struct rb_node_t vm_rb; struct vm_area_struct

10、*vm_next_share;struct vm_area_struct *vm_pprev_share;struct vm_operations_struct * vm_ops; /*对这个区间进行操作的函数 */ unsigned long vm_pgoff; /*映射文件中的偏移量 */struct file * vm_file; /*指向映射文件的文件对象 */unsigned long vm_raend; /* 预读信息 */void * vm_private_data; /* 指向内存区的私有数据 */.图2. Linux虚拟内存管理器的实现思路linux利用了面向对象的思想,把一

11、个虚存区看成一个对象,用vm_area_struct(vma)描述对象属性,其中的vm_operation描述了对象的操作,定义如下:struct vm_operations_struct void (*open)(struct vm_area_struct * area); void (*close)(struct vm_area_struct * area); struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused); void (*unmap)(struct vm_ar

12、ea_struct * area,unsigned long,size_t) int(*swapout)(struct vm_area_struct * area,struct page*); pte_t(*swapin)(struct vm_area_struct * area,unsigned long,unsigned long);3.4 虚拟内存区域虚拟内存管理器还需要一个地方来记录进程中与内存有关的信息,如进程页目录的位置,进程的代码、数据、堆栈等在虚拟空间的位置进程驻留在物理内存中的页面的个数,为此,Linux为每个进程重建了一个内存管理结构mm_struct,来管理进程中与虚拟内

13、存相关的信息。该结构定义如下:struct mm_struct struct vm_area_struct * mmap; /*指向虚拟区间(VMA)链表头 */ b_root_t mm_rb; *指向红黑树的根*/struct vm_area_struct * mmap_cache; /*指向最近找到的虚拟区间*/ pgd_t * pgd; *进程页目录基地址*/atomic_t mm_users; /*用户空间中的有多少用户*/ atomic_t mm_count; /*对"struct mm_struct"引用的计数*/ int map_count; /*虚拟区间的个

14、数*/ struct rw_semaphore mmap_sem;/*线性区的读写信号量*/spinlock_t page_table_lock; /*线性区的自旋锁和页表的自旋锁 */ struct list_head mmlist; /*所有活动(active)mm的链表 */unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack; /* 堆的相关信息*/ unsigned long arg_start, arg_end, env_start, e

15、nv_end; unsigned long rss, total_vm, locked_vm; unsigned long def_flags;/* 线性区默认的访问标志*/进程的task_struct结构中包含一个mm域,指向mm_struct。进程的mm_struct包含进程的可执行映像信息和进程页目录指针PGD等。该结构还包含指向vm_area_struct结构的指针,每一个vm_area_struct代表进程一个虚拟地址空间,如图3所示:图3. 相关数据结构之间的关系3.5 虚拟内存区域在进程的生命周期中,它的虚拟地址空间会不断变化,过程如下:(1)在进程重建时,从父进程拷贝虚拟地址空

16、间。在拷贝的过程中,系统根据父进程虚拟地址空间的定义,复制一套内存管理结构(mm_struct,vm_area_struct,页目录,页表)。(2)在进程需要装入自己的执行映像时,系统将先废弃进程当前的虚拟地址空间,而后再根据执行映像的定义重建新的内存管理系统。(3)在进程执行过程中,会不断的发生缺页异常,异常处理程序会不断的修改页目录和页表项。(4)在物理内存紧张,需要回收内存时,物理内存回收程序会将进程的某些暂时不用的页从内存中换出。一个虚拟页如何被换出有它所在的虚拟内存区域决定的。(5)在进程执行过程中,进程的虚拟页会不断的换进换出,系统只在内存中为每个进程保留它最需要的页。这样,系统就

17、用有限的物理内存为每个进程模拟出4GB的虚拟地址空间。(6)在进程结束时,系统会释放它的所有的内存管理的数据结构,同时释放它在内存中所有的页,从而释放它的所有虚拟地址空间。3.6 映射关系在早期的系统中,Linux仅用了mm_struct、vm_area_struct、页目录和页表描述进程的虚拟空间,这些数据定义了一种正映射关系。然而在某些时候比如物理页回收,还需要逆向映射关系,以便能方便的使用一个物理页或者是文件页的所有进程及该页在进程中对应的虚拟页,为此,新的linux版本引进了逆向映射关系。3.6.1 文件页到虚拟页的逆映射关系(1)如果虚拟页的内容来源于文件且该文件的文件区间仅仅被映射

18、到一个进程的虚拟内存空间里面,则虚拟内存建立的就是文件页与虚拟页的一一对应的关系。(2)如果某文件页的文件区间被同时映射到多个进程的虚拟地址空间中,那么,那么每个进程都会为包含该页的文件区间建立一个虚拟内存区域,这些内存区域建立的是文件页到虚拟页一对多的映射关系。为了找到一个文件页对应的所有的虚拟页,Linux为每个文件建立了一个文件地址空间address_space。给定一个文件页(页号为pgoff),查它的address_space,可得到包含该页的所有内存区域vma,进而可得出该页在各进程虚拟地址空间的虚拟地址。3.6.2 物理页到虚拟页的逆映射关系一个物理页的内容可能是动态建立的(匿名

19、页),也可能来源于一个文件(映射页)。来源于文件的页可能属于共享区域,也可能属于私有区域。不用来源的物理页需要不同的逆向映射关系。(1)匿名页属于匿名的虚拟内存空间。值得注意的是,共享物理页的多个匿名虚拟内存区域具有相同的属性和大小,也就是说物理页在各区域中的偏移量是相同的。为了便于一个物理页找到所有的虚拟页,Linux做了以下的安排:首先为每一类匿名虚拟内存空间定义一个匿名结构anno_vma,共享同样的物理页、具有相同属性的虚拟内存区域被组织在一个anno_vma结构中(双向链表),然后复制page结构中的三个域,让_mapcount记录映射到该页的虚拟页的个数,mapping指向anon

20、_vma结构、index记录页在虚拟内存区域的页号。给定一个物理页的page结构,查与之关联的anon_vma结构,可找到包含它的所有虚拟内存区域的vma,进而可得出它在各虚拟地址空间中的虚拟地址。(2)共享映射页属于共享区域,其内容来源于文件,可以被多个进程占用,因此会出现在多个进程的页表中。为了便于找到共享页对应的所有虚拟页,Linux复用了page中的三个域,在_mapcount中映射到该物理页的虚拟页的个数, mapping指向文件的地址空间address_space、在index中记录该页在文件中的偏移量。进而可得出该页在各虚拟空间的虚拟地址。(3)私有映射页属于私有区域,其内容来源

21、于文件,可以被多个进程读或者执行,但是只能被一个进程修改。私有类型的虚拟内存区域出现在文件的地址空间中。如果进程未对私有映射页实行写操作,则它使用的是该页的正本。正本的page结构设置与共享映射页相同。获得物理页对应的虚拟页的方式也相同。如果进程对私有页实行了写操作,则它使用的就是该页的副本,通过文件地址空间已经无法确定与副本页对应的虚拟页。linux做了如下处理:首先,将包含副本页的虚拟内存区域同时加入到文件地址空间和匿名域中,然后复用page结构中的三个域,让_mapcount记录映射该页的虚拟页的个数,mapping指向anon_vma结构、index记录页在文件中的页号。给定一个副本页

22、的page结构,查与之相关的anno_vma结构,可以找到包含他所有的虚拟内存区域vma,进而可以得出他在个虚拟地址空间中的虚拟地址。4 虚拟内存的重建和拷贝4.1 虚拟内存的重建进程创建时,通过虚拟内存的拷贝,已经为子进程建立了虚拟内存地址空间。只有当进程希望改变自己的行为时,它可以调用exec函数,根据新的执行映像重建自己的虚拟内存空间。完成执行映像加载的函数是exec,该函数在处理完参数以后,最终会调用函数do_execve,所以真正完成虚拟内存建立工作的函数是do_execve。除了exec以外,Linux还提供了一个系统调用old_mmap,让用户建立自己的内存映射区域,如为打开一个

23、数据文件建立虚拟映射区域。系统调用old_mmap函数直接从用户空间接受参数,该函数定义如下,包含了建立虚拟内存映射需要的所有的信息:asmlinkage int old_mmap(struct mmap_arg_struct *arg)函数old_mmap将参数拷贝到内核,然后调用函数do_mmap建立内存映射区域。do_mmap用于一个虚拟内存区域的建立,其建立的内存映射区域主要有两种:共享区域和私有区域。共享区域的页允许多个进程共享,它在内存中只有一份拷贝,进程可以直接修改共享映射区域的页,当需要将共享映射页从内存中换出时,系统会将修改过的共享映射页直接写回到映射文件。私有区域的页是进程

24、专有的,多进程可以读,但是某进程如果修改的话,系统会为写进程创建一个副本,其操作都是在副本上进行的,当要将私有映射页交换出内存时,系统会将其写到交换设备,而不是映射文件。函数do_mmap定义如下:unsigned long do_mmap(struct*file,unsigned long addr,unsigned long len,unsigned long prot,unsigned long flags,unsigned long off)该函数把文件file中的区域off,off+length)映射到进程虚拟内存的paddr,paddr+length),flags指定了映射类型(共

25、享、私有等),prot指定该内存区域的保护权限(读、写、执行、不可访问等)。如果映射类型指定为MAP_FIXED,则paddr就是addr,否则,paddr是系统根据情况决定的一个虚拟地址(addr是首选)。4.2 虚拟内存的拷贝linux提供了很灵活的进程创建机制,一般分为两种情况:第一种是在进程创建标志中指出了CLONE_VM,则父子进程共用同一个虚拟地址空间,页目录也是公用的。另一种进程的创建使用Copy on Write技术,从父进程拷贝页目录和页表,但将父子进程的页表项都设置为只读,页面的拷贝推迟到写操作进行。为了拷贝虚拟内存空间,需要将父进程的内存结构mm_struct拷贝到子进程

26、,拷贝的内容包括各个内存结构vm_area_struct和每个内存区对应的页目录,页表项,但是不拷贝内容。完成内存拷贝的函数是copy_mm。该函数的工作流程如下所示:(1)如果标志clone_flags中设置了CLONE_VM,则父子进程要共用同样的内存结构mm_struct,只需将父进程内存结构的引用计数加1即可,返回0.(2)否则,要拷贝内存结构:1) 向内存管理器申请一个mm_struct结构:mm=mm_alloc();2) 如果申请成功,则从父进程中拷贝内容:*mm=*current->mm;将该结构的应用计数值记为1;将mm结构的map_count,def_flags,mm

27、ap, mmap_avl,map_cache等区域清空。3)将申请到的mm_struct结构填入进程结构:tsk->mm=mm;4)设置进程结构的参数,如将min_flt,maj_flt,cmin_flt的值为05)为新进程创建段LDT:copy_segment(nr,tsk,mm)6)为新进程创建页目录:new_page_tables(tsk)7)将新页目录的首地址放到新进程TSS段的CR3域和新进程内存结构的页目录域中:SET_PAGE_DIR(tsk,new_page);tsk->mm->pgd=new_pg; 将父进程的所有的虚拟内存区域都拷贝到新进程中:dup_mm

28、ap(mm);函数dup_mmap(mm)的工作流程如下所示:(1)找到父进程的vma链表:mpnt=current->mm->mmap;(2)如果mpnt为空,则跳转到(11)。(3)从内存管理器中申请一个vm_area_srtuct结构tmp。(4)拷贝vm_area_srtuct结构的信息:*tmp=*mpnt(5)调整新vm_area_struct结构的某些域,如vm_flags,vm_mm等。 (6)如果是一个文件映射区域,则将文件结构vm_file的计数加1, 将新vma结构加入文件inode结构的vma中。拷贝页目录、页表项:retval=copy_page_range(mm,current->mm,tmp);(8)如果tmp的操作集合定义有open操作,则执行它:tmp->vm_ops->open(tmp);(9)将tmp加入到内存管理结构mm的vma队列中(10)mpnt=mpnt->vm_next,转(2)。(11)到此为止,所有的内存区域都已经拷贝完毕。如果新进程的内存区域总数大于AVL_MIN_MAP_COUNT,则为其建立

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论