小華的部落格: 2008/6/15 - 2008/6/22

bloggerads_Head

搜尋此網誌

星期四, 6月 19, 2008

NVRAM list v.s NVStore

最近接了一個新的案子,雖然還沒開始Run但是事前的準備也不能少,也因此遇到了新問題,所以在部落格留下紀錄以後好方便查詢!

在跟客戶接觸的過程中,他們要求我提供CMOS NVRAM List ,用過P公司的BIOS的人都知道, P公司會產生這個List ,而這個List其實就是對應我們在Setup Menu中的選項設定值(例如某個item內有Enable/Disable選項而選擇後的值會存放進去CMOS當中) ,有了這份List ,客戶就可以開發自己的工廠測試程式去修改CMOS內的設定值來達到他們的需求(不考慮Checksum問題時可以這樣做)。最常見的就是修改Boot Order (修改開機順序),當然這些工具還是需要BIOS端的支援啦!

而我的問題在於EFI架構中為了一些安全性的考量,已經建議這些設定值的存放地方改至NVStore,即直接寫入至BIOS ROM中的某個規劃出來的區塊,因此我沒辦法直接修改CMOS來達到修改某個item的設定值,除非你在POST的BIOS code中去讀取你自己定義的CMOS位置然後在去改變他,這部分我們學長已經是這樣子的方式來修改BootOrder!


方式一:
AP修改CMOS --> POST過程中BIOS去讀取CMOS值 -->BIOS修改至相關Variable位置

有關於NVStore部分,在不同的bios廠商中做法也是不見得會完全依照當初的建議去做,像是P公司現階段的BIOS code就比較尷尬...因為他不是完全的EFI 架構,所以有一部分還是存放在NVRAM 中 ,一部分是存放在NVStore ,所以在過度期中他還是有提供NVRAM list,只可惜這次的案子不是使用p公司的BIOS =.=!

路不通就自己通, 因此在EFI 架構下我自己寫了一個介面給AP端使用(修改cmos在由POST 開機時讀取出來修改的方式我學長已經實做成功,所以我才試試看改寫另一種方式),方式是透過SW SMI Driver來註冊一個SMI Routine ,然後在這個Routne中去得到AP端傳進來的RAM Buffer,而這塊RAM Buffer中說明了我要去修改/讀取哪一個NV Variable 以及要寫入/回傳的資料 ,因此在DOS或是Windows下就可以很方便的透過這個介面去修改設定值。

而ap端我是採用TC++ 3.0 先去配置一塊記憶體,然後把參數寫進去這塊記憶體,然後用ESI指向這塊記憶體,接著發送SW SMI ,如下面所示

type struct {
DWORD Protocol; (Byte/word/dword)
DWORD VarIndex;
DWORD VarData;
}OEM_BUFFER

STATUS OEM_SMI_Trigger(OEM_BUFFER *inputbuf,OEM_BUFFER *outputbuf)
{
AH=Select Fun (Read/Write)
AL=SW SMI function number
ESI=input buffer
EDI=output buffer
EBX = Signature '$OEM'
DX=B2h
}

方式二:
AP端將參數寫至RAM --> AP端設定好暫存器,指向存放參數的RAM --> AP端觸發SMI --> BIOS透過暫存器得到參數 --> BIOS SMM code設定相關Variable.


結論:
透過方式一的方式簡單又方便,但是缺點在於傳遞的資料量有限,且如果變數過多時會很麻煩!

透過方式二的方式複雜但是可以傳遞較大的資料量,應用也比較廣,變數過多也無所謂,因為BIOS端會把這些item都集中然後放在某個Structure中,所以只要指定好Index就可以了(以前叫做Token),其他應用可以類似寫一個燒BIOS ROM的介面,透過BIOS本身的Code去燒...目前某家EFI BIOS公司就是這樣子去開發Flash utility...