㈠ 操作系統虛擬地址變換物理地址的題,求解
065C / 1024(1K) = x (代表虛擬的頁號)x不來算了0 0
065C mod 1024 = y (頁內偏移量 )
在 根據題目中 0-3 頁號 被分配到的對應物理塊號 (比如 若 x 為頁號0 對應物理塊號 5 ,那麼實際地址就是 4*1K+y )
㈡ 操作系統-物理地址計算
答:邏輯地址0A5C(H)所對應的二進製表示形式是:0000 1010 0101 1100 ,由於1K=2^10,下劃線部分前的編碼為000010,表示該邏輯地址對應的頁號為2。查頁表,得到物理塊號是4(十進制),即物理塊地址為:0001 0010 0000 0000 ,拼接塊內地址0000 0000 0101 1100,得0001 0010 0101 1100,即125C(H)。
㈢ Linux下怎樣在進程中獲取虛擬地址對應的物理地址
Linux文件目錄中的/proc記錄著當前進程的信息,稱其為虛擬文件系統。在/proc下有一個鏈接目錄名為self,這意味著哪一個進程打開了它,self中存儲的信息就是所鏈接進程的。self中有一個名為page_map的文件,專門用來記錄所鏈接進程的物理頁號信息。這樣通過/proc/pid/page_map文件,允許一個用戶態的進程查看到每個虛擬頁映射到的物理頁
/proc/pid/page_map中的每一項都包含了一個64位的值,這個值內容如下所示。每一項的映射方式不同於真正的虛擬地址映射,其文件中遵循獨立的對應關系,即虛擬地址相對於0x0經過的頁面數是對應項在文件中的偏移量
* /proc/pid/pagemap. This file lets a userspace process find out which
physical frame each virtual page is mapped to. It contains one 64-bit
value for each virtual page, containing the following data (from
fs/proc/task_mmu.c, above pagemap_read):
* Bits 0-54 page frame number (PFN) if present//present為1時,bit0-54表示物理頁號
* Bits 0-4 swap type if swapped
* Bits 5-54 swap offset if swapped
* Bit 55 pte is soft-dirty (see Documentation/vm/soft-dirty.txt)
* Bit 56 page exclusively mapped (since 4.2)
* Bits 57-60 zero
* Bit 61 page is file-page or shared-anon (since 3.5)
* Bit 62 page swapped
* Bit 63 page present//如果為1,表示當前物理頁在內存中;為0,表示當前物理頁不在內存中
在計算物理地址時,只需要找到虛擬地址的對應項,再通過對應項中的bit63判斷此物理頁是否在內存中,若在內存中則對應項中的物理頁號加上偏移地址,就能得到物理地址
通過程序獲取物理地址並驗證寫時拷貝技術
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
//計算虛擬地址對應的地址,傳入虛擬地址vaddr,通過paddr傳出物理地址
void mem_addr(unsigned long vaddr, unsigned long *paddr)
{
int pageSize = getpagesize();//調用此函數獲取系統設定的頁面大小
unsigned long v_pageIndex = vaddr / pageSize;//計算此虛擬地址相對於0x0的經過的頁面數
unsigned long v_offset = v_pageIndex * sizeof(uint64_t);//計算在/proc/pid/page_map文件中的偏移量
unsigned long page_offset = vaddr % pageSize;//計算虛擬地址在頁面中的偏移量
uint64_t item = 0;//存儲對應項的值
int fd = open("/proc/self/pagemap", O_RDONLY);。。以只讀方式打開/proc/pid/page_map
if(fd == -1)//判斷是否打開失敗
{
printf("open /proc/self/pagemap error
");
return;
}
if(lseek(fd, v_offset, SEEK_SET) == -1)//將游標移動到相應位置,即對應項的起始地址且判斷是否移動失敗
{
printf("sleek error
");
return;
}
if(read(fd, &item, sizeof(uint64_t)) != sizeof(uint64_t))//讀取對應項的值,並存入item中,且判斷讀取數據位數是否正確
{
printf("read item error
");
return;
}
if((((uint64_t)1 << 63) & item) == 0)//判斷present是否為0
{
printf("page present is 0
");
return ;
}
uint64_t phy_pageIndex = (((uint64_t)1 << 55) - 1) & item;//計算物理頁號,即取item的bit0-54
*paddr = (phy_pageIndex * pageSize) + page_offset;//再加上頁內偏移量就得到了物理地址
}
const int a = 100;//全局常量
int main()
{
int b = 100;//局部變數
static c = 100;//局部靜態變數
const int d = 100;//局部常量
char *str = "Hello World!";
unsigned long phy = 0;//物理地址
char *p = (char*)malloc(100);//動態內存
int pid = fork();//創建子進程
if(pid == 0)
{
//p[0] = '1';//子進程中修改動態內存
mem_addr((unsigned long)&a, &phy);
printf("pid = %d, virtual addr = %x , physical addr = %x
", getpid(), &a, phy);
}
else
{
mem_addr((unsigned long)&a, &phy);
printf("pid = %d, virtual addr = %x , physical addr = %x
", getpid(), &a, phy);
}
sleep(100);
free(p);
waitpid();
return 0;
}
測試結果如下:
全局常量:符合寫時拷貝技術
子進程修改動態內存
*其實想要知道虛擬地址對應的物理地址,通過這樣的方式也可以得到物理地址而不用操作MMU。。。*
以上就是Linux下怎樣在進程中獲取虛擬地址對應的物理地址的全文介紹,希望對您學習和使用linux系統開發有所幫助.
㈣ 分頁,虛擬地址是怎麼轉換成物理地址的
虛擬地址(即圖中的邏輯地址)的高位表示頁號,由計算機硬體將頁號取出,且和頁表寄存器中的頁表始址一起送加法器,就可以得到該頁對應的頁表項的地址,根據此地址到內存讀出對應的塊號,最後將塊號和頁內地址拼接得到對應的物理地址。
㈤ 現代CPU如何自動把虛擬地址轉換成物理地址的硬體電路
虛擬內存是一個由存放在磁碟上的N個連續的位元組大小的單元組成的數組。
每個位元組都有一個唯一的地址,就是虛擬地址。通常,虛擬地址由頁號和偏移量組成,頁號就是抽象的虛擬頁的編號,偏移量用於計算實際的物理地址。
虛擬地址和物理地址的關系。進程雖然使用虛擬地址,但是用數據時還是要到實際的物理地址去取數據。這就存在一個虛擬地址到物理地址的轉化運算,這是由CPU晶元上一個叫做內存管理單元(MMU)的專用硬體來實現的。
通常,物理地址=頁號*頁大小+頁內偏移量。虛擬定址CPU通過虛擬地址來訪問主存,訪問內存使用的物理地址,MMU通過將虛擬地址進行翻譯,轉化為物理地址,然後再用這個物理地址去訪問內存數據。
㈥ Pentium的物理地址空間和虛擬地址空間分別為多少它們是如何計算出來的
物理地址空間為232位元組即為4GB;只分段時,每個邏輯段的最大長度為1MB,即用戶所擁有的虛擬地址空間是為2*213*1MB=16GB;分段又分頁時,邏輯段的最大長度為4GB,用戶所擁有的虛擬地址空間為214*4 GB=64TB