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"); 58*78884ef4SEddie Cai printf("PackBootLoader:\t\tpack\r\n"); 59*78884ef4SEddie 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 684*78884ef4SEddie Cai #include "boot_merger.h" 685*78884ef4SEddie Cai #define ENTRY_ALIGN (2048) 686*78884ef4SEddie Cai options gOpts; 687*78884ef4SEddie Cai 688*78884ef4SEddie Cai 689*78884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 690*78884ef4SEddie Cai char* gConfigPath; 691*78884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE]; 692*78884ef4SEddie Cai 693*78884ef4SEddie Cai static inline void fixPath(char* path) { 694*78884ef4SEddie Cai int i, len = strlen(path); 695*78884ef4SEddie Cai for(i=0; i<len; i++) { 696*78884ef4SEddie Cai if (path[i] == '\\') 697*78884ef4SEddie Cai path[i] = '/'; 698*78884ef4SEddie Cai else if (path[i] == '\r' || path[i] == '\n') 699*78884ef4SEddie Cai path[i] = '\0'; 700*78884ef4SEddie Cai } 701*78884ef4SEddie Cai } 702*78884ef4SEddie Cai 703*78884ef4SEddie Cai static bool parseChip(FILE* file) { 704*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 705*78884ef4SEddie Cai return false; 706*78884ef4SEddie Cai } 707*78884ef4SEddie Cai if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 708*78884ef4SEddie Cai return false; 709*78884ef4SEddie Cai } 710*78884ef4SEddie Cai printf("chip:%s\n", gOpts.chip); 711*78884ef4SEddie Cai return true; 712*78884ef4SEddie Cai } 713*78884ef4SEddie Cai 714*78884ef4SEddie Cai static bool parseVersion(FILE* file) { 715*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 716*78884ef4SEddie Cai return false; 717*78884ef4SEddie Cai } 718*78884ef4SEddie Cai if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 719*78884ef4SEddie Cai return false; 720*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 721*78884ef4SEddie Cai return false; 722*78884ef4SEddie Cai } 723*78884ef4SEddie Cai if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 724*78884ef4SEddie Cai return false; 725*78884ef4SEddie Cai printf("major:%d, minor:%d\n", gOpts.major, gOpts.minor); 726*78884ef4SEddie Cai return true; 727*78884ef4SEddie Cai } 728*78884ef4SEddie Cai 729*78884ef4SEddie Cai static bool parse471(FILE* file) { 730*78884ef4SEddie Cai int i, index, pos; 731*78884ef4SEddie Cai char buf[MAX_LINE_LEN]; 732*78884ef4SEddie Cai 733*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 734*78884ef4SEddie Cai return false; 735*78884ef4SEddie Cai } 736*78884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 737*78884ef4SEddie Cai return false; 738*78884ef4SEddie Cai printf("num:%d\n", gOpts.code471Num); 739*78884ef4SEddie Cai if (!gOpts.code471Num) 740*78884ef4SEddie Cai return true; 741*78884ef4SEddie Cai if (gOpts.code471Num < 0) 742*78884ef4SEddie Cai return false; 743*78884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 744*78884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 745*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 746*78884ef4SEddie Cai return false; 747*78884ef4SEddie Cai } 748*78884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 749*78884ef4SEddie Cai != 2) 750*78884ef4SEddie Cai return false; 751*78884ef4SEddie Cai index--; 752*78884ef4SEddie Cai fixPath(buf); 753*78884ef4SEddie Cai strcpy((char*)gOpts.code471Path[index], buf); 754*78884ef4SEddie Cai printf("path%i:%s\n", index, gOpts.code471Path[index]); 755*78884ef4SEddie Cai } 756*78884ef4SEddie Cai pos = ftell(file); 757*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 758*78884ef4SEddie Cai return false; 759*78884ef4SEddie Cai } 760*78884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 761*78884ef4SEddie Cai fseek(file, pos, SEEK_SET); 762*78884ef4SEddie Cai printf("sleep:%d\n", gOpts.code471Sleep); 763*78884ef4SEddie Cai return true; 764*78884ef4SEddie Cai } 765*78884ef4SEddie Cai 766*78884ef4SEddie Cai static bool parse472(FILE* file) { 767*78884ef4SEddie Cai int i, index, pos; 768*78884ef4SEddie Cai char buf[MAX_LINE_LEN]; 769*78884ef4SEddie Cai 770*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 771*78884ef4SEddie Cai return false; 772*78884ef4SEddie Cai } 773*78884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 774*78884ef4SEddie Cai return false; 775*78884ef4SEddie Cai printf("num:%d\n", gOpts.code472Num); 776*78884ef4SEddie Cai if (!gOpts.code472Num) 777*78884ef4SEddie Cai return true; 778*78884ef4SEddie Cai if (gOpts.code472Num < 0) 779*78884ef4SEddie Cai return false; 780*78884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 781*78884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 782*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 783*78884ef4SEddie Cai return false; 784*78884ef4SEddie Cai } 785*78884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 786*78884ef4SEddie Cai != 2) 787*78884ef4SEddie Cai return false; 788*78884ef4SEddie Cai fixPath(buf); 789*78884ef4SEddie Cai index--; 790*78884ef4SEddie Cai strcpy((char*)gOpts.code472Path[index], buf); 791*78884ef4SEddie Cai printf("path%i:%s\n", index, gOpts.code472Path[index]); 792*78884ef4SEddie Cai } 793*78884ef4SEddie Cai pos = ftell(file); 794*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 795*78884ef4SEddie Cai return false; 796*78884ef4SEddie Cai } 797*78884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 798*78884ef4SEddie Cai fseek(file, pos, SEEK_SET); 799*78884ef4SEddie Cai printf("sleep:%d\n", gOpts.code472Sleep); 800*78884ef4SEddie Cai return true; 801*78884ef4SEddie Cai } 802*78884ef4SEddie Cai 803*78884ef4SEddie Cai static bool parseLoader(FILE* file) { 804*78884ef4SEddie Cai int i, j, index, pos; 805*78884ef4SEddie Cai char buf[MAX_LINE_LEN]; 806*78884ef4SEddie Cai char buf2[MAX_LINE_LEN]; 807*78884ef4SEddie Cai 808*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 809*78884ef4SEddie Cai return false; 810*78884ef4SEddie Cai } 811*78884ef4SEddie Cai pos = ftell(file); 812*78884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 813*78884ef4SEddie Cai fseek(file, pos, SEEK_SET); 814*78884ef4SEddie Cai if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 815*78884ef4SEddie Cai return false; 816*78884ef4SEddie Cai } 817*78884ef4SEddie Cai } 818*78884ef4SEddie Cai printf("num:%d\n", gOpts.loaderNum); 819*78884ef4SEddie Cai if (!gOpts.loaderNum) 820*78884ef4SEddie Cai return false; 821*78884ef4SEddie Cai if (gOpts.loaderNum < 0) 822*78884ef4SEddie Cai return false; 823*78884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 824*78884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 825*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 826*78884ef4SEddie Cai return false; 827*78884ef4SEddie Cai } 828*78884ef4SEddie Cai if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 829*78884ef4SEddie Cai != 2) 830*78884ef4SEddie Cai return false; 831*78884ef4SEddie Cai index--; 832*78884ef4SEddie Cai strcpy(gOpts.loader[index].name, buf); 833*78884ef4SEddie Cai printf("name%d:%s\n", index, gOpts.loader[index].name); 834*78884ef4SEddie Cai } 835*78884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 836*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 837*78884ef4SEddie Cai return false; 838*78884ef4SEddie Cai } 839*78884ef4SEddie Cai if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 840*78884ef4SEddie Cai != 2) 841*78884ef4SEddie Cai return false; 842*78884ef4SEddie Cai for (j=0; j<gOpts.loaderNum; j++) { 843*78884ef4SEddie Cai if (!strcmp(gOpts.loader[j].name, buf)) { 844*78884ef4SEddie Cai fixPath(buf2); 845*78884ef4SEddie Cai strcpy(gOpts.loader[j].path, buf2); 846*78884ef4SEddie Cai printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 847*78884ef4SEddie Cai break; 848*78884ef4SEddie Cai } 849*78884ef4SEddie Cai } 850*78884ef4SEddie Cai if (j >= gOpts.loaderNum) { 851*78884ef4SEddie Cai return false; 852*78884ef4SEddie Cai } 853*78884ef4SEddie Cai } 854*78884ef4SEddie Cai return true; 855*78884ef4SEddie Cai } 856*78884ef4SEddie Cai 857*78884ef4SEddie Cai static bool parseOut(FILE* file) { 858*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 859*78884ef4SEddie Cai return false; 860*78884ef4SEddie Cai } 861*78884ef4SEddie Cai if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 862*78884ef4SEddie Cai return false; 863*78884ef4SEddie Cai fixPath(gOpts.outPath); 864*78884ef4SEddie Cai printf("out:%s\n", gOpts.outPath); 865*78884ef4SEddie Cai return true; 866*78884ef4SEddie Cai } 867*78884ef4SEddie Cai 868*78884ef4SEddie Cai 869*78884ef4SEddie Cai void printOpts(FILE* out) { 870*78884ef4SEddie Cai int i; 871*78884ef4SEddie Cai fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 872*78884ef4SEddie Cai fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 873*78884ef4SEddie Cai "=%d\n", gOpts.major, gOpts.minor); 874*78884ef4SEddie Cai 875*78884ef4SEddie Cai fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 876*78884ef4SEddie Cai for (i=0 ;i<gOpts.code471Num ;i++) { 877*78884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 878*78884ef4SEddie Cai } 879*78884ef4SEddie Cai if (gOpts.code471Sleep > 0) 880*78884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 881*78884ef4SEddie Cai 882*78884ef4SEddie Cai fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 883*78884ef4SEddie Cai for (i=0 ;i<gOpts.code472Num ;i++) { 884*78884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 885*78884ef4SEddie Cai } 886*78884ef4SEddie Cai if (gOpts.code472Sleep > 0) 887*78884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 888*78884ef4SEddie Cai 889*78884ef4SEddie Cai fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 890*78884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 891*78884ef4SEddie Cai fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 892*78884ef4SEddie Cai } 893*78884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 894*78884ef4SEddie Cai fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 895*78884ef4SEddie Cai } 896*78884ef4SEddie Cai 897*78884ef4SEddie Cai fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 898*78884ef4SEddie Cai } 899*78884ef4SEddie Cai 900*78884ef4SEddie Cai static bool parseOpts(void) { 901*78884ef4SEddie Cai bool ret = false; 902*78884ef4SEddie Cai bool chipOk = false; 903*78884ef4SEddie Cai bool versionOk = false; 904*78884ef4SEddie Cai bool code471Ok = true; 905*78884ef4SEddie Cai bool code472Ok = true; 906*78884ef4SEddie Cai bool loaderOk = false; 907*78884ef4SEddie Cai bool outOk = false; 908*78884ef4SEddie Cai char buf[MAX_LINE_LEN]; 909*78884ef4SEddie Cai 910*78884ef4SEddie Cai char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 911*78884ef4SEddie Cai FILE* file; 912*78884ef4SEddie Cai file = fopen(configPath, "r"); 913*78884ef4SEddie Cai if (!file) { 914*78884ef4SEddie Cai fprintf(stderr, "config(%s) not found!\n", configPath); 915*78884ef4SEddie Cai if (configPath == (char*)DEF_CONFIG_FILE) { 916*78884ef4SEddie Cai file = fopen(DEF_CONFIG_FILE, "w"); 917*78884ef4SEddie Cai if (file) { 918*78884ef4SEddie Cai fprintf(stderr, "create defconfig\n"); 919*78884ef4SEddie Cai printOpts(file); 920*78884ef4SEddie Cai } 921*78884ef4SEddie Cai } 922*78884ef4SEddie Cai goto end; 923*78884ef4SEddie Cai } 924*78884ef4SEddie Cai 925*78884ef4SEddie Cai printf("start parse\n"); 926*78884ef4SEddie Cai 927*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 928*78884ef4SEddie Cai goto end; 929*78884ef4SEddie Cai } 930*78884ef4SEddie Cai while(fscanf(file, "%s", buf) == 1) { 931*78884ef4SEddie Cai if (!strcmp(buf, SEC_CHIP)) { 932*78884ef4SEddie Cai chipOk = parseChip(file); 933*78884ef4SEddie Cai if (!chipOk) { 934*78884ef4SEddie Cai printf("parseChip failed!\n"); 935*78884ef4SEddie Cai goto end; 936*78884ef4SEddie Cai } 937*78884ef4SEddie Cai } else if (!strcmp(buf, SEC_VERSION)) { 938*78884ef4SEddie Cai versionOk = parseVersion(file); 939*78884ef4SEddie Cai if (!versionOk) { 940*78884ef4SEddie Cai printf("parseVersion failed!\n"); 941*78884ef4SEddie Cai goto end; 942*78884ef4SEddie Cai } 943*78884ef4SEddie Cai } else if (!strcmp(buf, SEC_471)) { 944*78884ef4SEddie Cai code471Ok = parse471(file); 945*78884ef4SEddie Cai if (!code471Ok) { 946*78884ef4SEddie Cai printf("parse471 failed!\n"); 947*78884ef4SEddie Cai goto end; 948*78884ef4SEddie Cai } 949*78884ef4SEddie Cai } else if (!strcmp(buf, SEC_472)) { 950*78884ef4SEddie Cai code472Ok = parse472(file); 951*78884ef4SEddie Cai if (!code472Ok) { 952*78884ef4SEddie Cai printf("parse472 failed!\n"); 953*78884ef4SEddie Cai goto end; 954*78884ef4SEddie Cai } 955*78884ef4SEddie Cai } else if (!strcmp(buf, SEC_LOADER)) { 956*78884ef4SEddie Cai loaderOk = parseLoader(file); 957*78884ef4SEddie Cai if (!loaderOk) { 958*78884ef4SEddie Cai printf("parseLoader failed!\n"); 959*78884ef4SEddie Cai goto end; 960*78884ef4SEddie Cai } 961*78884ef4SEddie Cai } else if (!strcmp(buf, SEC_OUT)) { 962*78884ef4SEddie Cai outOk = parseOut(file); 963*78884ef4SEddie Cai if (!outOk) { 964*78884ef4SEddie Cai printf("parseOut failed!\n"); 965*78884ef4SEddie Cai goto end; 966*78884ef4SEddie Cai } 967*78884ef4SEddie Cai } else if (buf[0] == '#') { 968*78884ef4SEddie Cai continue; 969*78884ef4SEddie Cai } else { 970*78884ef4SEddie Cai printf("unknown sec: %s!\n", buf); 971*78884ef4SEddie Cai goto end; 972*78884ef4SEddie Cai } 973*78884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 974*78884ef4SEddie Cai goto end; 975*78884ef4SEddie Cai } 976*78884ef4SEddie Cai } 977*78884ef4SEddie Cai 978*78884ef4SEddie Cai if (chipOk && versionOk && code471Ok && code472Ok 979*78884ef4SEddie Cai && loaderOk && outOk) 980*78884ef4SEddie Cai ret = true; 981*78884ef4SEddie Cai end: 982*78884ef4SEddie Cai if (file) 983*78884ef4SEddie Cai fclose(file); 984*78884ef4SEddie Cai return ret; 985*78884ef4SEddie Cai } 986*78884ef4SEddie Cai 987*78884ef4SEddie Cai bool initOpts(void) { 988*78884ef4SEddie Cai //set default opts 989*78884ef4SEddie Cai gOpts.major = DEF_MAJOR; 990*78884ef4SEddie Cai gOpts.minor = DEF_MINOR; 991*78884ef4SEddie Cai strcpy(gOpts.chip, DEF_CHIP); 992*78884ef4SEddie Cai gOpts.code471Sleep = DEF_CODE471_SLEEP; 993*78884ef4SEddie Cai gOpts.code472Sleep = DEF_CODE472_SLEEP; 994*78884ef4SEddie Cai gOpts.code471Num = DEF_CODE471_NUM; 995*78884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 996*78884ef4SEddie Cai strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 997*78884ef4SEddie Cai gOpts.code472Num = DEF_CODE472_NUM; 998*78884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 999*78884ef4SEddie Cai strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 1000*78884ef4SEddie Cai gOpts.loaderNum = DEF_LOADER_NUM; 1001*78884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 1002*78884ef4SEddie Cai strcpy(gOpts.loader[0].name, DEF_LOADER0); 1003*78884ef4SEddie Cai strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 1004*78884ef4SEddie Cai strcpy(gOpts.loader[1].name, DEF_LOADER1); 1005*78884ef4SEddie Cai strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 1006*78884ef4SEddie Cai strcpy(gOpts.outPath, DEF_OUT_PATH); 1007*78884ef4SEddie Cai 1008*78884ef4SEddie Cai return parseOpts(); 1009*78884ef4SEddie Cai } 1010*78884ef4SEddie Cai 1011*78884ef4SEddie Cai /************merge code****************/ 1012*78884ef4SEddie Cai 1013*78884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) { 1014*78884ef4SEddie Cai uint8_t tmp[2] = {0}; 1015*78884ef4SEddie Cai int i; 1016*78884ef4SEddie Cai uint32_t ret; 1017*78884ef4SEddie Cai //if (value > 0xFFFF) { 1018*78884ef4SEddie Cai // return 0; 1019*78884ef4SEddie Cai //} 1020*78884ef4SEddie Cai for(i=0; i < 2; i++) { 1021*78884ef4SEddie Cai tmp[i] = (((value/10)%10)<<4) | (value%10); 1022*78884ef4SEddie Cai value /= 100; 1023*78884ef4SEddie Cai } 1024*78884ef4SEddie Cai ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 1025*78884ef4SEddie Cai 1026*78884ef4SEddie Cai printf("ret:%x\n",ret); 1027*78884ef4SEddie Cai return ret&0xFF; 1028*78884ef4SEddie Cai } 1029*78884ef4SEddie Cai 1030*78884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len) 1031*78884ef4SEddie Cai { 1032*78884ef4SEddie Cai int i; 1033*78884ef4SEddie Cai for (i = 0; i < len; i++) { 1034*78884ef4SEddie Cai wide[i] = (uint16_t) str[i]; 1035*78884ef4SEddie Cai } 1036*78884ef4SEddie Cai wide[len] = 0; 1037*78884ef4SEddie Cai } 1038*78884ef4SEddie Cai 1039*78884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) { 1040*78884ef4SEddie Cai char* end; 1041*78884ef4SEddie Cai char* start; 1042*78884ef4SEddie Cai int len; 1043*78884ef4SEddie Cai if (!path || !dst) 1044*78884ef4SEddie Cai return; 1045*78884ef4SEddie Cai start = strrchr(path, '/'); 1046*78884ef4SEddie Cai if (!start) 1047*78884ef4SEddie Cai start = path; 1048*78884ef4SEddie Cai else 1049*78884ef4SEddie Cai start++; 1050*78884ef4SEddie Cai end = strrchr(path, '.'); 1051*78884ef4SEddie Cai if (!end) 1052*78884ef4SEddie Cai end = path + strlen(path); 1053*78884ef4SEddie Cai len = end - start; 1054*78884ef4SEddie Cai if (len >= MAX_NAME_LEN) 1055*78884ef4SEddie Cai len = MAX_NAME_LEN -1; 1056*78884ef4SEddie Cai str2wide(start, dst, len); 1057*78884ef4SEddie Cai 1058*78884ef4SEddie Cai 1059*78884ef4SEddie Cai char name[MAX_NAME_LEN]; 1060*78884ef4SEddie Cai memset(name, 0, sizeof(name)); 1061*78884ef4SEddie Cai memcpy(name, start, len); 1062*78884ef4SEddie Cai printf("path:%s, name:%s\n", path, name); 1063*78884ef4SEddie Cai 1064*78884ef4SEddie Cai } 1065*78884ef4SEddie Cai 1066*78884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) { 1067*78884ef4SEddie Cai struct stat st; 1068*78884ef4SEddie Cai if(stat(path, &st) < 0) 1069*78884ef4SEddie Cai return false; 1070*78884ef4SEddie Cai *size = st.st_size; 1071*78884ef4SEddie Cai printf("path:%s, size:%d\n", path, *size); 1072*78884ef4SEddie Cai return true; 1073*78884ef4SEddie Cai } 1074*78884ef4SEddie Cai 1075*78884ef4SEddie Cai static inline rk_time getTime(void) { 1076*78884ef4SEddie Cai rk_time rkTime; 1077*78884ef4SEddie Cai 1078*78884ef4SEddie Cai struct tm *tm; 1079*78884ef4SEddie Cai time_t tt = time(NULL); 1080*78884ef4SEddie Cai tm = localtime(&tt); 1081*78884ef4SEddie Cai rkTime.year = tm->tm_year + 1900; 1082*78884ef4SEddie Cai rkTime.month = tm->tm_mon + 1; 1083*78884ef4SEddie Cai rkTime.day = tm->tm_mday; 1084*78884ef4SEddie Cai rkTime.hour = tm->tm_hour; 1085*78884ef4SEddie Cai rkTime.minute = tm->tm_min; 1086*78884ef4SEddie Cai rkTime.second = tm->tm_sec; 1087*78884ef4SEddie Cai printf("%d-%d-%d %02d:%02d:%02d\n", 1088*78884ef4SEddie Cai rkTime.year, rkTime.month, rkTime.day, 1089*78884ef4SEddie Cai rkTime.hour, rkTime.minute, rkTime.second); 1090*78884ef4SEddie Cai return rkTime; 1091*78884ef4SEddie Cai } 1092*78884ef4SEddie Cai 1093*78884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) { 1094*78884ef4SEddie Cai bool ret = false; 1095*78884ef4SEddie Cai uint32_t size = 0, fixSize = 0; 1096*78884ef4SEddie Cai uint8_t* buf; 1097*78884ef4SEddie Cai 1098*78884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 1099*78884ef4SEddie Cai if (!inFile) 1100*78884ef4SEddie Cai goto end; 1101*78884ef4SEddie Cai 1102*78884ef4SEddie Cai if (!getFileSize(path, &size)) 1103*78884ef4SEddie Cai goto end; 1104*78884ef4SEddie Cai if (fix) { 1105*78884ef4SEddie Cai fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 1106*78884ef4SEddie Cai uint32_t tmp = fixSize % ENTRY_ALIGN; 1107*78884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 1108*78884ef4SEddie Cai fixSize +=tmp; 1109*78884ef4SEddie Cai memset(gBuf, 0, fixSize); 1110*78884ef4SEddie Cai } else { 1111*78884ef4SEddie Cai memset(gBuf, 0, size+ENTRY_ALIGN); 1112*78884ef4SEddie Cai } 1113*78884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 1114*78884ef4SEddie Cai goto end; 1115*78884ef4SEddie Cai 1116*78884ef4SEddie Cai if (fix) { 1117*78884ef4SEddie Cai 1118*78884ef4SEddie Cai buf = gBuf; 1119*78884ef4SEddie Cai size = fixSize; 1120*78884ef4SEddie Cai while(1) { 1121*78884ef4SEddie Cai P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 1122*78884ef4SEddie Cai buf += SMALL_PACKET; 1123*78884ef4SEddie Cai if (fixSize <= SMALL_PACKET) 1124*78884ef4SEddie Cai break; 1125*78884ef4SEddie Cai fixSize -= SMALL_PACKET; 1126*78884ef4SEddie Cai } 1127*78884ef4SEddie Cai } else { 1128*78884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 1129*78884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 1130*78884ef4SEddie Cai size +=tmp; 1131*78884ef4SEddie Cai P_RC4(gBuf, size); 1132*78884ef4SEddie Cai } 1133*78884ef4SEddie Cai 1134*78884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 1135*78884ef4SEddie Cai goto end; 1136*78884ef4SEddie Cai ret = true; 1137*78884ef4SEddie Cai end: 1138*78884ef4SEddie Cai if (inFile) 1139*78884ef4SEddie Cai fclose(inFile); 1140*78884ef4SEddie Cai if (!ret) 1141*78884ef4SEddie Cai printf("write entry(%s) failed\n", path); 1142*78884ef4SEddie Cai return ret; 1143*78884ef4SEddie Cai } 1144*78884ef4SEddie Cai 1145*78884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 1146*78884ef4SEddie Cai uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 1147*78884ef4SEddie Cai printf("write:%s\n", path); 1148*78884ef4SEddie Cai uint32_t size; 1149*78884ef4SEddie Cai rk_boot_entry entry; 1150*78884ef4SEddie Cai memset(&entry, 0, sizeof(rk_boot_entry)); 1151*78884ef4SEddie Cai 1152*78884ef4SEddie Cai printf("write:%s\n", path); 1153*78884ef4SEddie Cai 1154*78884ef4SEddie Cai getName(fixName ? fixName: path, entry.name); 1155*78884ef4SEddie Cai entry.size = sizeof(rk_boot_entry); 1156*78884ef4SEddie Cai entry.type = type; 1157*78884ef4SEddie Cai entry.dataOffset = *offset; 1158*78884ef4SEddie Cai if (!getFileSize(path, &size)) { 1159*78884ef4SEddie Cai printf("save entry(%s) failed:\n\tcannot get file size.\n", path); 1160*78884ef4SEddie Cai return false; 1161*78884ef4SEddie Cai } 1162*78884ef4SEddie Cai if (fix) 1163*78884ef4SEddie Cai size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 1164*78884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 1165*78884ef4SEddie Cai size += tmp ? (ENTRY_ALIGN - tmp): 0; 1166*78884ef4SEddie Cai printf("align size:%d\n", size); 1167*78884ef4SEddie Cai entry.dataSize = size; 1168*78884ef4SEddie Cai entry.dataDelay = delay; 1169*78884ef4SEddie Cai *offset += size; 1170*78884ef4SEddie Cai fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 1171*78884ef4SEddie Cai return true; 1172*78884ef4SEddie Cai } 1173*78884ef4SEddie Cai 1174*78884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) { 1175*78884ef4SEddie Cai char buffer[5]; 1176*78884ef4SEddie Cai memset(buffer, 0, sizeof(buffer)); 1177*78884ef4SEddie Cai snprintf(buffer, sizeof(buffer), "%s", chip); 1178*78884ef4SEddie Cai return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 1179*78884ef4SEddie Cai } 1180*78884ef4SEddie Cai 1181*78884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) { 1182*78884ef4SEddie Cai printf("chip:%s\n", chip); 1183*78884ef4SEddie Cai int chipType = RKNONE_DEVICE; 1184*78884ef4SEddie Cai if(!chip) { 1185*78884ef4SEddie Cai goto end; 1186*78884ef4SEddie Cai } 1187*78884ef4SEddie Cai if (!strcmp(chip, CHIP_RK28)) { 1188*78884ef4SEddie Cai chipType = RK28_DEVICE; 1189*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK28)) { 1190*78884ef4SEddie Cai chipType = RK28_DEVICE; 1191*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK281X)) { 1192*78884ef4SEddie Cai chipType = RK281X_DEVICE; 1193*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKPANDA)) { 1194*78884ef4SEddie Cai chipType = RKPANDA_DEVICE; 1195*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK27)) { 1196*78884ef4SEddie Cai chipType = RK27_DEVICE; 1197*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKNANO)) { 1198*78884ef4SEddie Cai chipType = RKNANO_DEVICE; 1199*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKSMART)) { 1200*78884ef4SEddie Cai chipType = RKSMART_DEVICE; 1201*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCROWN)) { 1202*78884ef4SEddie Cai chipType = RKCROWN_DEVICE; 1203*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 1204*78884ef4SEddie Cai chipType = RKCAYMAN_DEVICE; 1205*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK29)) { 1206*78884ef4SEddie Cai chipType = RK29_DEVICE; 1207*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK292X)) { 1208*78884ef4SEddie Cai chipType = RK292X_DEVICE; 1209*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30)) { 1210*78884ef4SEddie Cai chipType = RK30_DEVICE; 1211*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30B)) { 1212*78884ef4SEddie Cai chipType = RK30B_DEVICE; 1213*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK31)) { 1214*78884ef4SEddie Cai chipType = RK31_DEVICE; 1215*78884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK32)) { 1216*78884ef4SEddie Cai chipType = RK32_DEVICE; 1217*78884ef4SEddie Cai } else { 1218*78884ef4SEddie Cai chipType = convertChipType(chip + 2); 1219*78884ef4SEddie Cai } 1220*78884ef4SEddie Cai 1221*78884ef4SEddie Cai end: 1222*78884ef4SEddie Cai printf("type:0x%x\n", chipType); 1223*78884ef4SEddie Cai if (chipType == RKNONE_DEVICE) { 1224*78884ef4SEddie Cai printf("chip type not support!\n"); 1225*78884ef4SEddie Cai } 1226*78884ef4SEddie Cai return chipType; 1227*78884ef4SEddie Cai } 1228*78884ef4SEddie Cai 1229*78884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) { 1230*78884ef4SEddie Cai memset(hdr, 0, sizeof(rk_boot_header)); 1231*78884ef4SEddie Cai hdr->tag = TAG; 1232*78884ef4SEddie Cai hdr->size = sizeof(rk_boot_header); 1233*78884ef4SEddie Cai hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 1234*78884ef4SEddie Cai hdr->mergerVersion = MERGER_VERSION; 1235*78884ef4SEddie Cai hdr->releaseTime = getTime(); 1236*78884ef4SEddie Cai hdr->chipType = getChipType(gOpts.chip); 1237*78884ef4SEddie Cai 1238*78884ef4SEddie Cai hdr->code471Num = gOpts.code471Num; 1239*78884ef4SEddie Cai hdr->code471Offset = sizeof(rk_boot_header); 1240*78884ef4SEddie Cai hdr->code471Size = sizeof(rk_boot_entry); 1241*78884ef4SEddie Cai 1242*78884ef4SEddie Cai hdr->code472Num = gOpts.code472Num; 1243*78884ef4SEddie Cai hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 1244*78884ef4SEddie Cai hdr->code472Size = sizeof(rk_boot_entry); 1245*78884ef4SEddie Cai 1246*78884ef4SEddie Cai hdr->loaderNum = gOpts.loaderNum; 1247*78884ef4SEddie Cai hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 1248*78884ef4SEddie Cai hdr->loaderSize = sizeof(rk_boot_entry); 1249*78884ef4SEddie Cai #ifndef USE_P_RC4 1250*78884ef4SEddie Cai hdr->rc4Flag = 1; 1251*78884ef4SEddie Cai #endif 1252*78884ef4SEddie Cai } 1253*78884ef4SEddie Cai 1254*78884ef4SEddie Cai static inline uint32_t getCrc(const char* path) { 1255*78884ef4SEddie Cai uint32_t size = 0; 1256*78884ef4SEddie Cai uint32_t crc = 0; 1257*78884ef4SEddie Cai 1258*78884ef4SEddie Cai FILE* file = fopen(path, "rb"); 1259*78884ef4SEddie Cai getFileSize(path, &size); 1260*78884ef4SEddie Cai if (!file) 1261*78884ef4SEddie Cai goto end; 1262*78884ef4SEddie Cai if (!fread(gBuf, size, 1, file)) 1263*78884ef4SEddie Cai goto end; 1264*78884ef4SEddie Cai crc = CRC_32(gBuf, size); 1265*78884ef4SEddie Cai printf("crc:0x%08x\n", crc); 1266*78884ef4SEddie Cai end: 1267*78884ef4SEddie Cai if (file) 1268*78884ef4SEddie Cai fclose(file); 1269*78884ef4SEddie Cai return crc; 1270*78884ef4SEddie Cai } 1271*78884ef4SEddie Cai 1272*78884ef4SEddie Cai bool mergeBoot(void) { 1273*78884ef4SEddie Cai uint32_t dataOffset; 1274*78884ef4SEddie Cai bool ret = false; 1275*78884ef4SEddie Cai int i; 1276*78884ef4SEddie Cai FILE* outFile; 1277*78884ef4SEddie Cai uint32_t crc; 1278*78884ef4SEddie Cai rk_boot_header hdr; 1279*78884ef4SEddie Cai 1280*78884ef4SEddie Cai if (!initOpts()) 1281*78884ef4SEddie Cai return false; 1282*78884ef4SEddie Cai { 1283*78884ef4SEddie Cai char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 1284*78884ef4SEddie Cai char version[MAX_LINE_LEN]; 1285*78884ef4SEddie Cai snprintf(version, sizeof(version), "%s", gSubfix); 1286*78884ef4SEddie Cai if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 1287*78884ef4SEddie Cai subfix[0] = '\0'; 1288*78884ef4SEddie Cai } 1289*78884ef4SEddie Cai strcat(gOpts.outPath, version); 1290*78884ef4SEddie Cai printf("fix opt:%s\n", gOpts.outPath); 1291*78884ef4SEddie Cai } 1292*78884ef4SEddie Cai 1293*78884ef4SEddie Cai printf("---------------\nUSING CONFIG:\n"); 1294*78884ef4SEddie Cai printOpts(stdout); 1295*78884ef4SEddie Cai printf("---------------\n\n"); 1296*78884ef4SEddie Cai 1297*78884ef4SEddie Cai 1298*78884ef4SEddie Cai outFile = fopen(gOpts.outPath, "wb+"); 1299*78884ef4SEddie Cai if (!outFile) { 1300*78884ef4SEddie Cai printf("open out file(%s) failed\n", gOpts.outPath); 1301*78884ef4SEddie Cai goto end; 1302*78884ef4SEddie Cai } 1303*78884ef4SEddie Cai 1304*78884ef4SEddie Cai getBoothdr(&hdr); 1305*78884ef4SEddie Cai printf("write hdr\n"); 1306*78884ef4SEddie Cai fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 1307*78884ef4SEddie Cai 1308*78884ef4SEddie Cai dataOffset = sizeof(rk_boot_header) + 1309*78884ef4SEddie Cai (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 1310*78884ef4SEddie Cai sizeof(rk_boot_entry); 1311*78884ef4SEddie Cai 1312*78884ef4SEddie Cai printf("write code 471 entry\n"); 1313*78884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 1314*78884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 1315*78884ef4SEddie Cai &dataOffset, NULL, false)) 1316*78884ef4SEddie Cai goto end; 1317*78884ef4SEddie Cai } 1318*78884ef4SEddie Cai printf("write code 472 entry\n"); 1319*78884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 1320*78884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 1321*78884ef4SEddie Cai &dataOffset, NULL, false)) 1322*78884ef4SEddie Cai goto end; 1323*78884ef4SEddie Cai } 1324*78884ef4SEddie Cai printf("write loader entry\n"); 1325*78884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 1326*78884ef4SEddie Cai if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 1327*78884ef4SEddie Cai &dataOffset, gOpts.loader[i].name, true)) 1328*78884ef4SEddie Cai goto end; 1329*78884ef4SEddie Cai } 1330*78884ef4SEddie Cai 1331*78884ef4SEddie Cai printf("write code 471\n"); 1332*78884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 1333*78884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 1334*78884ef4SEddie Cai goto end; 1335*78884ef4SEddie Cai } 1336*78884ef4SEddie Cai printf("write code 472\n"); 1337*78884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 1338*78884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 1339*78884ef4SEddie Cai goto end; 1340*78884ef4SEddie Cai } 1341*78884ef4SEddie Cai printf("write loader\n"); 1342*78884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 1343*78884ef4SEddie Cai if (!writeFile(outFile, gOpts.loader[i].path, true)) 1344*78884ef4SEddie Cai goto end; 1345*78884ef4SEddie Cai } 1346*78884ef4SEddie Cai fflush(outFile); 1347*78884ef4SEddie Cai 1348*78884ef4SEddie Cai printf("write crc\n"); 1349*78884ef4SEddie Cai crc = getCrc(gOpts.outPath); 1350*78884ef4SEddie Cai if (!fwrite(&crc, sizeof(crc), 1, outFile)) 1351*78884ef4SEddie Cai goto end; 1352*78884ef4SEddie Cai printf("done\n"); 1353*78884ef4SEddie Cai ret = true; 1354*78884ef4SEddie Cai end: 1355*78884ef4SEddie Cai if (outFile) 1356*78884ef4SEddie Cai fclose(outFile); 1357*78884ef4SEddie Cai return ret; 1358*78884ef4SEddie Cai } 1359*78884ef4SEddie Cai 1360*78884ef4SEddie Cai /************merge code end************/ 1361*78884ef4SEddie Cai /************unpack code***************/ 1362*78884ef4SEddie Cai 1363*78884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len) 1364*78884ef4SEddie Cai { 1365*78884ef4SEddie Cai int i; 1366*78884ef4SEddie Cai for (i = 0; i < len; i++) { 1367*78884ef4SEddie Cai str[i] = (char) (wide[i] & 0xFF); 1368*78884ef4SEddie Cai } 1369*78884ef4SEddie Cai str[len] = 0; 1370*78884ef4SEddie Cai } 1371*78884ef4SEddie Cai 1372*78884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name, 1373*78884ef4SEddie Cai FILE* inFile) { 1374*78884ef4SEddie Cai bool ret = false; 1375*78884ef4SEddie Cai int size, i; 1376*78884ef4SEddie Cai FILE* outFile = fopen(name, "wb+"); 1377*78884ef4SEddie Cai if (!outFile) 1378*78884ef4SEddie Cai goto end; 1379*78884ef4SEddie Cai printf("unpack entry(%s)\n", name); 1380*78884ef4SEddie Cai fseek(inFile, entry->dataOffset, SEEK_SET); 1381*78884ef4SEddie Cai size = entry->dataSize; 1382*78884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 1383*78884ef4SEddie Cai goto end; 1384*78884ef4SEddie Cai if (entry->type == ENTRY_LOADER) { 1385*78884ef4SEddie Cai for(i=0; i<size/SMALL_PACKET; i++) 1386*78884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 1387*78884ef4SEddie Cai if (size % SMALL_PACKET) 1388*78884ef4SEddie Cai { 1389*78884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 1390*78884ef4SEddie Cai } 1391*78884ef4SEddie Cai } else { 1392*78884ef4SEddie Cai P_RC4(gBuf, size); 1393*78884ef4SEddie Cai } 1394*78884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 1395*78884ef4SEddie Cai goto end; 1396*78884ef4SEddie Cai ret = true; 1397*78884ef4SEddie Cai end: 1398*78884ef4SEddie Cai if (outFile) 1399*78884ef4SEddie Cai fclose(outFile); 1400*78884ef4SEddie Cai return ret; 1401*78884ef4SEddie Cai } 1402*78884ef4SEddie Cai 1403*78884ef4SEddie Cai bool unpackBoot(char* path) { 1404*78884ef4SEddie Cai bool ret = false; 1405*78884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 1406*78884ef4SEddie Cai int entryNum, i; 1407*78884ef4SEddie Cai char name[MAX_NAME_LEN]; 1408*78884ef4SEddie Cai rk_boot_entry* entrys; 1409*78884ef4SEddie Cai if (!inFile) { 1410*78884ef4SEddie Cai fprintf(stderr, "loader(%s) not found\n", path); 1411*78884ef4SEddie Cai goto end; 1412*78884ef4SEddie Cai } 1413*78884ef4SEddie Cai 1414*78884ef4SEddie Cai rk_boot_header hdr; 1415*78884ef4SEddie Cai if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 1416*78884ef4SEddie Cai fprintf(stderr, "read header failed\n"); 1417*78884ef4SEddie Cai goto end; 1418*78884ef4SEddie Cai } 1419*78884ef4SEddie Cai printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 1420*78884ef4SEddie Cai entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 1421*78884ef4SEddie Cai entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 1422*78884ef4SEddie Cai if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 1423*78884ef4SEddie Cai fprintf(stderr, "read data failed\n"); 1424*78884ef4SEddie Cai goto end; 1425*78884ef4SEddie Cai } 1426*78884ef4SEddie Cai 1427*78884ef4SEddie Cai printf("entry num:%d\n", entryNum); 1428*78884ef4SEddie Cai for (i=0; i<entryNum; i++) { 1429*78884ef4SEddie Cai wide2str(entrys[i].name, name, MAX_NAME_LEN); 1430*78884ef4SEddie Cai 1431*78884ef4SEddie Cai printf("entry:t=%d, name=%s, off=%d, size=%d\n", 1432*78884ef4SEddie Cai entrys[i].type, name, entrys[i].dataOffset, 1433*78884ef4SEddie Cai entrys[i].dataSize); 1434*78884ef4SEddie Cai if (!unpackEntry(entrys + i, name, inFile)) { 1435*78884ef4SEddie Cai fprintf(stderr, "unpack entry(%s) failed\n", name); 1436*78884ef4SEddie Cai goto end; 1437*78884ef4SEddie Cai } 1438*78884ef4SEddie Cai } 1439*78884ef4SEddie Cai printf("done\n"); 1440*78884ef4SEddie Cai ret = true; 1441*78884ef4SEddie Cai end: 1442*78884ef4SEddie Cai if (inFile) 1443*78884ef4SEddie Cai fclose(inFile); 1444*78884ef4SEddie Cai return ret; 1445*78884ef4SEddie Cai } 1446*78884ef4SEddie Cai 144776af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 144876af099aSliuyi { 144976af099aSliuyi if (!check_device_type(dev, RKUSB_MASKROM)) 145076af099aSliuyi return false; 145176af099aSliuyi CRKImage *pImage = NULL; 145276af099aSliuyi CRKBoot *pBoot = NULL; 145376af099aSliuyi bool bRet, bSuccess = false; 145476af099aSliuyi int iRet; 145576af099aSliuyi 145676af099aSliuyi pImage = new CRKImage(szLoader, bRet); 145776af099aSliuyi if (!bRet){ 145876af099aSliuyi ERROR_COLOR_ATTR; 145976af099aSliuyi printf("Open loader failed,exit download boot!"); 146076af099aSliuyi NORMAL_COLOR_ATTR; 146176af099aSliuyi printf("\r\n"); 146276af099aSliuyi return bSuccess; 146376af099aSliuyi } else { 146476af099aSliuyi pBoot = (CRKBoot *)pImage->m_bootObject; 146576af099aSliuyi CRKComm *pComm = NULL; 146676af099aSliuyi CRKDevice *pDevice = NULL; 146776af099aSliuyi 146876af099aSliuyi dev.emDeviceType = pBoot->SupportDevice; 146976af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 147076af099aSliuyi if (!bRet) { 147176af099aSliuyi if (pImage) 147276af099aSliuyi delete pImage; 147376af099aSliuyi ERROR_COLOR_ATTR; 147476af099aSliuyi printf("Creating Comm Object failed!"); 147576af099aSliuyi NORMAL_COLOR_ATTR; 147676af099aSliuyi printf("\r\n"); 147776af099aSliuyi return bSuccess; 147876af099aSliuyi } 147976af099aSliuyi 148076af099aSliuyi pDevice = new CRKDevice(dev); 148176af099aSliuyi if (!pDevice) { 148276af099aSliuyi if (pImage) 148376af099aSliuyi delete pImage; 148476af099aSliuyi if (pComm) 148576af099aSliuyi delete pComm; 148676af099aSliuyi ERROR_COLOR_ATTR; 148776af099aSliuyi printf("Creating device object failed!"); 148876af099aSliuyi NORMAL_COLOR_ATTR; 148976af099aSliuyi printf("\r\n"); 149076af099aSliuyi return bSuccess; 149176af099aSliuyi } 149276af099aSliuyi 149376af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 149476af099aSliuyi printf("Download boot...\r\n"); 149576af099aSliuyi iRet = pDevice->DownloadBoot(); 149676af099aSliuyi 149776af099aSliuyi CURSOR_MOVEUP_LINE(1); 149876af099aSliuyi CURSOR_DEL_LINE; 149976af099aSliuyi if (iRet == 0) { 150076af099aSliuyi pComm->Reset_Usb_Device(); 150176af099aSliuyi CRKScan *pScan = NULL; 150276af099aSliuyi pScan = new CRKScan(); 150376af099aSliuyi if (pScan) { 150476af099aSliuyi pScan->SetVidPid(); 150576af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 150676af099aSliuyi delete pScan; 150776af099aSliuyi } 150876af099aSliuyi bSuccess = true; 150976af099aSliuyi printf("Download boot ok.\r\n"); 151076af099aSliuyi } 151176af099aSliuyi else 151276af099aSliuyi printf("Download boot failed!\r\n"); 151376af099aSliuyi 151476af099aSliuyi if (pImage) 151576af099aSliuyi delete pImage; 151676af099aSliuyi if(pDevice) 151776af099aSliuyi delete pDevice; 151876af099aSliuyi } 151976af099aSliuyi return bSuccess; 152076af099aSliuyi } 1521c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1522c30d921cSKever Yang { 1523c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 1524c30d921cSKever Yang return false; 1525c30d921cSKever Yang CRKImage *pImage = NULL; 1526c30d921cSKever Yang CRKBoot *pBoot = NULL; 1527c30d921cSKever Yang CRKComm *pComm = NULL; 1528c30d921cSKever Yang bool bRet, bSuccess = false; 1529c30d921cSKever Yang int iRet; 1530c30d921cSKever Yang char index; 1531c30d921cSKever Yang USHORT usFlashDataSec, usFlashBootSec; 1532c30d921cSKever Yang DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1533c30d921cSKever Yang char loaderCodeName[] = "FlashBoot"; 1534c30d921cSKever Yang char loaderDataName[] = "FlashData"; 1535c30d921cSKever Yang PBYTE loaderCodeBuffer = NULL; 1536c30d921cSKever Yang PBYTE loaderDataBuffer = NULL; 1537c30d921cSKever Yang PBYTE pIDBData = NULL; 1538c30d921cSKever Yang pImage = new CRKImage(szLoader, bRet); 1539c30d921cSKever Yang if (!bRet){ 1540c30d921cSKever Yang ERROR_COLOR_ATTR; 1541c30d921cSKever Yang printf("Open loader failed,exit upgrade loader!"); 1542c30d921cSKever Yang NORMAL_COLOR_ATTR; 1543c30d921cSKever Yang printf("\r\n"); 1544c30d921cSKever Yang goto Exit_UpgradeLoader; 1545c30d921cSKever Yang } else { 1546c30d921cSKever Yang pBoot = (CRKBoot *)pImage->m_bootObject; 1547c30d921cSKever Yang dev.emDeviceType = pBoot->SupportDevice; 1548c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1549c30d921cSKever Yang if (!bRet) { 1550c30d921cSKever Yang ERROR_COLOR_ATTR; 1551c30d921cSKever Yang printf("Creating Comm Object failed!"); 1552c30d921cSKever Yang NORMAL_COLOR_ATTR; 1553c30d921cSKever Yang printf("\r\n"); 1554c30d921cSKever Yang goto Exit_UpgradeLoader; 1555c30d921cSKever Yang } 1556c30d921cSKever Yang 1557c30d921cSKever Yang printf("Upgrade loader...\r\n"); 1558c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1559c30d921cSKever Yang if (index == -1) { 1560c30d921cSKever Yang if (g_pLogObject) { 1561c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry failed"); 1562c30d921cSKever Yang } 1563c30d921cSKever Yang goto Exit_UpgradeLoader; 1564c30d921cSKever Yang } 1565c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1566c30d921cSKever Yang if (!bRet) { 1567c30d921cSKever Yang if (g_pLogObject) { 1568c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry Size failed"); 1569c30d921cSKever Yang } 1570c30d921cSKever Yang goto Exit_UpgradeLoader; 1571c30d921cSKever Yang } 1572c30d921cSKever Yang 1573c30d921cSKever Yang loaderCodeBuffer = new BYTE[dwLoaderSize]; 1574c30d921cSKever Yang memset(loaderCodeBuffer, 0, dwLoaderSize); 1575c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1576c30d921cSKever Yang if (g_pLogObject) { 1577c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Data failed"); 1578c30d921cSKever Yang } 1579c30d921cSKever Yang goto Exit_UpgradeLoader; 1580c30d921cSKever Yang } 1581c30d921cSKever Yang 1582c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1583c30d921cSKever Yang if (index == -1) { 1584c30d921cSKever Yang if (g_pLogObject) { 1585c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry failed"); 1586c30d921cSKever Yang } 1587c30d921cSKever Yang delete []loaderCodeBuffer; 1588c30d921cSKever Yang return -4; 1589c30d921cSKever Yang } 1590c30d921cSKever Yang 1591c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1592c30d921cSKever Yang if (!bRet) { 1593c30d921cSKever Yang if (g_pLogObject) { 1594c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry Size failed"); 1595c30d921cSKever Yang } 1596c30d921cSKever Yang goto Exit_UpgradeLoader; 1597c30d921cSKever Yang } 1598c30d921cSKever Yang 1599c30d921cSKever Yang loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1600c30d921cSKever Yang memset(loaderDataBuffer, 0, dwLoaderDataSize); 1601c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1602c30d921cSKever Yang if (g_pLogObject) { 1603c30d921cSKever Yang g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Data failed"); 1604c30d921cSKever Yang } 1605c30d921cSKever Yang goto Exit_UpgradeLoader; 1606c30d921cSKever Yang } 1607c30d921cSKever Yang 1608c30d921cSKever Yang usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1609c30d921cSKever Yang usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1610c30d921cSKever Yang dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1611c30d921cSKever Yang pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1612c30d921cSKever Yang if (!pIDBData) { 1613c30d921cSKever Yang ERROR_COLOR_ATTR; 1614c30d921cSKever Yang printf("New memory failed!"); 1615c30d921cSKever Yang NORMAL_COLOR_ATTR; 1616c30d921cSKever Yang printf("\r\n"); 1617c30d921cSKever Yang goto Exit_UpgradeLoader; 1618c30d921cSKever Yang } 1619c30d921cSKever Yang memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1620c30d921cSKever Yang iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize); 1621c30d921cSKever Yang if (iRet != 0) { 1622c30d921cSKever Yang ERROR_COLOR_ATTR; 1623c30d921cSKever Yang printf("Make idblock failed!"); 1624c30d921cSKever Yang NORMAL_COLOR_ATTR; 1625c30d921cSKever Yang printf("\r\n"); 1626c30d921cSKever Yang goto Exit_UpgradeLoader; 1627c30d921cSKever Yang } 1628c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1629c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 1630c30d921cSKever Yang CURSOR_DEL_LINE; 1631c30d921cSKever Yang if (iRet == ERR_SUCCESS) { 1632c30d921cSKever Yang pComm->Reset_Usb_Device(); 1633c30d921cSKever Yang bSuccess = true; 1634c30d921cSKever Yang printf("Upgrade loader ok.\r\n"); 1635c30d921cSKever Yang } else { 1636c30d921cSKever Yang printf("Upgrade loader failed!\r\n"); 1637c30d921cSKever Yang goto Exit_UpgradeLoader; 1638c30d921cSKever Yang } 1639c30d921cSKever Yang } 1640c30d921cSKever Yang Exit_UpgradeLoader: 1641c30d921cSKever Yang if (pImage) 1642c30d921cSKever Yang delete pImage; 1643c30d921cSKever Yang if (pComm) 1644c30d921cSKever Yang delete pComm; 1645c30d921cSKever Yang if (loaderCodeBuffer) 1646c30d921cSKever Yang delete []loaderCodeBuffer; 1647c30d921cSKever Yang if (loaderDataBuffer) 1648c30d921cSKever Yang delete []loaderDataBuffer; 1649c30d921cSKever Yang if (pIDBData) 1650c30d921cSKever Yang delete []pIDBData; 1651c30d921cSKever Yang return bSuccess; 1652c30d921cSKever Yang } 1653c30d921cSKever Yang 165476af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 165576af099aSliuyi { 165676af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 165776af099aSliuyi return false; 165876af099aSliuyi CRKImage *pImage = NULL; 165976af099aSliuyi bool bRet, bSuccess = false; 166076af099aSliuyi int iRet; 166176af099aSliuyi CRKScan *pScan = NULL; 166276af099aSliuyi pScan = new CRKScan(); 166376af099aSliuyi pScan->SetVidPid(); 166476af099aSliuyi 166576af099aSliuyi CRKComm *pComm = NULL; 166676af099aSliuyi CRKDevice *pDevice = NULL; 166776af099aSliuyi 166876af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 166976af099aSliuyi if (!bRet) { 167076af099aSliuyi if (pScan) 167176af099aSliuyi delete pScan; 167276af099aSliuyi ERROR_COLOR_ATTR; 167376af099aSliuyi printf("Creating Comm Object failed!"); 167476af099aSliuyi NORMAL_COLOR_ATTR; 167576af099aSliuyi printf("\r\n"); 167676af099aSliuyi return bSuccess; 167776af099aSliuyi } 167876af099aSliuyi 167976af099aSliuyi pDevice = new CRKDevice(dev); 168076af099aSliuyi if (!pDevice) { 168176af099aSliuyi if (pComm) 168276af099aSliuyi delete pComm; 168376af099aSliuyi if (pScan) 168476af099aSliuyi delete pScan; 168576af099aSliuyi ERROR_COLOR_ATTR; 168676af099aSliuyi printf("Creating device object failed!"); 168776af099aSliuyi NORMAL_COLOR_ATTR; 168876af099aSliuyi printf("\r\n"); 168976af099aSliuyi return bSuccess; 169076af099aSliuyi } 169176af099aSliuyi 169276af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 169376af099aSliuyi pDevice->CallBackPointer = ProgressInfoProc; 169476af099aSliuyi 169576af099aSliuyi printf("Start to erase flash...\r\n"); 169676af099aSliuyi iRet = pDevice->EraseAllBlocks(); 169776af099aSliuyi if (pDevice) 169876af099aSliuyi delete pDevice; 169976af099aSliuyi 170076af099aSliuyi if (iRet == 0) { 170176af099aSliuyi if (pScan) { 170276af099aSliuyi pScan->SetVidPid(); 170376af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 170476af099aSliuyi delete pScan; 170576af099aSliuyi } 170676af099aSliuyi CURSOR_MOVEUP_LINE(1); 170776af099aSliuyi CURSOR_DEL_LINE; 170876af099aSliuyi bSuccess = true; 170976af099aSliuyi printf("Erase flash ok.\r\n"); 171076af099aSliuyi } 171176af099aSliuyi 171276af099aSliuyi return bSuccess; 171376af099aSliuyi } 171476af099aSliuyi 171576af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev) 171676af099aSliuyi { 171776af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 171876af099aSliuyi return false; 171976af099aSliuyi CRKUsbComm *pComm = NULL; 172076af099aSliuyi bool bRet, bSuccess = false; 172176af099aSliuyi int iRet; 172276af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 172376af099aSliuyi if (bRet) { 172476af099aSliuyi iRet = pComm->RKU_TestDeviceReady(); 172576af099aSliuyi if (iRet != ERR_SUCCESS) { 172676af099aSliuyi if (g_pLogObject) 172776af099aSliuyi g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet); 172876af099aSliuyi printf("Test Device Fail!\r\n"); 172976af099aSliuyi } else { 173076af099aSliuyi bSuccess = true; 173176af099aSliuyi printf("Test Device OK.\r\n"); 173276af099aSliuyi } 173376af099aSliuyi } else { 173476af099aSliuyi printf("Test Device quit,Creating comm object failed!\r\n"); 173576af099aSliuyi } 173676af099aSliuyi if (pComm) { 173776af099aSliuyi delete pComm; 173876af099aSliuyi pComm = NULL; 173976af099aSliuyi } 174076af099aSliuyi return bSuccess; 174176af099aSliuyi } 174276af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 174376af099aSliuyi { 174476af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 174576af099aSliuyi return false; 174676af099aSliuyi CRKUsbComm *pComm = NULL; 174776af099aSliuyi bool bRet, bSuccess = false; 174876af099aSliuyi int iRet; 174976af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 175076af099aSliuyi if (bRet) { 175176af099aSliuyi iRet = pComm->RKU_ResetDevice(subCode); 175276af099aSliuyi if (iRet != ERR_SUCCESS) { 175376af099aSliuyi if (g_pLogObject) 175476af099aSliuyi g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet); 175576af099aSliuyi printf("Reset Device Fail!\r\n"); 175676af099aSliuyi } else { 175776af099aSliuyi bSuccess = true; 175876af099aSliuyi printf("Reset Device OK.\r\n"); 175976af099aSliuyi } 176076af099aSliuyi } else { 176176af099aSliuyi printf("Reset Device quit,Creating comm object failed!\r\n"); 176276af099aSliuyi } 176376af099aSliuyi if (pComm) { 176476af099aSliuyi delete pComm; 176576af099aSliuyi pComm = NULL; 176676af099aSliuyi } 176776af099aSliuyi return bSuccess; 176876af099aSliuyi } 176976af099aSliuyi 177076af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 177176af099aSliuyi { 177276af099aSliuyi CRKUsbComm *pComm = NULL; 177376af099aSliuyi bool bRet, bSuccess = false; 177476af099aSliuyi int iRet; 177576af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 177676af099aSliuyi return bSuccess; 177776af099aSliuyi 177876af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 177976af099aSliuyi if (bRet) { 178076af099aSliuyi BYTE flashID[5]; 178176af099aSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 178276af099aSliuyi if (iRet != ERR_SUCCESS) { 178376af099aSliuyi if (g_pLogObject) 178476af099aSliuyi g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet); 178576af099aSliuyi printf("Read flash ID Fail!\r\n"); 178676af099aSliuyi } else { 178776af099aSliuyi printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 178876af099aSliuyi bSuccess = true; 178976af099aSliuyi } 179076af099aSliuyi } else { 179176af099aSliuyi printf("Read flash ID quit,Creating comm object failed!\r\n"); 179276af099aSliuyi } 179376af099aSliuyi if (pComm) { 179476af099aSliuyi delete pComm; 179576af099aSliuyi pComm = NULL; 179676af099aSliuyi } 179776af099aSliuyi return bSuccess; 179876af099aSliuyi } 179976af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 180076af099aSliuyi { 180176af099aSliuyi CRKUsbComm *pComm = NULL; 180276af099aSliuyi bool bRet, bSuccess = false; 180376af099aSliuyi int iRet; 180476af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 180576af099aSliuyi return bSuccess; 180676af099aSliuyi 180776af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 180876af099aSliuyi if (bRet) { 180976af099aSliuyi STRUCT_FLASHINFO_CMD info; 181076af099aSliuyi UINT uiRead; 181176af099aSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 181276af099aSliuyi if (iRet != ERR_SUCCESS) { 181376af099aSliuyi if (g_pLogObject) 181476af099aSliuyi g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet); 181576af099aSliuyi printf("Read flash Info Fail!\r\n"); 181676af099aSliuyi } else { 181776af099aSliuyi printf("Flash Info:\r\n"); 181876af099aSliuyi if (info.bManufCode <= 7) { 181976af099aSliuyi printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 182076af099aSliuyi } 182176af099aSliuyi else 182276af099aSliuyi printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode); 182376af099aSliuyi 182476af099aSliuyi printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024); 182576af099aSliuyi printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2); 182676af099aSliuyi printf("\tPage Size: %dKB\r\n", info.bPageSize / 2); 182776af099aSliuyi printf("\tECC Bits: %d\r\n", info.bECCBits); 182876af099aSliuyi printf("\tAccess Time: %d\r\n", info.bAccessTime); 182976af099aSliuyi printf("\tFlash CS: "); 183076af099aSliuyi for(int i = 0; i < 8; i++) { 183176af099aSliuyi if( info.bFlashCS & (1 << i) ) 183276af099aSliuyi printf("Flash<%d> ", i); 183376af099aSliuyi } 183476af099aSliuyi printf("\r\n"); 183576af099aSliuyi bSuccess = true; 183676af099aSliuyi } 183776af099aSliuyi }else { 183876af099aSliuyi printf("Read flash Info quit,Creating comm object failed!\r\n"); 183976af099aSliuyi } 184076af099aSliuyi if (pComm) { 184176af099aSliuyi delete pComm; 184276af099aSliuyi pComm = NULL; 184376af099aSliuyi } 184476af099aSliuyi return bSuccess; 184576af099aSliuyi } 184676af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 184776af099aSliuyi { 184876af099aSliuyi CRKUsbComm *pComm = NULL; 184976af099aSliuyi bool bRet, bSuccess = false; 185076af099aSliuyi int iRet; 185176af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 185276af099aSliuyi return bSuccess; 185376af099aSliuyi 185476af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 185576af099aSliuyi if (bRet) { 185676af099aSliuyi BYTE chipInfo[16]; 185776af099aSliuyi iRet = pComm->RKU_ReadChipInfo(chipInfo); 185876af099aSliuyi if (iRet != ERR_SUCCESS) { 185976af099aSliuyi if (g_pLogObject) 186076af099aSliuyi g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet); 186176af099aSliuyi printf("Read Chip Info Fail!\r\n"); 186276af099aSliuyi } else { 186376af099aSliuyi string strChipInfo; 186476af099aSliuyi g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 186576af099aSliuyi printf("Chip Info:%s\r\n", strChipInfo.c_str()); 186676af099aSliuyi bSuccess = true; 186776af099aSliuyi } 186876af099aSliuyi } else { 186976af099aSliuyi printf("Read Chip Info quit,Creating comm object failed!\r\n"); 187076af099aSliuyi } 187176af099aSliuyi if (pComm) { 187276af099aSliuyi delete pComm; 187376af099aSliuyi pComm = NULL; 187476af099aSliuyi } 187576af099aSliuyi return bSuccess; 187676af099aSliuyi } 187776af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 187876af099aSliuyi { 187976af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 188076af099aSliuyi return false; 188176af099aSliuyi CRKUsbComm *pComm = NULL; 188276af099aSliuyi FILE *file = NULL; 188376af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 188476af099aSliuyi int iRet; 188576af099aSliuyi UINT iTotalRead = 0,iRead = 0; 188676af099aSliuyi int nSectorSize = 512; 188776af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 188876af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 188976af099aSliuyi if (bRet) { 189076af099aSliuyi if(szFile) { 189176af099aSliuyi file = fopen(szFile, "wb+"); 189276af099aSliuyi if( !file ) { 189376af099aSliuyi printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile); 189476af099aSliuyi goto Exit_ReadLBA; 189576af099aSliuyi } 189676af099aSliuyi } 189776af099aSliuyi 189876af099aSliuyi while(uiLen > 0) { 189976af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 190076af099aSliuyi iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 190176af099aSliuyi iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 190276af099aSliuyi if(ERR_SUCCESS == iRet) { 190376af099aSliuyi uiLen -= iRead; 190476af099aSliuyi iTotalRead += iRead; 190576af099aSliuyi 190676af099aSliuyi if(szFile) { 190776af099aSliuyi fwrite(pBuf, 1, iRead * nSectorSize, file); 190876af099aSliuyi if (bFirst){ 190976af099aSliuyi if (iTotalRead >= 1024) 191076af099aSliuyi printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 191176af099aSliuyi else 191276af099aSliuyi printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 191376af099aSliuyi bFirst = false; 191476af099aSliuyi } else { 191576af099aSliuyi CURSOR_MOVEUP_LINE(1); 191676af099aSliuyi CURSOR_DEL_LINE; 191776af099aSliuyi if (iTotalRead >= 1024) 191876af099aSliuyi printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 191976af099aSliuyi else 192076af099aSliuyi printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 192176af099aSliuyi } 192276af099aSliuyi } 192376af099aSliuyi else 192476af099aSliuyi PrintData(pBuf, nSectorSize * iRead); 192576af099aSliuyi } else { 192676af099aSliuyi if (g_pLogObject) 192776af099aSliuyi g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet); 192876af099aSliuyi 192976af099aSliuyi printf("Read LBA failed!\r\n"); 193076af099aSliuyi goto Exit_ReadLBA; 193176af099aSliuyi } 193276af099aSliuyi } 193376af099aSliuyi bSuccess = true; 193476af099aSliuyi } else { 193576af099aSliuyi printf("Read LBA quit,Creating comm object failed!\r\n"); 193676af099aSliuyi } 193776af099aSliuyi Exit_ReadLBA: 193876af099aSliuyi if (pComm) { 193976af099aSliuyi delete pComm; 194076af099aSliuyi pComm = NULL; 194176af099aSliuyi } 194276af099aSliuyi if (file) 194376af099aSliuyi fclose(file); 194476af099aSliuyi return bSuccess; 194576af099aSliuyi } 194676af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 194776af099aSliuyi { 194876af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 194976af099aSliuyi return false; 195076af099aSliuyi CRKUsbComm *pComm = NULL; 195176af099aSliuyi FILE *file = NULL; 195276af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 195376af099aSliuyi int iRet; 195476af099aSliuyi long long iTotalWrite = 0, iFileSize = 0; 195576af099aSliuyi UINT iWrite = 0, iRead = 0; 195676af099aSliuyi UINT uiLen; 195776af099aSliuyi int nSectorSize = 512; 195876af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 195976af099aSliuyi 196076af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 196176af099aSliuyi if (bRet) { 196276af099aSliuyi file = fopen(szFile, "rb"); 196376af099aSliuyi if( !file ) { 196476af099aSliuyi printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile); 196576af099aSliuyi goto Exit_WriteLBA; 196676af099aSliuyi } 196776af099aSliuyi 196876af099aSliuyi iRet = fseeko(file, 0, SEEK_END); 196976af099aSliuyi iFileSize = ftello(file); 197076af099aSliuyi fseeko(file, 0, SEEK_SET); 197176af099aSliuyi while(iTotalWrite < iFileSize) { 197276af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 197376af099aSliuyi iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 197476af099aSliuyi uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 197576af099aSliuyi iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 197676af099aSliuyi if(ERR_SUCCESS == iRet) { 197776af099aSliuyi uiBegin += uiLen; 197876af099aSliuyi iTotalWrite += iWrite; 197976af099aSliuyi if (bFirst) { 198076af099aSliuyi if (iTotalWrite >= 1024) 198176af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 198276af099aSliuyi else 198376af099aSliuyi printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize); 198476af099aSliuyi bFirst = false; 198576af099aSliuyi } else { 198676af099aSliuyi CURSOR_MOVEUP_LINE(1); 198776af099aSliuyi CURSOR_DEL_LINE; 198876af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 198976af099aSliuyi } 199076af099aSliuyi } else { 199176af099aSliuyi if (g_pLogObject) 199276af099aSliuyi g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet); 199376af099aSliuyi 199476af099aSliuyi printf("Write LBA failed!\r\n"); 199576af099aSliuyi goto Exit_WriteLBA; 199676af099aSliuyi } 199776af099aSliuyi } 199876af099aSliuyi bSuccess = true; 199976af099aSliuyi } else { 200076af099aSliuyi printf("Write LBA quit,Creating comm object failed!\r\n"); 200176af099aSliuyi } 200276af099aSliuyi Exit_WriteLBA: 200376af099aSliuyi if (pComm) { 200476af099aSliuyi delete pComm; 200576af099aSliuyi pComm = NULL; 200676af099aSliuyi } 200776af099aSliuyi if (file) 200876af099aSliuyi fclose(file); 200976af099aSliuyi return bSuccess; 201076af099aSliuyi } 201176af099aSliuyi 201276af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems) 201376af099aSliuyi { 201476af099aSliuyi string strItem; 201576af099aSliuyi char szItem[100]; 201676af099aSliuyi char *pos = NULL, *pStart; 201776af099aSliuyi pStart = pszItems; 201876af099aSliuyi pos = strchr(pStart, ','); 201976af099aSliuyi while(pos != NULL) { 202076af099aSliuyi memset(szItem, 0, 100); 202176af099aSliuyi strncpy(szItem, pStart, pos - pStart); 202276af099aSliuyi strItem = szItem; 202376af099aSliuyi vecItems.push_back(strItem); 202476af099aSliuyi pStart = pos + 1; 202576af099aSliuyi if (*pStart == 0) 202676af099aSliuyi break; 202776af099aSliuyi pos = strchr(pStart, ','); 202876af099aSliuyi } 202976af099aSliuyi if (strlen(pStart) > 0) { 203076af099aSliuyi memset(szItem, 0, 100); 203176af099aSliuyi strncpy(szItem, pStart, strlen(pStart)); 203276af099aSliuyi strItem = szItem; 203376af099aSliuyi vecItems.push_back(strItem); 203476af099aSliuyi } 203576af099aSliuyi } 2036c30d921cSKever Yang 203776af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan) 203876af099aSliuyi { 203976af099aSliuyi string strCmd; 204076af099aSliuyi strCmd = argv[1]; 204176af099aSliuyi ssize_t cnt; 204276af099aSliuyi bool bRet,bSuccess = false; 20438df2d64aSEddie Cai char *s; 20448df2d64aSEddie Cai int i, ret; 204576af099aSliuyi STRUCT_RKDEVICE_DESC dev; 204676af099aSliuyi 204776af099aSliuyi transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 20488df2d64aSEddie Cai s = (char*)strCmd.c_str(); 20498df2d64aSEddie Cai for(i = 0; i < (int)strlen(s); i++) 20508df2d64aSEddie Cai s[i] = toupper(s[i]); 2051*78884ef4SEddie Cai 20528df2d64aSEddie Cai if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 205376af099aSliuyi usage(); 205476af099aSliuyi return true; 20558df2d64aSEddie Cai } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2056c30d921cSKever Yang printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 205776af099aSliuyi return true; 2058*78884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 2059*78884ef4SEddie Cai mergeBoot(); 2060*78884ef4SEddie Cai 2061*78884ef4SEddie Cai return true; 2062*78884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 2063*78884ef4SEddie Cai string strLoader = argv[2]; 2064*78884ef4SEddie Cai 2065*78884ef4SEddie Cai unpackBoot((char*)strLoader.c_str()); 2066*78884ef4SEddie Cai return true; 206776af099aSliuyi } 206876af099aSliuyi cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 206976af099aSliuyi if (cnt < 1) { 207076af099aSliuyi ERROR_COLOR_ATTR; 207176af099aSliuyi printf("No found any rockusb device,please plug device in!"); 207276af099aSliuyi NORMAL_COLOR_ATTR; 207376af099aSliuyi printf("\r\n"); 207476af099aSliuyi return bSuccess; 207576af099aSliuyi } else if (cnt > 1) { 207676af099aSliuyi ERROR_COLOR_ATTR; 207776af099aSliuyi printf("Found many rockusb devices,please plug device out!"); 207876af099aSliuyi NORMAL_COLOR_ATTR; 207976af099aSliuyi printf("\r\n"); 208076af099aSliuyi return bSuccess; 208176af099aSliuyi } 208276af099aSliuyi 208376af099aSliuyi bRet = pScan->GetDevice(dev, 0); 208476af099aSliuyi if (!bRet) { 208576af099aSliuyi ERROR_COLOR_ATTR; 208676af099aSliuyi printf("Getting information of rockusb device failed!"); 208776af099aSliuyi NORMAL_COLOR_ATTR; 208876af099aSliuyi printf("\r\n"); 208976af099aSliuyi return bSuccess; 209076af099aSliuyi } 209176af099aSliuyi 209276af099aSliuyi if(strcmp(strCmd.c_str(), "RD") == 0) { 209376af099aSliuyi if ((argc != 2) && (argc != 3)) 209476af099aSliuyi printf("Parameter of [RD] command is invalid,please check help!\r\n"); 209576af099aSliuyi else { 209676af099aSliuyi if (argc == 2) 209776af099aSliuyi bSuccess = reset_device(dev); 209876af099aSliuyi else { 209976af099aSliuyi UINT uiSubCode; 210076af099aSliuyi char *pszEnd; 210176af099aSliuyi uiSubCode = strtoul(argv[2], &pszEnd, 0); 210276af099aSliuyi if (*pszEnd) 210376af099aSliuyi printf("Subcode is invalid,please check!\r\n"); 210476af099aSliuyi else { 210576af099aSliuyi if (uiSubCode <= 5) 210676af099aSliuyi bSuccess = reset_device(dev, uiSubCode); 210776af099aSliuyi else 210876af099aSliuyi printf("Subcode is invalid,please check!\r\n"); 210976af099aSliuyi } 211076af099aSliuyi } 211176af099aSliuyi } 211276af099aSliuyi } else if(strcmp(strCmd.c_str(), "TD") == 0) { 211376af099aSliuyi bSuccess = test_device(dev); 211476af099aSliuyi } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 211576af099aSliuyi bSuccess = read_flash_id(dev); 211676af099aSliuyi } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 211776af099aSliuyi bSuccess = read_flash_info(dev); 211876af099aSliuyi } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 211976af099aSliuyi bSuccess = read_chip_info(dev); 212076af099aSliuyi } else if(strcmp(strCmd.c_str(), "DB") == 0) { 212176af099aSliuyi if (argc > 2) { 212276af099aSliuyi string strLoader; 212376af099aSliuyi strLoader = argv[2]; 212476af099aSliuyi bSuccess = download_boot(dev, (char *)strLoader.c_str()); 212576af099aSliuyi } else if (argc == 2) { 212676af099aSliuyi ret = find_config_item("loader"); 212776af099aSliuyi if (ret == -1) 212876af099aSliuyi printf("No found loader item from config!\r\n"); 212976af099aSliuyi else 213076af099aSliuyi bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 213176af099aSliuyi } else 213276af099aSliuyi printf("Parameter of [DB] command is invalid,please check help!\r\n"); 2133c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2134c30d921cSKever Yang if (argc > 2) { 2135c30d921cSKever Yang string strParameter; 2136c30d921cSKever Yang strParameter = argv[2]; 2137c30d921cSKever Yang bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2138c30d921cSKever Yang } else 2139c30d921cSKever Yang printf("Parameter of [GPT] command is invalid,please check help!\r\n"); 2140c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2141c30d921cSKever Yang if (argc > 2) { 2142c30d921cSKever Yang string strLoader; 2143c30d921cSKever Yang strLoader = argv[2]; 2144c30d921cSKever Yang bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2145c30d921cSKever Yang } else 2146c30d921cSKever Yang printf("Parameter of [UL] command is invalid,please check help!\r\n"); 214776af099aSliuyi } else if(strcmp(strCmd.c_str(), "EF") == 0) { 214876af099aSliuyi if (argc == 2) { 214976af099aSliuyi bSuccess = erase_flash(dev); 215076af099aSliuyi } else 215176af099aSliuyi printf("Parameter of [EF] command is invalid,please check help!\r\n"); 215276af099aSliuyi } else if(strcmp(strCmd.c_str(), "WL") == 0) { 215376af099aSliuyi if (argc == 4) { 215476af099aSliuyi UINT uiBegin; 215576af099aSliuyi char *pszEnd; 215676af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 215776af099aSliuyi if (*pszEnd) 215876af099aSliuyi printf("Begin is invalid,please check!\r\n"); 215976af099aSliuyi else 216076af099aSliuyi bSuccess = write_lba(dev, uiBegin, argv[3]); 216176af099aSliuyi } else 216276af099aSliuyi printf("Parameter of [WL] command is invalid,please check help!\r\n"); 216376af099aSliuyi } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 216476af099aSliuyi char *pszEnd; 216576af099aSliuyi UINT uiBegin, uiLen; 216676af099aSliuyi if (argc != 5) 216776af099aSliuyi printf("Parameter of [RL] command is invalid,please check help!\r\n"); 216876af099aSliuyi else { 216976af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 217076af099aSliuyi if (*pszEnd) 217176af099aSliuyi printf("Begin is invalid,please check!\r\n"); 217276af099aSliuyi else { 217376af099aSliuyi uiLen = strtoul(argv[3], &pszEnd, 0); 217476af099aSliuyi if (*pszEnd) 217576af099aSliuyi printf("Len is invalid,please check!\r\n"); 217676af099aSliuyi else { 217776af099aSliuyi bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 217876af099aSliuyi } 217976af099aSliuyi } 218076af099aSliuyi } 218176af099aSliuyi } else { 2182c30d921cSKever Yang printf("command is invalid,please press rkDevelopTool -h to check usage!\r\n"); 218376af099aSliuyi } 218476af099aSliuyi return bSuccess; 218576af099aSliuyi } 218676af099aSliuyi 218776af099aSliuyi 218876af099aSliuyi int main(int argc, char* argv[]) 218976af099aSliuyi { 219076af099aSliuyi CRKScan *pScan = NULL; 219176af099aSliuyi int ret; 219276af099aSliuyi char szProgramProcPath[100]; 219376af099aSliuyi char szProgramDir[256]; 219476af099aSliuyi string strLogDir,strConfigFile; 219576af099aSliuyi struct stat statBuf; 219676af099aSliuyi 219776af099aSliuyi g_ConfigItemVec.clear(); 219876af099aSliuyi sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 219976af099aSliuyi if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 220076af099aSliuyi strcpy(szProgramDir, "."); 220176af099aSliuyi else { 220276af099aSliuyi char *pSlash; 220376af099aSliuyi pSlash = strrchr(szProgramDir, '/'); 220476af099aSliuyi if (pSlash) 220576af099aSliuyi *pSlash = '\0'; 220676af099aSliuyi } 220776af099aSliuyi strLogDir = szProgramDir; 220876af099aSliuyi strLogDir += "/log/"; 220976af099aSliuyi strConfigFile = szProgramDir; 221076af099aSliuyi strConfigFile += "/config.ini"; 221176af099aSliuyi if (opendir(strLogDir.c_str()) == NULL) 221276af099aSliuyi mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 221376af099aSliuyi g_pLogObject = new CRKLog(strLogDir.c_str(), "log"); 221476af099aSliuyi 221576af099aSliuyi if(stat(strConfigFile.c_str(), &statBuf) < 0) { 221676af099aSliuyi if (g_pLogObject) { 221776af099aSliuyi g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno); 221876af099aSliuyi } 221976af099aSliuyi } else if (S_ISREG(statBuf.st_mode)) { 222076af099aSliuyi parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 222176af099aSliuyi } 222276af099aSliuyi 222376af099aSliuyi ret = libusb_init(NULL); 222476af099aSliuyi if (ret < 0) { 222576af099aSliuyi if (g_pLogObject) { 222676af099aSliuyi g_pLogObject->Record("Error:libusb_init failed,err=%d", ret); 222776af099aSliuyi delete g_pLogObject; 222876af099aSliuyi } 222976af099aSliuyi return -1; 223076af099aSliuyi } 223176af099aSliuyi 223276af099aSliuyi pScan = new CRKScan(); 223376af099aSliuyi if (!pScan) { 223476af099aSliuyi if (g_pLogObject) { 223576af099aSliuyi g_pLogObject->Record("Error:failed to Create object for searching device"); 223676af099aSliuyi delete g_pLogObject; 223776af099aSliuyi } 223876af099aSliuyi libusb_exit(NULL); 223976af099aSliuyi return -2; 224076af099aSliuyi } 224176af099aSliuyi pScan->SetVidPid(); 224276af099aSliuyi 224376af099aSliuyi if (argc == 1) 224476af099aSliuyi usage(); 224576af099aSliuyi else if (!handle_command(argc, argv, pScan)) 224676af099aSliuyi return -0xFF; 224776af099aSliuyi if (pScan) 224876af099aSliuyi delete pScan; 224976af099aSliuyi if (g_pLogObject) 225076af099aSliuyi delete g_pLogObject; 225176af099aSliuyi libusb_exit(NULL); 225276af099aSliuyi return 0; 225376af099aSliuyi } 2254