谁分配进程地址

问题描述

我知道计算机中的每个进程都有一个地址空间,其中包含进程所有指令的地址。我也知道这个地址是一个虚拟地址 - 这意味着它映射到物理 RAM 地址,并且实际上并不存在。

一个进程要执行时,cpu将它需要的指令(我猜是页?)的虚拟地址发送给MMU,然后MMU可以提供它在RAM中的物理地址,这就是cpu 获取以执行指令。

我不明白的是,首先是谁将虚拟地址分配给了进程——cpu 是如何知道虚拟地址的?我知道这些虚拟地址是通用的(我读过:Difference between logical addresses,and physical addresses?,这在这方面非常有帮助),但我不知道是谁分配的。页表存储在哪里,为什么需要交换空间?

这几天我一直在尝试了解内存映射,主要是通过 YouTube 视频,但如果有人知道任何好的来源,我将不胜感激!

解决方法

在使用虚拟地址的旧时代,您有一个固定的布局:开头的一些数据、程序、程序数据、库,而不是堆栈。有时内核保留了最后一个字节。注意:有时具有不同的布局,但通常在相同的操作系统/版本上具有相同的结构。我们还可以预链接库,因此您可以快速加载。虚拟地址允许这样做。

现在是内核对地址进行随机化处理(以降低缓冲区溢出攻击的成功率)。所以你可能在随机的地方有库和程序。不是MMU,内核随机选择虚拟地址。

现在你有了虚拟地址。现在内核应该将它分配给某些东西。如果您克隆,虚拟地址指向父进程,或者当您执行程序时,您的虚拟地址指向磁盘(二进制文件所在的位置),并且一些(其余的,可能还有一些守卫)只是未分配,因此程序会出现segmentation fault(确实是CPU的保护异常)。这个“物理指针”可能会改变。因为交换物理地址可能会改变,或者指针可能指向磁盘的不同部分,但你也可能指向旧进程内存,然后指向你修改的内存,或者指向磁盘的不同部分。

所以虚拟地址是由内核定义的,内核会处理它(要么有物理地址,要么有异常,哪个内核可能会检查不同的源[其他进程内存,磁盘])。如果页面(虚拟地址块)链接了一个物理地址,则是 MMU 执行工作(并更新页面的访问计数),否则它是内核(而且速度要慢得多)。