两个进程中的两个相同的虚拟地址如何映射到不同的物理地址?

时间:2016-09-25 15:56:13

标签: linux

例如使用以下C代码

#include <stdio.h>
int main() {
    unsigned long temp = 0x12345678;
    printf("temp address is %p\n", &temp);
    int* func_addr = (int*)main;
    printf("main address is %p\n", func_addr);
    int i;
    // suspend process
    scanf("%d", &i);
    return 0;
}

在我的机器上编译代码()并在两个终端和两个过程输出中运行程序:

流程1:

临时地址是0xbfcc5350

主地址是0x80484bb

流程2:

临时地址是0xbf94e5d0

主地址是0x80484bb

我的问题基于图Linear Address

  1. main的虚拟地址在两个进程中是相同的,我们知道 根据地址,该虚拟地址等于线性地址 从线性地址和物理地址转换,两个相同 虚拟地址应映射到两个相同的物理 地址,但实际上两个主要的物理地址是不同的, 映射过程如何?
  2. 两个进程中的temp地址基于页面,它们的PGD part(高10位)是相同的(0x2ff),这意味着两个进程 有相同的Page Table Entry?
  3. 我的操作系统是Ubuntu 16.04.1 LTS,32位。

2 个答案:

答案 0 :(得分:0)

在您的示例中,两个main()物理地址实际上可能相同。因为只读代码段可能会在进程之间共享。但这并不意味着这些进程共享页表。数据部分是可写的,因此每个进程必须有自己的副本,由它自己的页表映射。为什么两个主要有相同的VA?可能是为了避免使用重定位修补代码,因此可以共享它。

答案 1 :(得分:0)

每个进程都有自己的PGD,当它运行时,CR3寄存器存储PGD的物理地址。此外,PAE是启用的,CR3寄存器存储PDPT的物理地址。