虛擬地址與物理地址怎么映射
虛擬地址與物理地址怎么映射
每個進程都是獨立的虛擬地址空間,兩個獨立進程的相同地址互不干擾,但是在物理上對每個進程可能也就分了一部分空間給了某個進程,所以中間就要用到映射,那么虛擬地址與物理地址怎么映射呢?今天學(xué)習(xí)啦小編與大家分享下虛擬地址與物理地址映射的具體操作步驟,有需要的朋友不妨了解下。
虛擬地址與物理地址映射過程
這里只談分頁管理的機制,也是目前最重要的內(nèi)存管理機制。
最初的設(shè)計想法:
結(jié)構(gòu)圖如下:
頁的尺寸是4KB,虛擬地址的前20位用于指定一個物理頁,后12位用于訪問頁內(nèi)偏移。
頁表項的結(jié)構(gòu):
各個位的含義:
P--位0是存在(Present)標(biāo)志,用于指明表項對地址轉(zhuǎn)換是否有效。P=1表示有效;P=0表示無效。在頁轉(zhuǎn)換過程中,如果說涉及的頁目錄或頁表的表項無效,則會導(dǎo)致一個異常。如果P=0,那么除表示表項無效外,其余位可供程序自由使用,如圖4-18b所示。例如,操作系統(tǒng)可以使用這些位來保存已存儲在磁盤上的頁面的序號。
R/W--位1是讀/寫(Read/Write)標(biāo)志。如果等于1,表示頁面可以被讀、寫或執(zhí)行。如果為0,表示頁面只讀或可執(zhí)行。當(dāng)處理器運行在超級用戶特權(quán)級(級別0、1或2)時,則R/W位不起作用。頁目錄項中的R/W位對其所映射的所有頁面起作用。
U/S--位2是用戶/超級用戶(User/Supervisor)標(biāo)志。如果為1,那么運行在任何特權(quán)級上的程序都可以訪問該頁面。如果為0,那么頁面只能被運行在超級用戶特權(quán)級(0、1或2)上的程序訪問。頁目錄項中的U/S位對其所映射的所有頁面起作用。
A--位5是已訪問(Accessed)標(biāo)志。當(dāng)處理器訪問頁表項映射的頁面時,頁表表項的這個標(biāo)志就會被置為1。當(dāng)處理器訪問頁目錄表項映射的任何頁面時,頁目錄表項的這個標(biāo)志就會被置為1。處理器只負(fù)責(zé)設(shè)置該標(biāo)志,操作系統(tǒng)可通過定期地復(fù)位該標(biāo)志來統(tǒng)計頁面的使用情況。
D--位6是頁面已被修改(Dirty)標(biāo)志。當(dāng)處理器對一個頁面執(zhí)行寫操作時,就會設(shè)置對應(yīng)頁表表項的D標(biāo)志。處理器并不會修改頁目錄項中的D標(biāo)志。
AVL--該字段保留專供程序使用。處理器不會修改這幾位,以后的升級處理器也不會。
由于頁表占用內(nèi)存空間太大(1M個元素*4B大小=4MB,也可以這么看:每個進程的虛擬地址空間=4G,頁面大小=4K,所以共有1M個頁,需要1M個頁表項,又因為每個頁表項=4B,所以頁表大小=4M),為了減少內(nèi)存占用量,因此設(shè)計了層次化的分頁結(jié)構(gòu):頁目錄表+頁表。
層次化的設(shè)計想法:
因為4GB的虛擬內(nèi)存共有1M=220=1048576個4K大小的頁面。
我們將這些頁面分成210=1024份,即從頁表1到頁表1024,由頁目錄表管理;
每一份(每一頁表)有210=1024個頁,由每一個頁表管理,頁在頁表中是隨機的,哪個頁位于哪個頁表中是沒有規(guī)律的;
結(jié)構(gòu)圖如下:
每個任務(wù)都有這樣的層次化的分頁結(jié)構(gòu),即每個任務(wù)都有自己的頁目錄表和頁表。
從硬件角度來分析:
在處理器中有個控制寄存器CR3,存放著當(dāng)前任務(wù)頁目錄的物理地址,故又叫做頁目錄基址寄存器(Page Directory Base Register,PDBR),每個任務(wù)都存放了自己的頁目錄物理地址,當(dāng)任務(wù)切換時,處理器切換到新任務(wù)開始執(zhí)行,更新CR3寄存器的內(nèi)容,以指向新任務(wù)的頁目錄位置;
相應(yīng)的,頁目錄又指向了一個個的頁表,每個頁表又根據(jù)任務(wù)的頁表項指向了相應(yīng)的頁。其中注意的是,頁目錄和頁表也是普通的頁,混跡于全部的物理頁中,它們和普通頁的不同之處僅僅在于功能不一樣,當(dāng)任務(wù)撤銷之后, 它們和任務(wù)所占用的普通頁一樣會被回收, 并分配給其他任務(wù)(如下圖所示)。
下面內(nèi)容轉(zhuǎn)自《分頁機制》,寫的很清楚。
地址變換的具體過程
對于Intel處理器來說, 有關(guān)分頁, 最簡單和最基本的機制就是這些; CR3寄存器給出了頁目錄的物理地址; 頁目錄給出了所有頁表的物理地址, 而每個頁表給出了它所包含的頁的物理地址. 好了, 該清楚的都清楚了, 唯一還不明白的, 應(yīng)該是如何用這種層次性的分頁結(jié)構(gòu)把線性地址轉(zhuǎn)換成物理地址? 這里舉個例子, 某任務(wù)加載后, 在4GB虛擬地址空間創(chuàng)建了一個段, 起始地址為0x00800000, 段界限為0x5000, 字節(jié)粒度. 當(dāng)前任務(wù)執(zhí)行時, 段寄存器DS指向該段. 又假設(shè)執(zhí)行了下面一條指令
mov edx, [0x1050]
此時, 段部件會輸出線性地址0x00801050. 在沒有開啟分頁機制時, 這就是要訪問的物理地址. 但現(xiàn)在開啟了分頁機制, 所以這是一個下虛擬地址, 要經(jīng)過頁部件轉(zhuǎn)換, 才能得到物理地址.
如下圖所示, 處理器的頁部件專門負(fù)責(zé)線性地址到物理地址的轉(zhuǎn)換工作. 它首先將段部件送來的32位線性地址分為3段, 分別是高10位, 中間10位, 低12位. 高10位是頁目錄的索引, 中間10位是頁表的索引, 低12位則作為頁內(nèi)偏移量來用.
當(dāng)前任務(wù)頁目錄的物理地址在處理器的CR3寄存器中, 假設(shè)它的內(nèi)容為0x00005000. 段管理部件輸出的線性地址是0x00801050, 其二進制的形式如圖中給出. 高10位是十六進制的0x002, 它是頁目錄表內(nèi)的索引,處理器將它乘以4(因為每個目錄項4字節(jié)), 作為偏移量訪問頁目錄. 最終處理器從物理地址00005008處取得頁表的物理地址0x08001000.
線性地址的中間10位為0x001, 處理器用它作為頁表索引取得頁的物理地址. 將該值乘以4, 作為偏移量訪問頁表. 最終, 處理器又從物理地址08001004處取得頁的物理地址, 這就是我們一直努力尋找的那個頁.
頁的物理地址是0x0000c000, 而線性地址的低12位是數(shù)據(jù)所在的頁內(nèi)偏移量. 故處理器將它們相加, 得到物理地址0x0000C050, 這就是線性地址0x00801050所對應(yīng)的物理地址, 要訪問的數(shù)據(jù)就在這里.
注意, 這種變換不是無緣無故的, 而是事先安排好的. 當(dāng)任務(wù)加載時, 操作系統(tǒng)先創(chuàng)建虛擬的段, 并根據(jù)段地址的高20位決定它要用到哪些頁目錄項和頁表項. 然后, 尋找空閑的頁, 將原本應(yīng)該寫入段中的數(shù)據(jù)寫到一個或者多個頁中, 并將頁的物理地址填寫到相對應(yīng)的頁表項中. 只有這樣做了, 當(dāng)程序運行的時候, 才能以相反的順序進行地址變換, 并找到正確的數(shù)據(jù).
頁目錄項, 頁表項, CR3和打開分頁
頁目錄項和頁表項
頁目錄和頁表中分別存放為頁目錄項和頁表項, 它們的格式如下:
可以看出, 在頁目錄和頁表中, 只保存了頁表或者頁物理地址的高20位. 原因很簡單, 頁表或者頁的物理地址, 都要求必須是4KB對齊的, 以便于放在一個頁內(nèi), 故其低12位全是0. 在這種情況下, 可以只關(guān)心其高20位, 低12位安排其他用途.
P 是存在位, 為1時, 表示頁表或者頁位于內(nèi)存中. 否則, 表示頁表或者頁不在內(nèi)存中, 必須先予以創(chuàng)建, 或者從磁盤調(diào)入內(nèi)存后方可使用.
RW 是讀/寫位. 為0時表示這樣的頁只能讀取, 為1時可讀可寫
US 是用戶/管理位. 為1時, 允許所有特權(quán)級別的程序訪問; 為0時, 只允許特權(quán)級別為0, 1和2的程序訪問.
PWT(Page-level Write-Through) 是頁級通寫位, 和高速緩存有關(guān). "通寫"是處理器高速緩存的一種工作方式, 這一位用來間接決定是否采用此種方式來改善頁面的訪問效率.
PCD(Page-level Cache Disable)是頁級高速緩存禁止位, 用來間接決定該表項所指向的那個頁是否使用高速緩存策略.
A 是訪問位. 該位由處理器固件設(shè)置, 用來指示此表項所指向的頁是否被訪問過.
D(Dirty) 是臟位. 該位由處理器固件設(shè)置, 用來指示此表項所指向的頁是否寫過數(shù)據(jù)
PAT(Page Attribute Table) 頁屬性表支持位. 此位涉及更復(fù)雜的分頁系統(tǒng), 和頁高速緩存有關(guān), 可以不予理會, 在普通的4KB分頁機制中, 處理器建議將其置0.
G 是全局位. 用來指示該表項所指向的頁是否為全局性質(zhì)的. 如果頁是全局的, 那么, 它將在高速緩存中一直保存(也就意味著地址轉(zhuǎn)換速度會很快). 因為頁高速緩存容量有限, 只能存放頻繁使用的那些表項. 而且, 當(dāng)因任務(wù)切換等原因改變CR3寄存器的內(nèi)容時, 整個頁高速緩存的內(nèi)容都會被刷新.
AVL位卑處理器忽略, 軟件可以使用.
CR3(PDBR)和開分頁機制
控制寄存器CR3, 也就是頁目錄表基地址寄存器PDBR, 該寄存器如上圖所示.
由于頁目錄表必須位于一個自然頁內(nèi)(4KB對齊), 故其物理地址的低12位是全0. 低12位除了PCD和PWT外, 都沒有使用. 這兩位用于控制頁目錄的高速緩存特性, 參見上面解釋.
控制寄存器CR0的最高位PG位, 用于開啟分頁或者關(guān)閉頁功能. 當(dāng)該位清0時, 頁功能關(guān)閉, 從段部件來的線性地址就是物理地址. 當(dāng)它置位時, 頁功能開啟. 只能在保護模式下才能開啟分頁功能, 當(dāng)PE位清0時(實模式), 設(shè)置PG位將導(dǎo)致處理器產(chǎn)生一個異常中斷.
不存在的頁表:
使用二級表結(jié)構(gòu),并沒有解決需要使用4MB內(nèi)存來存放頁表的問題。實際上,我們把問題搞得有些復(fù)雜了。因為我們需要另增一個頁面來存放目錄表。然而,二級表結(jié)構(gòu)允許頁表被分散在內(nèi)存各個頁面中,而不需要保存在連續(xù)的4MB內(nèi)存塊中。另外,并不需要為不存在的或線性地址空間未使用部分分配二級頁表。雖然目錄表頁面必須總是存在于物理內(nèi)存中,但是二級頁表可以在需要時再分配。這使得頁表結(jié)構(gòu)的大小對應(yīng)于實際使用的線性地址空間大小。
頁目錄表中每個表項也有一個存在(present)屬性,類似于頁表中的表項。頁目錄表項中的存在屬性指明對應(yīng)的二級頁表是否存在。如果目錄表項指明對應(yīng)的二級頁表存在,那么通過訪問二級表,表查找過程第2步將同如上描述繼續(xù)下去。如果存在位表明對應(yīng)的二級表不存在,那么處理器就會產(chǎn)生一個異常來通知操作系統(tǒng)。頁目錄表項中的存在屬性使得操作系統(tǒng)可以根據(jù)實際使用的線性地址范圍來分配二級頁表頁面。
目錄表項中的存在位還可以用于在虛擬內(nèi)存中存放二級頁表。這意味著在任何時候只有部分二級頁表需要存放在物理內(nèi)存中,而其余的可保存在磁盤上。處于物理內(nèi)存中頁表對應(yīng)的頁目錄項將被標(biāo)注為存在,以表明可用它們進行分頁轉(zhuǎn)換。處于磁盤上的頁表對應(yīng)的頁目錄項將被標(biāo)注為不存在。由于二級頁表不存在而引發(fā)的異常會通知操作系統(tǒng)把缺少的頁表從磁盤上加載進物理內(nèi)存。把頁表存儲在虛擬內(nèi)存中減少了保存分頁轉(zhuǎn)換表所需要的物理內(nèi)存量。
總結(jié):給定虛擬地址,怎么找到它對應(yīng)的物理地址?分兩步!
第一步從虛擬地址到線性地址,第二步從線性地址從物理地址。
第一步從段描述符表描述的段基址加上段偏移生成線性地址。
IA32中線性地址高10位為頁目錄索引,通過此找到頁表,線性地址中間10位為頁表項索引,通過前面找到的頁表加上這個索引,找到頁表項。頁表項指示著頁框號,頁框號加上線性地址低12位(頁內(nèi)偏移)就生成了物理地址。
看過“虛擬地址與物理地址怎么映射”的人還看了:
6.虛擬地址物理地址