虚拟内存,虚拟地址空间,用户空间,内核空间

虚拟内存,就是用磁盘作为介质,暂时性存储数据,和主存进行换入换出,使程序能够使用更多的内存。虚拟内存是单位是页,固定大小的数据方便数据的交换。如果一个应用程序要访问某段内存,通过MMU得到相应的页号,然后就去主存中去寻找相应的页,如果该页被换到了磁盘上,就会发生一个缺页,然后内核就会从磁盘上将需要的页换入主存,然后进行访问。还有一个问题就是内核空间和用户空间的数据交换,由于用户空间的数据是可以换入到磁盘上的,而内核数据永远是放在主存上的,所以如果内核访问用户数据时可能该地址的数据并不在主存中,所以要使用copytousr和copyfromusr这种机制来完成处理。

虚拟地址空间,空间个人理解就是一组地址的集合。LINUX的应用程序在编译后就拥有4G大小的地址空间,这4G大小的内存通过页机制映射到4G大小的物理地址,页是该机制的最小单位。至于虚拟地址映射到哪一块物理内存,这是由硬件决定的,采用一套不同的页目录,页表就能够做到虚拟地址相同但对应的物理地址不同。这就是操作系统能够做到多个应用程序同时运行但是数据之间不会相互干扰的原因,每个进程的页表信息都存放在PCB结构里,当要运行该进程时,将页表信息交给cpu就能够做到转换。

用户空间就是4G虚拟地址空间中的低3G的虚拟地址空间,是cpu用户态享有的,用户空间对应的页是可以在主存和磁盘之间进行交换的。

内核空间就是4G虚拟地址空间中的高1G的虚拟地址空间,是cpu内核态享有的,该空间对应的物理地址永远是位于主存当中的,不会被换到磁盘上。

个人觉得还有一个很重要的问题就是用户空间和内核空间的到物理内存的映射是不同的。

首先用户空间是通过页表进行映射到物理地址,而内核空间是通过线性一一映射到物理地址,即用虚拟地址减去一个偏移量0xc0000000。

用户态最多只能访问3G的内存,而内核态能访问所有的物理内存,这里若内核空间的映射是按照这种线性映射的话,显然内核态是不能够访问大于1G的内存的,所以这里就引入了高端内存的概念,简单的介绍一下就是将内核虚拟地址空间中开辟一段地址,然后将物理地址高于1G的地址中的某一段映射到我们开辟的虚拟地址上,然后就能够实现访问大于1G的内存了。

内核态下分配内存的函数kmalloc,传递给函数不同的标志来通知函数分配哪一部分的内存,kmallocGFP__KERNEL就是分配和物理内存一一映射的部分的内存

posted @ 2013-07-22 10:26  ideawu  阅读(2193)  评论(0编辑  收藏  举报