非分頁內(nèi)存是虛擬內(nèi)存嗎?
非分頁內(nèi)存是虛擬內(nèi)存嗎?
非分頁內(nèi)存是虛擬內(nèi)存嗎?分頁內(nèi)存和非分頁內(nèi)存區(qū)別是什么?下面是學(xué)習啦小編給大家整理的一些相關(guān)知識,希望對大家有幫助!
非分頁內(nèi)存是虛擬內(nèi)存嗎?
在寫驅(qū)動的時候,經(jīng)常要調(diào)用ExAllocatePoolWithTag函數(shù)分配內(nèi)存,其中第一個參數(shù)可以是如下幾個:
其中,主要的兩個區(qū)別就是分頁內(nèi)存和非分頁內(nèi)存。
分頁內(nèi)存是低中斷級別的例程可以訪問的。
而非分頁內(nèi)存則是各個中斷級別的例程都可以使用的。
區(qū)別在于:
分頁內(nèi)存是虛擬內(nèi)存,在物理上未必總是能得到。
操作系統(tǒng)實現(xiàn)虛擬內(nèi)存的主要方法就是通過分頁機制。在Win32中,物理地址空間,二維虛擬地址空間和實際內(nèi)存地址是三個不同的概念。操作系統(tǒng)通過段選擇子構(gòu)成二維虛擬地址空間,每個進程有一個4G的地址空間,然后操作系統(tǒng)的內(nèi)存管理器件把每個進程映射到一維物理地址空間的不同部分,但是因為我們實際機器上大都沒有4G內(nèi)存,所以,實際內(nèi)存空間是物理地址空間的子集。
分頁管理器把地址空間劃分成4K大小的頁面(非Intel X86體系與之不同),當進程訪問某個頁面時,操作系統(tǒng)首先在Cache中查找頁面,如果該頁面不在內(nèi)存中,則產(chǎn)生一個缺頁中斷(Page Fault),進程就會被阻塞,直至要訪問的頁面從外存調(diào)入內(nèi)存中。
我們知道,在處理低優(yōu)先級的中斷時,仍可以發(fā)生高優(yōu)先級的中斷。既然缺頁過程也是一個中斷過程,那么就產(chǎn)生一個問題,即,缺頁中斷和其他中斷的優(yōu)先級的問題。如果在高于缺頁中斷的中斷優(yōu)先級上再發(fā)生缺頁中斷,內(nèi)核就會崩潰。所以在DISPATCH_LEVEL級別以上,絕對不能使用分頁內(nèi)存,一旦使用分頁內(nèi)存,就有發(fā)生缺頁中斷的可能,前面說過,這樣會導(dǎo)致內(nèi)核崩潰。
另一種解釋:
雖然可以尋址4GB的內(nèi)存,而在PC里往往沒有如此多的真實物理內(nèi)存。操作系統(tǒng)和硬件(這里指的是CPU中的內(nèi)存管理單元MMU)為使用者提供了虛擬內(nèi)存的概念。Windows的所有程序(包括Ring0層和Ring3層的程序)可以操作的都是虛擬內(nèi)存。之所以稱為虛擬內(nèi)存,是因為對它的所有操作,最終會變成一系列對真實物理內(nèi)存的操作。在CPU中有一個重要的寄存器CR0,它是32位的寄存器,其中的一個位(PG位)是負責告訴系統(tǒng)是否分頁的。Windows在啟動前會將它的PG位置1,即允許分頁。宏P(guān)AGE_SIZE記錄分頁大小4KB,4GB的虛擬內(nèi)存會被分割成1M個分頁單元。
有一部分單元會和物理內(nèi)存對應(yīng)起來,這種對應(yīng)不是一一對應(yīng),而是多對一的映射,多個虛擬內(nèi)存頁可以映射同一個物理內(nèi)存頁。還有一部分單元會被映射成磁盤上的文件,并標記為臟的(Dirty)。0~0X7FFFFFFF范圍內(nèi)的虛擬內(nèi)存,即低于2GB的虛擬地址為用戶內(nèi)核模式地址,而0X80000000~0XFFFFFFFF范圍內(nèi)的虛擬內(nèi)存,即高2GB的虛擬內(nèi)存,為內(nèi)核模式地址。Windows的核心代碼和Windows的驅(qū)動程序加載的位置都是在高2GB的內(nèi)核地址里,所以一般的應(yīng)用程序是不能訪問到這些核心代碼和重要數(shù)據(jù)的。同時Windows操作系統(tǒng)在進程切換時,保持內(nèi)核模式地址是完全相同的。也就是說,所有進程的內(nèi)核地址映射完全一致,進程切換的時候,只改變用戶模式地址的映射。
Windows規(guī)定有些虛擬內(nèi)存頁面是可以交換到文件中的,這類內(nèi)存被稱為分頁內(nèi)存。而有些虛擬內(nèi)存永遠不會交換到文件中,這些內(nèi)存被稱為非分頁內(nèi)存。當程序的中斷請求級在DISPATCH_LEVEL之上(包括DISPATCH_LEVEL層),程序只能使用非分頁內(nèi)存,否則將導(dǎo)致藍屏死機。
相關(guān)拓展:
分頁內(nèi)存和非分頁內(nèi)存
首先介紹幾個術(shù)語:
進程上下文,就是表示進程信息的一系列東西,包括各種變量、寄存器以及進程的運行的環(huán)境。這樣,當進程被切換后,下次再切換回來繼續(xù)執(zhí)行,能夠知道原來的狀態(tài)。
中斷上下文,就是中斷發(fā)生時,原來的進程執(zhí)行被打斷,那么就要把原來的那些變量保存下來,以便中斷完成后再恢復(fù)。
Windows NT和Windows 98都是運行在支持虛擬地址空間的計算機上,虛擬地址空間或者映射到一段真實的物理內(nèi)存,或者映射到交換文件中的頁幀。
每一個進程有4G的虛擬地址空間空間(因為一般機器是32位),這4G的空間被分為用戶模式地址空間以及用戶模式地址空間。無論何時我們需要訪問計算機內(nèi)存,都要使用內(nèi)核模式的虛擬地址。每一個用戶模式進程都有自己的地址上下文,記錄了進程信息的一系列東西。當Windows NT調(diào)度器把控制從一個進程的當前線程切換到另一個進程的某個線程時,與進程相對應(yīng)的虛擬地址空間也被更換(執(zhí)行到別的進程了,也就是跑到另外的一個4G的地址)。線程切換的一個步驟就是改變處理器當前使用的頁表,以便它能引用新線程的進程上下文。
虛擬內(nèi)存系統(tǒng)的特征就是能使軟件有一個比物理內(nèi)存大得多的虛擬內(nèi)存空間。為了做到這一點,內(nèi)存管理器需要在物理內(nèi)存和磁盤文件間交換頁幀。但操作系統(tǒng)的某些部分是不能被分頁的,這些內(nèi)存用來支持內(nèi)存管理器本身。最明顯的例子就是,用于處理頁故障的代碼和數(shù)據(jù)結(jié)構(gòu)必須常駐內(nèi)存。
Windows NT把內(nèi)核模式地址空間分成分頁內(nèi)存池和非分頁內(nèi)存池。(用戶模式地址空間總是分頁的) 必須駐留的代碼和數(shù)據(jù)放在非分頁池;不必常駐的代碼和數(shù)據(jù)放在分頁池中。Windows NT為決定代碼和數(shù)據(jù)是否需要駐留非分頁池提供了一個簡單規(guī)則。
非分頁內(nèi)容的空間是很小的,所以一般的東西都會放入分頁內(nèi)存中。
執(zhí)行在高于或等于DISPATCH_LEVEL級上的代碼必須存在于非分頁內(nèi)存中。