2016-09-25 609 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

實際上兩個主要()物理地址是不同的,他們的虛擬地址是相同的,但被映射到不同的物理地址。 –