CSAPP–第九章–虚拟内存(中)

Aki 发布于 2023-01-24 233 次阅读


虚拟内存作为存储管理的工具、

一个非常关键的思想是,每个进程都有自己专属的独立的虚拟地址空间,内核通过为每个进程提供自己独立的页表来实现这一点,在进程的上下文中,它是内核中的数据结构,是内核为进程所维护的。

OS为每个进程提供一个独立的页表,就是一个独立的虚拟地址空间。多个虚拟页面可以映射到同一个共享物理页面上。

程序员可以认为每一个进程都有非常相似的虚拟地址空间,有相同的地址空间,代码和数据分别从同一个地址开始,但起始进程使用的页面实际上可能分布在内存中,这为我们提供了非常好的内存使用机制。

VM简化了链接和加载、代码和数据共享,以及应用程序的存储器分配。

简化链接:

独立的地址空间允许每个进程为它的存储器映像使用相同的格式,而不需要管 代码和数据 存放在物理存储器的何处。

  这样大大简化了链接器的设计和实现,允许链接器生成全链接的可执行文件,这些可执行文件是独立于物理存储器中代码和数据的最终位置。

链接器现在可以假设每个程序都加载到完全相同的位置,所以链接器能提前知道程序要加载到哪里。

简化加载:虚拟内存使得容易向内存中加载可执行文件和共享对象文件。

简化共享:

独立地址空间为OS提供了一个管理用户进程和操作系统自身之间共享的机制。一般而言,每个进程都有自己私有的代码、数据、堆以及栈区域,是不与其他进程共享的。当要共享时,操作系统将不同进程中的虚拟页映射到相同的物理页面,从而多个进程共享这部分的代码。

简化内存分配:虚拟内存向用户进程提供一个简单的分配额外内存的机制。当一个用户程序要求额外的堆空间时候,操作系统分配 k 个适当的连续的虚拟内存页面,并且将他们映射到物理内存的中的 k 个任意页面,操作系统没有必要分配 k 个连续的物理内存页面。

虚拟内存作为存储器保护的工具、

虚拟地址空间的有些部分是只读的,比如代码段;有些部分只能由内核执行。在64位系统上,指针和地址也是64位的,但实际上,真正的虚拟地址空间是48位的,48位之后的高比特位全部为0或者全部为1,这是英特尔的规则,高位都是1的地址是为内核(内核代码,内核数据)保留的,高位都是0的地址是为用户代码保留的。

因此,可以在PTE中设置一些位,表明用户代码是否可以访问某些虚拟页面,或者他们是否必须由内核访问,这就是所谓的管理员模式。

你还可以设置一些位,表明该页面是否可以读、写、执行。通过向PTE添加位的简单技术,我们提供了这种自动的方式来保护虚拟地址空间的不同部分面授未经授权的访问。MMU在每次访问时检查这些位,如果进行非法操作,那么它就会抛出一个异常,由内核来处理。