176af099aSliuyi /* 276af099aSliuyi * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 376af099aSliuyi * Seth Liu 2017.03.01 476af099aSliuyi * 576af099aSliuyi * SPDX-License-Identifier: GPL-2.0+ 676af099aSliuyi */ 776af099aSliuyi 876af099aSliuyi #include <unistd.h> 976af099aSliuyi #include <dirent.h> 10c30d921cSKever Yang #include "config.h" 1176af099aSliuyi #include "DefineHeader.h" 12c30d921cSKever Yang #include "gpt.h" 1376af099aSliuyi #include "RKLog.h" 1476af099aSliuyi #include "RKScan.h" 1576af099aSliuyi #include "RKComm.h" 1676af099aSliuyi #include "RKDevice.h" 1776af099aSliuyi #include "RKImage.h" 1876af099aSliuyi extern const char *szManufName[]; 1976af099aSliuyi CRKLog *g_pLogObject=NULL; 2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec; 2176af099aSliuyi #define DEFAULT_RW_LBA 128 2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n) 2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B) 2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B) 2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B) 2676af099aSliuyi #define ERROR_COLOR_ATTR printf("%c[30;41m", 0x1B); 2776af099aSliuyi #define NORMAL_COLOR_ATTR printf("%c[37;40m", 0x1B); 28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize); 29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize); 30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len); 31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len); 32c30d921cSKever Yang /* 33c30d921cSKever Yang u8 test_gpt_head[] = { 34c30d921cSKever Yang 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00, 35c30d921cSKever Yang 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36c30d921cSKever Yang 0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37c30d921cSKever Yang 0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B, 38c30d921cSKever Yang 0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39c30d921cSKever Yang 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08}; 40c30d921cSKever Yang */ 41c30d921cSKever Yang 4276af099aSliuyi void usage() 4376af099aSliuyi { 4476af099aSliuyi printf("\r\n---------------------Tool Usage ---------------------\r\n"); 45154ee062SEddie Cai printf("Help:\t\t\t-h or --version\r\n"); 46154ee062SEddie Cai printf("Version:\t\t-v or --version\r\n"); 47154ee062SEddie Cai printf("DownloadBoot:\t\tdb <Loader>\r\n"); 48154ee062SEddie Cai printf("UpgradeLoader:\t\tul <Loader>\r\n"); 49154ee062SEddie Cai printf("ReadLBA:\t\trl <BeginSec> <SectorLen> <File>\r\n"); 50154ee062SEddie Cai printf("WriteLBA:\t\twl <BeginSec> <File>\r\n"); 51154ee062SEddie Cai printf("WriteGPT:\t\tgpt <gpt partition table>\r\n"); 52154ee062SEddie Cai printf("EraseFlash:\t\tef \r\n"); 53154ee062SEddie Cai printf("TestDevice:\t\ttd\r\n"); 54154ee062SEddie Cai printf("ResetDevice:\t\trd [subcode]\r\n"); 55154ee062SEddie Cai printf("ReadFlashID:\t\trid\r\n"); 56154ee062SEddie Cai printf("ReadFlashInfo:\t\trfi\r\n"); 57154ee062SEddie Cai printf("ReadChipInfo:\t\trci\r\n"); 5878884ef4SEddie Cai printf("PackBootLoader:\t\tpack\r\n"); 5978884ef4SEddie Cai printf("UnpackBootLoader:\tunpack <boot loader>\r\n"); 6076af099aSliuyi printf("-------------------------------------------------------\r\n\r\n"); 6176af099aSliuyi } 6276af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall) 6376af099aSliuyi { 6476af099aSliuyi string strInfoText=""; 6576af099aSliuyi char szText[256]; 6676af099aSliuyi switch (promptID) { 6776af099aSliuyi case TESTDEVICE_PROGRESS: 6876af099aSliuyi sprintf(szText, "Test Device Total(%lld),Current(%lld)", totalValue, currentValue); 6976af099aSliuyi strInfoText = szText; 7076af099aSliuyi break; 7176af099aSliuyi case LOWERFORMAT_PROGRESS: 7276af099aSliuyi sprintf(szText, "Lowerformat Device Total(%lld),Current(%lld)", totalValue, currentValue); 7376af099aSliuyi strInfoText = szText; 7476af099aSliuyi break; 7576af099aSliuyi case DOWNLOADIMAGE_PROGRESS: 7676af099aSliuyi sprintf(szText, "Download Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024); 7776af099aSliuyi strInfoText = szText; 7876af099aSliuyi break; 7976af099aSliuyi case CHECKIMAGE_PROGRESS: 8076af099aSliuyi sprintf(szText, "Check Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024); 8176af099aSliuyi strInfoText = szText; 8276af099aSliuyi break; 8376af099aSliuyi case TAGBADBLOCK_PROGRESS: 8476af099aSliuyi sprintf(szText, "Tag Bad Block Total(%lld),Current(%lld)", totalValue, currentValue); 8576af099aSliuyi strInfoText = szText; 8676af099aSliuyi break; 8776af099aSliuyi case TESTBLOCK_PROGRESS: 8876af099aSliuyi sprintf(szText, "Test Block Total(%lld),Current(%lld)", totalValue, currentValue); 8976af099aSliuyi strInfoText = szText; 9076af099aSliuyi break; 9176af099aSliuyi case ERASEFLASH_PROGRESS: 9276af099aSliuyi sprintf(szText, "Erase Flash Total(%lld),Current(%lld)", totalValue, currentValue); 9376af099aSliuyi strInfoText = szText; 9476af099aSliuyi break; 9576af099aSliuyi case ERASESYSTEM_PROGRESS: 9676af099aSliuyi sprintf(szText, "Erase System partition Total(%lld),Current(%lld)", totalValue, currentValue); 9776af099aSliuyi strInfoText = szText; 9876af099aSliuyi break; 9976af099aSliuyi case ERASEUSERDATA_PROGRESS: 10076af099aSliuyi sprintf(szText, "<LocationID=%x> Erase Userdata partition Total(%lld),Current(%lld)",deviceLayer,totalValue, currentValue); 10176af099aSliuyi strInfoText = szText; 10276af099aSliuyi break; 10376af099aSliuyi } 10476af099aSliuyi if (strInfoText.size() > 0){ 10576af099aSliuyi CURSOR_MOVEUP_LINE(1); 10676af099aSliuyi CURSOR_DEL_LINE; 10776af099aSliuyi printf("%s\r\n", strInfoText.c_str()); 10876af099aSliuyi } 10976af099aSliuyi if (emCall == CALL_LAST) 11076af099aSliuyi deviceLayer = 0; 11176af099aSliuyi } 11276af099aSliuyi 11376af099aSliuyi char *strupr(char *szSrc) 11476af099aSliuyi { 11576af099aSliuyi char *p = szSrc; 11676af099aSliuyi while(*p){ 11776af099aSliuyi if ((*p >= 'a') && (*p <= 'z')) 11876af099aSliuyi *p = *p - 'a' + 'A'; 11976af099aSliuyi p++; 12076af099aSliuyi } 12176af099aSliuyi return szSrc; 12276af099aSliuyi } 12376af099aSliuyi void PrintData(PBYTE pData, int nSize) 12476af099aSliuyi { 12576af099aSliuyi char szPrint[17] = "\0"; 12676af099aSliuyi int i; 12776af099aSliuyi for( i = 0; i < nSize; i++){ 12876af099aSliuyi if(i % 16 == 0){ 12976af099aSliuyi if(i / 16 > 0) 13076af099aSliuyi printf(" %s\r\n", szPrint); 13176af099aSliuyi printf("%08d ", i / 16); 13276af099aSliuyi } 13376af099aSliuyi printf("%02X ", pData[i]); 13476af099aSliuyi szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.'; 13576af099aSliuyi } 13676af099aSliuyi if(i / 16 > 0) 13776af099aSliuyi printf(" %s\r\n", szPrint); 13876af099aSliuyi } 13976af099aSliuyi 14076af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest) 14176af099aSliuyi { 14276af099aSliuyi if (!pszSrc) 14376af099aSliuyi return false; 14476af099aSliuyi int nSrcLen = strlen(pszSrc); 14576af099aSliuyi int nDestLen = nSrcLen * 2; 14676af099aSliuyi 14776af099aSliuyi pszDest = NULL; 14876af099aSliuyi pszDest = new wchar_t[nDestLen]; 14976af099aSliuyi if (!pszDest) 15076af099aSliuyi return false; 15176af099aSliuyi nDestLen = nDestLen * sizeof(wchar_t); 15276af099aSliuyi memset(pszDest, 0, nDestLen); 15376af099aSliuyi int iRet; 15476af099aSliuyi iconv_t cd; 15576af099aSliuyi cd = iconv_open("UTF-32", "UTF-8"); 15676af099aSliuyi if((iconv_t)-1 == cd) { 15776af099aSliuyi delete []pszDest; 15876af099aSliuyi pszDest = NULL; 15976af099aSliuyi return false; 16076af099aSliuyi } 16176af099aSliuyi char *pIn, *pOut; 16276af099aSliuyi pIn = (char *)pszSrc; 16376af099aSliuyi pOut = (char *)pszDest; 16476af099aSliuyi 16576af099aSliuyi iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 16676af099aSliuyi 16776af099aSliuyi if(iRet == -1) { 16876af099aSliuyi delete []pszDest; 16976af099aSliuyi pszDest = NULL; 17076af099aSliuyi iconv_close(cd); 17176af099aSliuyi return false; 17276af099aSliuyi } 17376af099aSliuyi 17476af099aSliuyi iconv_close(cd); 17576af099aSliuyi 17676af099aSliuyi return true; 17776af099aSliuyi } 17876af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest) 17976af099aSliuyi { 18076af099aSliuyi if (!pszSrc) 18176af099aSliuyi return false; 18276af099aSliuyi int nSrcLen = wcslen(pszSrc); 18376af099aSliuyi int nDestLen = nSrcLen * 2; 18476af099aSliuyi nSrcLen = nSrcLen * sizeof(wchar_t); 18576af099aSliuyi pszDest = NULL; 18676af099aSliuyi pszDest = new char[nDestLen]; 18776af099aSliuyi if (!pszDest) 18876af099aSliuyi return false; 18976af099aSliuyi memset(pszDest, 0, nDestLen); 19076af099aSliuyi int iRet; 19176af099aSliuyi iconv_t cd; 19276af099aSliuyi cd = iconv_open("UTF-8", "UTF-32"); 19376af099aSliuyi 19476af099aSliuyi if((iconv_t)-1 == cd) { 19576af099aSliuyi delete []pszDest; 19676af099aSliuyi pszDest = NULL; 19776af099aSliuyi return false; 19876af099aSliuyi } 19976af099aSliuyi char *pIn, *pOut; 20076af099aSliuyi pIn = (char *)pszSrc; 20176af099aSliuyi pOut = (char *)pszDest; 20276af099aSliuyi iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 20376af099aSliuyi 20476af099aSliuyi if(iRet == -1) { 20576af099aSliuyi delete []pszDest; 20676af099aSliuyi pszDest = NULL; 20776af099aSliuyi iconv_close(cd); 20876af099aSliuyi return false; 20976af099aSliuyi } 21076af099aSliuyi 21176af099aSliuyi iconv_close(cd); 21276af099aSliuyi 21376af099aSliuyi return true; 21476af099aSliuyi } 21576af099aSliuyi int find_config_item(const char *pszName) 21676af099aSliuyi { 21776af099aSliuyi unsigned int i; 21876af099aSliuyi for(i = 0; i < g_ConfigItemVec.size(); i++){ 21976af099aSliuyi if (strcasecmp(pszName, g_ConfigItemVec[i].szItemName) == 0){ 22076af099aSliuyi return i; 22176af099aSliuyi } 22276af099aSliuyi } 22376af099aSliuyi return -1; 22476af099aSliuyi } 22576af099aSliuyi 22676af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 22776af099aSliuyi { 22876af099aSliuyi 22976af099aSliuyi stringstream configStream(pConfig); 23076af099aSliuyi string strLine, strItemName, strItemValue; 23176af099aSliuyi string::size_type line_size,pos; 23276af099aSliuyi STRUCT_CONFIG_ITEM item; 23376af099aSliuyi vecItem.clear(); 23476af099aSliuyi while (!configStream.eof()){ 23576af099aSliuyi getline(configStream, strLine); 23676af099aSliuyi line_size = strLine.size(); 23776af099aSliuyi if (line_size == 0) 23876af099aSliuyi continue; 23976af099aSliuyi if (strLine[line_size-1] == '\r'){ 24076af099aSliuyi strLine = strLine.substr(0, line_size-1); 24176af099aSliuyi } 242c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 243c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 244c30d921cSKever Yang if (strLine.size()==0 ) 245c30d921cSKever Yang continue; 246c30d921cSKever Yang if (strLine[0] == '#') 247c30d921cSKever Yang continue; 24876af099aSliuyi pos = strLine.find("="); 24976af099aSliuyi if (pos == string::npos){ 25076af099aSliuyi continue; 25176af099aSliuyi } 25276af099aSliuyi strItemName = strLine.substr(0, pos); 25376af099aSliuyi strItemValue = strLine.substr(pos + 1); 25476af099aSliuyi strItemName.erase(0, strItemName.find_first_not_of(" ")); 25576af099aSliuyi strItemName.erase(strItemName.find_last_not_of(" ") + 1); 25676af099aSliuyi strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 25776af099aSliuyi strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 25876af099aSliuyi if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 25976af099aSliuyi strcpy(item.szItemName, strItemName.c_str()); 26076af099aSliuyi strcpy(item.szItemValue, strItemValue.c_str()); 26176af099aSliuyi vecItem.push_back(item); 26276af099aSliuyi } 26376af099aSliuyi } 26476af099aSliuyi return true; 26576af099aSliuyi 26676af099aSliuyi } 26776af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 26876af099aSliuyi { 26976af099aSliuyi FILE *file = NULL; 27076af099aSliuyi file = fopen(pConfigFile, "rb"); 27176af099aSliuyi if( !file ){ 27276af099aSliuyi if (g_pLogObject) 27376af099aSliuyi g_pLogObject->Record("parse_config_file failed,err=%d,can't open file: %s\r\n", errno, pConfigFile); 27476af099aSliuyi return false; 27576af099aSliuyi } 27676af099aSliuyi int iFileSize; 27776af099aSliuyi fseek(file, 0, SEEK_END); 27876af099aSliuyi iFileSize = ftell(file); 27976af099aSliuyi fseek(file, 0, SEEK_SET); 28076af099aSliuyi char *pConfigBuf = NULL; 28176af099aSliuyi pConfigBuf = new char[iFileSize + 1]; 28276af099aSliuyi if (!pConfigBuf){ 28376af099aSliuyi fclose(file); 28476af099aSliuyi return false; 28576af099aSliuyi } 28676af099aSliuyi memset(pConfigBuf, 0, iFileSize + 1); 28776af099aSliuyi int iRead; 28876af099aSliuyi iRead = fread(pConfigBuf, 1, iFileSize, file); 28976af099aSliuyi if (iRead != iFileSize){ 29076af099aSliuyi if (g_pLogObject) 29176af099aSliuyi g_pLogObject->Record("parse_config_file failed,err=%d, read=%d, total=%d\r\n", errno, iRead, iFileSize); 29276af099aSliuyi fclose(file); 29376af099aSliuyi delete []pConfigBuf; 29476af099aSliuyi return false; 29576af099aSliuyi } 29676af099aSliuyi fclose(file); 29776af099aSliuyi bool bRet; 29876af099aSliuyi bRet = parse_config(pConfigBuf, vecItem); 29976af099aSliuyi delete []pConfigBuf; 30076af099aSliuyi return bRet; 30176af099aSliuyi } 302c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 303c30d921cSKever Yang { 304c30d921cSKever Yang string::size_type pos,prevPos; 305c30d921cSKever Yang string strOffset,strLen; 306c30d921cSKever Yang int iCount; 307c30d921cSKever Yang prevPos = pos = 0; 308c30d921cSKever Yang if (strPartInfo.size() <= 0) { 309c30d921cSKever Yang return false; 310c30d921cSKever Yang } 311c30d921cSKever Yang pos = strPartInfo.find('@'); 312c30d921cSKever Yang if (pos == string::npos) { 313c30d921cSKever Yang return false; 314c30d921cSKever Yang } 315c30d921cSKever Yang strLen = strPartInfo.substr(prevPos, pos - prevPos); 316c30d921cSKever Yang strLen.erase(0, strLen.find_first_not_of(" ")); 317c30d921cSKever Yang strLen.erase(strLen.find_last_not_of(" ") + 1); 318c30d921cSKever Yang if (strchr(strLen.c_str(), '-')) { 319c30d921cSKever Yang uiLen = 0xFFFFFFFF; 320c30d921cSKever Yang } else { 321c30d921cSKever Yang iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 322c30d921cSKever Yang if (iCount != 1) { 323c30d921cSKever Yang return false; 324c30d921cSKever Yang } 325c30d921cSKever Yang } 326c30d921cSKever Yang 327c30d921cSKever Yang prevPos = pos + 1; 328c30d921cSKever Yang pos = strPartInfo.find('(',prevPos); 329c30d921cSKever Yang if (pos == string::npos) { 330c30d921cSKever Yang return false; 331c30d921cSKever Yang } 332c30d921cSKever Yang strOffset = strPartInfo.substr(prevPos, pos - prevPos); 333c30d921cSKever Yang strOffset.erase(0, strOffset.find_first_not_of(" ")); 334c30d921cSKever Yang strOffset.erase(strOffset.find_last_not_of(" ") + 1); 335c30d921cSKever Yang iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 336c30d921cSKever Yang if (iCount != 1) { 337c30d921cSKever Yang return false; 338c30d921cSKever Yang } 339c30d921cSKever Yang prevPos = pos + 1; 340c30d921cSKever Yang pos = strPartInfo.find(')', prevPos); 341c30d921cSKever Yang if (pos == string::npos) { 342c30d921cSKever Yang return false; 343c30d921cSKever Yang } 344c30d921cSKever Yang strName = strPartInfo.substr(prevPos, pos - prevPos); 345c30d921cSKever Yang strName.erase(0, strName.find_first_not_of(" ")); 346c30d921cSKever Yang strName.erase(strName.find_last_not_of(" ") + 1); 347c30d921cSKever Yang 348c30d921cSKever Yang return true; 349c30d921cSKever Yang } 350c30d921cSKever Yang 351c30d921cSKever Yang bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem) 352c30d921cSKever Yang { 353c30d921cSKever Yang stringstream paramStream(pParameter); 354c30d921cSKever Yang bool bRet,bFind = false; 355c30d921cSKever Yang string strLine, strPartition, strPartInfo, strPartName; 356c30d921cSKever Yang string::size_type line_size, pos, posColon, posComma; 357c30d921cSKever Yang UINT uiPartOffset, uiPartSize; 358c30d921cSKever Yang STRUCT_PARAM_ITEM item; 359c30d921cSKever Yang vecItem.clear(); 360c30d921cSKever Yang while (!paramStream.eof()) { 361c30d921cSKever Yang getline(paramStream,strLine); 362c30d921cSKever Yang line_size = strLine.size(); 363c30d921cSKever Yang if (line_size == 0) 364c30d921cSKever Yang continue; 365c30d921cSKever Yang if (strLine[line_size - 1] == '\r'){ 366c30d921cSKever Yang strLine = strLine.substr(0, line_size - 1); 367c30d921cSKever Yang } 368c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 369c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 370c30d921cSKever Yang if (strLine.size()==0 ) 371c30d921cSKever Yang continue; 372c30d921cSKever Yang if (strLine[0] == '#') 373c30d921cSKever Yang continue; 374c30d921cSKever Yang pos = strLine.find("mtdparts"); 375c30d921cSKever Yang if (pos == string::npos) { 376c30d921cSKever Yang continue; 377c30d921cSKever Yang } 378c30d921cSKever Yang bFind = true; 379c30d921cSKever Yang posColon = strLine.find(':', pos); 380c30d921cSKever Yang if (posColon == string::npos) { 381c30d921cSKever Yang continue; 382c30d921cSKever Yang } 383c30d921cSKever Yang strPartition = strLine.substr(posColon + 1); 384c30d921cSKever Yang pos = 0; 385c30d921cSKever Yang posComma = strPartition.find(',', pos); 386c30d921cSKever Yang while (posComma != string::npos) { 387c30d921cSKever Yang strPartInfo = strPartition.substr(pos, posComma - pos); 388c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 389c30d921cSKever Yang if (bRet) { 390c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 391c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 392c30d921cSKever Yang item.uiItemSize = uiPartSize; 393c30d921cSKever Yang vecItem.push_back(item); 394c30d921cSKever Yang } 395c30d921cSKever Yang pos = posComma + 1; 396c30d921cSKever Yang posComma = strPartition.find(',', pos); 397c30d921cSKever Yang } 398c30d921cSKever Yang strPartInfo = strPartition.substr(pos); 399c30d921cSKever Yang if (strPartInfo.size() > 0) { 400c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 401c30d921cSKever Yang if (bRet) { 402c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 403c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 404c30d921cSKever Yang item.uiItemSize = uiPartSize; 405c30d921cSKever Yang vecItem.push_back(item); 406c30d921cSKever Yang } 407c30d921cSKever Yang } 408c30d921cSKever Yang break; 409c30d921cSKever Yang } 410c30d921cSKever Yang return bFind; 411c30d921cSKever Yang 412c30d921cSKever Yang } 413c30d921cSKever Yang bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem) 414c30d921cSKever Yang { 415c30d921cSKever Yang FILE *file = NULL; 416c30d921cSKever Yang file = fopen(pParamFile, "rb"); 417c30d921cSKever Yang if( !file ) { 418c30d921cSKever Yang if (g_pLogObject) 419c30d921cSKever Yang g_pLogObject->Record("parse_parameter_file failed, err=%d, can't open file: %s\r\n", errno, pParamFile); 420c30d921cSKever Yang return false; 421c30d921cSKever Yang } 422c30d921cSKever Yang int iFileSize; 423c30d921cSKever Yang fseek(file, 0, SEEK_END); 424c30d921cSKever Yang iFileSize = ftell(file); 425c30d921cSKever Yang fseek(file, 0, SEEK_SET); 426c30d921cSKever Yang char *pParamBuf = NULL; 427c30d921cSKever Yang pParamBuf = new char[iFileSize]; 428c30d921cSKever Yang if (!pParamBuf) { 429c30d921cSKever Yang fclose(file); 430c30d921cSKever Yang return false; 431c30d921cSKever Yang } 432c30d921cSKever Yang int iRead; 433c30d921cSKever Yang iRead = fread(pParamBuf, 1, iFileSize, file); 434c30d921cSKever Yang if (iRead != iFileSize) { 435c30d921cSKever Yang if (g_pLogObject) 436c30d921cSKever Yang g_pLogObject->Record("parse_parameter_file failed, err=%d, read=%d, total=%d\r\n", errno,iRead,iFileSize); 437c30d921cSKever Yang fclose(file); 438c30d921cSKever Yang delete []pParamBuf; 439c30d921cSKever Yang return false; 440c30d921cSKever Yang } 441c30d921cSKever Yang fclose(file); 442c30d921cSKever Yang bool bRet; 443c30d921cSKever Yang bRet = parse_parameter(pParamBuf, vecItem); 444c30d921cSKever Yang delete []pParamBuf; 445c30d921cSKever Yang return bRet; 446c30d921cSKever Yang } 447c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin) 448c30d921cSKever Yang { 449c30d921cSKever Yang efi_guid_t id; 450c30d921cSKever Yang unsigned int *ptr = (unsigned int *)&id; 451c30d921cSKever Yang unsigned int i; 452c30d921cSKever Yang 453c30d921cSKever Yang /* Set all fields randomly */ 454c30d921cSKever Yang for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 455c30d921cSKever Yang *(ptr + i) = cpu_to_be32(rand()); 456c30d921cSKever Yang 457c30d921cSKever Yang id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 458c30d921cSKever Yang id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 459c30d921cSKever Yang 460c30d921cSKever Yang memcpy(uuid_bin, id.raw, sizeof(id)); 461c30d921cSKever Yang } 462c30d921cSKever Yang 463c30d921cSKever Yang void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, u64 diskSectors) 464c30d921cSKever Yang { 465c30d921cSKever Yang legacy_mbr *mbr = (legacy_mbr *)gpt; 466c30d921cSKever Yang gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 467c30d921cSKever Yang gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 468c30d921cSKever Yang u32 i,j; 469c30d921cSKever Yang string strPartName; 470c30d921cSKever Yang string::size_type colonPos; 471c30d921cSKever Yang /*1.protective mbr*/ 472c30d921cSKever Yang memset(gpt, 0, SECTOR_SIZE); 473c30d921cSKever Yang mbr->signature = MSDOS_MBR_SIGNATURE; 474c30d921cSKever Yang mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 475c30d921cSKever Yang mbr->partition_record[0].start_sect = 1; 476c30d921cSKever Yang mbr->partition_record[0].nr_sects = (u32)-1; 477c30d921cSKever Yang /*2.gpt header*/ 478c30d921cSKever Yang memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 479c30d921cSKever Yang gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 480c30d921cSKever Yang gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 481c30d921cSKever Yang gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 482c30d921cSKever Yang gptHead->my_lba = cpu_to_le64(1); 483c30d921cSKever Yang gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 484c30d921cSKever Yang gptHead->first_usable_lba = cpu_to_le64(34); 485c30d921cSKever Yang gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 486c30d921cSKever Yang gptHead->partition_entry_lba = cpu_to_le64(2); 487c30d921cSKever Yang gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 488c30d921cSKever Yang gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 489c30d921cSKever Yang gptHead->header_crc32 = 0; 490c30d921cSKever Yang gptHead->partition_entry_array_crc32 = 0; 491c30d921cSKever Yang gen_rand_uuid(gptHead->disk_guid.raw); 492c30d921cSKever Yang 493c30d921cSKever Yang /*3.gpt partition entry*/ 494c30d921cSKever Yang memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 495c30d921cSKever Yang for (i = 0; i < vecParts.size(); i++) { 496c30d921cSKever Yang gen_rand_uuid(gptEntry->partition_type_guid.raw); 497c30d921cSKever Yang gen_rand_uuid(gptEntry->unique_partition_guid.raw); 498c30d921cSKever Yang gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 499c30d921cSKever Yang gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 500c30d921cSKever Yang gptEntry->attributes.raw = 0; 501c30d921cSKever Yang strPartName = vecParts[i].szItemName; 502c30d921cSKever Yang colonPos = strPartName.find_first_of(':'); 503c30d921cSKever Yang if (colonPos != string::npos) { 504c30d921cSKever Yang if (strPartName.find("bootable") != string::npos) 505c30d921cSKever Yang gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 506c30d921cSKever Yang strPartName = strPartName.substr(0, colonPos); 507c30d921cSKever Yang vecParts[i].szItemName[strPartName.size()] = 0; 508c30d921cSKever Yang } 509c30d921cSKever Yang for (j = 0; j < strlen(vecParts[i].szItemName); j++) 510c30d921cSKever Yang gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 511c30d921cSKever Yang gptEntry++; 512c30d921cSKever Yang } 513c30d921cSKever Yang 514c30d921cSKever Yang gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 515c30d921cSKever Yang gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 516c30d921cSKever Yang 517c30d921cSKever Yang } 518c30d921cSKever Yang bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec) 519c30d921cSKever Yang { 520c30d921cSKever Yang PRK28_IDB_SEC0 pSec0; 521c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 522c30d921cSKever Yang pSec0 = (PRK28_IDB_SEC0)pSector; 523c30d921cSKever Yang 524c30d921cSKever Yang pSec0->dwTag = 0x0FF0AA55; 525c30d921cSKever Yang pSec0->uiRc4Flag = 1; 526c30d921cSKever Yang pSec0->usBootCode1Offset = 0x4; 527c30d921cSKever Yang pSec0->usBootCode2Offset = 0x4; 528c30d921cSKever Yang pSec0->usBootDataSize = usFlashDataSec; 529c30d921cSKever Yang pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 530c30d921cSKever Yang return true; 531c30d921cSKever Yang } 532c30d921cSKever Yang 533c30d921cSKever Yang 534c30d921cSKever Yang bool MakeSector1(PBYTE pSector) 535c30d921cSKever Yang { 536c30d921cSKever Yang PRK28_IDB_SEC1 pSec1; 537c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 538c30d921cSKever Yang pSec1 = (PRK28_IDB_SEC1)pSector; 539c30d921cSKever Yang 540c30d921cSKever Yang pSec1->usSysReservedBlock = 0xC; 541c30d921cSKever Yang pSec1->usDisk0Size = 0xFFFF; 542c30d921cSKever Yang pSec1->uiChipTag = 0x38324B52; 543c30d921cSKever Yang return true; 544c30d921cSKever Yang } 545c30d921cSKever Yang 546c30d921cSKever Yang bool MakeSector2(PBYTE pSector) 547c30d921cSKever Yang { 548c30d921cSKever Yang PRK28_IDB_SEC2 pSec2; 549c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 550c30d921cSKever Yang pSec2 = (PRK28_IDB_SEC2)pSector; 551c30d921cSKever Yang 552c30d921cSKever Yang strcpy(pSec2->szVcTag, "VC"); 553c30d921cSKever Yang strcpy(pSec2->szCrcTag, "CRC"); 554c30d921cSKever Yang return true; 555c30d921cSKever Yang } 556c30d921cSKever Yang 557c30d921cSKever Yang bool MakeSector3(PBYTE pSector) 558c30d921cSKever Yang { 559c30d921cSKever Yang memset(pSector,0,SECTOR_SIZE); 560c30d921cSKever Yang return true; 561c30d921cSKever Yang } 562c30d921cSKever Yang 563c30d921cSKever Yang int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize) 564c30d921cSKever Yang { 565c30d921cSKever Yang RK28_IDB_SEC0 sector0Info; 566c30d921cSKever Yang RK28_IDB_SEC1 sector1Info; 567c30d921cSKever Yang RK28_IDB_SEC2 sector2Info; 568c30d921cSKever Yang RK28_IDB_SEC3 sector3Info; 569c30d921cSKever Yang UINT i; 570c30d921cSKever Yang 571c30d921cSKever Yang MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec); 572c30d921cSKever Yang MakeSector1((PBYTE)§or1Info); 573c30d921cSKever Yang if (!MakeSector2((PBYTE)§or2Info)) { 574c30d921cSKever Yang return -6; 575c30d921cSKever Yang } 576c30d921cSKever Yang if (!MakeSector3((PBYTE)§or3Info)) { 577c30d921cSKever Yang return -7; 578c30d921cSKever Yang } 579c30d921cSKever Yang sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 580c30d921cSKever Yang sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 581c30d921cSKever Yang sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 582c30d921cSKever Yang 583c30d921cSKever Yang memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 584c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 585c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 586c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 587c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 588c30d921cSKever Yang 589c30d921cSKever Yang sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 590c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 591c30d921cSKever Yang for(i = 0; i < 4; i++) { 592c30d921cSKever Yang if(i == 1) { 593c30d921cSKever Yang continue; 594c30d921cSKever Yang } else { 595c30d921cSKever Yang P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 596c30d921cSKever Yang } 597c30d921cSKever Yang } 598c30d921cSKever Yang return 0; 599c30d921cSKever Yang } 600c30d921cSKever Yang 601c30d921cSKever Yang 60276af099aSliuyi 60376af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 60476af099aSliuyi { 60576af099aSliuyi if ((dev.emUsbType & uiSupportType) == dev.emUsbType) 60676af099aSliuyi return true; 60776af099aSliuyi else 60876af099aSliuyi { 60976af099aSliuyi ERROR_COLOR_ATTR; 61076af099aSliuyi printf("The Device did not support this operation!"); 61176af099aSliuyi NORMAL_COLOR_ATTR; 61276af099aSliuyi printf("\r\n"); 61376af099aSliuyi return false; 61476af099aSliuyi } 61576af099aSliuyi } 616c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 617c30d921cSKever Yang { 618c30d921cSKever Yang u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 619c30d921cSKever Yang u32 total_size_sector; 620c30d921cSKever Yang CRKComm *pComm = NULL; 621c30d921cSKever Yang PARAM_ITEM_VECTOR vecItems; 622c30d921cSKever Yang int iRet; 623c30d921cSKever Yang bool bRet, bSuccess = false; 624c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 625c30d921cSKever Yang return false; 626c30d921cSKever Yang 627c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 628c30d921cSKever Yang if (!bRet) { 629c30d921cSKever Yang ERROR_COLOR_ATTR; 630c30d921cSKever Yang printf("Creating Comm Object failed!"); 631c30d921cSKever Yang NORMAL_COLOR_ATTR; 632c30d921cSKever Yang printf("\r\n"); 633c30d921cSKever Yang return bSuccess; 634c30d921cSKever Yang } 635c30d921cSKever Yang printf("Write gpt...\r\n"); 636c30d921cSKever Yang //1.get flash info 637c30d921cSKever Yang iRet = pComm->RKU_ReadFlashInfo(flash_info); 638c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 639c30d921cSKever Yang ERROR_COLOR_ATTR; 640c30d921cSKever Yang printf("Reading Flash Info failed!"); 641c30d921cSKever Yang NORMAL_COLOR_ATTR; 642c30d921cSKever Yang printf("\r\n"); 643c30d921cSKever Yang return bSuccess; 644c30d921cSKever Yang } 645c30d921cSKever Yang total_size_sector = *(u32 *)flash_info; 646c30d921cSKever Yang //2.get partition from parameter 647c30d921cSKever Yang bRet = parse_parameter_file(szParameter, vecItems); 648c30d921cSKever Yang if (!bRet) { 649c30d921cSKever Yang ERROR_COLOR_ATTR; 650c30d921cSKever Yang printf("Parsing parameter failed!"); 651c30d921cSKever Yang NORMAL_COLOR_ATTR; 652c30d921cSKever Yang printf("\r\n"); 653c30d921cSKever Yang return bSuccess; 654c30d921cSKever Yang } 655c30d921cSKever Yang vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 34; 656c30d921cSKever Yang //3.generate gpt info 657c30d921cSKever Yang create_gpt_buffer(master_gpt, vecItems, total_size_sector); 658c30d921cSKever Yang memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 659c30d921cSKever Yang memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 660c30d921cSKever Yang //4. write gpt 661c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 662c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 663c30d921cSKever Yang ERROR_COLOR_ATTR; 664c30d921cSKever Yang printf("Writing master gpt failed!"); 665c30d921cSKever Yang NORMAL_COLOR_ATTR; 666c30d921cSKever Yang printf("\r\n"); 667c30d921cSKever Yang return bSuccess; 668c30d921cSKever Yang } 669c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(total_size_sector - 34, 33, backup_gpt); 670c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 671c30d921cSKever Yang ERROR_COLOR_ATTR; 672c30d921cSKever Yang printf("Writing backup gpt failed!"); 673c30d921cSKever Yang NORMAL_COLOR_ATTR; 674c30d921cSKever Yang printf("\r\n"); 675c30d921cSKever Yang return bSuccess; 676c30d921cSKever Yang } 677c30d921cSKever Yang bSuccess = true; 678c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 679c30d921cSKever Yang CURSOR_DEL_LINE; 680c30d921cSKever Yang printf("Write gpt ok.\r\n"); 681c30d921cSKever Yang return bSuccess; 682c30d921cSKever Yang } 68376af099aSliuyi 68478884ef4SEddie Cai #include "boot_merger.h" 68578884ef4SEddie Cai #define ENTRY_ALIGN (2048) 68678884ef4SEddie Cai options gOpts; 68778884ef4SEddie Cai 68878884ef4SEddie Cai 68978884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 69078884ef4SEddie Cai char* gConfigPath; 69178884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE]; 69278884ef4SEddie Cai 69378884ef4SEddie Cai static inline void fixPath(char* path) { 69478884ef4SEddie Cai int i, len = strlen(path); 69578884ef4SEddie Cai for(i=0; i<len; i++) { 69678884ef4SEddie Cai if (path[i] == '\\') 69778884ef4SEddie Cai path[i] = '/'; 69878884ef4SEddie Cai else if (path[i] == '\r' || path[i] == '\n') 69978884ef4SEddie Cai path[i] = '\0'; 70078884ef4SEddie Cai } 70178884ef4SEddie Cai } 70278884ef4SEddie Cai 70378884ef4SEddie Cai static bool parseChip(FILE* file) { 70478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 70578884ef4SEddie Cai return false; 70678884ef4SEddie Cai } 70778884ef4SEddie Cai if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 70878884ef4SEddie Cai return false; 70978884ef4SEddie Cai } 71078884ef4SEddie Cai printf("chip:%s\n", gOpts.chip); 71178884ef4SEddie Cai return true; 71278884ef4SEddie Cai } 71378884ef4SEddie Cai 71478884ef4SEddie Cai static bool parseVersion(FILE* file) { 71578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 71678884ef4SEddie Cai return false; 71778884ef4SEddie Cai } 71878884ef4SEddie Cai if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 71978884ef4SEddie Cai return false; 72078884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 72178884ef4SEddie Cai return false; 72278884ef4SEddie Cai } 72378884ef4SEddie Cai if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 72478884ef4SEddie Cai return false; 72578884ef4SEddie Cai printf("major:%d, minor:%d\n", gOpts.major, gOpts.minor); 72678884ef4SEddie Cai return true; 72778884ef4SEddie Cai } 72878884ef4SEddie Cai 72978884ef4SEddie Cai static bool parse471(FILE* file) { 73078884ef4SEddie Cai int i, index, pos; 73178884ef4SEddie Cai char buf[MAX_LINE_LEN]; 73278884ef4SEddie Cai 73378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 73478884ef4SEddie Cai return false; 73578884ef4SEddie Cai } 73678884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 73778884ef4SEddie Cai return false; 73878884ef4SEddie Cai printf("num:%d\n", gOpts.code471Num); 73978884ef4SEddie Cai if (!gOpts.code471Num) 74078884ef4SEddie Cai return true; 74178884ef4SEddie Cai if (gOpts.code471Num < 0) 74278884ef4SEddie Cai return false; 74378884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 74478884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 74578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 74678884ef4SEddie Cai return false; 74778884ef4SEddie Cai } 74878884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 74978884ef4SEddie Cai != 2) 75078884ef4SEddie Cai return false; 75178884ef4SEddie Cai index--; 75278884ef4SEddie Cai fixPath(buf); 75378884ef4SEddie Cai strcpy((char*)gOpts.code471Path[index], buf); 75478884ef4SEddie Cai printf("path%i:%s\n", index, gOpts.code471Path[index]); 75578884ef4SEddie Cai } 75678884ef4SEddie Cai pos = ftell(file); 75778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 75878884ef4SEddie Cai return false; 75978884ef4SEddie Cai } 76078884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 76178884ef4SEddie Cai fseek(file, pos, SEEK_SET); 76278884ef4SEddie Cai printf("sleep:%d\n", gOpts.code471Sleep); 76378884ef4SEddie Cai return true; 76478884ef4SEddie Cai } 76578884ef4SEddie Cai 76678884ef4SEddie Cai static bool parse472(FILE* file) { 76778884ef4SEddie Cai int i, index, pos; 76878884ef4SEddie Cai char buf[MAX_LINE_LEN]; 76978884ef4SEddie Cai 77078884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 77178884ef4SEddie Cai return false; 77278884ef4SEddie Cai } 77378884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 77478884ef4SEddie Cai return false; 77578884ef4SEddie Cai printf("num:%d\n", gOpts.code472Num); 77678884ef4SEddie Cai if (!gOpts.code472Num) 77778884ef4SEddie Cai return true; 77878884ef4SEddie Cai if (gOpts.code472Num < 0) 77978884ef4SEddie Cai return false; 78078884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 78178884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 78278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 78378884ef4SEddie Cai return false; 78478884ef4SEddie Cai } 78578884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 78678884ef4SEddie Cai != 2) 78778884ef4SEddie Cai return false; 78878884ef4SEddie Cai fixPath(buf); 78978884ef4SEddie Cai index--; 79078884ef4SEddie Cai strcpy((char*)gOpts.code472Path[index], buf); 79178884ef4SEddie Cai printf("path%i:%s\n", index, gOpts.code472Path[index]); 79278884ef4SEddie Cai } 79378884ef4SEddie Cai pos = ftell(file); 79478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 79578884ef4SEddie Cai return false; 79678884ef4SEddie Cai } 79778884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 79878884ef4SEddie Cai fseek(file, pos, SEEK_SET); 79978884ef4SEddie Cai printf("sleep:%d\n", gOpts.code472Sleep); 80078884ef4SEddie Cai return true; 80178884ef4SEddie Cai } 80278884ef4SEddie Cai 80378884ef4SEddie Cai static bool parseLoader(FILE* file) { 80478884ef4SEddie Cai int i, j, index, pos; 80578884ef4SEddie Cai char buf[MAX_LINE_LEN]; 80678884ef4SEddie Cai char buf2[MAX_LINE_LEN]; 80778884ef4SEddie Cai 80878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 80978884ef4SEddie Cai return false; 81078884ef4SEddie Cai } 81178884ef4SEddie Cai pos = ftell(file); 81278884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 81378884ef4SEddie Cai fseek(file, pos, SEEK_SET); 81478884ef4SEddie Cai if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 81578884ef4SEddie Cai return false; 81678884ef4SEddie Cai } 81778884ef4SEddie Cai } 81878884ef4SEddie Cai printf("num:%d\n", gOpts.loaderNum); 81978884ef4SEddie Cai if (!gOpts.loaderNum) 82078884ef4SEddie Cai return false; 82178884ef4SEddie Cai if (gOpts.loaderNum < 0) 82278884ef4SEddie Cai return false; 82378884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 82478884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 82578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 82678884ef4SEddie Cai return false; 82778884ef4SEddie Cai } 82878884ef4SEddie Cai if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 82978884ef4SEddie Cai != 2) 83078884ef4SEddie Cai return false; 83178884ef4SEddie Cai index--; 83278884ef4SEddie Cai strcpy(gOpts.loader[index].name, buf); 83378884ef4SEddie Cai printf("name%d:%s\n", index, gOpts.loader[index].name); 83478884ef4SEddie Cai } 83578884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 83678884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 83778884ef4SEddie Cai return false; 83878884ef4SEddie Cai } 83978884ef4SEddie Cai if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 84078884ef4SEddie Cai != 2) 84178884ef4SEddie Cai return false; 84278884ef4SEddie Cai for (j=0; j<gOpts.loaderNum; j++) { 84378884ef4SEddie Cai if (!strcmp(gOpts.loader[j].name, buf)) { 84478884ef4SEddie Cai fixPath(buf2); 84578884ef4SEddie Cai strcpy(gOpts.loader[j].path, buf2); 84678884ef4SEddie Cai printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 84778884ef4SEddie Cai break; 84878884ef4SEddie Cai } 84978884ef4SEddie Cai } 85078884ef4SEddie Cai if (j >= gOpts.loaderNum) { 85178884ef4SEddie Cai return false; 85278884ef4SEddie Cai } 85378884ef4SEddie Cai } 85478884ef4SEddie Cai return true; 85578884ef4SEddie Cai } 85678884ef4SEddie Cai 85778884ef4SEddie Cai static bool parseOut(FILE* file) { 85878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 85978884ef4SEddie Cai return false; 86078884ef4SEddie Cai } 86178884ef4SEddie Cai if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 86278884ef4SEddie Cai return false; 86378884ef4SEddie Cai fixPath(gOpts.outPath); 86478884ef4SEddie Cai printf("out:%s\n", gOpts.outPath); 86578884ef4SEddie Cai return true; 86678884ef4SEddie Cai } 86778884ef4SEddie Cai 86878884ef4SEddie Cai 86978884ef4SEddie Cai void printOpts(FILE* out) { 87078884ef4SEddie Cai int i; 87178884ef4SEddie Cai fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 87278884ef4SEddie Cai fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 87378884ef4SEddie Cai "=%d\n", gOpts.major, gOpts.minor); 87478884ef4SEddie Cai 87578884ef4SEddie Cai fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 87678884ef4SEddie Cai for (i=0 ;i<gOpts.code471Num ;i++) { 87778884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 87878884ef4SEddie Cai } 87978884ef4SEddie Cai if (gOpts.code471Sleep > 0) 88078884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 88178884ef4SEddie Cai 88278884ef4SEddie Cai fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 88378884ef4SEddie Cai for (i=0 ;i<gOpts.code472Num ;i++) { 88478884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 88578884ef4SEddie Cai } 88678884ef4SEddie Cai if (gOpts.code472Sleep > 0) 88778884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 88878884ef4SEddie Cai 88978884ef4SEddie Cai fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 89078884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 89178884ef4SEddie Cai fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 89278884ef4SEddie Cai } 89378884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 89478884ef4SEddie Cai fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 89578884ef4SEddie Cai } 89678884ef4SEddie Cai 89778884ef4SEddie Cai fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 89878884ef4SEddie Cai } 89978884ef4SEddie Cai 90078884ef4SEddie Cai static bool parseOpts(void) { 90178884ef4SEddie Cai bool ret = false; 90278884ef4SEddie Cai bool chipOk = false; 90378884ef4SEddie Cai bool versionOk = false; 90478884ef4SEddie Cai bool code471Ok = true; 90578884ef4SEddie Cai bool code472Ok = true; 90678884ef4SEddie Cai bool loaderOk = false; 90778884ef4SEddie Cai bool outOk = false; 90878884ef4SEddie Cai char buf[MAX_LINE_LEN]; 90978884ef4SEddie Cai 91078884ef4SEddie Cai char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 91178884ef4SEddie Cai FILE* file; 91278884ef4SEddie Cai file = fopen(configPath, "r"); 91378884ef4SEddie Cai if (!file) { 91478884ef4SEddie Cai fprintf(stderr, "config(%s) not found!\n", configPath); 91578884ef4SEddie Cai if (configPath == (char*)DEF_CONFIG_FILE) { 91678884ef4SEddie Cai file = fopen(DEF_CONFIG_FILE, "w"); 91778884ef4SEddie Cai if (file) { 91878884ef4SEddie Cai fprintf(stderr, "create defconfig\n"); 91978884ef4SEddie Cai printOpts(file); 92078884ef4SEddie Cai } 92178884ef4SEddie Cai } 92278884ef4SEddie Cai goto end; 92378884ef4SEddie Cai } 92478884ef4SEddie Cai 92578884ef4SEddie Cai printf("start parse\n"); 92678884ef4SEddie Cai 92778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 92878884ef4SEddie Cai goto end; 92978884ef4SEddie Cai } 93078884ef4SEddie Cai while(fscanf(file, "%s", buf) == 1) { 93178884ef4SEddie Cai if (!strcmp(buf, SEC_CHIP)) { 93278884ef4SEddie Cai chipOk = parseChip(file); 93378884ef4SEddie Cai if (!chipOk) { 93478884ef4SEddie Cai printf("parseChip failed!\n"); 93578884ef4SEddie Cai goto end; 93678884ef4SEddie Cai } 93778884ef4SEddie Cai } else if (!strcmp(buf, SEC_VERSION)) { 93878884ef4SEddie Cai versionOk = parseVersion(file); 93978884ef4SEddie Cai if (!versionOk) { 94078884ef4SEddie Cai printf("parseVersion failed!\n"); 94178884ef4SEddie Cai goto end; 94278884ef4SEddie Cai } 94378884ef4SEddie Cai } else if (!strcmp(buf, SEC_471)) { 94478884ef4SEddie Cai code471Ok = parse471(file); 94578884ef4SEddie Cai if (!code471Ok) { 94678884ef4SEddie Cai printf("parse471 failed!\n"); 94778884ef4SEddie Cai goto end; 94878884ef4SEddie Cai } 94978884ef4SEddie Cai } else if (!strcmp(buf, SEC_472)) { 95078884ef4SEddie Cai code472Ok = parse472(file); 95178884ef4SEddie Cai if (!code472Ok) { 95278884ef4SEddie Cai printf("parse472 failed!\n"); 95378884ef4SEddie Cai goto end; 95478884ef4SEddie Cai } 95578884ef4SEddie Cai } else if (!strcmp(buf, SEC_LOADER)) { 95678884ef4SEddie Cai loaderOk = parseLoader(file); 95778884ef4SEddie Cai if (!loaderOk) { 95878884ef4SEddie Cai printf("parseLoader failed!\n"); 95978884ef4SEddie Cai goto end; 96078884ef4SEddie Cai } 96178884ef4SEddie Cai } else if (!strcmp(buf, SEC_OUT)) { 96278884ef4SEddie Cai outOk = parseOut(file); 96378884ef4SEddie Cai if (!outOk) { 96478884ef4SEddie Cai printf("parseOut failed!\n"); 96578884ef4SEddie Cai goto end; 96678884ef4SEddie Cai } 96778884ef4SEddie Cai } else if (buf[0] == '#') { 96878884ef4SEddie Cai continue; 96978884ef4SEddie Cai } else { 97078884ef4SEddie Cai printf("unknown sec: %s!\n", buf); 97178884ef4SEddie Cai goto end; 97278884ef4SEddie Cai } 97378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 97478884ef4SEddie Cai goto end; 97578884ef4SEddie Cai } 97678884ef4SEddie Cai } 97778884ef4SEddie Cai 97878884ef4SEddie Cai if (chipOk && versionOk && code471Ok && code472Ok 97978884ef4SEddie Cai && loaderOk && outOk) 98078884ef4SEddie Cai ret = true; 98178884ef4SEddie Cai end: 98278884ef4SEddie Cai if (file) 98378884ef4SEddie Cai fclose(file); 98478884ef4SEddie Cai return ret; 98578884ef4SEddie Cai } 98678884ef4SEddie Cai 98778884ef4SEddie Cai bool initOpts(void) { 98878884ef4SEddie Cai //set default opts 98978884ef4SEddie Cai gOpts.major = DEF_MAJOR; 99078884ef4SEddie Cai gOpts.minor = DEF_MINOR; 99178884ef4SEddie Cai strcpy(gOpts.chip, DEF_CHIP); 99278884ef4SEddie Cai gOpts.code471Sleep = DEF_CODE471_SLEEP; 99378884ef4SEddie Cai gOpts.code472Sleep = DEF_CODE472_SLEEP; 99478884ef4SEddie Cai gOpts.code471Num = DEF_CODE471_NUM; 99578884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 99678884ef4SEddie Cai strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 99778884ef4SEddie Cai gOpts.code472Num = DEF_CODE472_NUM; 99878884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 99978884ef4SEddie Cai strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 100078884ef4SEddie Cai gOpts.loaderNum = DEF_LOADER_NUM; 100178884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 100278884ef4SEddie Cai strcpy(gOpts.loader[0].name, DEF_LOADER0); 100378884ef4SEddie Cai strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 100478884ef4SEddie Cai strcpy(gOpts.loader[1].name, DEF_LOADER1); 100578884ef4SEddie Cai strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 100678884ef4SEddie Cai strcpy(gOpts.outPath, DEF_OUT_PATH); 100778884ef4SEddie Cai 100878884ef4SEddie Cai return parseOpts(); 100978884ef4SEddie Cai } 101078884ef4SEddie Cai 101178884ef4SEddie Cai /************merge code****************/ 101278884ef4SEddie Cai 101378884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) { 101478884ef4SEddie Cai uint8_t tmp[2] = {0}; 101578884ef4SEddie Cai int i; 101678884ef4SEddie Cai uint32_t ret; 101778884ef4SEddie Cai //if (value > 0xFFFF) { 101878884ef4SEddie Cai // return 0; 101978884ef4SEddie Cai //} 102078884ef4SEddie Cai for(i=0; i < 2; i++) { 102178884ef4SEddie Cai tmp[i] = (((value/10)%10)<<4) | (value%10); 102278884ef4SEddie Cai value /= 100; 102378884ef4SEddie Cai } 102478884ef4SEddie Cai ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 102578884ef4SEddie Cai 102678884ef4SEddie Cai printf("ret:%x\n",ret); 102778884ef4SEddie Cai return ret&0xFF; 102878884ef4SEddie Cai } 102978884ef4SEddie Cai 103078884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len) 103178884ef4SEddie Cai { 103278884ef4SEddie Cai int i; 103378884ef4SEddie Cai for (i = 0; i < len; i++) { 103478884ef4SEddie Cai wide[i] = (uint16_t) str[i]; 103578884ef4SEddie Cai } 103678884ef4SEddie Cai wide[len] = 0; 103778884ef4SEddie Cai } 103878884ef4SEddie Cai 103978884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) { 104078884ef4SEddie Cai char* end; 104178884ef4SEddie Cai char* start; 104278884ef4SEddie Cai int len; 104378884ef4SEddie Cai if (!path || !dst) 104478884ef4SEddie Cai return; 104578884ef4SEddie Cai start = strrchr(path, '/'); 104678884ef4SEddie Cai if (!start) 104778884ef4SEddie Cai start = path; 104878884ef4SEddie Cai else 104978884ef4SEddie Cai start++; 105078884ef4SEddie Cai end = strrchr(path, '.'); 1051*641cfa16SEddie Cai if (!end || (end < start)) 105278884ef4SEddie Cai end = path + strlen(path); 105378884ef4SEddie Cai len = end - start; 105478884ef4SEddie Cai if (len >= MAX_NAME_LEN) 105578884ef4SEddie Cai len = MAX_NAME_LEN -1; 105678884ef4SEddie Cai str2wide(start, dst, len); 105778884ef4SEddie Cai 105878884ef4SEddie Cai 105978884ef4SEddie Cai char name[MAX_NAME_LEN]; 106078884ef4SEddie Cai memset(name, 0, sizeof(name)); 106178884ef4SEddie Cai memcpy(name, start, len); 106278884ef4SEddie Cai printf("path:%s, name:%s\n", path, name); 106378884ef4SEddie Cai 106478884ef4SEddie Cai } 106578884ef4SEddie Cai 106678884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) { 106778884ef4SEddie Cai struct stat st; 106878884ef4SEddie Cai if(stat(path, &st) < 0) 106978884ef4SEddie Cai return false; 107078884ef4SEddie Cai *size = st.st_size; 107178884ef4SEddie Cai printf("path:%s, size:%d\n", path, *size); 107278884ef4SEddie Cai return true; 107378884ef4SEddie Cai } 107478884ef4SEddie Cai 107578884ef4SEddie Cai static inline rk_time getTime(void) { 107678884ef4SEddie Cai rk_time rkTime; 107778884ef4SEddie Cai 107878884ef4SEddie Cai struct tm *tm; 107978884ef4SEddie Cai time_t tt = time(NULL); 108078884ef4SEddie Cai tm = localtime(&tt); 108178884ef4SEddie Cai rkTime.year = tm->tm_year + 1900; 108278884ef4SEddie Cai rkTime.month = tm->tm_mon + 1; 108378884ef4SEddie Cai rkTime.day = tm->tm_mday; 108478884ef4SEddie Cai rkTime.hour = tm->tm_hour; 108578884ef4SEddie Cai rkTime.minute = tm->tm_min; 108678884ef4SEddie Cai rkTime.second = tm->tm_sec; 108778884ef4SEddie Cai printf("%d-%d-%d %02d:%02d:%02d\n", 108878884ef4SEddie Cai rkTime.year, rkTime.month, rkTime.day, 108978884ef4SEddie Cai rkTime.hour, rkTime.minute, rkTime.second); 109078884ef4SEddie Cai return rkTime; 109178884ef4SEddie Cai } 109278884ef4SEddie Cai 109378884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) { 109478884ef4SEddie Cai bool ret = false; 109578884ef4SEddie Cai uint32_t size = 0, fixSize = 0; 109678884ef4SEddie Cai uint8_t* buf; 109778884ef4SEddie Cai 109878884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 109978884ef4SEddie Cai if (!inFile) 110078884ef4SEddie Cai goto end; 110178884ef4SEddie Cai 110278884ef4SEddie Cai if (!getFileSize(path, &size)) 110378884ef4SEddie Cai goto end; 110478884ef4SEddie Cai if (fix) { 110578884ef4SEddie Cai fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 110678884ef4SEddie Cai uint32_t tmp = fixSize % ENTRY_ALIGN; 110778884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 110878884ef4SEddie Cai fixSize +=tmp; 110978884ef4SEddie Cai memset(gBuf, 0, fixSize); 111078884ef4SEddie Cai } else { 111178884ef4SEddie Cai memset(gBuf, 0, size+ENTRY_ALIGN); 111278884ef4SEddie Cai } 111378884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 111478884ef4SEddie Cai goto end; 111578884ef4SEddie Cai 111678884ef4SEddie Cai if (fix) { 111778884ef4SEddie Cai 111878884ef4SEddie Cai buf = gBuf; 111978884ef4SEddie Cai size = fixSize; 112078884ef4SEddie Cai while(1) { 112178884ef4SEddie Cai P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 112278884ef4SEddie Cai buf += SMALL_PACKET; 112378884ef4SEddie Cai if (fixSize <= SMALL_PACKET) 112478884ef4SEddie Cai break; 112578884ef4SEddie Cai fixSize -= SMALL_PACKET; 112678884ef4SEddie Cai } 112778884ef4SEddie Cai } else { 112878884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 112978884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 113078884ef4SEddie Cai size +=tmp; 113178884ef4SEddie Cai P_RC4(gBuf, size); 113278884ef4SEddie Cai } 113378884ef4SEddie Cai 113478884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 113578884ef4SEddie Cai goto end; 113678884ef4SEddie Cai ret = true; 113778884ef4SEddie Cai end: 113878884ef4SEddie Cai if (inFile) 113978884ef4SEddie Cai fclose(inFile); 114078884ef4SEddie Cai if (!ret) 114178884ef4SEddie Cai printf("write entry(%s) failed\n", path); 114278884ef4SEddie Cai return ret; 114378884ef4SEddie Cai } 114478884ef4SEddie Cai 114578884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 114678884ef4SEddie Cai uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 114778884ef4SEddie Cai uint32_t size; 114878884ef4SEddie Cai rk_boot_entry entry; 114978884ef4SEddie Cai 115078884ef4SEddie Cai printf("write:%s\n", path); 1151*641cfa16SEddie Cai memset(&entry, 0, sizeof(rk_boot_entry)); 115278884ef4SEddie Cai getName(fixName ? fixName: path, entry.name); 115378884ef4SEddie Cai entry.size = sizeof(rk_boot_entry); 115478884ef4SEddie Cai entry.type = type; 115578884ef4SEddie Cai entry.dataOffset = *offset; 115678884ef4SEddie Cai if (!getFileSize(path, &size)) { 115778884ef4SEddie Cai printf("save entry(%s) failed:\n\tcannot get file size.\n", path); 115878884ef4SEddie Cai return false; 115978884ef4SEddie Cai } 116078884ef4SEddie Cai if (fix) 116178884ef4SEddie Cai size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 116278884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 116378884ef4SEddie Cai size += tmp ? (ENTRY_ALIGN - tmp): 0; 116478884ef4SEddie Cai printf("align size:%d\n", size); 116578884ef4SEddie Cai entry.dataSize = size; 116678884ef4SEddie Cai entry.dataDelay = delay; 116778884ef4SEddie Cai *offset += size; 116878884ef4SEddie Cai fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 116978884ef4SEddie Cai return true; 117078884ef4SEddie Cai } 117178884ef4SEddie Cai 117278884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) { 117378884ef4SEddie Cai char buffer[5]; 117478884ef4SEddie Cai memset(buffer, 0, sizeof(buffer)); 117578884ef4SEddie Cai snprintf(buffer, sizeof(buffer), "%s", chip); 117678884ef4SEddie Cai return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 117778884ef4SEddie Cai } 117878884ef4SEddie Cai 117978884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) { 118078884ef4SEddie Cai printf("chip:%s\n", chip); 118178884ef4SEddie Cai int chipType = RKNONE_DEVICE; 118278884ef4SEddie Cai if(!chip) { 118378884ef4SEddie Cai goto end; 118478884ef4SEddie Cai } 118578884ef4SEddie Cai if (!strcmp(chip, CHIP_RK28)) { 118678884ef4SEddie Cai chipType = RK28_DEVICE; 118778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK28)) { 118878884ef4SEddie Cai chipType = RK28_DEVICE; 118978884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK281X)) { 119078884ef4SEddie Cai chipType = RK281X_DEVICE; 119178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKPANDA)) { 119278884ef4SEddie Cai chipType = RKPANDA_DEVICE; 119378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK27)) { 119478884ef4SEddie Cai chipType = RK27_DEVICE; 119578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKNANO)) { 119678884ef4SEddie Cai chipType = RKNANO_DEVICE; 119778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKSMART)) { 119878884ef4SEddie Cai chipType = RKSMART_DEVICE; 119978884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCROWN)) { 120078884ef4SEddie Cai chipType = RKCROWN_DEVICE; 120178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 120278884ef4SEddie Cai chipType = RKCAYMAN_DEVICE; 120378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK29)) { 120478884ef4SEddie Cai chipType = RK29_DEVICE; 120578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK292X)) { 120678884ef4SEddie Cai chipType = RK292X_DEVICE; 120778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30)) { 120878884ef4SEddie Cai chipType = RK30_DEVICE; 120978884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30B)) { 121078884ef4SEddie Cai chipType = RK30B_DEVICE; 121178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK31)) { 121278884ef4SEddie Cai chipType = RK31_DEVICE; 121378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK32)) { 121478884ef4SEddie Cai chipType = RK32_DEVICE; 121578884ef4SEddie Cai } else { 121678884ef4SEddie Cai chipType = convertChipType(chip + 2); 121778884ef4SEddie Cai } 121878884ef4SEddie Cai 121978884ef4SEddie Cai end: 122078884ef4SEddie Cai printf("type:0x%x\n", chipType); 122178884ef4SEddie Cai if (chipType == RKNONE_DEVICE) { 122278884ef4SEddie Cai printf("chip type not support!\n"); 122378884ef4SEddie Cai } 122478884ef4SEddie Cai return chipType; 122578884ef4SEddie Cai } 122678884ef4SEddie Cai 122778884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) { 122878884ef4SEddie Cai memset(hdr, 0, sizeof(rk_boot_header)); 122978884ef4SEddie Cai hdr->tag = TAG; 123078884ef4SEddie Cai hdr->size = sizeof(rk_boot_header); 123178884ef4SEddie Cai hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 123278884ef4SEddie Cai hdr->mergerVersion = MERGER_VERSION; 123378884ef4SEddie Cai hdr->releaseTime = getTime(); 123478884ef4SEddie Cai hdr->chipType = getChipType(gOpts.chip); 123578884ef4SEddie Cai 123678884ef4SEddie Cai hdr->code471Num = gOpts.code471Num; 123778884ef4SEddie Cai hdr->code471Offset = sizeof(rk_boot_header); 123878884ef4SEddie Cai hdr->code471Size = sizeof(rk_boot_entry); 123978884ef4SEddie Cai 124078884ef4SEddie Cai hdr->code472Num = gOpts.code472Num; 124178884ef4SEddie Cai hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 124278884ef4SEddie Cai hdr->code472Size = sizeof(rk_boot_entry); 124378884ef4SEddie Cai 124478884ef4SEddie Cai hdr->loaderNum = gOpts.loaderNum; 124578884ef4SEddie Cai hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 124678884ef4SEddie Cai hdr->loaderSize = sizeof(rk_boot_entry); 124778884ef4SEddie Cai #ifndef USE_P_RC4 124878884ef4SEddie Cai hdr->rc4Flag = 1; 124978884ef4SEddie Cai #endif 125078884ef4SEddie Cai } 125178884ef4SEddie Cai 125278884ef4SEddie Cai static inline uint32_t getCrc(const char* path) { 125378884ef4SEddie Cai uint32_t size = 0; 125478884ef4SEddie Cai uint32_t crc = 0; 125578884ef4SEddie Cai 125678884ef4SEddie Cai FILE* file = fopen(path, "rb"); 125778884ef4SEddie Cai getFileSize(path, &size); 125878884ef4SEddie Cai if (!file) 125978884ef4SEddie Cai goto end; 126078884ef4SEddie Cai if (!fread(gBuf, size, 1, file)) 126178884ef4SEddie Cai goto end; 126278884ef4SEddie Cai crc = CRC_32(gBuf, size); 126378884ef4SEddie Cai printf("crc:0x%08x\n", crc); 126478884ef4SEddie Cai end: 126578884ef4SEddie Cai if (file) 126678884ef4SEddie Cai fclose(file); 126778884ef4SEddie Cai return crc; 126878884ef4SEddie Cai } 126978884ef4SEddie Cai 127078884ef4SEddie Cai bool mergeBoot(void) { 127178884ef4SEddie Cai uint32_t dataOffset; 127278884ef4SEddie Cai bool ret = false; 127378884ef4SEddie Cai int i; 127478884ef4SEddie Cai FILE* outFile; 127578884ef4SEddie Cai uint32_t crc; 127678884ef4SEddie Cai rk_boot_header hdr; 127778884ef4SEddie Cai 127878884ef4SEddie Cai if (!initOpts()) 127978884ef4SEddie Cai return false; 128078884ef4SEddie Cai { 128178884ef4SEddie Cai char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 128278884ef4SEddie Cai char version[MAX_LINE_LEN]; 128378884ef4SEddie Cai snprintf(version, sizeof(version), "%s", gSubfix); 128478884ef4SEddie Cai if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 128578884ef4SEddie Cai subfix[0] = '\0'; 128678884ef4SEddie Cai } 128778884ef4SEddie Cai strcat(gOpts.outPath, version); 128878884ef4SEddie Cai printf("fix opt:%s\n", gOpts.outPath); 128978884ef4SEddie Cai } 129078884ef4SEddie Cai 129178884ef4SEddie Cai printf("---------------\nUSING CONFIG:\n"); 129278884ef4SEddie Cai printOpts(stdout); 129378884ef4SEddie Cai printf("---------------\n\n"); 129478884ef4SEddie Cai 129578884ef4SEddie Cai 129678884ef4SEddie Cai outFile = fopen(gOpts.outPath, "wb+"); 129778884ef4SEddie Cai if (!outFile) { 129878884ef4SEddie Cai printf("open out file(%s) failed\n", gOpts.outPath); 129978884ef4SEddie Cai goto end; 130078884ef4SEddie Cai } 130178884ef4SEddie Cai 130278884ef4SEddie Cai getBoothdr(&hdr); 130378884ef4SEddie Cai printf("write hdr\n"); 130478884ef4SEddie Cai fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 130578884ef4SEddie Cai 130678884ef4SEddie Cai dataOffset = sizeof(rk_boot_header) + 130778884ef4SEddie Cai (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 130878884ef4SEddie Cai sizeof(rk_boot_entry); 130978884ef4SEddie Cai 131078884ef4SEddie Cai printf("write code 471 entry\n"); 131178884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 131278884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 131378884ef4SEddie Cai &dataOffset, NULL, false)) 131478884ef4SEddie Cai goto end; 131578884ef4SEddie Cai } 131678884ef4SEddie Cai printf("write code 472 entry\n"); 131778884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 131878884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 131978884ef4SEddie Cai &dataOffset, NULL, false)) 132078884ef4SEddie Cai goto end; 132178884ef4SEddie Cai } 132278884ef4SEddie Cai printf("write loader entry\n"); 132378884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 132478884ef4SEddie Cai if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 132578884ef4SEddie Cai &dataOffset, gOpts.loader[i].name, true)) 132678884ef4SEddie Cai goto end; 132778884ef4SEddie Cai } 132878884ef4SEddie Cai 132978884ef4SEddie Cai printf("write code 471\n"); 133078884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 133178884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 133278884ef4SEddie Cai goto end; 133378884ef4SEddie Cai } 133478884ef4SEddie Cai printf("write code 472\n"); 133578884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 133678884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 133778884ef4SEddie Cai goto end; 133878884ef4SEddie Cai } 133978884ef4SEddie Cai printf("write loader\n"); 134078884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 134178884ef4SEddie Cai if (!writeFile(outFile, gOpts.loader[i].path, true)) 134278884ef4SEddie Cai goto end; 134378884ef4SEddie Cai } 134478884ef4SEddie Cai fflush(outFile); 134578884ef4SEddie Cai 134678884ef4SEddie Cai printf("write crc\n"); 134778884ef4SEddie Cai crc = getCrc(gOpts.outPath); 134878884ef4SEddie Cai if (!fwrite(&crc, sizeof(crc), 1, outFile)) 134978884ef4SEddie Cai goto end; 135078884ef4SEddie Cai printf("done\n"); 135178884ef4SEddie Cai ret = true; 135278884ef4SEddie Cai end: 135378884ef4SEddie Cai if (outFile) 135478884ef4SEddie Cai fclose(outFile); 135578884ef4SEddie Cai return ret; 135678884ef4SEddie Cai } 135778884ef4SEddie Cai 135878884ef4SEddie Cai /************merge code end************/ 135978884ef4SEddie Cai /************unpack code***************/ 136078884ef4SEddie Cai 136178884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len) 136278884ef4SEddie Cai { 136378884ef4SEddie Cai int i; 136478884ef4SEddie Cai for (i = 0; i < len; i++) { 136578884ef4SEddie Cai str[i] = (char) (wide[i] & 0xFF); 136678884ef4SEddie Cai } 136778884ef4SEddie Cai str[len] = 0; 136878884ef4SEddie Cai } 136978884ef4SEddie Cai 137078884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name, 137178884ef4SEddie Cai FILE* inFile) { 137278884ef4SEddie Cai bool ret = false; 137378884ef4SEddie Cai int size, i; 137478884ef4SEddie Cai FILE* outFile = fopen(name, "wb+"); 137578884ef4SEddie Cai if (!outFile) 137678884ef4SEddie Cai goto end; 137778884ef4SEddie Cai printf("unpack entry(%s)\n", name); 137878884ef4SEddie Cai fseek(inFile, entry->dataOffset, SEEK_SET); 137978884ef4SEddie Cai size = entry->dataSize; 138078884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 138178884ef4SEddie Cai goto end; 138278884ef4SEddie Cai if (entry->type == ENTRY_LOADER) { 138378884ef4SEddie Cai for(i=0; i<size/SMALL_PACKET; i++) 138478884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 138578884ef4SEddie Cai if (size % SMALL_PACKET) 138678884ef4SEddie Cai { 138778884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 138878884ef4SEddie Cai } 138978884ef4SEddie Cai } else { 139078884ef4SEddie Cai P_RC4(gBuf, size); 139178884ef4SEddie Cai } 139278884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 139378884ef4SEddie Cai goto end; 139478884ef4SEddie Cai ret = true; 139578884ef4SEddie Cai end: 139678884ef4SEddie Cai if (outFile) 139778884ef4SEddie Cai fclose(outFile); 139878884ef4SEddie Cai return ret; 139978884ef4SEddie Cai } 140078884ef4SEddie Cai 140178884ef4SEddie Cai bool unpackBoot(char* path) { 140278884ef4SEddie Cai bool ret = false; 140378884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 140478884ef4SEddie Cai int entryNum, i; 140578884ef4SEddie Cai char name[MAX_NAME_LEN]; 140678884ef4SEddie Cai rk_boot_entry* entrys; 140778884ef4SEddie Cai if (!inFile) { 140878884ef4SEddie Cai fprintf(stderr, "loader(%s) not found\n", path); 140978884ef4SEddie Cai goto end; 141078884ef4SEddie Cai } 141178884ef4SEddie Cai 141278884ef4SEddie Cai rk_boot_header hdr; 141378884ef4SEddie Cai if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 141478884ef4SEddie Cai fprintf(stderr, "read header failed\n"); 141578884ef4SEddie Cai goto end; 141678884ef4SEddie Cai } 141778884ef4SEddie Cai printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 141878884ef4SEddie Cai entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 141978884ef4SEddie Cai entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 142078884ef4SEddie Cai if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 142178884ef4SEddie Cai fprintf(stderr, "read data failed\n"); 142278884ef4SEddie Cai goto end; 142378884ef4SEddie Cai } 142478884ef4SEddie Cai 142578884ef4SEddie Cai printf("entry num:%d\n", entryNum); 142678884ef4SEddie Cai for (i=0; i<entryNum; i++) { 142778884ef4SEddie Cai wide2str(entrys[i].name, name, MAX_NAME_LEN); 142878884ef4SEddie Cai 142978884ef4SEddie Cai printf("entry:t=%d, name=%s, off=%d, size=%d\n", 143078884ef4SEddie Cai entrys[i].type, name, entrys[i].dataOffset, 143178884ef4SEddie Cai entrys[i].dataSize); 143278884ef4SEddie Cai if (!unpackEntry(entrys + i, name, inFile)) { 143378884ef4SEddie Cai fprintf(stderr, "unpack entry(%s) failed\n", name); 143478884ef4SEddie Cai goto end; 143578884ef4SEddie Cai } 143678884ef4SEddie Cai } 143778884ef4SEddie Cai printf("done\n"); 143878884ef4SEddie Cai ret = true; 143978884ef4SEddie Cai end: 144078884ef4SEddie Cai if (inFile) 144178884ef4SEddie Cai fclose(inFile); 144278884ef4SEddie Cai return ret; 144378884ef4SEddie Cai } 144478884ef4SEddie Cai 144576af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 144676af099aSliuyi { 144776af099aSliuyi if (!check_device_type(dev, RKUSB_MASKROM)) 144876af099aSliuyi return false; 144976af099aSliuyi CRKImage *pImage = NULL; 145076af099aSliuyi CRKBoot *pBoot = NULL; 145176af099aSliuyi bool bRet, bSuccess = false; 145276af099aSliuyi int iRet; 145376af099aSliuyi 145476af099aSliuyi pImage = new CRKImage(szLoader, bRet); 145576af099aSliuyi if (!bRet){ 145676af099aSliuyi ERROR_COLOR_ATTR; 145776af099aSliuyi printf("Open loader failed,exit download boot!"); 145876af099aSliuyi NORMAL_COLOR_ATTR; 145976af099aSliuyi printf("\r\n"); 146076af099aSliuyi return bSuccess; 146176af099aSliuyi } else { 146276af099aSliuyi pBoot = (CRKBoot *)pImage->m_bootObject; 146376af099aSliuyi CRKComm *pComm = NULL; 146476af099aSliuyi CRKDevice *pDevice = NULL; 146576af099aSliuyi 146676af099aSliuyi dev.emDeviceType = pBoot->SupportDevice; 146776af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 146876af099aSliuyi if (!bRet) { 146976af099aSliuyi if (pImage) 147076af099aSliuyi delete pImage; 147176af099aSliuyi ERROR_COLOR_ATTR; 147276af099aSliuyi printf("Creating Comm Object failed!"); 147376af099aSliuyi NORMAL_COLOR_ATTR; 147476af099aSliuyi printf("\r\n"); 147576af099aSliuyi return bSuccess; 147676af099aSliuyi } 147776af099aSliuyi 147876af099aSliuyi pDevice = new CRKDevice(dev); 147976af099aSliuyi if (!pDevice) { 148076af099aSliuyi if (pImage) 148176af099aSliuyi delete pImage; 148276af099aSliuyi if (pComm) 148376af099aSliuyi delete pComm; 148476af099aSliuyi ERROR_COLOR_ATTR; 148576af099aSliuyi printf("Creating device object failed!"); 148676af099aSliuyi NORMAL_COLOR_ATTR; 148776af099aSliuyi printf("\r\n"); 148876af099aSliuyi return bSuccess; 148976af099aSliuyi } 149076af099aSliuyi 149176af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 149276af099aSliuyi printf("Download boot...\r\n"); 149376af099aSliuyi iRet = pDevice->DownloadBoot(); 149476af099aSliuyi 149576af099aSliuyi CURSOR_MOVEUP_LINE(1); 149676af099aSliuyi CURSOR_DEL_LINE; 149776af099aSliuyi if (iRet == 0) { 149876af099aSliuyi pComm->Reset_Usb_Device(); 149976af099aSliuyi CRKScan *pScan = NULL; 150076af099aSliuyi pScan = new CRKScan(); 150176af099aSliuyi if (pScan) { 150276af099aSliuyi pScan->SetVidPid(); 150376af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 150476af099aSliuyi delete pScan; 150576af099aSliuyi } 150676af099aSliuyi bSuccess = true; 150776af099aSliuyi printf("Download boot ok.\r\n"); 150876af099aSliuyi } 150976af099aSliuyi else 151076af099aSliuyi printf("Download boot failed!\r\n"); 151176af099aSliuyi 151276af099aSliuyi if (pImage) 151376af099aSliuyi delete pImage; 151476af099aSliuyi if(pDevice) 151576af099aSliuyi delete pDevice; 151676af099aSliuyi } 151776af099aSliuyi return bSuccess; 151876af099aSliuyi } 1519c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1520c30d921cSKever Yang { 1521c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 1522c30d921cSKever Yang return false; 1523c30d921cSKever Yang CRKImage *pImage = NULL; 1524c30d921cSKever Yang CRKBoot *pBoot = NULL; 1525c30d921cSKever Yang CRKComm *pComm = NULL; 1526c30d921cSKever Yang bool bRet, bSuccess = false; 1527c30d921cSKever Yang int iRet; 1528c30d921cSKever Yang char index; 1529c30d921cSKever Yang USHORT usFlashDataSec, usFlashBootSec; 1530c30d921cSKever Yang DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1531c30d921cSKever Yang char loaderCodeName[] = "FlashBoot"; 1532c30d921cSKever Yang char loaderDataName[] = "FlashData"; 1533c30d921cSKever Yang PBYTE loaderCodeBuffer = NULL; 1534c30d921cSKever Yang PBYTE loaderDataBuffer = NULL; 1535c30d921cSKever Yang PBYTE pIDBData = NULL; 1536c30d921cSKever Yang pImage = new CRKImage(szLoader, bRet); 1537c30d921cSKever Yang if (!bRet){ 1538c30d921cSKever Yang ERROR_COLOR_ATTR; 1539c30d921cSKever Yang printf("Open loader failed,exit upgrade loader!"); 1540c30d921cSKever Yang NORMAL_COLOR_ATTR; 1541c30d921cSKever Yang printf("\r\n"); 1542c30d921cSKever Yang goto Exit_UpgradeLoader; 1543c30d921cSKever Yang } else { 1544c30d921cSKever Yang pBoot = (CRKBoot *)pImage->m_bootObject; 1545c30d921cSKever Yang dev.emDeviceType = pBoot->SupportDevice; 1546c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1547c30d921cSKever Yang if (!bRet) { 1548c30d921cSKever Yang ERROR_COLOR_ATTR; 1549c30d921cSKever Yang printf("Creating Comm Object failed!"); 1550c30d921cSKever Yang NORMAL_COLOR_ATTR; 1551c30d921cSKever Yang printf("\r\n"); 1552c30d921cSKever Yang goto Exit_UpgradeLoader; 1553c30d921cSKever Yang } 1554c30d921cSKever Yang 1555c30d921cSKever Yang printf("Upgrade loader...\r\n"); 1556c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1557c30d921cSKever Yang if (index == -1) { 1558c30d921cSKever Yang if (g_pLogObject) { 1559c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry failed"); 1560c30d921cSKever Yang } 1561c30d921cSKever Yang goto Exit_UpgradeLoader; 1562c30d921cSKever Yang } 1563c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1564c30d921cSKever Yang if (!bRet) { 1565c30d921cSKever Yang if (g_pLogObject) { 1566c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry Size failed"); 1567c30d921cSKever Yang } 1568c30d921cSKever Yang goto Exit_UpgradeLoader; 1569c30d921cSKever Yang } 1570c30d921cSKever Yang 1571c30d921cSKever Yang loaderCodeBuffer = new BYTE[dwLoaderSize]; 1572c30d921cSKever Yang memset(loaderCodeBuffer, 0, dwLoaderSize); 1573c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1574c30d921cSKever Yang if (g_pLogObject) { 1575c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Data failed"); 1576c30d921cSKever Yang } 1577c30d921cSKever Yang goto Exit_UpgradeLoader; 1578c30d921cSKever Yang } 1579c30d921cSKever Yang 1580c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1581c30d921cSKever Yang if (index == -1) { 1582c30d921cSKever Yang if (g_pLogObject) { 1583c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry failed"); 1584c30d921cSKever Yang } 1585c30d921cSKever Yang delete []loaderCodeBuffer; 1586c30d921cSKever Yang return -4; 1587c30d921cSKever Yang } 1588c30d921cSKever Yang 1589c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1590c30d921cSKever Yang if (!bRet) { 1591c30d921cSKever Yang if (g_pLogObject) { 1592c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry Size failed"); 1593c30d921cSKever Yang } 1594c30d921cSKever Yang goto Exit_UpgradeLoader; 1595c30d921cSKever Yang } 1596c30d921cSKever Yang 1597c30d921cSKever Yang loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1598c30d921cSKever Yang memset(loaderDataBuffer, 0, dwLoaderDataSize); 1599c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1600c30d921cSKever Yang if (g_pLogObject) { 1601c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Data failed"); 1602c30d921cSKever Yang } 1603c30d921cSKever Yang goto Exit_UpgradeLoader; 1604c30d921cSKever Yang } 1605c30d921cSKever Yang 1606c30d921cSKever Yang usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1607c30d921cSKever Yang usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1608c30d921cSKever Yang dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1609c30d921cSKever Yang pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1610c30d921cSKever Yang if (!pIDBData) { 1611c30d921cSKever Yang ERROR_COLOR_ATTR; 1612c30d921cSKever Yang printf("New memory failed!"); 1613c30d921cSKever Yang NORMAL_COLOR_ATTR; 1614c30d921cSKever Yang printf("\r\n"); 1615c30d921cSKever Yang goto Exit_UpgradeLoader; 1616c30d921cSKever Yang } 1617c30d921cSKever Yang memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1618c30d921cSKever Yang iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize); 1619c30d921cSKever Yang if (iRet != 0) { 1620c30d921cSKever Yang ERROR_COLOR_ATTR; 1621c30d921cSKever Yang printf("Make idblock failed!"); 1622c30d921cSKever Yang NORMAL_COLOR_ATTR; 1623c30d921cSKever Yang printf("\r\n"); 1624c30d921cSKever Yang goto Exit_UpgradeLoader; 1625c30d921cSKever Yang } 1626c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1627c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 1628c30d921cSKever Yang CURSOR_DEL_LINE; 1629c30d921cSKever Yang if (iRet == ERR_SUCCESS) { 1630c30d921cSKever Yang pComm->Reset_Usb_Device(); 1631c30d921cSKever Yang bSuccess = true; 1632c30d921cSKever Yang printf("Upgrade loader ok.\r\n"); 1633c30d921cSKever Yang } else { 1634c30d921cSKever Yang printf("Upgrade loader failed!\r\n"); 1635c30d921cSKever Yang goto Exit_UpgradeLoader; 1636c30d921cSKever Yang } 1637c30d921cSKever Yang } 1638c30d921cSKever Yang Exit_UpgradeLoader: 1639c30d921cSKever Yang if (pImage) 1640c30d921cSKever Yang delete pImage; 1641c30d921cSKever Yang if (pComm) 1642c30d921cSKever Yang delete pComm; 1643c30d921cSKever Yang if (loaderCodeBuffer) 1644c30d921cSKever Yang delete []loaderCodeBuffer; 1645c30d921cSKever Yang if (loaderDataBuffer) 1646c30d921cSKever Yang delete []loaderDataBuffer; 1647c30d921cSKever Yang if (pIDBData) 1648c30d921cSKever Yang delete []pIDBData; 1649c30d921cSKever Yang return bSuccess; 1650c30d921cSKever Yang } 1651c30d921cSKever Yang 165276af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 165376af099aSliuyi { 165476af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 165576af099aSliuyi return false; 165676af099aSliuyi CRKImage *pImage = NULL; 165776af099aSliuyi bool bRet, bSuccess = false; 165876af099aSliuyi int iRet; 165976af099aSliuyi CRKScan *pScan = NULL; 166076af099aSliuyi pScan = new CRKScan(); 166176af099aSliuyi pScan->SetVidPid(); 166276af099aSliuyi 166376af099aSliuyi CRKComm *pComm = NULL; 166476af099aSliuyi CRKDevice *pDevice = NULL; 166576af099aSliuyi 166676af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 166776af099aSliuyi if (!bRet) { 166876af099aSliuyi if (pScan) 166976af099aSliuyi delete pScan; 167076af099aSliuyi ERROR_COLOR_ATTR; 167176af099aSliuyi printf("Creating Comm Object failed!"); 167276af099aSliuyi NORMAL_COLOR_ATTR; 167376af099aSliuyi printf("\r\n"); 167476af099aSliuyi return bSuccess; 167576af099aSliuyi } 167676af099aSliuyi 167776af099aSliuyi pDevice = new CRKDevice(dev); 167876af099aSliuyi if (!pDevice) { 167976af099aSliuyi if (pComm) 168076af099aSliuyi delete pComm; 168176af099aSliuyi if (pScan) 168276af099aSliuyi delete pScan; 168376af099aSliuyi ERROR_COLOR_ATTR; 168476af099aSliuyi printf("Creating device object failed!"); 168576af099aSliuyi NORMAL_COLOR_ATTR; 168676af099aSliuyi printf("\r\n"); 168776af099aSliuyi return bSuccess; 168876af099aSliuyi } 168976af099aSliuyi 169076af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 169176af099aSliuyi pDevice->CallBackPointer = ProgressInfoProc; 169276af099aSliuyi 169376af099aSliuyi printf("Start to erase flash...\r\n"); 169476af099aSliuyi iRet = pDevice->EraseAllBlocks(); 169576af099aSliuyi if (pDevice) 169676af099aSliuyi delete pDevice; 169776af099aSliuyi 169876af099aSliuyi if (iRet == 0) { 169976af099aSliuyi if (pScan) { 170076af099aSliuyi pScan->SetVidPid(); 170176af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 170276af099aSliuyi delete pScan; 170376af099aSliuyi } 170476af099aSliuyi CURSOR_MOVEUP_LINE(1); 170576af099aSliuyi CURSOR_DEL_LINE; 170676af099aSliuyi bSuccess = true; 170776af099aSliuyi printf("Erase flash ok.\r\n"); 170876af099aSliuyi } 170976af099aSliuyi 171076af099aSliuyi return bSuccess; 171176af099aSliuyi } 171276af099aSliuyi 171376af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev) 171476af099aSliuyi { 171576af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 171676af099aSliuyi return false; 171776af099aSliuyi CRKUsbComm *pComm = NULL; 171876af099aSliuyi bool bRet, bSuccess = false; 171976af099aSliuyi int iRet; 172076af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 172176af099aSliuyi if (bRet) { 172276af099aSliuyi iRet = pComm->RKU_TestDeviceReady(); 172376af099aSliuyi if (iRet != ERR_SUCCESS) { 172476af099aSliuyi if (g_pLogObject) 172576af099aSliuyi g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet); 172676af099aSliuyi printf("Test Device Fail!\r\n"); 172776af099aSliuyi } else { 172876af099aSliuyi bSuccess = true; 172976af099aSliuyi printf("Test Device OK.\r\n"); 173076af099aSliuyi } 173176af099aSliuyi } else { 173276af099aSliuyi printf("Test Device quit,Creating comm object failed!\r\n"); 173376af099aSliuyi } 173476af099aSliuyi if (pComm) { 173576af099aSliuyi delete pComm; 173676af099aSliuyi pComm = NULL; 173776af099aSliuyi } 173876af099aSliuyi return bSuccess; 173976af099aSliuyi } 174076af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 174176af099aSliuyi { 174276af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 174376af099aSliuyi return false; 174476af099aSliuyi CRKUsbComm *pComm = NULL; 174576af099aSliuyi bool bRet, bSuccess = false; 174676af099aSliuyi int iRet; 174776af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 174876af099aSliuyi if (bRet) { 174976af099aSliuyi iRet = pComm->RKU_ResetDevice(subCode); 175076af099aSliuyi if (iRet != ERR_SUCCESS) { 175176af099aSliuyi if (g_pLogObject) 175276af099aSliuyi g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet); 175376af099aSliuyi printf("Reset Device Fail!\r\n"); 175476af099aSliuyi } else { 175576af099aSliuyi bSuccess = true; 175676af099aSliuyi printf("Reset Device OK.\r\n"); 175776af099aSliuyi } 175876af099aSliuyi } else { 175976af099aSliuyi printf("Reset Device quit,Creating comm object failed!\r\n"); 176076af099aSliuyi } 176176af099aSliuyi if (pComm) { 176276af099aSliuyi delete pComm; 176376af099aSliuyi pComm = NULL; 176476af099aSliuyi } 176576af099aSliuyi return bSuccess; 176676af099aSliuyi } 176776af099aSliuyi 176876af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 176976af099aSliuyi { 177076af099aSliuyi CRKUsbComm *pComm = NULL; 177176af099aSliuyi bool bRet, bSuccess = false; 177276af099aSliuyi int iRet; 177376af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 177476af099aSliuyi return bSuccess; 177576af099aSliuyi 177676af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 177776af099aSliuyi if (bRet) { 177876af099aSliuyi BYTE flashID[5]; 177976af099aSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 178076af099aSliuyi if (iRet != ERR_SUCCESS) { 178176af099aSliuyi if (g_pLogObject) 178276af099aSliuyi g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet); 178376af099aSliuyi printf("Read flash ID Fail!\r\n"); 178476af099aSliuyi } else { 178576af099aSliuyi printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 178676af099aSliuyi bSuccess = true; 178776af099aSliuyi } 178876af099aSliuyi } else { 178976af099aSliuyi printf("Read flash ID quit,Creating comm object failed!\r\n"); 179076af099aSliuyi } 179176af099aSliuyi if (pComm) { 179276af099aSliuyi delete pComm; 179376af099aSliuyi pComm = NULL; 179476af099aSliuyi } 179576af099aSliuyi return bSuccess; 179676af099aSliuyi } 179776af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 179876af099aSliuyi { 179976af099aSliuyi CRKUsbComm *pComm = NULL; 180076af099aSliuyi bool bRet, bSuccess = false; 180176af099aSliuyi int iRet; 180276af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 180376af099aSliuyi return bSuccess; 180476af099aSliuyi 180576af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 180676af099aSliuyi if (bRet) { 180776af099aSliuyi STRUCT_FLASHINFO_CMD info; 180876af099aSliuyi UINT uiRead; 180976af099aSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 181076af099aSliuyi if (iRet != ERR_SUCCESS) { 181176af099aSliuyi if (g_pLogObject) 181276af099aSliuyi g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet); 181376af099aSliuyi printf("Read flash Info Fail!\r\n"); 181476af099aSliuyi } else { 181576af099aSliuyi printf("Flash Info:\r\n"); 181676af099aSliuyi if (info.bManufCode <= 7) { 181776af099aSliuyi printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 181876af099aSliuyi } 181976af099aSliuyi else 182076af099aSliuyi printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode); 182176af099aSliuyi 182276af099aSliuyi printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024); 182376af099aSliuyi printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2); 182476af099aSliuyi printf("\tPage Size: %dKB\r\n", info.bPageSize / 2); 182576af099aSliuyi printf("\tECC Bits: %d\r\n", info.bECCBits); 182676af099aSliuyi printf("\tAccess Time: %d\r\n", info.bAccessTime); 182776af099aSliuyi printf("\tFlash CS: "); 182876af099aSliuyi for(int i = 0; i < 8; i++) { 182976af099aSliuyi if( info.bFlashCS & (1 << i) ) 183076af099aSliuyi printf("Flash<%d> ", i); 183176af099aSliuyi } 183276af099aSliuyi printf("\r\n"); 183376af099aSliuyi bSuccess = true; 183476af099aSliuyi } 183576af099aSliuyi }else { 183676af099aSliuyi printf("Read flash Info quit,Creating comm object failed!\r\n"); 183776af099aSliuyi } 183876af099aSliuyi if (pComm) { 183976af099aSliuyi delete pComm; 184076af099aSliuyi pComm = NULL; 184176af099aSliuyi } 184276af099aSliuyi return bSuccess; 184376af099aSliuyi } 184476af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 184576af099aSliuyi { 184676af099aSliuyi CRKUsbComm *pComm = NULL; 184776af099aSliuyi bool bRet, bSuccess = false; 184876af099aSliuyi int iRet; 184976af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 185076af099aSliuyi return bSuccess; 185176af099aSliuyi 185276af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 185376af099aSliuyi if (bRet) { 185476af099aSliuyi BYTE chipInfo[16]; 185576af099aSliuyi iRet = pComm->RKU_ReadChipInfo(chipInfo); 185676af099aSliuyi if (iRet != ERR_SUCCESS) { 185776af099aSliuyi if (g_pLogObject) 185876af099aSliuyi g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet); 185976af099aSliuyi printf("Read Chip Info Fail!\r\n"); 186076af099aSliuyi } else { 186176af099aSliuyi string strChipInfo; 186276af099aSliuyi g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 186376af099aSliuyi printf("Chip Info:%s\r\n", strChipInfo.c_str()); 186476af099aSliuyi bSuccess = true; 186576af099aSliuyi } 186676af099aSliuyi } else { 186776af099aSliuyi printf("Read Chip Info quit,Creating comm object failed!\r\n"); 186876af099aSliuyi } 186976af099aSliuyi if (pComm) { 187076af099aSliuyi delete pComm; 187176af099aSliuyi pComm = NULL; 187276af099aSliuyi } 187376af099aSliuyi return bSuccess; 187476af099aSliuyi } 187576af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 187676af099aSliuyi { 187776af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 187876af099aSliuyi return false; 187976af099aSliuyi CRKUsbComm *pComm = NULL; 188076af099aSliuyi FILE *file = NULL; 188176af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 188276af099aSliuyi int iRet; 188376af099aSliuyi UINT iTotalRead = 0,iRead = 0; 188476af099aSliuyi int nSectorSize = 512; 188576af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 188676af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 188776af099aSliuyi if (bRet) { 188876af099aSliuyi if(szFile) { 188976af099aSliuyi file = fopen(szFile, "wb+"); 189076af099aSliuyi if( !file ) { 189176af099aSliuyi printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile); 189276af099aSliuyi goto Exit_ReadLBA; 189376af099aSliuyi } 189476af099aSliuyi } 189576af099aSliuyi 189676af099aSliuyi while(uiLen > 0) { 189776af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 189876af099aSliuyi iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 189976af099aSliuyi iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 190076af099aSliuyi if(ERR_SUCCESS == iRet) { 190176af099aSliuyi uiLen -= iRead; 190276af099aSliuyi iTotalRead += iRead; 190376af099aSliuyi 190476af099aSliuyi if(szFile) { 190576af099aSliuyi fwrite(pBuf, 1, iRead * nSectorSize, file); 190676af099aSliuyi if (bFirst){ 190776af099aSliuyi if (iTotalRead >= 1024) 190876af099aSliuyi printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 190976af099aSliuyi else 191076af099aSliuyi printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 191176af099aSliuyi bFirst = false; 191276af099aSliuyi } else { 191376af099aSliuyi CURSOR_MOVEUP_LINE(1); 191476af099aSliuyi CURSOR_DEL_LINE; 191576af099aSliuyi if (iTotalRead >= 1024) 191676af099aSliuyi printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 191776af099aSliuyi else 191876af099aSliuyi printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 191976af099aSliuyi } 192076af099aSliuyi } 192176af099aSliuyi else 192276af099aSliuyi PrintData(pBuf, nSectorSize * iRead); 192376af099aSliuyi } else { 192476af099aSliuyi if (g_pLogObject) 192576af099aSliuyi g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet); 192676af099aSliuyi 192776af099aSliuyi printf("Read LBA failed!\r\n"); 192876af099aSliuyi goto Exit_ReadLBA; 192976af099aSliuyi } 193076af099aSliuyi } 193176af099aSliuyi bSuccess = true; 193276af099aSliuyi } else { 193376af099aSliuyi printf("Read LBA quit,Creating comm object failed!\r\n"); 193476af099aSliuyi } 193576af099aSliuyi Exit_ReadLBA: 193676af099aSliuyi if (pComm) { 193776af099aSliuyi delete pComm; 193876af099aSliuyi pComm = NULL; 193976af099aSliuyi } 194076af099aSliuyi if (file) 194176af099aSliuyi fclose(file); 194276af099aSliuyi return bSuccess; 194376af099aSliuyi } 194476af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 194576af099aSliuyi { 194676af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 194776af099aSliuyi return false; 194876af099aSliuyi CRKUsbComm *pComm = NULL; 194976af099aSliuyi FILE *file = NULL; 195076af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 195176af099aSliuyi int iRet; 195276af099aSliuyi long long iTotalWrite = 0, iFileSize = 0; 195376af099aSliuyi UINT iWrite = 0, iRead = 0; 195476af099aSliuyi UINT uiLen; 195576af099aSliuyi int nSectorSize = 512; 195676af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 195776af099aSliuyi 195876af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 195976af099aSliuyi if (bRet) { 196076af099aSliuyi file = fopen(szFile, "rb"); 196176af099aSliuyi if( !file ) { 196276af099aSliuyi printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile); 196376af099aSliuyi goto Exit_WriteLBA; 196476af099aSliuyi } 196576af099aSliuyi 196676af099aSliuyi iRet = fseeko(file, 0, SEEK_END); 196776af099aSliuyi iFileSize = ftello(file); 196876af099aSliuyi fseeko(file, 0, SEEK_SET); 196976af099aSliuyi while(iTotalWrite < iFileSize) { 197076af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 197176af099aSliuyi iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 197276af099aSliuyi uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 197376af099aSliuyi iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 197476af099aSliuyi if(ERR_SUCCESS == iRet) { 197576af099aSliuyi uiBegin += uiLen; 197676af099aSliuyi iTotalWrite += iWrite; 197776af099aSliuyi if (bFirst) { 197876af099aSliuyi if (iTotalWrite >= 1024) 197976af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 198076af099aSliuyi else 198176af099aSliuyi printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize); 198276af099aSliuyi bFirst = false; 198376af099aSliuyi } else { 198476af099aSliuyi CURSOR_MOVEUP_LINE(1); 198576af099aSliuyi CURSOR_DEL_LINE; 198676af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 198776af099aSliuyi } 198876af099aSliuyi } else { 198976af099aSliuyi if (g_pLogObject) 199076af099aSliuyi g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet); 199176af099aSliuyi 199276af099aSliuyi printf("Write LBA failed!\r\n"); 199376af099aSliuyi goto Exit_WriteLBA; 199476af099aSliuyi } 199576af099aSliuyi } 199676af099aSliuyi bSuccess = true; 199776af099aSliuyi } else { 199876af099aSliuyi printf("Write LBA quit,Creating comm object failed!\r\n"); 199976af099aSliuyi } 200076af099aSliuyi Exit_WriteLBA: 200176af099aSliuyi if (pComm) { 200276af099aSliuyi delete pComm; 200376af099aSliuyi pComm = NULL; 200476af099aSliuyi } 200576af099aSliuyi if (file) 200676af099aSliuyi fclose(file); 200776af099aSliuyi return bSuccess; 200876af099aSliuyi } 200976af099aSliuyi 201076af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems) 201176af099aSliuyi { 201276af099aSliuyi string strItem; 201376af099aSliuyi char szItem[100]; 201476af099aSliuyi char *pos = NULL, *pStart; 201576af099aSliuyi pStart = pszItems; 201676af099aSliuyi pos = strchr(pStart, ','); 201776af099aSliuyi while(pos != NULL) { 201876af099aSliuyi memset(szItem, 0, 100); 201976af099aSliuyi strncpy(szItem, pStart, pos - pStart); 202076af099aSliuyi strItem = szItem; 202176af099aSliuyi vecItems.push_back(strItem); 202276af099aSliuyi pStart = pos + 1; 202376af099aSliuyi if (*pStart == 0) 202476af099aSliuyi break; 202576af099aSliuyi pos = strchr(pStart, ','); 202676af099aSliuyi } 202776af099aSliuyi if (strlen(pStart) > 0) { 202876af099aSliuyi memset(szItem, 0, 100); 202976af099aSliuyi strncpy(szItem, pStart, strlen(pStart)); 203076af099aSliuyi strItem = szItem; 203176af099aSliuyi vecItems.push_back(strItem); 203276af099aSliuyi } 203376af099aSliuyi } 2034c30d921cSKever Yang 203576af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan) 203676af099aSliuyi { 203776af099aSliuyi string strCmd; 203876af099aSliuyi strCmd = argv[1]; 203976af099aSliuyi ssize_t cnt; 204076af099aSliuyi bool bRet,bSuccess = false; 20418df2d64aSEddie Cai char *s; 20428df2d64aSEddie Cai int i, ret; 204376af099aSliuyi STRUCT_RKDEVICE_DESC dev; 204476af099aSliuyi 204576af099aSliuyi transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 20468df2d64aSEddie Cai s = (char*)strCmd.c_str(); 20478df2d64aSEddie Cai for(i = 0; i < (int)strlen(s); i++) 20488df2d64aSEddie Cai s[i] = toupper(s[i]); 204978884ef4SEddie Cai 20508df2d64aSEddie Cai if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 205176af099aSliuyi usage(); 205276af099aSliuyi return true; 20538df2d64aSEddie Cai } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2054c30d921cSKever Yang printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 205576af099aSliuyi return true; 205678884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 205778884ef4SEddie Cai mergeBoot(); 205878884ef4SEddie Cai 205978884ef4SEddie Cai return true; 206078884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 206178884ef4SEddie Cai string strLoader = argv[2]; 206278884ef4SEddie Cai 206378884ef4SEddie Cai unpackBoot((char*)strLoader.c_str()); 206478884ef4SEddie Cai return true; 206576af099aSliuyi } 206676af099aSliuyi cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 206776af099aSliuyi if (cnt < 1) { 206876af099aSliuyi ERROR_COLOR_ATTR; 206976af099aSliuyi printf("No found any rockusb device,please plug device in!"); 207076af099aSliuyi NORMAL_COLOR_ATTR; 207176af099aSliuyi printf("\r\n"); 207276af099aSliuyi return bSuccess; 207376af099aSliuyi } else if (cnt > 1) { 207476af099aSliuyi ERROR_COLOR_ATTR; 207576af099aSliuyi printf("Found many rockusb devices,please plug device out!"); 207676af099aSliuyi NORMAL_COLOR_ATTR; 207776af099aSliuyi printf("\r\n"); 207876af099aSliuyi return bSuccess; 207976af099aSliuyi } 208076af099aSliuyi 208176af099aSliuyi bRet = pScan->GetDevice(dev, 0); 208276af099aSliuyi if (!bRet) { 208376af099aSliuyi ERROR_COLOR_ATTR; 208476af099aSliuyi printf("Getting information of rockusb device failed!"); 208576af099aSliuyi NORMAL_COLOR_ATTR; 208676af099aSliuyi printf("\r\n"); 208776af099aSliuyi return bSuccess; 208876af099aSliuyi } 208976af099aSliuyi 209076af099aSliuyi if(strcmp(strCmd.c_str(), "RD") == 0) { 209176af099aSliuyi if ((argc != 2) && (argc != 3)) 209276af099aSliuyi printf("Parameter of [RD] command is invalid,please check help!\r\n"); 209376af099aSliuyi else { 209476af099aSliuyi if (argc == 2) 209576af099aSliuyi bSuccess = reset_device(dev); 209676af099aSliuyi else { 209776af099aSliuyi UINT uiSubCode; 209876af099aSliuyi char *pszEnd; 209976af099aSliuyi uiSubCode = strtoul(argv[2], &pszEnd, 0); 210076af099aSliuyi if (*pszEnd) 210176af099aSliuyi printf("Subcode is invalid,please check!\r\n"); 210276af099aSliuyi else { 210376af099aSliuyi if (uiSubCode <= 5) 210476af099aSliuyi bSuccess = reset_device(dev, uiSubCode); 210576af099aSliuyi else 210676af099aSliuyi printf("Subcode is invalid,please check!\r\n"); 210776af099aSliuyi } 210876af099aSliuyi } 210976af099aSliuyi } 211076af099aSliuyi } else if(strcmp(strCmd.c_str(), "TD") == 0) { 211176af099aSliuyi bSuccess = test_device(dev); 211276af099aSliuyi } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 211376af099aSliuyi bSuccess = read_flash_id(dev); 211476af099aSliuyi } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 211576af099aSliuyi bSuccess = read_flash_info(dev); 211676af099aSliuyi } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 211776af099aSliuyi bSuccess = read_chip_info(dev); 211876af099aSliuyi } else if(strcmp(strCmd.c_str(), "DB") == 0) { 211976af099aSliuyi if (argc > 2) { 212076af099aSliuyi string strLoader; 212176af099aSliuyi strLoader = argv[2]; 212276af099aSliuyi bSuccess = download_boot(dev, (char *)strLoader.c_str()); 212376af099aSliuyi } else if (argc == 2) { 212476af099aSliuyi ret = find_config_item("loader"); 212576af099aSliuyi if (ret == -1) 212676af099aSliuyi printf("No found loader item from config!\r\n"); 212776af099aSliuyi else 212876af099aSliuyi bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 212976af099aSliuyi } else 213076af099aSliuyi printf("Parameter of [DB] command is invalid,please check help!\r\n"); 2131c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2132c30d921cSKever Yang if (argc > 2) { 2133c30d921cSKever Yang string strParameter; 2134c30d921cSKever Yang strParameter = argv[2]; 2135c30d921cSKever Yang bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2136c30d921cSKever Yang } else 2137c30d921cSKever Yang printf("Parameter of [GPT] command is invalid,please check help!\r\n"); 2138c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2139c30d921cSKever Yang if (argc > 2) { 2140c30d921cSKever Yang string strLoader; 2141c30d921cSKever Yang strLoader = argv[2]; 2142c30d921cSKever Yang bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2143c30d921cSKever Yang } else 2144c30d921cSKever Yang printf("Parameter of [UL] command is invalid,please check help!\r\n"); 214576af099aSliuyi } else if(strcmp(strCmd.c_str(), "EF") == 0) { 214676af099aSliuyi if (argc == 2) { 214776af099aSliuyi bSuccess = erase_flash(dev); 214876af099aSliuyi } else 214976af099aSliuyi printf("Parameter of [EF] command is invalid,please check help!\r\n"); 215076af099aSliuyi } else if(strcmp(strCmd.c_str(), "WL") == 0) { 215176af099aSliuyi if (argc == 4) { 215276af099aSliuyi UINT uiBegin; 215376af099aSliuyi char *pszEnd; 215476af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 215576af099aSliuyi if (*pszEnd) 215676af099aSliuyi printf("Begin is invalid,please check!\r\n"); 215776af099aSliuyi else 215876af099aSliuyi bSuccess = write_lba(dev, uiBegin, argv[3]); 215976af099aSliuyi } else 216076af099aSliuyi printf("Parameter of [WL] command is invalid,please check help!\r\n"); 216176af099aSliuyi } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 216276af099aSliuyi char *pszEnd; 216376af099aSliuyi UINT uiBegin, uiLen; 216476af099aSliuyi if (argc != 5) 216576af099aSliuyi printf("Parameter of [RL] command is invalid,please check help!\r\n"); 216676af099aSliuyi else { 216776af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 216876af099aSliuyi if (*pszEnd) 216976af099aSliuyi printf("Begin is invalid,please check!\r\n"); 217076af099aSliuyi else { 217176af099aSliuyi uiLen = strtoul(argv[3], &pszEnd, 0); 217276af099aSliuyi if (*pszEnd) 217376af099aSliuyi printf("Len is invalid,please check!\r\n"); 217476af099aSliuyi else { 217576af099aSliuyi bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 217676af099aSliuyi } 217776af099aSliuyi } 217876af099aSliuyi } 217976af099aSliuyi } else { 2180c30d921cSKever Yang printf("command is invalid,please press rkDevelopTool -h to check usage!\r\n"); 218176af099aSliuyi } 218276af099aSliuyi return bSuccess; 218376af099aSliuyi } 218476af099aSliuyi 218576af099aSliuyi 218676af099aSliuyi int main(int argc, char* argv[]) 218776af099aSliuyi { 218876af099aSliuyi CRKScan *pScan = NULL; 218976af099aSliuyi int ret; 219076af099aSliuyi char szProgramProcPath[100]; 219176af099aSliuyi char szProgramDir[256]; 219276af099aSliuyi string strLogDir,strConfigFile; 219376af099aSliuyi struct stat statBuf; 219476af099aSliuyi 219576af099aSliuyi g_ConfigItemVec.clear(); 219676af099aSliuyi sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 219776af099aSliuyi if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 219876af099aSliuyi strcpy(szProgramDir, "."); 219976af099aSliuyi else { 220076af099aSliuyi char *pSlash; 220176af099aSliuyi pSlash = strrchr(szProgramDir, '/'); 220276af099aSliuyi if (pSlash) 220376af099aSliuyi *pSlash = '\0'; 220476af099aSliuyi } 220576af099aSliuyi strLogDir = szProgramDir; 220676af099aSliuyi strLogDir += "/log/"; 220776af099aSliuyi strConfigFile = szProgramDir; 220876af099aSliuyi strConfigFile += "/config.ini"; 220976af099aSliuyi if (opendir(strLogDir.c_str()) == NULL) 221076af099aSliuyi mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 221176af099aSliuyi g_pLogObject = new CRKLog(strLogDir.c_str(), "log"); 221276af099aSliuyi 221376af099aSliuyi if(stat(strConfigFile.c_str(), &statBuf) < 0) { 221476af099aSliuyi if (g_pLogObject) { 221576af099aSliuyi g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno); 221676af099aSliuyi } 221776af099aSliuyi } else if (S_ISREG(statBuf.st_mode)) { 221876af099aSliuyi parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 221976af099aSliuyi } 222076af099aSliuyi 222176af099aSliuyi ret = libusb_init(NULL); 222276af099aSliuyi if (ret < 0) { 222376af099aSliuyi if (g_pLogObject) { 222476af099aSliuyi g_pLogObject->Record("Error:libusb_init failed,err=%d", ret); 222576af099aSliuyi delete g_pLogObject; 222676af099aSliuyi } 222776af099aSliuyi return -1; 222876af099aSliuyi } 222976af099aSliuyi 223076af099aSliuyi pScan = new CRKScan(); 223176af099aSliuyi if (!pScan) { 223276af099aSliuyi if (g_pLogObject) { 223376af099aSliuyi g_pLogObject->Record("Error:failed to Create object for searching device"); 223476af099aSliuyi delete g_pLogObject; 223576af099aSliuyi } 223676af099aSliuyi libusb_exit(NULL); 223776af099aSliuyi return -2; 223876af099aSliuyi } 223976af099aSliuyi pScan->SetVidPid(); 224076af099aSliuyi 224176af099aSliuyi if (argc == 1) 224276af099aSliuyi usage(); 224376af099aSliuyi else if (!handle_command(argc, argv, pScan)) 224476af099aSliuyi return -0xFF; 224576af099aSliuyi if (pScan) 224676af099aSliuyi delete pScan; 224776af099aSliuyi if (g_pLogObject) 224876af099aSliuyi delete g_pLogObject; 224976af099aSliuyi libusb_exit(NULL); 225076af099aSliuyi return 0; 225176af099aSliuyi } 2252