2016-09-25 608 views
1

例如用下面的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. 主要的虚拟地址在两个进程是相同的,我们知道 虚拟地址等于线性地址,根据地址 翻译自线性地址和物理地址,两个相同的 虚拟地址应映射到两个相同的物理 地址,但实际上两个主要的物理地址是不同的, 如何映射过程?
  2. 临时地址在两个过程中是基于页面的,它们的PGD 部分(高10位)是相同的(0x2ff),这意味着两个过程 具有相同的页表项?

我的操作系统是Ubuntu 16.04.1 LTS,32bit。

+0

对于每个过程,CR3是不同的。 – ninjalj

+0

另请参阅:http://stackoverflow.com/questions/4022127/how-the-share-library-be-shared-by-different-processes – ninjalj

+0

@ninjalj是正确的,每个进程都有它的PGD,它在[kernel .org](https://www.kernel.org/doc/gorman/html/understand/understand006.html) –

回答

0

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

0

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

+0

实际上两个主要()物理地址是不同的,他们的虚拟地址是相同的,但被映射到不同的物理地址。 –