小華的部落格: 2008/7/20 - 2008/7/27

搜尋此網誌

網頁

星期四, 7月 24, 2008

INT 15h/AX=E820h 程式範例

昨天下午拿起了ACPI Spec , 把之前還沒實做的INT15h E820h 部份拿起來練習了一下。

由Google大神找到的文件中的說明中可以了解到INT15h E820h 的用途和歷史,下面就我找到的文件中截取ㄧ部份出來給各位參考,如果要看全文的可以透過連結去查看我找到的那篇文章!

Linux MemoryCapacity Detection

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

由於在booting階段的絕大部分時間裏,主機處於Real Mode下,而在RealMode下,我們通過正常手段能夠訪問的實體記憶體最大只能達到1M+64K(在A20Gate被打開的情況下,否則,最大只能訪問1M),所以我們無法直接通過記憶體訪問來獲取記憶體總量。因此,剩下的唯一手段就是通過BIOS中斷。

但不幸的是,通過BIOS中斷獲取記憶體容量並非在所有情況都可以完全工作。
獲取機器記憶體容量的方法一般來講有三種方法,這三種方法都是基於BIOS INT15h中斷,它們的名稱依此為88h,E801h,E820h。

其中,88h方法是在Intel80286出現的那天起就存在的,後續的PC及其兼容機為了保持向下相容,都繼續保留了這種方法。因此,這種方法在所有的IBMPC及其兼容機上都存在,所以看起來,booting只需要這種方法就可以獲取實體記憶體總量,其他兩種方法似乎沒有存在的必要。但事實上,這種方法存在一個重要的缺陷,由於這種方法是在16-bit時代就存在的,所以,它通過16-bit寄存器來保存記憶體容量作為返回值。但16-bit所能夠表示的最大值是64KB。由於這種方法的返回值是以KB為單位,所以它能夠表示的系統最大實體記憶體容量為64 MB。而對於今天的PC機來說,64MB已經是很低的記憶體配置了,大多數PC機的實際實體記憶體配置都大於64 MB。

另外,需要注意的是,由於這種方法出現於Intel80286時代,而80286的24-bit位址匯流排能夠訪問的最大位址為16MB,所以,儘管這種方法使用16-bit寄存器能夠表示的最大記憶體數量為64MB,但標準的BIOS只允許通過這種方法獲取最大16 MB的實體記憶體數量。

為了能夠獲取大於64MB的記憶體,就必須通過另外兩種方法的一種。但並非每一台PC機都實現了這兩種方法或這兩種方法之一。

當今流行的桌面作業系統在Booting階段進行記憶體檢測的方法都是採用這三種方法,比如Microsoft WindowsNT,Linux等。所以在某些不支持E820h,E801h的PC上,它們也最多只能檢測到64 MB或16MB實體記憶體(依賴於88h的最大返回值限制)。
但請不必過分擔心,對於絕大多數現代PC機來說,至少提供了這兩種方法的一種;而對於過去的PC機,又很少有超過64MB的配置。從這個意義上來說,這已經足夠了。

INT 15h, AX=E820h Query SystemAddress Map
E820h只能用在Real Mode下使用
這個中斷調用返回所有被安裝在主機上的RAM,以及被BIOS所保留的實體記憶體範圍的記憶體映象。

Reference
http://docs.huihoo.com/gnu_linux/own_os/booting-memory_check_6.htm
Acpi Spec 3.0b

底下是範例程式下載以及執行後的結果,我是用7-Zip 免費壓縮軟體壓縮的,所以請使用最新版WinRar或是7-Zip 才能解壓縮喔...

點我下載E820範例程式 <~~記得在DOS下跑喔...


BassLow BaseHigh SizeLow SizeHigh Type

------------------------------------------------------
00000000 0000 0009FC00 0000 1 AddressRangeMemory(EfiLoaderCode)
0009FC00 0000 00000400 0000 2 AddressRangeMemory(EfiLoaderData)
000E0000 0000 00020000 0000 2 AddressRangeMemory(EfiLoaderData)
00100000 0000 363E6000 0000 1 AddressRangeMemory(EfiLoaderCode)
364E6000 0000 00003000 0000 4 AddressRangeMemory(EfiBootServiceData)
364E9000 0000 01583000 0000 1 AddressRangeMemory(EfiLoaderCode)
37A6C000 0000 00053000 0000 2 AddressRangeMemory(EfiLoaderData)
37ABF000 0000 000C6000 0000 1 AddressRangeMemory(EfiLoaderCode)
37B85000 0000 0003A000 0000 4 AddressRangeMemory(EfiBootServiceData)
37BBF000 0000 00025000 0000 1 AddressRangeMemory(EfiLoaderCode)
37BE4000 0000 00013000 0000 3 AddressRangeMemory(EfiBootServiceCode)
37BF7000 0000 00009000 0000 1 AddressRangeMemory(EfiLoaderCode)
37C00000 0000 08400000 0000 2 AddressRangeMemory(EfiLoaderData)
F8000000 0000 04000000 0000 2 AddressRangeMemory(EfiLoaderData)
FEC00000 0000 00001000 0000 2 AddressRangeMemory(EfiLoaderData)
FED10000 0000 00004000 0000 2 AddressRangeMemory(EfiLoaderData)
FED18000 0000 00002000 0000 2 AddressRangeMemory(EfiLoaderData)
FED1C000 0000 00004000 0000 2 AddressRangeMemory(EfiLoaderData)
FEE00000 0000 00001000 0000 2 AddressRangeMemory(EfiLoaderData)
FFF00000 0000 00100000 0000 2 AddressRangeMemory(EfiLoaderData)

看的出來這台是1MB 的BIOS ROM吧 ...^^


Dump Memory map v1.0.0 by Harrison Hsieh

星期二, 7月 22, 2008

CRB V.S ERB

公板,大家都這樣叫,CRB (Customer Reference Board) ,這是入行的時候一直聽到的名詞。

記得當入行的時候很多人都跟我說I晶片公司會出ㄧ個CRB 板子,然後我們也會有個CRB BIOS,剛開始的時候搞不清楚那是什麼,後來才慢慢的有些概念。

查詢了相關文獻中指出,以前晶片組廠商各家爭鳴,但是相容性卻是個最大的問題,後來就有些廠商乾脆就自己做塊板子然後把自己的晶片組放上去,順便跟客戶展示一下Performance ,這塊板子就是所謂的CRB,用來給客戶參考用的板子。

隨著時間的演變,系統廠便直接參考CRB的設計去設計出不同的系統出來,也就是我們現在在做的事情,這樣的好處是不用擔心太多相容性的問題,而且可以快速開發出機種。

有些系統廠可能直接拿CRB板子,上面可能就多加個USB 接口就是一個機種,然後就可以拿去賣了,當然也有些系統廠特別針對某些晶片功能去設計一些特別的Features,當然售價也就不同於直接拿CRB修改的機種。

ERB, Evaluation Reference Board 當某個新的晶片組在研發過程中,總是會需要有模擬的板子來測試,因此這類型的板子會在現成的Platform 基礎上,去配置出新的晶片組的線路,並且讓BIOS廠商開始Study ㄧ些相關問題(Bring up next BIOS code),由於他是模擬的環境,所以往往Bring up出來的BIOS code跟實際上新的晶片組的CRB BIOS code還是會有些差距。

實際上我並沒有參與過CRB/ERB開發過程,畢竟我是系統端的BIOS, 因此我不能確定我所述一定正確,如有誤的地方請大家不吝指正。
  

星期一, 7月 21, 2008

Verb Table v.s S3 resume

前幾天在英業達的網友小偉用msn問了我一個問題,有關於Verb Table 在S3回來後不正確的問題.
他人還在大陸打拼中,目前情況不明,也不知道能不能回的了台灣........在此希望他能順利解決問題,早點回家吧!

Verb Table , 一般我們在設定的時候就是拿著Data Sheet然後設定相關的設定值進去BIOS code或是偷懶點請教廠商設定值是什麼然後加入進去,而BIOS會自己透過相關介面寫入Audio device.

在bios的觀點中,我們進入S3 前我們會去存PCI Regs 以確保HDA 相關暫存器有回填正確,當 S3 Resume 後一般我們會去回填PCI Reg 但是不會去回填Verb Table , 頂多就是拿工具去看S3 resume後Verb table是否一樣(一般都一樣),所以進入S3的時候並不會把Verb Table儲存到RAM中. 以上是我原本接觸的這部分設定時候的認知........但是經過小偉一問,我才發現原來我錯了 >.<

目前查詢到的資料如下:

Windows XP 之前的作業系統 - S3 Resume 時 , BIOS 需要自己手動回填Verb Table ,因為OS不會幫你回填.

Vista - 作業系統"理論上應該會/看似"會幫你回填 ,不過我沒找到M$有相關的說明,只有在某"紅皮"的書裡面有提到(也有可能不會=.=), 因此我們BIOS端就不需要再去填 (因為我都是接觸到這種會自己填的OS , 所以讓我以為BIOS 不用再填 一次, 由此可知 bios的知識還真的不能以偏蓋全,而且多接觸不同種類的平台才能累積更多經驗 >.<)

由於我接觸的還是某大公司的晶片組 , 而情況大概就是這樣 , 在某本書上提到的資訊是屬於保密部分,所以我也不能說太清楚,請自行查閱有關這部分的說明. 至於其他家的晶片組請自行測試.

另外BIOS如果要回填Verb Table , 做法大同小異 , 就是註冊SMI Routine , 在S3 Resume的點去跑你的Routine , 然後自己在回填一次Verb Table就可以了!

至於註冊方式, 依照各家bios做法不同,所以請自行參考BIOS廠商的範例!