關於內存探測

2009-08-12 19:29

操作系統必須知道系統物理內存的數量,才能夠有效的使用和管理這些物理內存。所以在booting階段,我們必須通過某種手段來檢測和獲取物理內存的總量。

獲取物理內存容量的方法主要分爲兩大類:一類是通過BIOS軟中斷方式獲取,另一類是通過讀取北橋芯片內存控制器相關寄存器獲取。

第一類方法的優點是歷史悠久,自80286以來,絕大多數IBM PC兼容機都提供這一功能,現在的Windows和linux也是通過這一類方法在啓動階段獲取物理內存容量,另外由於這種方法是通過對內存的遍歷來獲取內存容量的,因此一些內存檢測工具也是通過這類方法對內存進行檢測。但是,這類方法在檢測大容量內存時,若只需要物理內存總容量信息,則效率低於第二類方法。

第二類方法與第一類方法本質的區別在於這種方法使用硬件方法實現物理內存容量的獲取,因此速度較快。但是這種方法僅能獲取物理內存容量,不包括對內存的檢測。

第一類方法包括三種具體做法,這三種做法都是基於BIOS INT15h中斷(在PC和XT機上是BIOS磁帶I/O功能調用。在AT機上是AT擴充服務功能調用),它們的名稱依此爲88h,E801h,E820h。其中,88h方法是在Intel80286出現的那天起就存在的,後續的PC及其兼容機爲了保持向下兼容,都繼續保留了這種方法。因此,這種方法在所有的IBMPC及其兼容機上都存在。但事實上,這種方法存在一個重要的缺陷,由於這種方法是在16bit時代就存在的,所以,它通過16bit寄存器來保存內存容量作爲返回值。但16bit所能夠表示的最大值是64KB。由於這種方法的返回值是以KB爲單位,所以它能夠表示的系統最大物理內存容量爲64 MB。而對於今天的PC機來說,64MB已經是很低的內存配置了,大多數PC機的實際物理內存配置都大於64 MB。另外,需要注意的是,由於這種方法出現於Intel80286時代,而80286的24bit地址總線能夠訪問的最大地址爲16MB,所以,儘管這種方法使用16bit寄存器能夠表示的最大內存數量爲64MB,但標準的BIOS只允許通過這種方法獲取最大16MB的物理內存數量。

爲了能夠獲取大於64MB的內存,就必須通過另外兩種方法的一種。但並非每一臺PC機都實現了這兩種方法或這兩種方法之一。對於絕大多數現代PC機來說,至少提供了這兩種方法的一種;而對於過去的PC機,又很少有超過64MB的配置。從這個意義上來說,這已經足夠了。

 

1.Int 15/AX=E820h是用來獲取系統中的內存映地址描述符的,操作系統常用來獲取內存大小。

PS:內存(Memory)可以是我們平時所說的在主板上的內存條,我們稱作Base Memory,也可以是毗邊Base Memory 的並作爲普通內存擴展的內存。

相關的數據結構:

地址範圍描述符結構

Offset

Name

Description

0

BaseAddrLow

基地址的低32位

4

BaseAddrHigh

基地址的高32位

8

LengthLow

長度(字節)的低32位

12

LengthHigh

長度(字節)的高32位

16

Type

這個地址範圍的地址類型

其中Type的取值及其意義如下:

1

AddressRangeMemory

這個內存段是一段可以被OS使用的RAM

2

AddressRangeReserved

這個地址段正在被使用,或者被系統保留,所以一定不要被OS使用

Other

Undefined

保留爲未來使用,任何其它值都必需被OS認爲是AddressRangeReserved

輸入參數:

Register

Meaning

Description

EAX

功能碼

E820h

EBX

後續值

放置着"後續值",這個值是爲了得到下一塊物理內存段,它應該指定上一次調用此程序所返回的值,如果這是第一次調用,EBX必須被指定爲0。

ES:DI

緩衝指針

指向一個地址範圍描述符結構,BIOS將會填充此結構。

ECX

緩衝大小

緩衝指針所指向的地址範圍描述符結構的大小,以Byte爲單位,無論ES:DI所指向的結構如何設置,BIOS最多將會填充ECX個字節,必需被BIOS以及調用者所支持的最小尺寸是20個字節,未來的實現將會擴展此限制。

EDX

標誌

'SMAP' -BIOS將會使用此標誌,對調用者將要請求的系統映象信息進行校驗,這些信息會被BIOS放置到ES:DI所指向的結構中。

輸出結果:

Register

Meaning

Description

CF

進位標誌

不進位表示沒有錯誤,否則則存在錯誤。

EAX

標誌

'SMAP'

ES:DI

緩衝指針

返回的地址範圍描述符結構指針,和輸入值相同。

ECX

緩衝大小

BIOS所填充在地址範圍描述符中的字節數量,被BIOS所返回的最小值是20個字節。

EBX

後續

這裏放置着爲了等到下一個地址描述符所需要的"後續值",這個值的實際形勢倚賴於具體的BIOS的實現,調用者不必要關心它的具體形式,只需要在下次迭代的時候,將其原封不動的放置到EBX中,就可以通過它獲取下一個地址範圍描述符。如果它的值爲0,則表示它是最後一個地址範圍描述符。

一定注意,只有這個後續值爲零,並且CF沒有進位的時候,才表示這是最後一個地址範圍描述符。

如下一些原因造成BIOS將某個內存段標記爲AddressRangeReserved:

  • 這個地址範圍包含着系統ROM;
  • 這個地址範圍包含着被ROM使用的RAM;
  • 這個地址範圍被用作系統設備內存映射;
  • 這個地址範圍由於某種原因,不適合被標準設備用作設備內存空間。

原理描述:
調用此功能可以從系統某一個地方(這裏存放有一個List(列表),這個列表裏存放的都是一個個的
Entry)通過設置EBX(20的倍數)的值,然後調用int 0x15就可以講EBX所指向的Entry拷貝
到ES:DI所指向的內存區)

2.INT 15h, AX=E801h

E801h只能在Real Mode下使用。

最初,這種方式是爲EISA服務定義的,這個接口能夠報告多達4G的RAM。然而它不象E820h方式那麼通用,E820h在更多的系統上可以使用。

輸入:

Register

Meaning

Description

AX

功能碼

E801h

輸出:

Register

Meaning

Description

CF

進位標誌

不進位表示沒有錯誤

AX

擴展1

1到16M內存的容量,以KB爲單位,最大數量0x3C00 =15M

BX

擴展2

16MB到4GB之間的內存容量,以64K爲單位

CX

配置1

1到16M內存的容量,以KB爲單位,最大數量0x3C00 =15M

DX

配置2

16MB到4GB之間的內存容量,以64K爲單位


無法確定"擴展"和"配置"之間的不同到底在哪裏,事實上它們的值是相同的。

注意:一個機器可能使用這個接口來報告16M以下內存空洞(count1小於15M,但count2卻爲非0)。

 

3.INT 15h, AH=88h

E88h只能在實模式下使用。

這個接口是相當原語性的,它返回1M地址以上的後續內存容量。最大的限止是它的返回值是16-bit的,以KB爲單位,所以它最多能夠返回64M。在某些系統上,它僅僅能夠返回16M以內的內存。

和前兩者相比,它的唯一好處是它在所有的PC上都工作。

輸入:

Register

Meaning

Description

AH

功能碼

88h


輸出:

Register

Meaning

Description

CF

進位標誌

不進位表示沒有錯誤

AX

內存容量

以KB爲單位,1MB以上的內存容量

 

PS:需要說明的是,使用BIOS的方法在某些情況下會無法工作。在這些情況下,可以使用直接探測內存方法。直接探測內存,是一種不依賴於BIOS的內存檢測方法,這使得它是一種更加輕便的方法。當使用這種方法的時候,需要考慮系統內存空洞,以及被映射到外部設備上的內存(比如framebuffering SVGA cards)。

使用這種方法的時候,必須進入Protected Mode。

另外,由於Intel的386以後的CPU爲了提高內存訪問速度,使用了memorycache,來緩衝內存中的內容。但對於我們想通過直接探測內存來確定內存容量的方法來講, memorycache反而會造成負面的影響,因此我們必須禁止memory cache。留着以後有時間再慢慢研究吧:)

 

4.使用硬件方式獲取物理內存容量

通過讀內存spd和北橋的memory controller相關的寄存器,再根據內存的當前模式(mirror或者non-mirror)計算內存大小。不過,對於普通開發者來說,使用這種方式獲取內存容量信息,需要知道北橋芯片相關寄存器地址,這就需要依賴北橋芯片datasheet了。Intel生產的芯片組datasheet一般來說比較容易獲得,但是諸如VIA、NV等廠商生產的芯片組datasheet在網上比較少見,而且對應型號也都比較老,因此這種方法在有些時候並不是那麼可行:)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章