MTK之NVRAM研究(1)
MTK之NVRAM研究[一]
lzq :2009-7-16 下午 04:54:37
由NVRAM檔案管理器管理的資料單元都是邏輯資料項,一個數據項可以被看作為一個固定大小的記錄,所以我們根據他們的記錄的大小將所有的邏輯資料項分為兩種型別;
1,透明資料元(Transparent EF):這個型別的資料項的記錄的大小為一個byte;因此,這種資料項可以認為是一系列的bytes;
2,線性固定資料元(linear fixed EF):這個型別的資料項的記錄的大小遠大於一個byte;所有的資料按線性儲存;
如下圖所示:
一,先來看“線性固定資料元”
首先我們來新建一項NV;分析每個步驟的原理;
總的步驟必須遵循如下幾步:
1,在檔案:“nvram_user_defs.h”的列舉結構體“nvram_LID_cust_enum”中定義一個新的LID:“NVRAM_EF_[new logical data item name]_LID”;
注意:請將新LID項加在NVRAM_EF_LAST_LID_CORE.之前;
ex: NVRAM_EF_PORT_SETTING_LID;
lzq:這個LID項的主要作用是什麼呢?為什麼一定要新增一個LID?因為NVRAM中的資料是在fs檔案系統的管理中操作的,而文
件操作需要識別資料項和管理資料項,都是通過這個LID來操作的;
2,在檔案:“nvram_user_defs.h”中定義兩個常量:SIZE和TOTAL;
ex: #define NVRAM_EF_PORT_SETTING_SIZE 16
#define NVRAM_EF_PORT_SETTING_TOTAL 1
lzq:既然是一塊記憶體,很明顯就必須要設定這塊記憶體的大小;這樣將結構體的資料儲存和讀取時都很容易的操作到了特定的記憶體中;
並且有效的控制的記憶體不足和溢位的問題;就像是初始話一個數組的大小;
(lzq_091216_補充:如果size是個結構體,則注意這個結構體的定義就和上面的定義寫在一起
如:
#ifdef __HL_WEB_PHONE__
typedef struct
{
kal_uint8 status; //open or close;
kal_uint32 phone_number[11]; //本機號碼;
kal_uint8 number_exten[10];//號碼字首;
kal_uint8 number_zone[8]; //本地區號;
}MY_WEB_PHONE;
#define NVRAM_EF_MY_WEB_PHONE_DATA_SIZE sizeof(MY_WEB_PHONE) //MY_WEB_PHONE
#define NVRAM_EF_MY_WEB_PHONE_DATA_TOTAL 1 //1
#endif
3,在檔案:“custom_nvram_editor_data_item.h”中定義版本號:“NVRAM_[new data item name]_LID_VERNO”。
ex: #define NVRAM_EF_PORT_SETTING_LID_VERNO "000"
lzq:由於檔案系統管理了這些NV資料;這些資料難免要進行各式的操作,比如修改,新增,刪除的操作,那麼檔案系統是怎麼知道
它所管理的這些NV資料已經改變了呢?就是通過這個版本號來識別的,比如你修改了某個NV資料但沒有更該它的版本號,檔案
系統是不會對原始資料更改的;只有在更改了NV值並且修改了版本號,這時檔案系統才識別到已經更改,並進行相應的資料更新
例如 short型別NV的版本號是:NVRAM_EF_CACHE_SHORT_LID_VERNO ;
4,在檔案:“nvram_user_config.c”中設定這個新nv項的預設值;
ex:
static kal_uint8 const NVRAM_EF_PORT_SETTING_DEFAULT[] = {
0x01, 0x00,
0x00, 0x00,
0x00, 0xC2, 0x01, 0x00,
0x00, 0xC2, 0x01, 0x00,
0x01, 0x00, 0x00, 0x00
};
lzq:在申請了一塊記憶體後,需要進行初始化預設值;這樣在手機的異常時,比如恢復出廠設定時,NV將只載入預設值;
5,在檔案:“nvram_user_config.c”中的結構體陣列logical_data_item_table_cust[]中新新增一個條目(Add a new entry);
注意:這個新的條目是設定這個LID項的屬性的;以提供檔案系統來對它操作;
ex:
{
NVRAM_EF_PORT_SETTING_LID,
NVRAM_EF_PORT_SETTING_SIZE,
NVRAM_EF_PORT_SETTING_TOTAL,
NVRAM_EF_PORT_SETTING_DEFAULT,
NVRAM_ATTR_AVERAGE,
NVRAM_CATEGORY_USER,
"MP1y", //注意:在這裡如果上個是MP1y,那麼這裡應該為加一為:MP2y,表明有新的條目添加了;
VER(NVRAM_EF_PORT_SETTING_LID),
"Port Settings\0",
NVRAM_RESERVED_VALUE
},
6,在檔案custom_nvram_editor_data_item.h 中新增結構體定義;這個結構體定義只為了在使用mata工具時,能看到的新新增的NV項的結構體陣列中的各個值;如果不新增將在mata工具中看不到這個新新增的nv項 ;
ex:這個是透明資料元byte在META工具中將要顯示的byte的NV項中所有記錄的字串描述陣列的結構體;
typedef struct
{
kal_uint8 CacheByte[NVRAM_CACHE_SIZE];
} nvram_cache_byte_struct ;
7,在檔案:custom_nvram_editor_data_item.h中.新增 bit-level 說明;這個也是隻為了在mata工具中的操作而實現的;在程式中並用不到 ;
ex:這個是byte項的NV 的META工具中的字串初始化預設值;
LID_BIT VER_LID(NVRAM_EF_CACHE_BYTE_LID) nvram_cache_byte_struct*NVRAM_CACHE_TOTAL
{
CacheByte:"One-byte parameter setting ";
CacheByte[14]
{
default_lang:8 "Default Language "
{
};
};
CacheByte[24]
{
time_zone:8 "Time Zone (Current City )"
{
};
};
CacheByte[25]
{
date_format:8 "Time Format "
{
};
};
CacheByte[26]
{
date_format:8 "Date Format "
{
};
};
};
整個過程如下圖:
lzq總結:NV資料實現了資料的讀防寫,保證了資料在手機上正常而安全的使用;我們知道對於手機上的一些屬性值,比如開機聲音,待機畫面等是由一些資料來控制的,這些資料是全域性的,可以在隨時隨地的對它呼叫;如果是在一個遊戲應用中,我們只要將它設定為一個全域性的變數,在遊戲開始時進行初始化就可以了;但在手機上我們必須保證這些資料不能丟失,並且在整個系統執行中當系統出現數據損壞並崩潰時,這些資料也是不會被丟失和更改;保證了手機系統的安全執行;也許我們可以說為什麼不用一個檔案來儲存這些資料呢?我們知道如果用檔案的話,雖然實現了資料的異地儲存,但一旦這個檔案丟失,將導致系統致命錯誤;另外,這些資料接受使用者的個性修改,如果用檔案儲存的話,資料修改並不方便;而且在讀寫速度上明顯不及直接NVRAM儲存器的操作;因此,我們可以這樣認為,NV讓我們將一些資料從全域性中取了出來,並放入了一個不能擦除的儲存器中保護起來;
接下來讓我們看看NVRAM的結構:
從上圖中我們發現,在檔案系統中Data Item Management System 管理著NVRAM;而這個管理系統(Data Item Management System)通過內部的一個查詢表(lookup table)來獲得每個資料項的具體細節;
而這個查詢表(lookup table )包含以下4個部分:
1. MT reign, for project independent data items;
2. MP reign, for MTK /PMT common applications;
3. CT reign, for the customer usage.
4. CV reign, for the vendor of customer usage.
下圖顯示了NVRAM定製檔案佈局。我們經常操作的檔案一般在CT部分;
NVRAM LID 的定義部分都在以下幾個檔案中進行:
- nvram_data_items.h : for MT use
- nvram_data_items.c : for MT use
- nvram_common_defs.h : for MP use
- nvram_common_config.c : for MP use
- nvram_user_defs.h : for CT use
- nvram_user_config.c : for CT use
- nvram_cust_pack.c: for CustPack use
- nvram_vendor_config.c: for CV use
- nvram_vendor_defs.h: for CV use
META tool 的說明介紹內容都在以下幾個檔案中實現;:
- nvram_editor_data_item.h: for MT use
- common_nvram_editor_data_item.h : for MP use
- custom_ nvram_editor_data_item.h : for CT use
- vendor_nvram_editor_data_item.h: for CV use
現在我們回頭去看步驟5,新增新的條目的操作中,我們會問,為什麼要新增新的條目,而且在這些變數中,各個項的涵義是什麼呢? 如下:
ex:
{
NVRAM_EF_PORT_SETTING_LID,
NVRAM_EF_PORT_SETTING_SIZE,
NVRAM_EF_PORT_SETTING_TOTAL,
NVRAM_EF_PORT_SETTING_DEFAULT,
NVRAM_ATTR_AVERAGE,
NVRAM_CATEGORY_USER,
"MP1y",
VER(NVRAM_EF_PORT_SETTING_LID),
"Port Settings\0",
NVRAM_RESERVED_VALUE
},
我們剛才知道了,管理系統(Data Item Management System)通過內部的一個查詢表(lookup table)來獲得每個資料項的具體細節的,我們在這裡實現的這個新的條目就是為了讓管理系統通過查詢表來找到它並對它進行操作; 所以每個新的LID都要來這裡新增新的條目;
那麼每個新的條目的具體的資料結構是什麼樣的呢?如下是它的定義:
typedef struct
{
nvram_lid_enum LID;
kal_uint16 size;
kal_uint16 total_records;
kal_uint8 const *default_value;
nvram_attr_enum attr;
nvram_category_enum category;
kal_char fileprefix[FILE_PREFIX_LEN + 1];
kal_char fileverno[FILE_VERNO_LEN + 1];
kal_char *description;
kal_uint8 record_ID;
} ltable_entry_struct;
具體涵義如下:
接下來分別分析一些具體資料項的涵義:
1,屬性attr ;
屬性選項是個可選的,它由列舉:nvram_attr_enum定義:
NVRAM_ATTR_AVERAGE: 0x0000 //這是個預設的屬性選項;
NVRAM_ATTR_IMPORTANT: 0x0001 //當一個IMPORTANT的資料項被更改時,會先將相關程式停止,並被要求進行備份和儲存,
//只有在成功備份和儲存後,才會將程式重新安全開啟;
NVRAM_ATTR_WRITEPROTECT: 0x0002 //防寫,只讀;
NVRAM_ATTR_MULTIPLE: 0x0004 //如果一個數據項的屬性是multiple,那麼NVRAM會自動將它做一個備份,並當在其中有一個數據
//被損壞時,NVRAM會從另個數據中將它還原;
NVRAM_ATTR_CONFIDENTIAL: 0x0008 //對資料採用對稱演算法進行加密或解密;所以:mulitiple+confidential能實現最好的資料保護;
NVRAM_ATTR_MULTIREC_READ: 0x0010 //適用於那些需要一次性對一資料進行多次讀取操作的資料項;
NVRAM_ATTR_OTP: 0x0020 //This attribute is supported only if One Time Programming (OTP) function exists on the flash storage. NVRAM will
//maintain a small table to OTP region; the table consists of all OTP data items, by order in the lookup table.
NVRAM_ATTR_DIFFERENCE: 0x0080 //NVRAM保留。
2,模板category;
這個選項和attr非常相似,可以說是attr的分支;一個數據項可以屬於很多category的或者是很多資料項屬於一個category;所以NVRAM需要找到那些需要被category重新設定的資料項;它的列舉包含如下:
NVRAM_CATEGORY_USER: 0x0000 //預設屬性;
NVRAM_CATEGORY_SYSTEM: 0x0001 //一旦版本號更改,這個資料項將被初始化為預設值;
NVRAM_CATEGORY_COMPOSED: 0x0002 //NVRAM 保留;
NVRAM_CATEGORY_FACTORY: 0x0004 //當MSG_ID_NVRAM_RESET_REQ隨著 reset_category = NVRAM_RESET_FACTORY,NVRAM
將重新設定NVRAM_CATEGORY_FACTORY的值,並且清除預定義的檔案和設定;
NVRAM_CATEGORY_MULTI_DEFAULT: 0x0008 //這樣的資料項的每個記錄可能有不能的值,但是所有的預設值必須在一個連續的數組裡。
NVRAM_CATEGORY_CUSTPACK: 0x0010 //NVRAM will auto assign default values in CustPack BIN to this category. Once the version of
CustPack BIN changes, NVRAM_CATEGORY_CUSTPACK will be reset to default.
NVRAM_CATEGORY_BRANCH: 0x0020 //This category of data item will be kept even the branch number of software version changes. Every
time the branch number is different from previous one, NVRAM will clear all data items except NVRAM_CATEGORY_BRANCH.
NVRAM_CATEGORY_SHADOW: 0x0040 //This category is only used for single bank NOR-flash. With single bank NOR-flash,
only this category could be modified in normal mode. NVRAM uses Shadow mechanism to
make device type transparent to applications. Please see chapter 7. to get more details.
IMPORTANT: Shadow needs additional memory.
NVRAM_CATEGORY_SHADOW_MS: 0x0080 //When USB boot mode, all data item can’t be accessed because of storage exporting.
Thus NVRAM uses Shadow mechanism to make a few applications still can access their data.
IMPORTANT: Shadow needs additional memory.
我們再來看看LID檔案的命名和LID的版本號規則:
File Name Format:
(0~3) File Name | ( 4) M. | (5~7) Version |
1. File Name: The first 4 bytes of the File Name Format are used for the file name, which needs to be
distinguishable from all other file names. The File naming rule:
- Data items in the core: MT[x][y], where x and y in the range (0~9, a~z)
- Data items in custom/common folder: MP[x][y] , where x and y in the range (0~9, a~z)
- Data items in custom/app folder: CT[x][y] , where x and y in the range (0~9, a~z)
- Data items in vendor folder: CV[x][y] , where x and y in the range (0~9, a~z)
-
?? 4-byte filenames. The file naming MT[x][y], MP[x][y] ,CT[x][y] and CV[]x[y] allow maximum sequence
number up to 36*36 = 1296 each.
IMPORTANT: Any file name MUST be unique.
2. M byte: The byte is used to indicate the ‘multiple’ attribute of the data item.
- If a data item is defined to be ‘multiple’, M can be ‘a’ or ‘b’ to represent two copies of the file.
- If a data item is defined w/o the ‘multiple’ attribute, M will be ‘_’.
3. Version: Three human-readable digits, for example, ‘000’
?? the version number is incremented when a data item is added / deleted or its data structure is changed, or
its attribute is changed.
?? For ease of reading, the 3-byte version number can be used from 000 ~ 999. That means a single LID can
be versioned 1000 times. If the limit is hit, a work-around is to delete the LID and make it a new one with
version 000.