Cstyle的UEFI导读:第18.0篇 NVRAM的工作原理(上)
雖有句話說的好,實(shí)用的東西記在腦子里。沒有的記在筆記本上。
可是如今的信息量越來越大,并且隨著時(shí)間的推移記憶力會(huì)越來越不可靠,所以僅僅好把近期工作之余看的一些東西記錄下來,避免被迅速忘記。這里就記錄一下一些NVRAM相關(guān)的東西。
NVRAM的定義就不必羅嗦了,非易失性存儲器,當(dāng)然這樣的定義非常寬泛。我們且不一樣一個(gè)去說明。這里僅僅說UEFI 里面最經(jīng)常使用的狹義的NVRAM(SPI ROM里面的一塊區(qū)域)。
一般而論UEFI其中會(huì)用到兩塊區(qū)域作為NVRAM分別為NVRAM,NVRAM_BackUp,至于為什么要這么做事實(shí)上原因非常easy。那就是備份和安全保護(hù),應(yīng)為NVRAM在DXE階段是能夠讀寫的,既然能寫就表示可能會(huì)出錯(cuò),比方突然斷電,軟件或者硬件錯(cuò)誤等等,而NVRAM作為UEFI其中非常重要的一個(gè)可供用來提供系統(tǒng)靈活配置的機(jī)制假設(shè)沒有一套完美的容錯(cuò)機(jī)制就會(huì)發(fā)生非常嚴(yán)重的問題,比方某個(gè)block因?yàn)槟承┰虺鲥e(cuò)。我們就須要保證這樣的錯(cuò)誤不會(huì)導(dǎo)致系統(tǒng)的崩潰。
再來,NVRAM事實(shí)上就是在整個(gè)SPI rom的區(qū)域劃分出兩個(gè)FV,這個(gè)FV的屬性是能夠讀寫的,在PEI階段提供readonly variable 的ppi來僅提供讀取的功能。在DXE階段我們就能在RT service里面提供getvariable和setvariable的服務(wù)來通過GUID和variableName來搜索我們須要的變量,如setup的設(shè)定值。在X86其中NVRAM所存儲的區(qū)域是剛好被南橋映射到CPU的內(nèi)存空間,這個(gè)區(qū)域能夠使用MMIO的方式直接讀取和寫入
就類似于x86系統(tǒng)在reset的時(shí)候從FFFFFFF0位置通過MMIO方式讀取第一條指令一樣。這個(gè)區(qū)域的大小是能夠通過南橋的相關(guān)寄存器來設(shè)定的,通常會(huì)在sec階段或者早期的pei階段去設(shè)置它。保證該區(qū)域能被正確的映射。
當(dāng)然我們也能夠使用南橋的SPI控制器來直接使用NOR Flash的讀寫命令來直接讀寫這段區(qū)域,就類似于在dos下用軟件來刷新bios一樣。這樣的通常會(huì)在RT或者是SMM模式下提供一些服務(wù)提供給其它的工具來調(diào)用,這些超出了NVRAM要將的范疇,先無論。
先講下NVRAM在SPI Nor Flahs其中是怎樣存儲的。事實(shí)上它大概分成3部分:每一家的BIOS vendor的實(shí)現(xiàn)都不太一樣,可是主要的東西差點(diǎn)兒相同,就我看到的AMI A4的和UDK2014里面的實(shí)現(xiàn)就不一樣。為了不違法NDA這里就僅僅介紹UDK里面的實(shí)現(xiàn)方式。
第一部分:這里就僅僅有一個(gè)EFI_FIRMWARE_VOLUME_HEADER的頭。主要是將整個(gè)NVRAM當(dāng)作一個(gè)FV來看待,這里FV的位置有是在buid的時(shí)候定義好的不可更改,在AMI的方案其中一般用token來控制,在UDK其中能夠使用FDF里面來定義。
我們能夠從實(shí)際的build logo里面找到它相應(yīng)的位置。然后使用UE來打開2進(jìn)制文件來查看。這里先上一個(gè)UDK里面的圖,這里定義NVRAM存在0x280000位置,長度為0xc000.
第二部分:這里就是FFS的區(qū)域。不同的實(shí)現(xiàn)方式可能不太一樣,能夠使用FFS2或者是FFS的格式。
<img src="http://img.blog.csdn.net/20141030224424031?
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ1N0eWxlXzB4MDA3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
第三部分:這里就是真正的FFS file區(qū)域了,這里的數(shù)據(jù)依照Variable store(VARIABLE_STORE_HEADER)的格式來存儲。然后使用variable來順序的存儲每個(gè)數(shù)據(jù)包含他們的名字,長度,GUID。屬性(VARIABLE_HEADER)
以下是一個(gè)實(shí)際的SPI里面的數(shù)據(jù)存放格式,能夠?qū)φ丈厦娴臄?shù)據(jù)逐個(gè)對照,樓主也對照過AMI的A4的實(shí)現(xiàn)。盡管他們的Variable store和variable的數(shù)據(jù)結(jié)構(gòu)和實(shí)現(xiàn)方式不太一樣。可是實(shí)現(xiàn)起來邏輯上是一模一樣的。區(qū)別在于少量的算法實(shí)現(xiàn)不太一樣,有興趣能夠自己對照看看:
下面先來說NVRAM的讀取,為了簡化,這里臨時(shí)不考慮FTW(FaultTolerantWrite)的部分,先簡介怎樣從NVRAM讀取所需數(shù)據(jù)。這里僅僅須要2個(gè)數(shù)據(jù)結(jié)構(gòu)就能夠完畢對NVRAM變量的索引。一個(gè)是變量的存儲倉庫variable store。一個(gè)是實(shí)際的變量variable他們都有相應(yīng)的文件頭來表示。從剛剛上面降到的FV和FFS開始依次往下查找就能夠了,同一時(shí)候須要注意的是pack的大小,是否須要填充字節(jié)。考慮到Flash的物理特性有可能會(huì)有位反轉(zhuǎn)現(xiàn)象所以在讀之前。須要先校驗(yàn)下面的兩個(gè)文件頭是否合法。假設(shè)出錯(cuò),就須要使用到FTW以及NVRAM_BackUp的機(jī)制來處理,這個(gè)留著下次再說。還有就是下面是基于UDK的實(shí)現(xiàn)。其它的實(shí)現(xiàn)類似A4的實(shí)現(xiàn)跟這個(gè)不太一樣,只是基本差點(diǎn)兒相同也是有GUID和Name來作為變量的頭,然后把變量存儲在緊接著“頭”的后面。詳細(xì)的算法非常easy能夠參考Variable.c這個(gè)文件的實(shí)現(xiàn),僅僅要略微有一點(diǎn)點(diǎn)的基礎(chǔ)就能讀懂,不須要贅述。
好了今天就先記錄到這里,明天繼續(xù)。
轉(zhuǎn)載請注明出處
Cstyle.z.zhou@outlook.com// http://blog.csdn.net/CStyle_0x007
總結(jié)
以上是生活随笔為你收集整理的Cstyle的UEFI导读:第18.0篇 NVRAM的工作原理(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10 字体渲染优化 色彩调整
- 下一篇: 我问我自己,你究竟想成为一个什么样的人?