虚拟内存的作用:
1.
扩展实际有限的物理内存,当然这种扩展是虚拟的,比如物理内存512M,对于一个需要1G空间的进程来说,照样可以运行。这增加了操作系统是应用范围。
2.
使得进程中的数据空间增大,增大到多少与硬件有关,对于一个32位的芯片,进程中的数据空间可以为4G[2^32],对于64位的芯片则支持2^64大小
的空间。这一点使得进程自身可操作的空间大大增加。
通俗来讲,虚拟内存的管理的核心是解决如何在小的物理内存中运行更大程序的问题。
在Linux中,解决这个问题的关键是一个叫做page
table[PT页面转换表]的结构。Linux把物理内存分为了固定统一大小的块,称为page[页],一般为4KB,并且每个页都有一个编号
[page frame
number]。这样一个512M大小的内存将包括128K个页。这种方式称为paging,使得操作系统对内存的管理更方便。page
table的作用就是将进程操作的地址[虚拟地址]转换成物理地址。
其原理很简单,如下:
用一个32位芯片的系统为例[64位同理],运行的每个进程的可操作数据空间为2^32,即2^20个页,设其物理内存为512M,则物理页有
2^17个,现在就说明如何将2^20个页放入2^17个页中运行。我们把进程操作的地址分为两部分,第一部分为地址的高20位,第二部分为后12位,这
样很容易将第一部分理解为虚拟页标号,第二部分理解为在页中的offset。那么现在我们只需将虚拟页标号对应到物理页号即可,这个对应就是page
table的工作,在这个例子中page
table包括了2^20个记录,每个记录有两部分组成:20位的虚拟标号和17位的物理标号,这样CPU用进程地址的第一部分作为索引找到对应的17位
物理标号,与地址的第二部分一起便组成一个29位的地址,这个地址就是要找的物理地址。因为物理页少于虚拟页,所以page
table中的有些记录的后17位是空的或无效的。
利用这个方法,使得运行的进程无需知道自己操作的地址是虚拟的,和运行在一个真实的大物理内存中效果是一样的。
可以看出,在进程的运行过程中,page table必须一直保存在内存中,在上面的例子中,我们把虚拟地址分了2层,page
table有2^20个记录,需要1M左右的空间,为了节省空间我们可以将地址分为3层,第一层10位,需要1K左右的空间,第二层10位,需要1K左右
的空间,第三层12位,这样在一段时间内只需要2K的空间保存page
table。实际上,Alpha的芯片采用的就是这种3层的分法,Intel的芯片采用的2层的分法。
Figure: Three Level Page Tables
Linux assumes that there are three levels of page tables.
Each Page Table contains the page frame number of the next level of Page Table. The
Figure above shows how a virtual address can
be broken into a number of fields; each field providing an offset into a
particular Page Table.
To translate a virtual address into a physical one, the processor must take the
contents of each level field, convert it into an offset into the physical
page containing the Page Table and read the page frame number of the next level of Page
Table.
This is repeated three times until the page frame number of the physical page
containing the virtual address is found.
Now the final field in the virtual address, the byte offset, is used to
find the data inside the page.
Each platform that Linux runs on must provide translation macros that allow
the kernel to traverse the page tables for a particular process.
This way, the kernel does not need to know the format of the page table entries or
how they are arranged.
This is so successful that Linux uses the same page table manipulation code for
the Alpha processor, which has three levels of page tables, and for Intel x86 processors,
which have two levels of page tables.