本文轉載自:https://blog.csdn.net/suofeng12345/article/details/52713993
一,引言
1. 什么是NV
高通平台的NV,保存了系統運行過程中各個模塊可能用到的一些參數值,它是以單個文件的形式保存在EFS中,但用戶是不能隨意訪問的,只能通過QXDM來進行讀寫。對於60X0平台,NV就有將近5千多項。
2. 為什么要備份恢復NV
NV值是需要通過校准和終測才能使手機硬件達到最佳工作狀態,特別是其中的RF相關的NV項,經過校准及終測后,每台手機的這些NV值基本上都不一樣,又加上NV數據是是存儲在EFS,而EFS的數據很可能遭到破壞(如:重新燒寫版本),這時的NV數據也將被破壞,之前校准和終測后的NV數據也將無法恢復,使得手機將面臨重新走校准、終測的生產流程。
3. 備份恢復的原則
備份:首先要確定需要備份的NV有那些項(一般是RF相關的),一旦檢測到對NV項的修改,則在EFS中創建一個標志文件,在每次開機時判斷這個標志文件是否存在而執行是否做備份。
恢復:同樣在每次開機的時候判斷EFS中是否存在恢復標志文件,如果不存在則恢復NV,然后創建這個標志文件,創建成功后,下次開機就會不進行恢復。
二,NV的備份
1. 備份的區域
由於所需要備份的NV項不是很多(一般就幾十項),所以我們可以在FLASH上開辟一塊區域專門用於保存NV備份數據。備份區域是以一定的組織格式來存放數據的(如圖):

其中每個Item都是以:Item號+內容大小(Byte)+內容 的形式來存放的。比如第10項NV可能有2個值,分別是0x11,0x22,則它在FLASH中存放的形式就是:
0a 00 00 00 02 00 00 00 11 22 --------(這里Item號、內容大小都是UINT32 類型)。
2. 備份的時機
一般一台機器在出廠前,都要通過終測儀進行校准、終測。這個過程就會修改到一些RF相關的NV項,也就是我們需要備份的NV。對於軟件上來說,不管是用終測儀,或則高通的QPST,QXDM工具來修改NV項,最后都會調用到寫NV的函數:nvdiag_write(),我們可以在這個函數里面創建備份標志文件,在下次系統啟動時讀取這個文件是否存在來判斷是否要做備份。
3. 備份的方法
之前說過,高通的NV都是以單個文件的形式存放在EFS中,每個文件的文件名就是NV項的序列號,所以我們可以直接調用EFS的讀函數nv_read來讀取某個特定的NV項的值。
三,NV的恢復
1. 恢復的時機
恢復就是備份的逆過程,即把存放在FLASH中的備份數據恢復到EFS中對應的NV項中去。如果手機出廠以后一旦要進行軟件升級,並且同時需要破壞EFS,則就不得不進行NV項的恢復。所以系統在每次開機運行時,都會檢查文件系統中是否存在恢復標志文件,如果不存在則進行恢復並創建;反之則不恢復。這就要求我們每次發布的軟件版本中打包的EFS不能包含這個標志文件。
2. 恢復的方法
進行恢復的時候就要讀取備份區域中備份的每項NV,然后同樣調用EFS的寫函數nv_write把數據寫到對於的NV項中。
四,小結
目前幾個項目都是使用這套備份恢復機制,通過反復實驗,沒有發現什么問題。之前的恢復標志是放在FLASH中,即在升級版本的時候在FLASH中設置一個標志位,在升級完成以后開機,讀取這個標志位,如果存在則恢復,恢復成功后清除這個標志。但是在一個手機項目(采用spansion 250M nor+ 128M ram)經常遇到升級完版本開機運行緩慢的BUG,通過跟蹤發現是在清除恢復標志的時候出了問題,之后把恢復標志也放到EFS中,這個BUG就沒有出現。 現在懷疑是在恢復的時候,對FLASH的一個BANK進行同時讀寫導致的,有待進一步驗證。