天天看點

【UEFI】--- 探究BIOS NvRam空間的位置以及大小

按照國際慣例--先上問題:

1. 什麼是NvRam空間,裡面存儲了什麼資料

2. 如何找到NvRam空間在BIOS-bin檔案中的位置

NvRam空間的學名為: Non-Volatile Ram即非易失性存儲空間,簡單來說就是一段掉電也不丢失資料的存儲空間。這類存儲媒體有很多,像多數的E2prom,Rom都是可以作為該類空間的媒體。而具體到BIOS的話,多數情況下可以了解為在BIOS-Rom中挖了一段空間,用來作為我們希望掉電也不丢失資料的存儲空間。

問題1:NvRam空間都存儲了什麼資料?

NvRam在BIOS實際用途中其實分為幾類,其中最常用的應該是就是BiosSetup配置界面下你能看到的一大堆配置接口了吧。BIOS-Setup下所有的資料變量最終在代碼中呈現的樣子應該是這樣:

【UEFI】--- 探究BIOS NvRam空間的位置以及大小

 當然其實還有很多,沒有完全顯示出來,而通過最後的SYSTEM_CONFIGURATION這個結構體變量名應該也可以看到,所有的變量最終都被封裝進了一個很大的結構體變量中。最終這個結構體變量會被存在NvRam空間中,使用者每次在BIOS Setup界面下的操作其實最終都是修改這個變量并且最後儲存在Rom中NvRam那段空間中。

問題2:NvRam空間在BIOS-Bin檔案的哪個位置?

提出這個原因的目的是因為有一個需求是要求BMC在更新BIOS時要做到儲存使用者設定資料,那麼方案就是BMC在更新BIOS的資料時,先從BIOS中把NvRam那段空間的資料讀出來做備份,然後刷掉整個ROM空間中的資料,再把新版本得BIOS資料寫入ROM存儲媒體中,最後再把預先備份的資料按照BIOS Layout布局寫入指定的位置即可。基于這樣的一個目的,是以BIOS需要提供NvRam空間的布局。也算是折騰了一段時間吧,大緻的方式如下:

1)在layout布局檔案中找到整個工程檔案的整體布局,一般是在*.fdf檔案中,例如我用的insyde的工程可以看到project.fdf檔案可以看到每個區域的Size和Offset公式計算定義。标紅框的時NVRam區域的SIZE,下面也有每個具體的NvRam區域的Offset計算,沒截出來。根據這裡的定義應該能最終可以計算出來。

【UEFI】--- 探究BIOS NvRam空間的位置以及大小

擴充問題思考與分析:

問題3:如何快速計算頻移位址?

在計算這一大堆資料的時候,請一定使用python/shell腳本,不然手算累死了,學會運用的你計算機技能,學習是為了用,學軟體就是為了讓事情變得更簡單。

問題4:為何查閱最終的16M的Bin檔案找不到期望的資料?

根據我最終計算出來的值為0x5b0000,我在編譯出來的16M的BIOS-Bin檔案找不到理想的值,全是0xff。

【UEFI】--- 探究BIOS NvRam空間的位置以及大小

原因:由于目前的BIOS是已經将ME和最原始的BIOS-bin檔案打包進一起後的檔案,是以這裡的0x005b0000實際根本就不是我們原始BIOS的資料。原始BIOS的文檔應該是*.fd檔案,按照我的工程可找到GRANGEVILLE.fd也就是GrangeVille這個平台的BIOS檔案,通過二進制文檔可檢視結果如下圖:GRANGEVILLE.fd這個BIOS源檔案的大小是8M,這個檔案無論大小,還是layout都是由是源碼中*.fdf檔案指定的,具體可查閱該檔案。

【UEFI】--- 探究BIOS NvRam空間的位置以及大小

問題5:為何在GRANGEVILLE.fd找到了目标資料,但實際資料的數量卻少的可憐?

這個地方不得不牽扯到BIOS的代碼執行,雖然BIOS已經定義了大量的NvRam的Variable資料來進行資料儲存,但是這是第一次編譯的結果,實際的資料應該是BIOS代碼在執行時,讀取後再寫入到這個位置的。而且由于Variable實際存儲是以Variable的方式來Get或者Set,是以甚至可能出現同一個ROM不做任何改動過,就在機器上做兩次啟動,然後用燒錄器把BIOS-Bin檔案讀取出來,NvRam空間的資料都是不一樣的。詳細原因就要跟BIOS通過GUID來Get或者Set變量這種方式有關,有時間再把這個給普及下。

問題6:包過ME的Bin檔案如何确定Offset,以及ME是按照什麼規則來進行打包的?

剛已說過,實際BIOS的程式編譯出來的文檔大小是8M,但是我們通過ME工具打包後,通常可以将BIOS擴充到16M或者32M,那麼是如何擴充的呢?我以16M的BIOS.bin構成介紹,如下圖:32M的話,中間OXFF填充部分随之擴大。

【UEFI】--- 探究BIOS NvRam空間的位置以及大小

問題7:借助工具進行分析

我也是後來才知道可以用工具直接分析BIOS最終Bin的構成,以此來确定。不過總歸是要知道原理了解的才深刻,下面簡單介紹下工具,來和我們上述分析過程進行驗證.使用工具為UEFITool.exe工具

【UEFI】--- 探究BIOS NvRam空間的位置以及大小
【UEFI】--- 探究BIOS NvRam空間的位置以及大小

如上圖,我們可以在該工具下,BIOS-Region中NVRam空間的類型,以及詳細資訊。Offset為0x5b0000,Full Size為0x30000。剛開始判斷NvRam空間是,我以為僅有下面标紅的一個,是以對比了半天bin檔案資料,總是對不上。後來才意識到下圖四個都是NvRam的布局,隻是用途不同,下面四個資料的Size相加可得也是0x30000,和工具剛好對上。

【UEFI】--- 探究BIOS NvRam空間的位置以及大小

問題8:就NvRam區域如何在BIOS更新時實作資料保留得功能

 通常情況下,使用者在BIOS下得設定在版本更新時一般是需要儲存的,而且還有個更重要的原因,在BIOS進行作業系統的枚舉時對于新安裝的未知作業系統,其引導檔案的路徑是在Nv區域中的Variable儲存的,是以版本更新時,保留Nv區域的資料更為重要。

這裡提供了一種由BMC系統更新BIOS固件時,保留資料的方案。

首先BIOS的Flash對CPU和BMC均可見,更新固件的動作由BMC完成,BMC系統擦除整個BIOS的Flash,然後将最新的鏡像燒錄寫入的整個flash中。這其中為了實作BIOS的資料儲存,Nv區域一定要提前備份,在寫入新得鏡像後,再将備份的資料寫入到該段區域中。方案還是挺簡單的。過程中遇到幾個難點問題:

  1)  對于Nv區域的起始位址和Size确定,前文已經給出介紹

  2)筆者最開始為了省時省力,直接手動在BIOS的Bin文做了Nv區域的資料替換,但是始終不能成功,從code來看,應該是替換後的區域CRC校驗不過,導緻第一次啟動BIOS又将Nv區域的資料作了恢複。但是這個動作交由BMC完成的時候,就不會遇到這個問題,也不知道什麼原因。

至此,将此次分析中所遇到的所有問題,均分析完畢。如有錯誤之處,歡迎随時聯系我指出。

也請随時關注我的公衆号:像蚊子一樣飛翔。

一起探讨,一起進步!謝謝!