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