1. 开机后,加载nvram,围绕nvram_daemon.c中main函数进行
代码:
alps/vendor/mediatek/proprietary/external/libnvram/nvram_daemon/nvram_daemon.c
1)152 int main(void) { 153 int iMaxLidNum = 0; 154 int ret_callback = -1; 155 156 iMaxLidNum = NVM_Init();--NVM_Init只在开机阶段init一次,init完成后会置init flag为1,后面过程就不再重复进行init,以免消耗资源 157 NVRAM_LOG("Total nvram Lid number is %d\n", iMaxLidNum); 158 umask(000); 159 if (iMaxLidNum <= 0) { 160 NVRAM_LOG("Total nvram Lid number is error !!!\n"); 161 exit(EXIT_FAILURE); 162 } 163 164 if (nvram_emmc_support() || nvram_ufs_support()) { 165 if (!Check_UpdateStatus()) { 166 NVRAM_LOG("fail to check upgrade status in first boot\n"); 167 } 168 } 169 #ifdef MTK_NVRAM_AUTO_BACKUP 170 if (!FileOp_CmpBackupFileNum()) { 171 FileOp_BackupToBinRegion_All(); 172 FileOp_SetCleanBootFlag(true); 173 } else { 174 #endif 175 if (!FileOp_RecoveryData()) 176 //if(!FileOp_RestoreFromBinRegionForDM()) 177 { 178 NVRAM_LOG("Bin Region Restore to NvRam Fail\n"); 179 //exit(EXIT_FAILURE); 180 } 181 #ifdef MTK_NVRAM_AUTO_BACKUP 182 } 183 #endif 184 185 if (!Check_FileVerinFirstBoot()) { 186 NVRAM_LOG("Check FILE_VER in first boot, and fail to generate FILE_VER\n"); 187 } 188 189 //Add for product info feature 190 if (nvram_new_partition_support()) { 191 NVRAM_LOG("Begin excute customer callback!!!\n"); 192 init_callback(); 193 if (callback_for_nvram_daemon != NULL) 194 ret_callback = callback_for_nvram_daemon(); 195 NVRAM_LOG("Callback return %d\n", ret_callback); 196 } 197 //end for product info feature 198 199 if (!Init_AllThreads_In_Nvram()) { 200 NVRAM_LOG("init all threads fail\n"); 201 } else { 202 if (0 == property_set("vendor.service.nvram_init", "Ready")) { 203 NVRAM_LOG("Set Ready property success\n"); 204 } else { 205 NVRAM_LOG("Set property failed, %s\n", (char*)strerror(errno)); 206 } 207 } 208 209 NVRAM_LOG("NVRAM daemon sleep !\n"); 210 sleep(10); 211 NVRAM_LOG("NVRAM daemon sync start !\n"); 212 sync(); 213 NVRAM_LOG("NVRAM daemon sync end !\n"); 214 NVRAM_LOG("NVRAM daemon exits !\n"); 215 exit(EXIT_SUCCESS); 216 } 217 2)函数Init_AllThreads_In_Nvram中遍历g_akNUData数组
98 bool Init_AllThreads_In_Nvram(void) { 99 int i, ret; 100 void* thread_result; 101 for (i = 0; i < NU_MAX; ++i) { 102 if (g_akNUData[i].start_routine) { 103 ret = pthread_create(&g_akNUData[i].kThread, NULL, g_akNUData[i].start_routine, 104 NULL); 105 if (ret != 0) { 106 //NVRAM_LOG("%s Thread creation failed\n", g_akNUData[i].pcName); 107 return false; 108 } 109 } 110 } 111 //NVRAM_LOG("Finish thread create\n"); 112 113 for (i = NU_MAX - 1; i >= 0 ; --i) { 114 if (g_akNUData[i].start_routine) { 115 ret = pthread_join(g_akNUData[i].kThread, &thread_result); 116 if (ret != 0) { 117 //NVRAM_LOG("%s Thread join failed\n", g_akNUData[i].pcName); 118 return false; 119 } 120 } 121 } 122 //NVRAM_LOG("Finish thread joint\n"); 123 return true; 124 }
3)g_akNUData数组中跑到NVRAM_WIFI,由此进入到wifi moudle nv操作
80 static NVRAM_USER_DATA g_akNUData[NU_MAX] = { 81 {"Battery", 0, NVRAM_BATTERY}, 82 #ifdef NVRAM_HAVE_WIFI_BT 83 {"Bluetooth", 0, NVRAM_BT}, 84 {"WIFI", 0, NVRAM_WIFI}, 85 #endif
2. 下面进入到nvram_wifi.c中,开始进行wifi模块的nvram动作
63 /* Just tell NVRAM to create wifi default record */ 64 void* NVRAM_WIFI(void* arg) { 65 F_ID wifi_nvram_fd, wifi_custom_nvram_fd; 66 int rec_size = 0; 67 int rec_num = 0; 68 #ifdef WIFI_MULTI_NVRAM_SUPPORT 69 WIFI_CFG_PARAM_STRUCT wifi_nvram, zero; 70 unsigned int chipId = 0; 71 int chipId_ready_retry = 0; 72 char ready_val[PROPERTY_VALUE_MAX] = {0}; 73 char chipId_val[PROPERTY_VALUE_MAX] = {0}; 74 char hwboardid[PROPERTY_VALUE_MAX] = {0}; 75 #endif 76 //NVRAM_LOG("[NVRAM Daemon]wifi lid %d ++\n",AP_CFG_RDEB_FILE_WIFI_LID); 77 NVRAM_LOG("[NVRAM Daemon]wifi lid %d ++\n", iFileWIFILID); 78 //wifi_nvram_fd = NVM_GetFileDesc(AP_CFG_RDEB_FILE_WIFI_LID, &rec_size, &rec_num, true); 79 wifi_nvram_fd = NVM_GetFileDesc(iFileWIFILID, &rec_size, &rec_num, ISWRITE); 80 NVRAM_LOG("[wifi] wifi FD %d rec_size %d rec_num %d\n", wifi_nvram_fd.iFileDesc, rec_size, rec_num); 81 82 #ifdef WIFI_MULTI_NVRAM_SUPPORT 83 do { 84 if (property_get("vendor.connsys.driver.ready", ready_val, NULL) && 85 0 == strcmp(ready_val, "yes")) { 86 property_get("vendor.connsys.adie.chipid", chipId_val, NULL); 87 chipId = (unsigned int)strtoul(chipId_val, NULL, 16); 88 break; 89 } else { 90 chipId_ready_retry ++; 91 usleep(500000); 92 } 93 } while (chipId_ready_retry < 100); 94 95 NVRAM_LOG("[wifi] chipId = %x chipId_ready_retry = %d\n", chipId, chipId_ready_retry); 96 if (rec_num != 1) { 97 NVRAM_LOG("Unexpected record num %d", rec_num); 98 NVM_CloseFileDesc(wifi_nvram_fd); 99 return NULL; 100 } 101 102 if (read(wifi_nvram_fd.iFileDesc, &wifi_nvram, rec_num * rec_size) < 0) { 103 NVRAM_LOG("Read NVRAM fails %d\n", errno); 104 return NULL; 105 } 106 107 memset(&zero, 0, sizeof(WIFI_CFG_PARAM_STRUCT)); 108 109 lseek(wifi_nvram_fd.iFileDesc, 0, 0); 110 if (0 == memcmp(&wifi_nvram, &zero, sizeof(WIFI_CFG_PARAM_STRUCT))) { 111 if (chipId == 0x6631) { 112
第一个主要动作在NVM_GetFileDesc中
先open WIFI文件,检查WIFI file是否存在
4832 if (IsRead) { 4833 iFileDesc = open(pCfgFielTable[iRealFileLid].cFileName, O_RDONLY); 4834 } else { 4835 iFileDesc = open(pCfgFielTable[iRealFileLid].cFileName, O_RDWR); 4836 }
如果不存在,Create the dir path,并NVM_ResetFileToDefault
4842 if (iFileDesc == -1) { //if file doesn't exist 4843 if (access(g_pcNVM_Flag, F_OK) == 0) { 4844 NVRAM_LOG("File is not exist, try to restore from binregion!!!"); 4845 for (i = 0; i < (int)g_Backup_File_Count; i++) { 4846 if ((unsigned int)file_lid == aBackupToBinRegion[i].iLID) { 4847 if (NVM_RestoreFromBinRegion_OneFile(file_lid, NULL)) { 4848 NVRAM_LOG("successfully restore.\n"); 4849 goto ProtectData; 4850 } 4851 break; 4852 } 4853 } 4854 } 4855 NVRAM_LOG("Create the dir path of %s\n", pCfgFielTable[iRealFileLid].cFileName); 4856 iFileDesc = open_file_with_dirs(pCfgFielTable[iRealFileLid].cFileName, 4857 O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); //create the file 4858 if (iFileDesc == -1) { 4859 NVRAM_LOG("Error Num %s\n", (char*)strerror(errno)); 4860 NVRAM_LOG("Error NVM_GetFileDesc open_file_with_dirs file fail: %s\n", 4861 pCfgFielTable[iRealFileLid].cFileName); 4862 } else { 4863 close(iFileDesc); 4864 } 4865 if (!NVM_ResetFileToDefault(file_lid)) { 4866 NVRAM_LOG("ResetFileToDefault Failed\n"); 4867 return FileID; 4868 } 4869 }
需要关注 NVM_ResetFileToDefault中的switch (pCfgFielTable[iRealFileLid].stDefualType,与CFG_file_info_custom.h中的参数设置:DEFAULT_ZERO
106 "/mnt/vendor/nvdata/APCFG/APRDEB/WIFI", VER(AP_CFG_RDEB_FILE_WIFI_LID), CFG_FILE_WIFI_REC_SIZE, 107 CFG_FILE_WIFI_REC_TOTAL, DEFAULT_ZERO, 0, DataConvert , WIFI_ConvertFunc_wifimac 108 }, 109
如果存在,则比较前后版本的wifi LID version值并决定是否进行覆盖
4869 } else { 4870 close(iFileDesc);//avoid the bug of re-open file 4871 if (!NVM_CmpFileVerNo(file_lid)) { 4872 // if file version is not same, convert it. 4873 if (pCfgFielTable[iRealFileLid].bDataProcessingType == DataReset) { //Reset Data 4874 NVRAM_LOG("NVM_ReadFileVerInfo NVM_CheckFileInfo Fail: Reset!!! \n"); 4875 iFileDesc = open(pCfgFielTable[iRealFileLid].cFileName, O_TRUNC); 4876 if (iFileDesc == -1) { 4877 NVRAM_LOG("NVM_Clear File Content Fail_Get File Desc \n"); 4878 return FileID; 4879 } 4880 close(iFileDesc); 4881 if (!NVM_ResetFileToDefault(file_lid)) 4882 return FileID; 4883 } else { 4884 NVRAM_LOG("NVM_ReadFileVerInfo NVM_CheckFileInfo Fail: Convert!!! \n"); 4885 //only for test 4886 iResult = NVM_DataVerConvert(file_lid); 4887 if (iResult == 0) { 4888 iFileDesc = open(pCfgFielTable[iRealFileLid].cFileName, O_TRUNC); 4889 if (iFileDesc == -1) { 4890 NVRAM_LOG("NVM_Clear File Content Fail_Get File Desc \n"); 4891 return FileID; 4892 } 4893 close(iFileDesc); 4894 if (!NVM_ResetFileToDefault(file_lid)) 4895 return FileID; 4896 } 4897 } 4898 } 4899 4900 }