天天看點

隻有當實體記憶體超過2GB時才需要/3GB

首先請記住:實體記憶體和虛拟位址空間不是一回事兒。

我認為,這又是另一個容易令人搞混的兩個概念。解實體記憶體和虛拟記憶體之間并非簡單的一對一的關系。在一般情況下,你所擁有的虛拟記憶體會遠遠多于機器上配備的實體記憶體。空閑實體不會映射到任何虛拟位址空間中,而共享記憶體在多個虛拟位址空間中實際上是映射到同一個實體記憶體頁面。

這令我想起了另外一則曆史小故事。

在Windows 386的古老年代,核心恰好将所有實體記憶體映射到核心模式虛拟位址空間中。曾有這麼一個API函數:_MapPhysToLinear。給它傳遞一個實體記憶體範圍,它會傳回一個傳回一段線性位址空間中的一個起始位址,然後我們就可以使用這個起始位址來通路實體記憶體。有一些驅動開發者發現:核心映射了所有實體記憶體,然後使用了單一的映射機制。結果就是:開發者調用了_MapPhysToLinear(0, 0x1000),然後隻要他們想在将來通路實體記憶體,他們隻需要在傳回值上添加一定的偏移量就可以了。換句話說:他們認為存在下面的對應關系:

隻有當實體記憶體超過2GB時才需要/3GB

到了Windows 95的時代,記憶體管理器被完全地重寫了,而上面的等式(也可以說是巧合)不再成立。為了節省核心模式虛拟位址空間,實體記憶體現在僅在必要時才進行線性映射。

當然,依賴于原有行為的驅動現在就不能正常工作了,因為驅動代碼中所依賴的對應關系不再有效了。

是以,當Windows 95啟動的時候,它會檢查一些常見的驅動子產品是否依賴這一行為并被加載了。(Windows 3.1由于不支援動态驅動子產品加載,是以它隻需要在啟動啟動的時候檢查一次就可以了)

如果發現有這樣的驅動子產品,則系統會将所有實體記憶體都映射到核心模式位址空間中,進而確定這些驅動能繼續工作。這樣的設計雖然浪費了一定的虛拟位址空間,但是它卻可以保持驅動子產品繼續正常工作。

我也經常聽到有人說,”微軟不應該允許這些帶有Bug的驅動繼續工作,就應該讓這些驅動直接崩潰,這樣就可以促使驅動開發者修複他們的問題。”

這意味着,崩潰的原因首先可以追溯到有問題的驅動。核心模式中一個非常常見的野指針的表現是記憶體損壞,就是說這個子產品崩潰的元件很少是首先導緻問題的元件。

舉個例子,VMM(01)元件中幾乎所有Windows 95藍屏崩潰都是由記憶體損壞引起的。 VMM(01)元件是 Windows 95 核心的不可交換部分,它是記憶體管理器所在的位置。如果驅動程式損壞了核心模式堆,則首先出現藍屏的元件将會是記憶體管理器。是以,大家明白我們的苦衷了吧?

總結

1) 我們要盡可能地確定軟體的相容性,也就是:能跑起來就盡量讓它跑起來。

2) 如果還是不行,就按照第一條。

最後

最近我寫了個東西

繼續閱讀