虛擬地址空間映射到物理地址空間
虛擬地址空間映射到物理地址空間
學(xué)習(xí)啦小編整理了虛擬地址空間映射到物理地址空間的相關(guān)資料。供大家參考!
虛擬地址空間映射到物理地址空間參考如下
當(dāng)處理器讀或?qū)懭雰?nèi)存位置時(shí),它會(huì)使用虛擬地址。作為讀或?qū)懖僮鞯囊徊糠?,處理器將虛擬地址轉(zhuǎn)換為物理地址。通過(guò)虛擬地址訪問(wèn)內(nèi)存有以下優(yōu)勢(shì):
程序可以使用一系列相鄰的虛擬地址來(lái)訪問(wèn)物理內(nèi)存中不相鄰的大內(nèi)存緩沖區(qū)。
程序可以使用一系列虛擬地址來(lái)訪問(wèn)大于可用物理內(nèi)存的內(nèi)存緩沖區(qū)。當(dāng)物理內(nèi)存的供應(yīng)量變小時(shí),內(nèi)存管理器會(huì)將物理內(nèi)存頁(yè)(通常大小為 4 KB)保存到磁盤(pán)文件。數(shù)據(jù)或代碼頁(yè)會(huì)根據(jù)需要在物理內(nèi)存與磁盤(pán)之間移動(dòng)。
不同進(jìn)程使用的虛擬地址彼此隔離。一個(gè)進(jìn)程中的代碼無(wú)法更改正在由另一進(jìn)程或操作系統(tǒng)使用的物理內(nèi)存。
進(jìn)程可用的虛擬地址范圍稱(chēng)為該進(jìn)程的“虛擬地址空間”。每個(gè)用戶(hù)模式進(jìn)程都有其各自的專(zhuān)用虛擬地址空間。 對(duì)于 32 位進(jìn)程,虛擬地址空間通常為 2 GB,范圍從 0x00000000 至 0x7FFFFFFF。對(duì)于 64 位進(jìn)程,虛擬地址空間為 8 TB,范圍從 0x000'00000000 至 0x7FF'FFFFFFFF。一系列虛擬地址有時(shí)稱(chēng)為一系列“虛擬內(nèi)存”。
此圖說(shuō)明了虛擬地址空間的一些重要功能。
該圖顯示了兩個(gè) 64 位進(jìn)程的虛擬地址空間:Notepad.exe 和 MyApp.exe。每個(gè)進(jìn)程都有其各自的虛擬地址空間,范圍從 0x000'0000000 至 0x7FF'FFFFFFFF。每個(gè)陰影框都表示虛擬內(nèi)存或物理內(nèi)存的一個(gè)頁(yè)面(大小為 4 KB)。注意,Notepad 進(jìn)程使用從 0x7F7'93950000 開(kāi)始的虛擬地址的三個(gè)相鄰頁(yè)面。但虛擬地址的這三個(gè)相鄰頁(yè)面會(huì)映射到物理內(nèi)存中的非相鄰頁(yè)面。而且還注意,兩個(gè)進(jìn)程都使用從 0x7F7'93950000 開(kāi)始的虛擬內(nèi)存頁(yè)面,但這些虛擬頁(yè)面都映射到物理內(nèi)存的不同頁(yè)面。
用戶(hù)空間和系統(tǒng)空間
諸如 Notepad.exe 和 MyApp.exe 的進(jìn)程在用戶(hù)模式下運(yùn)行。核心操作系統(tǒng)組件和多個(gè)驅(qū)動(dòng)程序在更有特權(quán)的內(nèi)核模式下運(yùn)行。有關(guān)處理器模式的詳細(xì)信息,請(qǐng)參閱用戶(hù)模式和內(nèi)核模式。每個(gè)用戶(hù)模式進(jìn)程都有其各自的專(zhuān)用虛擬地址空間,但在內(nèi)核模式下運(yùn)行的所有代碼都共享稱(chēng)為“系統(tǒng)空間”的單個(gè)虛擬地址空間。當(dāng)前用戶(hù)模式進(jìn)程的虛擬地址空間稱(chēng)為“用戶(hù)空間”。
在 32 位 Windows 中,可用的虛擬地址空間共計(jì)為 2^32 字節(jié)(4 GB)。通常較下的 2 GB 用于用戶(hù)空間,較上的 2 GB 用于系統(tǒng)空間。
在 32 位 Windows 中,你可以指定(在啟動(dòng)時(shí))超過(guò) 2 GB 用于用戶(hù)空間。結(jié)果是系統(tǒng)空間可用的虛擬地址更少??梢詫⒂脩?hù)空間的大小增至 3 GB,在這種情形下系統(tǒng)空間僅有 1 GB。若要增大用戶(hù)空間的大小,請(qǐng)使用 BCDEdit /set increaseuserva。
在 64 位 Windows 中,虛擬地址空間的理論大小為 2^64 字節(jié)(16 百億億字節(jié)),但實(shí)際上僅使用 16 百億億字節(jié)范圍的一小部分。范圍從 0x000'00000000 至 0x7FF'FFFFFFFF 的 8 TB 用于用戶(hù)空間,范圍從 0xFFFF0800'00000000 至 0xFFFFFFFF'FFFFFFFF 的 248 TB 的部分用于系統(tǒng)空間。
用戶(hù)模式下運(yùn)行的代碼可以訪問(wèn)用戶(hù)空間,但不能訪問(wèn)系統(tǒng)空間。此限制可防止用戶(hù)模式代碼讀或更改受保護(hù)的操作系統(tǒng)數(shù)據(jù)結(jié)構(gòu)。內(nèi)核模式下運(yùn)行的代碼既可以訪問(wèn)用戶(hù)空間,也可以訪問(wèn)系統(tǒng)空間。即,在內(nèi)核模式下運(yùn)行的代碼可以訪問(wèn)系統(tǒng)空間和當(dāng)前用戶(hù)模式進(jìn)程的虛擬地址空間。
在內(nèi)核模式下運(yùn)行的驅(qū)動(dòng)程序必須在直接從用戶(hù)空間地址中讀取或?qū)懭脒@些地址時(shí)非常小心。此方案說(shuō)明了原因。
用戶(hù)模式程序發(fā)起從設(shè)備讀取某些數(shù)據(jù)的請(qǐng)求。程序提供緩沖區(qū)的起始地址以接收數(shù)據(jù)。
在內(nèi)核模式下運(yùn)行的設(shè)備驅(qū)動(dòng)程序例程啟動(dòng)讀取操作并將控制權(quán)返回到其調(diào)用程序。
然后,設(shè)備中斷了當(dāng)前運(yùn)行的任何線程以顯示讀取操作完成。 中斷由在此任意線程上運(yùn)行的內(nèi)核模式驅(qū)動(dòng)程序例程進(jìn)行處理,該例程屬于任意進(jìn)程。
此時(shí),驅(qū)動(dòng)程序不得將數(shù)據(jù)寫(xiě)入用戶(hù)模式程序在步驟 1 中提供的開(kāi)始地址。此地址位于發(fā)起請(qǐng)求的進(jìn)程的虛擬地址空間,該進(jìn)程可能很大程度上不同于當(dāng)前進(jìn)程。
虛擬地址(Virtual Address Space)
Win32通過(guò)一個(gè)兩層的表結(jié)構(gòu)來(lái)實(shí)現(xiàn)地址映射,因?yàn)槊總€(gè)進(jìn)程都擁有私有的4G的虛擬內(nèi)存空間,相應(yīng)的,每個(gè)進(jìn)程都有自己的層次表結(jié)構(gòu)來(lái)實(shí)現(xiàn)其地址映射。
第一層稱(chēng)為頁(yè)目錄,實(shí)際就是一個(gè)內(nèi)存頁(yè),Win32的內(nèi)存頁(yè)有4KB大小,這個(gè)內(nèi)存頁(yè)以4個(gè)字節(jié)分為1024項(xiàng),每一項(xiàng)稱(chēng)為“頁(yè)目錄項(xiàng)”(PDE);
第二層稱(chēng)為頁(yè)表,這一層共有1024個(gè)頁(yè)表,頁(yè)表結(jié)構(gòu)與頁(yè)目錄相似,每個(gè)頁(yè)表也都是一個(gè)內(nèi)存頁(yè),這個(gè)內(nèi)存頁(yè)以4KB的大小被分為1024項(xiàng),頁(yè)表的每一項(xiàng)被稱(chēng)為頁(yè)表項(xiàng)(PTE),易知共有1024×1024個(gè)頁(yè)表項(xiàng)。每一個(gè)頁(yè)表項(xiàng)對(duì)應(yīng)一個(gè)物理內(nèi)存中的某一個(gè)“內(nèi)存頁(yè)”,即共有1024×1024個(gè)物理內(nèi)存頁(yè),每個(gè)物理內(nèi)存頁(yè)為4KB,這樣就可以索引到4G大小的虛擬物理內(nèi)存。
如下圖所示(注下圖中的頁(yè)目錄項(xiàng)的大小應(yīng)該是4個(gè)字節(jié),而不是4kB):
Win32提供了4GB大小的虛擬地址空間。因此每個(gè)虛擬地址都是一個(gè)32位的整數(shù)值,也就是我們平時(shí)所說(shuō)的指針,即指針的大小為4B。它由三部分組成,如下圖:
這三個(gè)部分的第一部分,即前10位為頁(yè)目錄下標(biāo),用來(lái)尋址頁(yè)目錄項(xiàng),頁(yè)目錄項(xiàng)剛好1024個(gè)。找到頁(yè)目錄項(xiàng)后,找對(duì)頁(yè)目錄項(xiàng)對(duì)應(yīng)的的頁(yè)表。第二部分則是用來(lái)在頁(yè)表內(nèi)尋址,用來(lái)找到頁(yè)表項(xiàng),共有1024個(gè)頁(yè)表項(xiàng),通過(guò)頁(yè)表項(xiàng)找到物理內(nèi)存頁(yè)。第三部分用來(lái)在物理內(nèi)存頁(yè)中找到對(duì)應(yīng)的字節(jié),一個(gè)頁(yè)的大小是4KB,12位剛好可以滿(mǎn)足尋址要求。
具體的例子:
假設(shè)一個(gè)線程正在訪問(wèn)一個(gè)指針(Win32的指針指的就是虛擬地址)指向的數(shù)據(jù),此指針指為0x2A8E317F,下圖表示了這一個(gè)過(guò)程:
0x2A8E317F的二進(jìn)制寫(xiě)法為0010101010_0011100011_000101111111,為了方便我們把它分為三個(gè)部分。
首先按照0010101010尋址,找到頁(yè)目錄項(xiàng)。因?yàn)橐粋€(gè)頁(yè)目錄項(xiàng)為4KB,那么先將0010101010左移兩位,001010101000(0x2A8),用此下標(biāo)找到頁(yè)目錄項(xiàng),然后根據(jù)此頁(yè)目錄項(xiàng)定位到下一層的某個(gè)頁(yè)表。
然后按照0011100011尋址,在上一步找到頁(yè)表中尋找頁(yè)表項(xiàng)。尋址方法與上述方法類(lèi)似。找到頁(yè)表項(xiàng)后,就可以找到對(duì)應(yīng)的物理內(nèi)存頁(yè)。
最后按照000101111111尋址,尋找頁(yè)內(nèi)偏移。
上面的假設(shè)的是此數(shù)據(jù)已在物理內(nèi)存中,其實(shí)判斷訪問(wèn)的數(shù)據(jù)是否在內(nèi)存中也是在地址映射過(guò)程中完成的。Win32系統(tǒng)總是假設(shè)數(shù)據(jù)已在物理內(nèi)存中,并進(jìn)行地址映射。頁(yè)表項(xiàng)中有一位標(biāo)志位,用來(lái)標(biāo)識(shí)包含此數(shù)據(jù)的頁(yè)是否在物理內(nèi)存中,如果在的話,就直接做地址映射,否則,拋出缺頁(yè)中斷,此時(shí)頁(yè)表項(xiàng)也可標(biāo)識(shí)包含此數(shù)據(jù)的頁(yè)是否在調(diào)頁(yè)文件中(外存),如果不在則訪問(wèn)違例,程序?qū)?huì)退出,如果在,頁(yè)表項(xiàng)會(huì)查出此數(shù)據(jù)頁(yè)在哪個(gè)調(diào)頁(yè)文件中,然后將此數(shù)據(jù)頁(yè)調(diào)入物理內(nèi)存,再繼續(xù)進(jìn)行地址映射。為了實(shí)現(xiàn)每個(gè)進(jìn)程擁有私有4G的虛擬地址空間,也就是說(shuō)每個(gè)進(jìn)程都擁有自己的頁(yè)目錄和頁(yè)表結(jié)構(gòu),對(duì)不同進(jìn)程而言,即使是相同的指針(虛擬地址)被不同的進(jìn)程映射到的物理地址也是不同的,這也意味著在進(jìn)程之間傳遞指針是沒(méi)有意義的。
看過(guò)“虛擬地址空間映射到物理地址空間 ”的人還看了: