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); 273601cc08SAndreas Färber #define NORMAL_COLOR_ATTR printf("%c[0m", 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: 6932268622SAndreas Färber sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue); 7076af099aSliuyi strInfoText = szText; 7176af099aSliuyi break; 7276af099aSliuyi case LOWERFORMAT_PROGRESS: 7332268622SAndreas Färber sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue); 7476af099aSliuyi strInfoText = szText; 7576af099aSliuyi break; 7676af099aSliuyi case DOWNLOADIMAGE_PROGRESS: 7732268622SAndreas Färber sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 7876af099aSliuyi strInfoText = szText; 7976af099aSliuyi break; 8076af099aSliuyi case CHECKIMAGE_PROGRESS: 8132268622SAndreas Färber sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 8276af099aSliuyi strInfoText = szText; 8376af099aSliuyi break; 8476af099aSliuyi case TAGBADBLOCK_PROGRESS: 8532268622SAndreas Färber sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue); 8676af099aSliuyi strInfoText = szText; 8776af099aSliuyi break; 8876af099aSliuyi case TESTBLOCK_PROGRESS: 8932268622SAndreas Färber sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue); 9076af099aSliuyi strInfoText = szText; 9176af099aSliuyi break; 9276af099aSliuyi case ERASEFLASH_PROGRESS: 9332268622SAndreas Färber sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue); 9476af099aSliuyi strInfoText = szText; 9576af099aSliuyi break; 9676af099aSliuyi case ERASESYSTEM_PROGRESS: 9732268622SAndreas Färber sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue); 9876af099aSliuyi strInfoText = szText; 9976af099aSliuyi break; 10076af099aSliuyi case ERASEUSERDATA_PROGRESS: 10132268622SAndreas Färber 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 } 216*c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName) 21776af099aSliuyi { 21876af099aSliuyi unsigned int i; 219*c29e5f0fSliuyi for(i = 0; i < vecItems.size(); i++){ 220*c29e5f0fSliuyi if (strcasecmp(pszName, vecItems[i].szItemName) == 0){ 22176af099aSliuyi return i; 22276af099aSliuyi } 22376af099aSliuyi } 22476af099aSliuyi return -1; 22576af099aSliuyi } 226*c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid) 227*c29e5f0fSliuyi { 228*c29e5f0fSliuyi unsigned int i; 229*c29e5f0fSliuyi char value; 230*c29e5f0fSliuyi memset(uuid, 0, 16); 231*c29e5f0fSliuyi for (i =0; i < strUUid.size(); i++) { 232*c29e5f0fSliuyi value = 0; 233*c29e5f0fSliuyi if ((strUUid[i] >= '0')&&(strUUid[i] <= '9')) 234*c29e5f0fSliuyi value = strUUid[i] - '0'; 235*c29e5f0fSliuyi if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f')) 236*c29e5f0fSliuyi value = strUUid[i] - 'a' + 10; 237*c29e5f0fSliuyi if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F')) 238*c29e5f0fSliuyi value = strUUid[i] - 'A' + 10; 239*c29e5f0fSliuyi if ((i % 2) == 0) 240*c29e5f0fSliuyi uuid[i / 2] += (value << 4); 241*c29e5f0fSliuyi else 242*c29e5f0fSliuyi uuid[i / 2] += value; 243*c29e5f0fSliuyi } 244*c29e5f0fSliuyi unsigned int *p32; 245*c29e5f0fSliuyi unsigned short *p16; 246*c29e5f0fSliuyi p32 = (unsigned int*)uuid; 247*c29e5f0fSliuyi *p32 = cpu_to_be32(*p32); 248*c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 4); 249*c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 250*c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 6); 251*c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 252*c29e5f0fSliuyi } 25376af099aSliuyi 25476af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 25576af099aSliuyi { 25676af099aSliuyi 25776af099aSliuyi stringstream configStream(pConfig); 25876af099aSliuyi string strLine, strItemName, strItemValue; 25976af099aSliuyi string::size_type line_size,pos; 26076af099aSliuyi STRUCT_CONFIG_ITEM item; 26176af099aSliuyi vecItem.clear(); 26276af099aSliuyi while (!configStream.eof()){ 26376af099aSliuyi getline(configStream, strLine); 26476af099aSliuyi line_size = strLine.size(); 26576af099aSliuyi if (line_size == 0) 26676af099aSliuyi continue; 26776af099aSliuyi if (strLine[line_size-1] == '\r'){ 26876af099aSliuyi strLine = strLine.substr(0, line_size-1); 26976af099aSliuyi } 270c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 271c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 272c30d921cSKever Yang if (strLine.size()==0 ) 273c30d921cSKever Yang continue; 274c30d921cSKever Yang if (strLine[0] == '#') 275c30d921cSKever Yang continue; 27676af099aSliuyi pos = strLine.find("="); 27776af099aSliuyi if (pos == string::npos){ 27876af099aSliuyi continue; 27976af099aSliuyi } 28076af099aSliuyi strItemName = strLine.substr(0, pos); 28176af099aSliuyi strItemValue = strLine.substr(pos + 1); 28276af099aSliuyi strItemName.erase(0, strItemName.find_first_not_of(" ")); 28376af099aSliuyi strItemName.erase(strItemName.find_last_not_of(" ") + 1); 28476af099aSliuyi strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 28576af099aSliuyi strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 28676af099aSliuyi if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 28776af099aSliuyi strcpy(item.szItemName, strItemName.c_str()); 28876af099aSliuyi strcpy(item.szItemValue, strItemValue.c_str()); 28976af099aSliuyi vecItem.push_back(item); 29076af099aSliuyi } 29176af099aSliuyi } 29276af099aSliuyi return true; 29376af099aSliuyi 29476af099aSliuyi } 29576af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 29676af099aSliuyi { 29776af099aSliuyi FILE *file = NULL; 29876af099aSliuyi file = fopen(pConfigFile, "rb"); 29976af099aSliuyi if( !file ){ 30076af099aSliuyi if (g_pLogObject) 30132268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile); 30276af099aSliuyi return false; 30376af099aSliuyi } 30476af099aSliuyi int iFileSize; 30576af099aSliuyi fseek(file, 0, SEEK_END); 30676af099aSliuyi iFileSize = ftell(file); 30776af099aSliuyi fseek(file, 0, SEEK_SET); 30876af099aSliuyi char *pConfigBuf = NULL; 30976af099aSliuyi pConfigBuf = new char[iFileSize + 1]; 31076af099aSliuyi if (!pConfigBuf){ 31176af099aSliuyi fclose(file); 31276af099aSliuyi return false; 31376af099aSliuyi } 31476af099aSliuyi memset(pConfigBuf, 0, iFileSize + 1); 31576af099aSliuyi int iRead; 31676af099aSliuyi iRead = fread(pConfigBuf, 1, iFileSize, file); 31776af099aSliuyi if (iRead != iFileSize){ 31876af099aSliuyi if (g_pLogObject) 31932268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize); 32076af099aSliuyi fclose(file); 32176af099aSliuyi delete []pConfigBuf; 32276af099aSliuyi return false; 32376af099aSliuyi } 32476af099aSliuyi fclose(file); 32576af099aSliuyi bool bRet; 32676af099aSliuyi bRet = parse_config(pConfigBuf, vecItem); 32776af099aSliuyi delete []pConfigBuf; 32876af099aSliuyi return bRet; 32976af099aSliuyi } 330c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 331c30d921cSKever Yang { 332c30d921cSKever Yang string::size_type pos,prevPos; 333c30d921cSKever Yang string strOffset,strLen; 334c30d921cSKever Yang int iCount; 335c30d921cSKever Yang prevPos = pos = 0; 336c30d921cSKever Yang if (strPartInfo.size() <= 0) { 337c30d921cSKever Yang return false; 338c30d921cSKever Yang } 339c30d921cSKever Yang pos = strPartInfo.find('@'); 340c30d921cSKever Yang if (pos == string::npos) { 341c30d921cSKever Yang return false; 342c30d921cSKever Yang } 343c30d921cSKever Yang strLen = strPartInfo.substr(prevPos, pos - prevPos); 344c30d921cSKever Yang strLen.erase(0, strLen.find_first_not_of(" ")); 345c30d921cSKever Yang strLen.erase(strLen.find_last_not_of(" ") + 1); 346c30d921cSKever Yang if (strchr(strLen.c_str(), '-')) { 347c30d921cSKever Yang uiLen = 0xFFFFFFFF; 348c30d921cSKever Yang } else { 349c30d921cSKever Yang iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 350c30d921cSKever Yang if (iCount != 1) { 351c30d921cSKever Yang return false; 352c30d921cSKever Yang } 353c30d921cSKever Yang } 354c30d921cSKever Yang 355c30d921cSKever Yang prevPos = pos + 1; 356c30d921cSKever Yang pos = strPartInfo.find('(',prevPos); 357c30d921cSKever Yang if (pos == string::npos) { 358c30d921cSKever Yang return false; 359c30d921cSKever Yang } 360c30d921cSKever Yang strOffset = strPartInfo.substr(prevPos, pos - prevPos); 361c30d921cSKever Yang strOffset.erase(0, strOffset.find_first_not_of(" ")); 362c30d921cSKever Yang strOffset.erase(strOffset.find_last_not_of(" ") + 1); 363c30d921cSKever Yang iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 364c30d921cSKever Yang if (iCount != 1) { 365c30d921cSKever Yang return false; 366c30d921cSKever Yang } 367c30d921cSKever Yang prevPos = pos + 1; 368c30d921cSKever Yang pos = strPartInfo.find(')', prevPos); 369c30d921cSKever Yang if (pos == string::npos) { 370c30d921cSKever Yang return false; 371c30d921cSKever Yang } 372c30d921cSKever Yang strName = strPartInfo.substr(prevPos, pos - prevPos); 373c30d921cSKever Yang strName.erase(0, strName.find_first_not_of(" ")); 374c30d921cSKever Yang strName.erase(strName.find_last_not_of(" ") + 1); 375c30d921cSKever Yang 376c30d921cSKever Yang return true; 377c30d921cSKever Yang } 378*c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid) 379*c29e5f0fSliuyi { 380*c29e5f0fSliuyi string::size_type pos(0); 381c30d921cSKever Yang 382*c29e5f0fSliuyi if (strUuidInfo.size() <= 0) { 383*c29e5f0fSliuyi return false; 384*c29e5f0fSliuyi } 385*c29e5f0fSliuyi pos = strUuidInfo.find('='); 386*c29e5f0fSliuyi if (pos == string::npos) { 387*c29e5f0fSliuyi return false; 388*c29e5f0fSliuyi } 389*c29e5f0fSliuyi strName = strUuidInfo.substr(0, pos); 390*c29e5f0fSliuyi strName.erase(0, strName.find_first_not_of(" ")); 391*c29e5f0fSliuyi strName.erase(strName.find_last_not_of(" ") + 1); 392*c29e5f0fSliuyi 393*c29e5f0fSliuyi strUUid = strUuidInfo.substr(pos+1); 394*c29e5f0fSliuyi strUUid.erase(0, strUUid.find_first_not_of(" ")); 395*c29e5f0fSliuyi strUUid.erase(strUUid.find_last_not_of(" ") + 1); 396*c29e5f0fSliuyi 397*c29e5f0fSliuyi while(true) { 398*c29e5f0fSliuyi pos = 0; 399*c29e5f0fSliuyi if( (pos = strUUid.find("-")) != string::npos) 400*c29e5f0fSliuyi strUUid.replace(pos,1,""); 401*c29e5f0fSliuyi else 402*c29e5f0fSliuyi break; 403*c29e5f0fSliuyi } 404*c29e5f0fSliuyi if (strUUid.size() != 32) 405*c29e5f0fSliuyi return false; 406*c29e5f0fSliuyi return true; 407*c29e5f0fSliuyi } 408*c29e5f0fSliuyi 409*c29e5f0fSliuyi 410*c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 411c30d921cSKever Yang { 412c30d921cSKever Yang stringstream paramStream(pParameter); 413c30d921cSKever Yang bool bRet,bFind = false; 414*c29e5f0fSliuyi string strLine, strPartition, strPartInfo, strPartName, strUUid; 415c30d921cSKever Yang string::size_type line_size, pos, posColon, posComma; 416c30d921cSKever Yang UINT uiPartOffset, uiPartSize; 417c30d921cSKever Yang STRUCT_PARAM_ITEM item; 418*c29e5f0fSliuyi STRUCT_CONFIG_ITEM uuid_item; 419c30d921cSKever Yang vecItem.clear(); 420*c29e5f0fSliuyi vecUuidItem.clear(); 421c30d921cSKever Yang while (!paramStream.eof()) { 422c30d921cSKever Yang getline(paramStream,strLine); 423c30d921cSKever Yang line_size = strLine.size(); 424c30d921cSKever Yang if (line_size == 0) 425c30d921cSKever Yang continue; 426c30d921cSKever Yang if (strLine[line_size - 1] == '\r'){ 427c30d921cSKever Yang strLine = strLine.substr(0, line_size - 1); 428c30d921cSKever Yang } 429c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 430c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 431c30d921cSKever Yang if (strLine.size()==0 ) 432c30d921cSKever Yang continue; 433c30d921cSKever Yang if (strLine[0] == '#') 434c30d921cSKever Yang continue; 435*c29e5f0fSliuyi pos = strLine.find("uuid:"); 436*c29e5f0fSliuyi if (pos != string::npos) { 437*c29e5f0fSliuyi strPartInfo = strLine.substr(pos+5); 438*c29e5f0fSliuyi bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid); 439*c29e5f0fSliuyi if (bRet) { 440*c29e5f0fSliuyi strcpy(uuid_item.szItemName, strPartName.c_str()); 441*c29e5f0fSliuyi string_to_uuid(strUUid,uuid_item.szItemValue); 442*c29e5f0fSliuyi vecUuidItem.push_back(uuid_item); 443*c29e5f0fSliuyi } 444*c29e5f0fSliuyi continue; 445*c29e5f0fSliuyi } 446*c29e5f0fSliuyi 447c30d921cSKever Yang pos = strLine.find("mtdparts"); 448c30d921cSKever Yang if (pos == string::npos) { 449c30d921cSKever Yang continue; 450c30d921cSKever Yang } 451c30d921cSKever Yang bFind = true; 452c30d921cSKever Yang posColon = strLine.find(':', pos); 453c30d921cSKever Yang if (posColon == string::npos) { 454c30d921cSKever Yang continue; 455c30d921cSKever Yang } 456c30d921cSKever Yang strPartition = strLine.substr(posColon + 1); 457c30d921cSKever Yang pos = 0; 458c30d921cSKever Yang posComma = strPartition.find(',', pos); 459c30d921cSKever Yang while (posComma != string::npos) { 460c30d921cSKever Yang strPartInfo = strPartition.substr(pos, posComma - pos); 461c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 462c30d921cSKever Yang if (bRet) { 463c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 464c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 465c30d921cSKever Yang item.uiItemSize = uiPartSize; 466c30d921cSKever Yang vecItem.push_back(item); 467c30d921cSKever Yang } 468c30d921cSKever Yang pos = posComma + 1; 469c30d921cSKever Yang posComma = strPartition.find(',', pos); 470c30d921cSKever Yang } 471c30d921cSKever Yang strPartInfo = strPartition.substr(pos); 472c30d921cSKever Yang if (strPartInfo.size() > 0) { 473c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 474c30d921cSKever Yang if (bRet) { 475c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 476c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 477c30d921cSKever Yang item.uiItemSize = uiPartSize; 478c30d921cSKever Yang vecItem.push_back(item); 479c30d921cSKever Yang } 480c30d921cSKever Yang } 481c30d921cSKever Yang break; 482c30d921cSKever Yang } 483c30d921cSKever Yang return bFind; 484c30d921cSKever Yang 485c30d921cSKever Yang } 486*c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 487c30d921cSKever Yang { 488c30d921cSKever Yang FILE *file = NULL; 489c30d921cSKever Yang file = fopen(pParamFile, "rb"); 490c30d921cSKever Yang if( !file ) { 491c30d921cSKever Yang if (g_pLogObject) 49232268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 493c30d921cSKever Yang return false; 494c30d921cSKever Yang } 495c30d921cSKever Yang int iFileSize; 496c30d921cSKever Yang fseek(file, 0, SEEK_END); 497c30d921cSKever Yang iFileSize = ftell(file); 498c30d921cSKever Yang fseek(file, 0, SEEK_SET); 499c30d921cSKever Yang char *pParamBuf = NULL; 500c30d921cSKever Yang pParamBuf = new char[iFileSize]; 501c30d921cSKever Yang if (!pParamBuf) { 502c30d921cSKever Yang fclose(file); 503c30d921cSKever Yang return false; 504c30d921cSKever Yang } 505c30d921cSKever Yang int iRead; 506c30d921cSKever Yang iRead = fread(pParamBuf, 1, iFileSize, file); 507c30d921cSKever Yang if (iRead != iFileSize) { 508c30d921cSKever Yang if (g_pLogObject) 50932268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize); 510c30d921cSKever Yang fclose(file); 511c30d921cSKever Yang delete []pParamBuf; 512c30d921cSKever Yang return false; 513c30d921cSKever Yang } 514c30d921cSKever Yang fclose(file); 515c30d921cSKever Yang bool bRet; 516*c29e5f0fSliuyi bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem); 517c30d921cSKever Yang delete []pParamBuf; 518c30d921cSKever Yang return bRet; 519c30d921cSKever Yang } 520c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin) 521c30d921cSKever Yang { 522c30d921cSKever Yang efi_guid_t id; 523c30d921cSKever Yang unsigned int *ptr = (unsigned int *)&id; 524c30d921cSKever Yang unsigned int i; 525c30d921cSKever Yang 526c30d921cSKever Yang /* Set all fields randomly */ 527c30d921cSKever Yang for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 528c30d921cSKever Yang *(ptr + i) = cpu_to_be32(rand()); 529c30d921cSKever Yang 530c30d921cSKever Yang id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 531c30d921cSKever Yang id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 532c30d921cSKever Yang 533c30d921cSKever Yang memcpy(uuid_bin, id.raw, sizeof(id)); 534c30d921cSKever Yang } 535c30d921cSKever Yang 536*c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup) 537*c29e5f0fSliuyi { 538*c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 539*c29e5f0fSliuyi gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE); 540*c29e5f0fSliuyi u32 calc_crc32; 541*c29e5f0fSliuyi u64 val; 542*c29e5f0fSliuyi 543*c29e5f0fSliuyi /* recalculate the values for the Backup GPT Header */ 544*c29e5f0fSliuyi val = le64_to_cpu(gptMasterHead->my_lba); 545*c29e5f0fSliuyi gptBackupHead->my_lba = gptMasterHead->alternate_lba; 546*c29e5f0fSliuyi gptBackupHead->alternate_lba = cpu_to_le64(val); 547*c29e5f0fSliuyi gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1); 548*c29e5f0fSliuyi gptBackupHead->header_crc32 = 0; 549*c29e5f0fSliuyi 550*c29e5f0fSliuyi calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size)); 551*c29e5f0fSliuyi gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32); 552*c29e5f0fSliuyi } 553*c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector) 554*c29e5f0fSliuyi { 555*c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 556*c29e5f0fSliuyi gpt_entry *gptLastPartEntry = NULL; 557*c29e5f0fSliuyi u32 i; 558*c29e5f0fSliuyi u64 old_disksize; 559*c29e5f0fSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 560*c29e5f0fSliuyi 561*c29e5f0fSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 562*c29e5f0fSliuyi old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1; 563*c29e5f0fSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 564*c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 565*c29e5f0fSliuyi if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0) 566*c29e5f0fSliuyi break; 567*c29e5f0fSliuyi } 568*c29e5f0fSliuyi i--; 569*c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry)); 570*c29e5f0fSliuyi 571*c29e5f0fSliuyi gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1); 572*c29e5f0fSliuyi gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34); 573*c29e5f0fSliuyi 574*c29e5f0fSliuyi if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition 575*c29e5f0fSliuyi gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34); 576*c29e5f0fSliuyi gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 577*c29e5f0fSliuyi } 578*c29e5f0fSliuyi gptMasterHead->header_crc32 = 0; 579*c29e5f0fSliuyi gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header))); 580*c29e5f0fSliuyi memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS); 581*c29e5f0fSliuyi memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE); 582*c29e5f0fSliuyi prepare_gpt_backup(master, backup); 583*c29e5f0fSliuyi 584*c29e5f0fSliuyi } 585*c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup) 586*c29e5f0fSliuyi { 587*c29e5f0fSliuyi FILE *file = NULL; 588*c29e5f0fSliuyi file = fopen(pParamFile, "rb"); 589*c29e5f0fSliuyi if( !file ) { 590*c29e5f0fSliuyi if (g_pLogObject) 591*c29e5f0fSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 592*c29e5f0fSliuyi return false; 593*c29e5f0fSliuyi } 594*c29e5f0fSliuyi int iFileSize; 595*c29e5f0fSliuyi fseek(file, 0, SEEK_END); 596*c29e5f0fSliuyi iFileSize = ftell(file); 597*c29e5f0fSliuyi fseek(file, 0, SEEK_SET); 598*c29e5f0fSliuyi if (iFileSize != 67 * SECTOR_SIZE) { 599*c29e5f0fSliuyi if (g_pLogObject) 600*c29e5f0fSliuyi g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile); 601*c29e5f0fSliuyi fclose(file); 602*c29e5f0fSliuyi return false; 603*c29e5f0fSliuyi } 604*c29e5f0fSliuyi 605*c29e5f0fSliuyi int iRead; 606*c29e5f0fSliuyi iRead = fread(master, 1, 34 * SECTOR_SIZE, file); 607*c29e5f0fSliuyi if (iRead != 34 * SECTOR_SIZE) { 608*c29e5f0fSliuyi if (g_pLogObject) 609*c29e5f0fSliuyi g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE); 610*c29e5f0fSliuyi fclose(file); 611*c29e5f0fSliuyi return false; 612*c29e5f0fSliuyi } 613*c29e5f0fSliuyi iRead = fread(backup, 1, 33 * SECTOR_SIZE, file); 614*c29e5f0fSliuyi if (iRead != 33 * SECTOR_SIZE) { 615*c29e5f0fSliuyi if (g_pLogObject) 616*c29e5f0fSliuyi g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE); 617*c29e5f0fSliuyi fclose(file); 618*c29e5f0fSliuyi return false; 619*c29e5f0fSliuyi } 620*c29e5f0fSliuyi fclose(file); 621*c29e5f0fSliuyi return true; 622*c29e5f0fSliuyi } 623*c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors) 624c30d921cSKever Yang { 625c30d921cSKever Yang legacy_mbr *mbr = (legacy_mbr *)gpt; 626c30d921cSKever Yang gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 627c30d921cSKever Yang gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 628c30d921cSKever Yang u32 i,j; 629*c29e5f0fSliuyi int pos; 630c30d921cSKever Yang string strPartName; 631c30d921cSKever Yang string::size_type colonPos; 632c30d921cSKever Yang /*1.protective mbr*/ 633c30d921cSKever Yang memset(gpt, 0, SECTOR_SIZE); 634c30d921cSKever Yang mbr->signature = MSDOS_MBR_SIGNATURE; 635c30d921cSKever Yang mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 636c30d921cSKever Yang mbr->partition_record[0].start_sect = 1; 637c30d921cSKever Yang mbr->partition_record[0].nr_sects = (u32)-1; 638c30d921cSKever Yang /*2.gpt header*/ 639c30d921cSKever Yang memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 640c30d921cSKever Yang gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 641c30d921cSKever Yang gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 642c30d921cSKever Yang gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 643c30d921cSKever Yang gptHead->my_lba = cpu_to_le64(1); 644c30d921cSKever Yang gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 645c30d921cSKever Yang gptHead->first_usable_lba = cpu_to_le64(34); 646c30d921cSKever Yang gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 647c30d921cSKever Yang gptHead->partition_entry_lba = cpu_to_le64(2); 648c30d921cSKever Yang gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 649c30d921cSKever Yang gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 650c30d921cSKever Yang gptHead->header_crc32 = 0; 651c30d921cSKever Yang gptHead->partition_entry_array_crc32 = 0; 652c30d921cSKever Yang gen_rand_uuid(gptHead->disk_guid.raw); 653c30d921cSKever Yang 654c30d921cSKever Yang /*3.gpt partition entry*/ 655c30d921cSKever Yang memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 656c30d921cSKever Yang for (i = 0; i < vecParts.size(); i++) { 657c30d921cSKever Yang gen_rand_uuid(gptEntry->partition_type_guid.raw); 658c30d921cSKever Yang gen_rand_uuid(gptEntry->unique_partition_guid.raw); 659c30d921cSKever Yang gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 660c30d921cSKever Yang gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 661c30d921cSKever Yang gptEntry->attributes.raw = 0; 662c30d921cSKever Yang strPartName = vecParts[i].szItemName; 663c30d921cSKever Yang colonPos = strPartName.find_first_of(':'); 664c30d921cSKever Yang if (colonPos != string::npos) { 665c30d921cSKever Yang if (strPartName.find("bootable") != string::npos) 666c30d921cSKever Yang gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 667*c29e5f0fSliuyi if (strPartName.find("grow") != string::npos) 668*c29e5f0fSliuyi gptEntry->ending_lba = cpu_to_le64(diskSectors - 34); 669c30d921cSKever Yang strPartName = strPartName.substr(0, colonPos); 670c30d921cSKever Yang vecParts[i].szItemName[strPartName.size()] = 0; 671c30d921cSKever Yang } 672c30d921cSKever Yang for (j = 0; j < strlen(vecParts[i].szItemName); j++) 673c30d921cSKever Yang gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 674*c29e5f0fSliuyi if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1) 675*c29e5f0fSliuyi memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16); 676c30d921cSKever Yang gptEntry++; 677c30d921cSKever Yang } 678c30d921cSKever Yang 679c30d921cSKever Yang gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 680c30d921cSKever Yang gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 681c30d921cSKever Yang 682c30d921cSKever Yang } 683b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag) 684c30d921cSKever Yang { 685c30d921cSKever Yang PRK28_IDB_SEC0 pSec0; 686c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 687c30d921cSKever Yang pSec0 = (PRK28_IDB_SEC0)pSector; 688c30d921cSKever Yang 689c30d921cSKever Yang pSec0->dwTag = 0x0FF0AA55; 690b38fe5fcSliuyi pSec0->uiRc4Flag = rc4Flag; 691c30d921cSKever Yang pSec0->usBootCode1Offset = 0x4; 692c30d921cSKever Yang pSec0->usBootCode2Offset = 0x4; 693c30d921cSKever Yang pSec0->usBootDataSize = usFlashDataSec; 694c30d921cSKever Yang pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 695c30d921cSKever Yang return true; 696c30d921cSKever Yang } 697c30d921cSKever Yang 698c30d921cSKever Yang 699c30d921cSKever Yang bool MakeSector1(PBYTE pSector) 700c30d921cSKever Yang { 701c30d921cSKever Yang PRK28_IDB_SEC1 pSec1; 702c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 703c30d921cSKever Yang pSec1 = (PRK28_IDB_SEC1)pSector; 704c30d921cSKever Yang 705c30d921cSKever Yang pSec1->usSysReservedBlock = 0xC; 706c30d921cSKever Yang pSec1->usDisk0Size = 0xFFFF; 707c30d921cSKever Yang pSec1->uiChipTag = 0x38324B52; 708c30d921cSKever Yang return true; 709c30d921cSKever Yang } 710c30d921cSKever Yang 711c30d921cSKever Yang bool MakeSector2(PBYTE pSector) 712c30d921cSKever Yang { 713c30d921cSKever Yang PRK28_IDB_SEC2 pSec2; 714c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 715c30d921cSKever Yang pSec2 = (PRK28_IDB_SEC2)pSector; 716c30d921cSKever Yang 717c30d921cSKever Yang strcpy(pSec2->szVcTag, "VC"); 718c30d921cSKever Yang strcpy(pSec2->szCrcTag, "CRC"); 719c30d921cSKever Yang return true; 720c30d921cSKever Yang } 721c30d921cSKever Yang 722c30d921cSKever Yang bool MakeSector3(PBYTE pSector) 723c30d921cSKever Yang { 724c30d921cSKever Yang memset(pSector,0,SECTOR_SIZE); 725c30d921cSKever Yang return true; 726c30d921cSKever Yang } 727c30d921cSKever Yang 728b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag) 729c30d921cSKever Yang { 730c30d921cSKever Yang RK28_IDB_SEC0 sector0Info; 731c30d921cSKever Yang RK28_IDB_SEC1 sector1Info; 732c30d921cSKever Yang RK28_IDB_SEC2 sector2Info; 733c30d921cSKever Yang RK28_IDB_SEC3 sector3Info; 734c30d921cSKever Yang UINT i; 735b38fe5fcSliuyi MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag); 736c30d921cSKever Yang MakeSector1((PBYTE)§or1Info); 737c30d921cSKever Yang if (!MakeSector2((PBYTE)§or2Info)) { 738c30d921cSKever Yang return -6; 739c30d921cSKever Yang } 740c30d921cSKever Yang if (!MakeSector3((PBYTE)§or3Info)) { 741c30d921cSKever Yang return -7; 742c30d921cSKever Yang } 743c30d921cSKever Yang sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 744c30d921cSKever Yang sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 745c30d921cSKever Yang sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 746c30d921cSKever Yang 747c30d921cSKever Yang memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 748c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 749c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 750b38fe5fcSliuyi 751b38fe5fcSliuyi if (rc4Flag) { 752b38fe5fcSliuyi for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++) 753b38fe5fcSliuyi P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE); 754b38fe5fcSliuyi for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++) 755b38fe5fcSliuyi P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE); 756b38fe5fcSliuyi } 757b38fe5fcSliuyi 758c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 759c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 760c30d921cSKever Yang 761c30d921cSKever Yang sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 762c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 763c30d921cSKever Yang for(i = 0; i < 4; i++) { 764c30d921cSKever Yang if(i == 1) { 765c30d921cSKever Yang continue; 766c30d921cSKever Yang } else { 767c30d921cSKever Yang P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 768c30d921cSKever Yang } 769c30d921cSKever Yang } 770c30d921cSKever Yang return 0; 771c30d921cSKever Yang } 772c30d921cSKever Yang 773c30d921cSKever Yang 77476af099aSliuyi 77576af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 77676af099aSliuyi { 77776af099aSliuyi if ((dev.emUsbType & uiSupportType) == dev.emUsbType) 77876af099aSliuyi return true; 77976af099aSliuyi else 78076af099aSliuyi { 78176af099aSliuyi ERROR_COLOR_ATTR; 78232268622SAndreas Färber printf("The device does not support this operation!"); 78376af099aSliuyi NORMAL_COLOR_ATTR; 78476af099aSliuyi printf("\r\n"); 78576af099aSliuyi return false; 78676af099aSliuyi } 78776af099aSliuyi } 788c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 789c30d921cSKever Yang { 790c30d921cSKever Yang u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 791c30d921cSKever Yang u32 total_size_sector; 792c30d921cSKever Yang CRKComm *pComm = NULL; 793c30d921cSKever Yang PARAM_ITEM_VECTOR vecItems; 794*c29e5f0fSliuyi CONFIG_ITEM_VECTOR vecUuid; 795c30d921cSKever Yang int iRet; 796c30d921cSKever Yang bool bRet, bSuccess = false; 797c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 798c30d921cSKever Yang return false; 799c30d921cSKever Yang 800c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 801c30d921cSKever Yang if (!bRet) { 802c30d921cSKever Yang ERROR_COLOR_ATTR; 803c30d921cSKever Yang printf("Creating Comm Object failed!"); 804c30d921cSKever Yang NORMAL_COLOR_ATTR; 805c30d921cSKever Yang printf("\r\n"); 806c30d921cSKever Yang return bSuccess; 807c30d921cSKever Yang } 80832268622SAndreas Färber printf("Writing gpt...\r\n"); 809c30d921cSKever Yang //1.get flash info 810c30d921cSKever Yang iRet = pComm->RKU_ReadFlashInfo(flash_info); 811c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 812c30d921cSKever Yang ERROR_COLOR_ATTR; 813c30d921cSKever Yang printf("Reading Flash Info failed!"); 814c30d921cSKever Yang NORMAL_COLOR_ATTR; 815c30d921cSKever Yang printf("\r\n"); 816c30d921cSKever Yang return bSuccess; 817c30d921cSKever Yang } 818c30d921cSKever Yang total_size_sector = *(u32 *)flash_info; 819*c29e5f0fSliuyi if (strstr(szParameter, ".img")) { 820*c29e5f0fSliuyi if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) { 821*c29e5f0fSliuyi ERROR_COLOR_ATTR; 822*c29e5f0fSliuyi printf("Loading partition image failed!"); 823*c29e5f0fSliuyi NORMAL_COLOR_ATTR; 824*c29e5f0fSliuyi printf("\r\n"); 825*c29e5f0fSliuyi return bSuccess; 826*c29e5f0fSliuyi } 827*c29e5f0fSliuyi update_gpt_disksize(master_gpt, backup_gpt, total_size_sector); 828*c29e5f0fSliuyi } else { 829c30d921cSKever Yang //2.get partition from parameter 830*c29e5f0fSliuyi bRet = parse_parameter_file(szParameter, vecItems, vecUuid); 831c30d921cSKever Yang if (!bRet) { 832c30d921cSKever Yang ERROR_COLOR_ATTR; 833c30d921cSKever Yang printf("Parsing parameter failed!"); 834c30d921cSKever Yang NORMAL_COLOR_ATTR; 835c30d921cSKever Yang printf("\r\n"); 836c30d921cSKever Yang return bSuccess; 837c30d921cSKever Yang } 838*c29e5f0fSliuyi vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33; 839c30d921cSKever Yang //3.generate gpt info 840*c29e5f0fSliuyi create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector); 841c30d921cSKever Yang memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 842c30d921cSKever Yang memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 843*c29e5f0fSliuyi prepare_gpt_backup(master_gpt, backup_gpt); 844*c29e5f0fSliuyi } 845*c29e5f0fSliuyi 846c30d921cSKever Yang //4. write gpt 847c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 848c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 849c30d921cSKever Yang ERROR_COLOR_ATTR; 850c30d921cSKever Yang printf("Writing master gpt failed!"); 851c30d921cSKever Yang NORMAL_COLOR_ATTR; 852c30d921cSKever Yang printf("\r\n"); 853c30d921cSKever Yang return bSuccess; 854c30d921cSKever Yang } 855*c29e5f0fSliuyi iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt); 856c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 857c30d921cSKever Yang ERROR_COLOR_ATTR; 858c30d921cSKever Yang printf("Writing backup gpt failed!"); 859c30d921cSKever Yang NORMAL_COLOR_ATTR; 860c30d921cSKever Yang printf("\r\n"); 861c30d921cSKever Yang return bSuccess; 862c30d921cSKever Yang } 863*c29e5f0fSliuyi 864c30d921cSKever Yang bSuccess = true; 865c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 866c30d921cSKever Yang CURSOR_DEL_LINE; 86732268622SAndreas Färber printf("Writing gpt succeeded.\r\n"); 868c30d921cSKever Yang return bSuccess; 869c30d921cSKever Yang } 87076af099aSliuyi 87178884ef4SEddie Cai #include "boot_merger.h" 87278884ef4SEddie Cai #define ENTRY_ALIGN (2048) 87378884ef4SEddie Cai options gOpts; 87478884ef4SEddie Cai 87578884ef4SEddie Cai 87678884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 87778884ef4SEddie Cai char* gConfigPath; 87878884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE]; 87978884ef4SEddie Cai 88078884ef4SEddie Cai static inline void fixPath(char* path) { 88178884ef4SEddie Cai int i, len = strlen(path); 88278884ef4SEddie Cai for(i=0; i<len; i++) { 88378884ef4SEddie Cai if (path[i] == '\\') 88478884ef4SEddie Cai path[i] = '/'; 88578884ef4SEddie Cai else if (path[i] == '\r' || path[i] == '\n') 88678884ef4SEddie Cai path[i] = '\0'; 88778884ef4SEddie Cai } 88878884ef4SEddie Cai } 88978884ef4SEddie Cai 89078884ef4SEddie Cai static bool parseChip(FILE* file) { 89178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 89278884ef4SEddie Cai return false; 89378884ef4SEddie Cai } 89478884ef4SEddie Cai if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 89578884ef4SEddie Cai return false; 89678884ef4SEddie Cai } 89778884ef4SEddie Cai printf("chip: %s\n", gOpts.chip); 89878884ef4SEddie Cai return true; 89978884ef4SEddie Cai } 90078884ef4SEddie Cai 90178884ef4SEddie Cai static bool parseVersion(FILE* file) { 90278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 90378884ef4SEddie Cai return false; 90478884ef4SEddie Cai } 90578884ef4SEddie Cai if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 90678884ef4SEddie Cai return false; 90778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 90878884ef4SEddie Cai return false; 90978884ef4SEddie Cai } 91078884ef4SEddie Cai if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 91178884ef4SEddie Cai return false; 91278884ef4SEddie Cai printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor); 91378884ef4SEddie Cai return true; 91478884ef4SEddie Cai } 91578884ef4SEddie Cai 91678884ef4SEddie Cai static bool parse471(FILE* file) { 91778884ef4SEddie Cai int i, index, pos; 91878884ef4SEddie Cai char buf[MAX_LINE_LEN]; 91978884ef4SEddie Cai 92078884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 92178884ef4SEddie Cai return false; 92278884ef4SEddie Cai } 92378884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 92478884ef4SEddie Cai return false; 92578884ef4SEddie Cai printf("num: %d\n", gOpts.code471Num); 92678884ef4SEddie Cai if (!gOpts.code471Num) 92778884ef4SEddie Cai return true; 92878884ef4SEddie Cai if (gOpts.code471Num < 0) 92978884ef4SEddie Cai return false; 93078884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 93178884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 93278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 93378884ef4SEddie Cai return false; 93478884ef4SEddie Cai } 93578884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 93678884ef4SEddie Cai != 2) 93778884ef4SEddie Cai return false; 93878884ef4SEddie Cai index--; 93978884ef4SEddie Cai fixPath(buf); 94078884ef4SEddie Cai strcpy((char*)gOpts.code471Path[index], buf); 94178884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code471Path[index]); 94278884ef4SEddie Cai } 94378884ef4SEddie Cai pos = ftell(file); 94478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 94578884ef4SEddie Cai return false; 94678884ef4SEddie Cai } 94778884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 94878884ef4SEddie Cai fseek(file, pos, SEEK_SET); 94978884ef4SEddie Cai printf("sleep: %d\n", gOpts.code471Sleep); 95078884ef4SEddie Cai return true; 95178884ef4SEddie Cai } 95278884ef4SEddie Cai 95378884ef4SEddie Cai static bool parse472(FILE* file) { 95478884ef4SEddie Cai int i, index, pos; 95578884ef4SEddie Cai char buf[MAX_LINE_LEN]; 95678884ef4SEddie Cai 95778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 95878884ef4SEddie Cai return false; 95978884ef4SEddie Cai } 96078884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 96178884ef4SEddie Cai return false; 96278884ef4SEddie Cai printf("num: %d\n", gOpts.code472Num); 96378884ef4SEddie Cai if (!gOpts.code472Num) 96478884ef4SEddie Cai return true; 96578884ef4SEddie Cai if (gOpts.code472Num < 0) 96678884ef4SEddie Cai return false; 96778884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 96878884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 96978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 97078884ef4SEddie Cai return false; 97178884ef4SEddie Cai } 97278884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 97378884ef4SEddie Cai != 2) 97478884ef4SEddie Cai return false; 97578884ef4SEddie Cai fixPath(buf); 97678884ef4SEddie Cai index--; 97778884ef4SEddie Cai strcpy((char*)gOpts.code472Path[index], buf); 97878884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code472Path[index]); 97978884ef4SEddie Cai } 98078884ef4SEddie Cai pos = ftell(file); 98178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 98278884ef4SEddie Cai return false; 98378884ef4SEddie Cai } 98478884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 98578884ef4SEddie Cai fseek(file, pos, SEEK_SET); 98678884ef4SEddie Cai printf("sleep: %d\n", gOpts.code472Sleep); 98778884ef4SEddie Cai return true; 98878884ef4SEddie Cai } 98978884ef4SEddie Cai 99078884ef4SEddie Cai static bool parseLoader(FILE* file) { 99178884ef4SEddie Cai int i, j, index, pos; 99278884ef4SEddie Cai char buf[MAX_LINE_LEN]; 99378884ef4SEddie Cai char buf2[MAX_LINE_LEN]; 99478884ef4SEddie Cai 99578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 99678884ef4SEddie Cai return false; 99778884ef4SEddie Cai } 99878884ef4SEddie Cai pos = ftell(file); 99978884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 100078884ef4SEddie Cai fseek(file, pos, SEEK_SET); 100178884ef4SEddie Cai if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 100278884ef4SEddie Cai return false; 100378884ef4SEddie Cai } 100478884ef4SEddie Cai } 100578884ef4SEddie Cai printf("num: %d\n", gOpts.loaderNum); 100678884ef4SEddie Cai if (!gOpts.loaderNum) 100778884ef4SEddie Cai return false; 100878884ef4SEddie Cai if (gOpts.loaderNum < 0) 100978884ef4SEddie Cai return false; 101078884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 101178884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 101278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 101378884ef4SEddie Cai return false; 101478884ef4SEddie Cai } 101578884ef4SEddie Cai if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 101678884ef4SEddie Cai != 2) 101778884ef4SEddie Cai return false; 101878884ef4SEddie Cai index--; 101978884ef4SEddie Cai strcpy(gOpts.loader[index].name, buf); 102078884ef4SEddie Cai printf("name%d: %s\n", index, gOpts.loader[index].name); 102178884ef4SEddie Cai } 102278884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 102378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 102478884ef4SEddie Cai return false; 102578884ef4SEddie Cai } 102678884ef4SEddie Cai if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 102778884ef4SEddie Cai != 2) 102878884ef4SEddie Cai return false; 102978884ef4SEddie Cai for (j=0; j<gOpts.loaderNum; j++) { 103078884ef4SEddie Cai if (!strcmp(gOpts.loader[j].name, buf)) { 103178884ef4SEddie Cai fixPath(buf2); 103278884ef4SEddie Cai strcpy(gOpts.loader[j].path, buf2); 103378884ef4SEddie Cai printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 103478884ef4SEddie Cai break; 103578884ef4SEddie Cai } 103678884ef4SEddie Cai } 103778884ef4SEddie Cai if (j >= gOpts.loaderNum) { 103878884ef4SEddie Cai return false; 103978884ef4SEddie Cai } 104078884ef4SEddie Cai } 104178884ef4SEddie Cai return true; 104278884ef4SEddie Cai } 104378884ef4SEddie Cai 104478884ef4SEddie Cai static bool parseOut(FILE* file) { 104578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 104678884ef4SEddie Cai return false; 104778884ef4SEddie Cai } 104878884ef4SEddie Cai if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 104978884ef4SEddie Cai return false; 105078884ef4SEddie Cai fixPath(gOpts.outPath); 105178884ef4SEddie Cai printf("out: %s\n", gOpts.outPath); 105278884ef4SEddie Cai return true; 105378884ef4SEddie Cai } 105478884ef4SEddie Cai 105578884ef4SEddie Cai 105678884ef4SEddie Cai void printOpts(FILE* out) { 105778884ef4SEddie Cai int i; 105878884ef4SEddie Cai fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 105978884ef4SEddie Cai fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 106078884ef4SEddie Cai "=%d\n", gOpts.major, gOpts.minor); 106178884ef4SEddie Cai 106278884ef4SEddie Cai fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 106378884ef4SEddie Cai for (i=0 ;i<gOpts.code471Num ;i++) { 106478884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 106578884ef4SEddie Cai } 106678884ef4SEddie Cai if (gOpts.code471Sleep > 0) 106778884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 106878884ef4SEddie Cai 106978884ef4SEddie Cai fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 107078884ef4SEddie Cai for (i=0 ;i<gOpts.code472Num ;i++) { 107178884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 107278884ef4SEddie Cai } 107378884ef4SEddie Cai if (gOpts.code472Sleep > 0) 107478884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 107578884ef4SEddie Cai 107678884ef4SEddie Cai fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 107778884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 107878884ef4SEddie Cai fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 107978884ef4SEddie Cai } 108078884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 108178884ef4SEddie Cai fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 108278884ef4SEddie Cai } 108378884ef4SEddie Cai 108478884ef4SEddie Cai fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 108578884ef4SEddie Cai } 108678884ef4SEddie Cai 108778884ef4SEddie Cai static bool parseOpts(void) { 108878884ef4SEddie Cai bool ret = false; 108978884ef4SEddie Cai bool chipOk = false; 109078884ef4SEddie Cai bool versionOk = false; 109178884ef4SEddie Cai bool code471Ok = true; 109278884ef4SEddie Cai bool code472Ok = true; 109378884ef4SEddie Cai bool loaderOk = false; 109478884ef4SEddie Cai bool outOk = false; 109578884ef4SEddie Cai char buf[MAX_LINE_LEN]; 109678884ef4SEddie Cai 109778884ef4SEddie Cai char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 109878884ef4SEddie Cai FILE* file; 109978884ef4SEddie Cai file = fopen(configPath, "r"); 110078884ef4SEddie Cai if (!file) { 110178884ef4SEddie Cai fprintf(stderr, "config (%s) not found!\n", configPath); 110278884ef4SEddie Cai if (configPath == (char*)DEF_CONFIG_FILE) { 110378884ef4SEddie Cai file = fopen(DEF_CONFIG_FILE, "w"); 110478884ef4SEddie Cai if (file) { 110532268622SAndreas Färber fprintf(stderr, "creating defconfig\n"); 110678884ef4SEddie Cai printOpts(file); 110778884ef4SEddie Cai } 110878884ef4SEddie Cai } 110978884ef4SEddie Cai goto end; 111078884ef4SEddie Cai } 111178884ef4SEddie Cai 111232268622SAndreas Färber printf("Starting to parse...\n"); 111378884ef4SEddie Cai 111478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 111578884ef4SEddie Cai goto end; 111678884ef4SEddie Cai } 111778884ef4SEddie Cai while(fscanf(file, "%s", buf) == 1) { 111878884ef4SEddie Cai if (!strcmp(buf, SEC_CHIP)) { 111978884ef4SEddie Cai chipOk = parseChip(file); 112078884ef4SEddie Cai if (!chipOk) { 112178884ef4SEddie Cai printf("parseChip failed!\n"); 112278884ef4SEddie Cai goto end; 112378884ef4SEddie Cai } 112478884ef4SEddie Cai } else if (!strcmp(buf, SEC_VERSION)) { 112578884ef4SEddie Cai versionOk = parseVersion(file); 112678884ef4SEddie Cai if (!versionOk) { 112778884ef4SEddie Cai printf("parseVersion failed!\n"); 112878884ef4SEddie Cai goto end; 112978884ef4SEddie Cai } 113078884ef4SEddie Cai } else if (!strcmp(buf, SEC_471)) { 113178884ef4SEddie Cai code471Ok = parse471(file); 113278884ef4SEddie Cai if (!code471Ok) { 113378884ef4SEddie Cai printf("parse471 failed!\n"); 113478884ef4SEddie Cai goto end; 113578884ef4SEddie Cai } 113678884ef4SEddie Cai } else if (!strcmp(buf, SEC_472)) { 113778884ef4SEddie Cai code472Ok = parse472(file); 113878884ef4SEddie Cai if (!code472Ok) { 113978884ef4SEddie Cai printf("parse472 failed!\n"); 114078884ef4SEddie Cai goto end; 114178884ef4SEddie Cai } 114278884ef4SEddie Cai } else if (!strcmp(buf, SEC_LOADER)) { 114378884ef4SEddie Cai loaderOk = parseLoader(file); 114478884ef4SEddie Cai if (!loaderOk) { 114578884ef4SEddie Cai printf("parseLoader failed!\n"); 114678884ef4SEddie Cai goto end; 114778884ef4SEddie Cai } 114878884ef4SEddie Cai } else if (!strcmp(buf, SEC_OUT)) { 114978884ef4SEddie Cai outOk = parseOut(file); 115078884ef4SEddie Cai if (!outOk) { 115178884ef4SEddie Cai printf("parseOut failed!\n"); 115278884ef4SEddie Cai goto end; 115378884ef4SEddie Cai } 115478884ef4SEddie Cai } else if (buf[0] == '#') { 115578884ef4SEddie Cai continue; 115678884ef4SEddie Cai } else { 115778884ef4SEddie Cai printf("unknown sec: %s!\n", buf); 115878884ef4SEddie Cai goto end; 115978884ef4SEddie Cai } 116078884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 116178884ef4SEddie Cai goto end; 116278884ef4SEddie Cai } 116378884ef4SEddie Cai } 116478884ef4SEddie Cai 116578884ef4SEddie Cai if (chipOk && versionOk && code471Ok && code472Ok 116678884ef4SEddie Cai && loaderOk && outOk) 116778884ef4SEddie Cai ret = true; 116878884ef4SEddie Cai end: 116978884ef4SEddie Cai if (file) 117078884ef4SEddie Cai fclose(file); 117178884ef4SEddie Cai return ret; 117278884ef4SEddie Cai } 117378884ef4SEddie Cai 117478884ef4SEddie Cai bool initOpts(void) { 117578884ef4SEddie Cai //set default opts 117678884ef4SEddie Cai gOpts.major = DEF_MAJOR; 117778884ef4SEddie Cai gOpts.minor = DEF_MINOR; 117878884ef4SEddie Cai strcpy(gOpts.chip, DEF_CHIP); 117978884ef4SEddie Cai gOpts.code471Sleep = DEF_CODE471_SLEEP; 118078884ef4SEddie Cai gOpts.code472Sleep = DEF_CODE472_SLEEP; 118178884ef4SEddie Cai gOpts.code471Num = DEF_CODE471_NUM; 118278884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 118378884ef4SEddie Cai strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 118478884ef4SEddie Cai gOpts.code472Num = DEF_CODE472_NUM; 118578884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 118678884ef4SEddie Cai strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 118778884ef4SEddie Cai gOpts.loaderNum = DEF_LOADER_NUM; 118878884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 118978884ef4SEddie Cai strcpy(gOpts.loader[0].name, DEF_LOADER0); 119078884ef4SEddie Cai strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 119178884ef4SEddie Cai strcpy(gOpts.loader[1].name, DEF_LOADER1); 119278884ef4SEddie Cai strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 119378884ef4SEddie Cai strcpy(gOpts.outPath, DEF_OUT_PATH); 119478884ef4SEddie Cai 119578884ef4SEddie Cai return parseOpts(); 119678884ef4SEddie Cai } 119778884ef4SEddie Cai 119878884ef4SEddie Cai /************merge code****************/ 119978884ef4SEddie Cai 120078884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) { 120178884ef4SEddie Cai uint8_t tmp[2] = {0}; 120278884ef4SEddie Cai int i; 120378884ef4SEddie Cai uint32_t ret; 120478884ef4SEddie Cai //if (value > 0xFFFF) { 120578884ef4SEddie Cai // return 0; 120678884ef4SEddie Cai //} 120778884ef4SEddie Cai for(i=0; i < 2; i++) { 120878884ef4SEddie Cai tmp[i] = (((value/10)%10)<<4) | (value%10); 120978884ef4SEddie Cai value /= 100; 121078884ef4SEddie Cai } 121178884ef4SEddie Cai ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 121278884ef4SEddie Cai 121378884ef4SEddie Cai printf("ret: %x\n",ret); 121478884ef4SEddie Cai return ret&0xFF; 121578884ef4SEddie Cai } 121678884ef4SEddie Cai 121778884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len) 121878884ef4SEddie Cai { 121978884ef4SEddie Cai int i; 122078884ef4SEddie Cai for (i = 0; i < len; i++) { 122178884ef4SEddie Cai wide[i] = (uint16_t) str[i]; 122278884ef4SEddie Cai } 122378884ef4SEddie Cai wide[len] = 0; 122478884ef4SEddie Cai } 122578884ef4SEddie Cai 122678884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) { 122778884ef4SEddie Cai char* end; 122878884ef4SEddie Cai char* start; 122978884ef4SEddie Cai int len; 123078884ef4SEddie Cai if (!path || !dst) 123178884ef4SEddie Cai return; 123278884ef4SEddie Cai start = strrchr(path, '/'); 123378884ef4SEddie Cai if (!start) 123478884ef4SEddie Cai start = path; 123578884ef4SEddie Cai else 123678884ef4SEddie Cai start++; 123778884ef4SEddie Cai end = strrchr(path, '.'); 1238641cfa16SEddie Cai if (!end || (end < start)) 123978884ef4SEddie Cai end = path + strlen(path); 124078884ef4SEddie Cai len = end - start; 124178884ef4SEddie Cai if (len >= MAX_NAME_LEN) 124278884ef4SEddie Cai len = MAX_NAME_LEN -1; 124378884ef4SEddie Cai str2wide(start, dst, len); 124478884ef4SEddie Cai 124578884ef4SEddie Cai 124678884ef4SEddie Cai char name[MAX_NAME_LEN]; 124778884ef4SEddie Cai memset(name, 0, sizeof(name)); 124878884ef4SEddie Cai memcpy(name, start, len); 124978884ef4SEddie Cai printf("path: %s, name: %s\n", path, name); 125078884ef4SEddie Cai 125178884ef4SEddie Cai } 125278884ef4SEddie Cai 125378884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) { 125478884ef4SEddie Cai struct stat st; 125578884ef4SEddie Cai if(stat(path, &st) < 0) 125678884ef4SEddie Cai return false; 125778884ef4SEddie Cai *size = st.st_size; 125878884ef4SEddie Cai printf("path: %s, size: %d\n", path, *size); 125978884ef4SEddie Cai return true; 126078884ef4SEddie Cai } 126178884ef4SEddie Cai 126278884ef4SEddie Cai static inline rk_time getTime(void) { 126378884ef4SEddie Cai rk_time rkTime; 126478884ef4SEddie Cai 126578884ef4SEddie Cai struct tm *tm; 126678884ef4SEddie Cai time_t tt = time(NULL); 126778884ef4SEddie Cai tm = localtime(&tt); 126878884ef4SEddie Cai rkTime.year = tm->tm_year + 1900; 126978884ef4SEddie Cai rkTime.month = tm->tm_mon + 1; 127078884ef4SEddie Cai rkTime.day = tm->tm_mday; 127178884ef4SEddie Cai rkTime.hour = tm->tm_hour; 127278884ef4SEddie Cai rkTime.minute = tm->tm_min; 127378884ef4SEddie Cai rkTime.second = tm->tm_sec; 127478884ef4SEddie Cai printf("%d-%d-%d %02d:%02d:%02d\n", 127578884ef4SEddie Cai rkTime.year, rkTime.month, rkTime.day, 127678884ef4SEddie Cai rkTime.hour, rkTime.minute, rkTime.second); 127778884ef4SEddie Cai return rkTime; 127878884ef4SEddie Cai } 127978884ef4SEddie Cai 128078884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) { 128178884ef4SEddie Cai bool ret = false; 128278884ef4SEddie Cai uint32_t size = 0, fixSize = 0; 128378884ef4SEddie Cai uint8_t* buf; 128478884ef4SEddie Cai 128578884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 128678884ef4SEddie Cai if (!inFile) 128778884ef4SEddie Cai goto end; 128878884ef4SEddie Cai 128978884ef4SEddie Cai if (!getFileSize(path, &size)) 129078884ef4SEddie Cai goto end; 129178884ef4SEddie Cai if (fix) { 129278884ef4SEddie Cai fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 129378884ef4SEddie Cai uint32_t tmp = fixSize % ENTRY_ALIGN; 129478884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 129578884ef4SEddie Cai fixSize +=tmp; 129678884ef4SEddie Cai memset(gBuf, 0, fixSize); 129778884ef4SEddie Cai } else { 129878884ef4SEddie Cai memset(gBuf, 0, size+ENTRY_ALIGN); 129978884ef4SEddie Cai } 130078884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 130178884ef4SEddie Cai goto end; 130278884ef4SEddie Cai 130378884ef4SEddie Cai if (fix) { 130478884ef4SEddie Cai 130578884ef4SEddie Cai buf = gBuf; 130678884ef4SEddie Cai size = fixSize; 130778884ef4SEddie Cai while(1) { 130878884ef4SEddie Cai P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 130978884ef4SEddie Cai buf += SMALL_PACKET; 131078884ef4SEddie Cai if (fixSize <= SMALL_PACKET) 131178884ef4SEddie Cai break; 131278884ef4SEddie Cai fixSize -= SMALL_PACKET; 131378884ef4SEddie Cai } 131478884ef4SEddie Cai } else { 131578884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 131678884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 131778884ef4SEddie Cai size +=tmp; 131878884ef4SEddie Cai P_RC4(gBuf, size); 131978884ef4SEddie Cai } 132078884ef4SEddie Cai 132178884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 132278884ef4SEddie Cai goto end; 132378884ef4SEddie Cai ret = true; 132478884ef4SEddie Cai end: 132578884ef4SEddie Cai if (inFile) 132678884ef4SEddie Cai fclose(inFile); 132778884ef4SEddie Cai if (!ret) 132832268622SAndreas Färber printf("writing entry (%s) failed\n", path); 132978884ef4SEddie Cai return ret; 133078884ef4SEddie Cai } 133178884ef4SEddie Cai 133278884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 133378884ef4SEddie Cai uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 133478884ef4SEddie Cai uint32_t size; 133578884ef4SEddie Cai rk_boot_entry entry; 133678884ef4SEddie Cai 133732268622SAndreas Färber printf("writing: %s\n", path); 1338641cfa16SEddie Cai memset(&entry, 0, sizeof(rk_boot_entry)); 133978884ef4SEddie Cai getName(fixName ? fixName: path, entry.name); 134078884ef4SEddie Cai entry.size = sizeof(rk_boot_entry); 134178884ef4SEddie Cai entry.type = type; 134278884ef4SEddie Cai entry.dataOffset = *offset; 134378884ef4SEddie Cai if (!getFileSize(path, &size)) { 134432268622SAndreas Färber printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path); 134578884ef4SEddie Cai return false; 134678884ef4SEddie Cai } 134778884ef4SEddie Cai if (fix) 134878884ef4SEddie Cai size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 134978884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 135078884ef4SEddie Cai size += tmp ? (ENTRY_ALIGN - tmp): 0; 135132268622SAndreas Färber printf("alignment size: %d\n", size); 135278884ef4SEddie Cai entry.dataSize = size; 135378884ef4SEddie Cai entry.dataDelay = delay; 135478884ef4SEddie Cai *offset += size; 135578884ef4SEddie Cai fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 135678884ef4SEddie Cai return true; 135778884ef4SEddie Cai } 135878884ef4SEddie Cai 135978884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) { 136078884ef4SEddie Cai char buffer[5]; 136178884ef4SEddie Cai memset(buffer, 0, sizeof(buffer)); 136278884ef4SEddie Cai snprintf(buffer, sizeof(buffer), "%s", chip); 136378884ef4SEddie Cai return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 136478884ef4SEddie Cai } 136578884ef4SEddie Cai 136678884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) { 136778884ef4SEddie Cai printf("chip: %s\n", chip); 136878884ef4SEddie Cai int chipType = RKNONE_DEVICE; 136978884ef4SEddie Cai if(!chip) { 137078884ef4SEddie Cai goto end; 137178884ef4SEddie Cai } 137278884ef4SEddie Cai if (!strcmp(chip, CHIP_RK28)) { 137378884ef4SEddie Cai chipType = RK28_DEVICE; 137478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK28)) { 137578884ef4SEddie Cai chipType = RK28_DEVICE; 137678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK281X)) { 137778884ef4SEddie Cai chipType = RK281X_DEVICE; 137878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKPANDA)) { 137978884ef4SEddie Cai chipType = RKPANDA_DEVICE; 138078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK27)) { 138178884ef4SEddie Cai chipType = RK27_DEVICE; 138278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKNANO)) { 138378884ef4SEddie Cai chipType = RKNANO_DEVICE; 138478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKSMART)) { 138578884ef4SEddie Cai chipType = RKSMART_DEVICE; 138678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCROWN)) { 138778884ef4SEddie Cai chipType = RKCROWN_DEVICE; 138878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 138978884ef4SEddie Cai chipType = RKCAYMAN_DEVICE; 139078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK29)) { 139178884ef4SEddie Cai chipType = RK29_DEVICE; 139278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK292X)) { 139378884ef4SEddie Cai chipType = RK292X_DEVICE; 139478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30)) { 139578884ef4SEddie Cai chipType = RK30_DEVICE; 139678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30B)) { 139778884ef4SEddie Cai chipType = RK30B_DEVICE; 139878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK31)) { 139978884ef4SEddie Cai chipType = RK31_DEVICE; 140078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK32)) { 140178884ef4SEddie Cai chipType = RK32_DEVICE; 140278884ef4SEddie Cai } else { 140378884ef4SEddie Cai chipType = convertChipType(chip + 2); 140478884ef4SEddie Cai } 140578884ef4SEddie Cai 140678884ef4SEddie Cai end: 140778884ef4SEddie Cai printf("type: 0x%x\n", chipType); 140878884ef4SEddie Cai if (chipType == RKNONE_DEVICE) { 140932268622SAndreas Färber printf("chip type not supported!\n"); 141078884ef4SEddie Cai } 141178884ef4SEddie Cai return chipType; 141278884ef4SEddie Cai } 141378884ef4SEddie Cai 141478884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) { 141578884ef4SEddie Cai memset(hdr, 0, sizeof(rk_boot_header)); 141678884ef4SEddie Cai hdr->tag = TAG; 141778884ef4SEddie Cai hdr->size = sizeof(rk_boot_header); 141878884ef4SEddie Cai hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 141978884ef4SEddie Cai hdr->mergerVersion = MERGER_VERSION; 142078884ef4SEddie Cai hdr->releaseTime = getTime(); 142178884ef4SEddie Cai hdr->chipType = getChipType(gOpts.chip); 142278884ef4SEddie Cai 142378884ef4SEddie Cai hdr->code471Num = gOpts.code471Num; 142478884ef4SEddie Cai hdr->code471Offset = sizeof(rk_boot_header); 142578884ef4SEddie Cai hdr->code471Size = sizeof(rk_boot_entry); 142678884ef4SEddie Cai 142778884ef4SEddie Cai hdr->code472Num = gOpts.code472Num; 142878884ef4SEddie Cai hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 142978884ef4SEddie Cai hdr->code472Size = sizeof(rk_boot_entry); 143078884ef4SEddie Cai 143178884ef4SEddie Cai hdr->loaderNum = gOpts.loaderNum; 143278884ef4SEddie Cai hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 143378884ef4SEddie Cai hdr->loaderSize = sizeof(rk_boot_entry); 143478884ef4SEddie Cai #ifndef USE_P_RC4 143578884ef4SEddie Cai hdr->rc4Flag = 1; 143678884ef4SEddie Cai #endif 143778884ef4SEddie Cai } 143878884ef4SEddie Cai 143978884ef4SEddie Cai static inline uint32_t getCrc(const char* path) { 144078884ef4SEddie Cai uint32_t size = 0; 144178884ef4SEddie Cai uint32_t crc = 0; 144278884ef4SEddie Cai 144378884ef4SEddie Cai FILE* file = fopen(path, "rb"); 144478884ef4SEddie Cai getFileSize(path, &size); 144578884ef4SEddie Cai if (!file) 144678884ef4SEddie Cai goto end; 144778884ef4SEddie Cai if (!fread(gBuf, size, 1, file)) 144878884ef4SEddie Cai goto end; 144978884ef4SEddie Cai crc = CRC_32(gBuf, size); 145078884ef4SEddie Cai printf("crc: 0x%08x\n", crc); 145178884ef4SEddie Cai end: 145278884ef4SEddie Cai if (file) 145378884ef4SEddie Cai fclose(file); 145478884ef4SEddie Cai return crc; 145578884ef4SEddie Cai } 145678884ef4SEddie Cai 145778884ef4SEddie Cai bool mergeBoot(void) { 145878884ef4SEddie Cai uint32_t dataOffset; 145978884ef4SEddie Cai bool ret = false; 146078884ef4SEddie Cai int i; 146178884ef4SEddie Cai FILE* outFile; 146278884ef4SEddie Cai uint32_t crc; 146378884ef4SEddie Cai rk_boot_header hdr; 146478884ef4SEddie Cai 146578884ef4SEddie Cai if (!initOpts()) 146678884ef4SEddie Cai return false; 146778884ef4SEddie Cai { 146878884ef4SEddie Cai char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 146978884ef4SEddie Cai char version[MAX_LINE_LEN]; 147078884ef4SEddie Cai snprintf(version, sizeof(version), "%s", gSubfix); 147178884ef4SEddie Cai if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 147278884ef4SEddie Cai subfix[0] = '\0'; 147378884ef4SEddie Cai } 147478884ef4SEddie Cai strcat(gOpts.outPath, version); 147578884ef4SEddie Cai printf("fix opt: %s\n", gOpts.outPath); 147678884ef4SEddie Cai } 147778884ef4SEddie Cai 147878884ef4SEddie Cai printf("---------------\nUSING CONFIG:\n"); 147978884ef4SEddie Cai printOpts(stdout); 148078884ef4SEddie Cai printf("---------------\n\n"); 148178884ef4SEddie Cai 148278884ef4SEddie Cai 148378884ef4SEddie Cai outFile = fopen(gOpts.outPath, "wb+"); 148478884ef4SEddie Cai if (!outFile) { 148532268622SAndreas Färber printf("Opening output file (%s) failed\n", gOpts.outPath); 148678884ef4SEddie Cai goto end; 148778884ef4SEddie Cai } 148878884ef4SEddie Cai 148978884ef4SEddie Cai getBoothdr(&hdr); 149032268622SAndreas Färber printf("Writing header...\n"); 149178884ef4SEddie Cai fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 149278884ef4SEddie Cai 149378884ef4SEddie Cai dataOffset = sizeof(rk_boot_header) + 149478884ef4SEddie Cai (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 149578884ef4SEddie Cai sizeof(rk_boot_entry); 149678884ef4SEddie Cai 149732268622SAndreas Färber printf("Writing code 471 entry...\n"); 149878884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 149978884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 150078884ef4SEddie Cai &dataOffset, NULL, false)) 150178884ef4SEddie Cai goto end; 150278884ef4SEddie Cai } 150332268622SAndreas Färber printf("Writing code 472 entry...\n"); 150478884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 150578884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 150678884ef4SEddie Cai &dataOffset, NULL, false)) 150778884ef4SEddie Cai goto end; 150878884ef4SEddie Cai } 150932268622SAndreas Färber printf("Writing loader entry...\n"); 151078884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 151178884ef4SEddie Cai if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 151278884ef4SEddie Cai &dataOffset, gOpts.loader[i].name, true)) 151378884ef4SEddie Cai goto end; 151478884ef4SEddie Cai } 151578884ef4SEddie Cai 151632268622SAndreas Färber printf("Writing code 471...\n"); 151778884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 151878884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 151978884ef4SEddie Cai goto end; 152078884ef4SEddie Cai } 152132268622SAndreas Färber printf("Writing code 472...\n"); 152278884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 152378884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 152478884ef4SEddie Cai goto end; 152578884ef4SEddie Cai } 152632268622SAndreas Färber printf("Writing loader...\n"); 152778884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 152878884ef4SEddie Cai if (!writeFile(outFile, gOpts.loader[i].path, true)) 152978884ef4SEddie Cai goto end; 153078884ef4SEddie Cai } 153178884ef4SEddie Cai fflush(outFile); 153278884ef4SEddie Cai 153332268622SAndreas Färber printf("Writing crc...\n"); 153478884ef4SEddie Cai crc = getCrc(gOpts.outPath); 153578884ef4SEddie Cai if (!fwrite(&crc, sizeof(crc), 1, outFile)) 153678884ef4SEddie Cai goto end; 153732268622SAndreas Färber printf("Done.\n"); 153878884ef4SEddie Cai ret = true; 153978884ef4SEddie Cai end: 154078884ef4SEddie Cai if (outFile) 154178884ef4SEddie Cai fclose(outFile); 154278884ef4SEddie Cai return ret; 154378884ef4SEddie Cai } 154478884ef4SEddie Cai 154578884ef4SEddie Cai /************merge code end************/ 154678884ef4SEddie Cai /************unpack code***************/ 154778884ef4SEddie Cai 154878884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len) 154978884ef4SEddie Cai { 155078884ef4SEddie Cai int i; 155178884ef4SEddie Cai for (i = 0; i < len; i++) { 155278884ef4SEddie Cai str[i] = (char) (wide[i] & 0xFF); 155378884ef4SEddie Cai } 155478884ef4SEddie Cai str[len] = 0; 155578884ef4SEddie Cai } 155678884ef4SEddie Cai 155778884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name, 155878884ef4SEddie Cai FILE* inFile) { 155978884ef4SEddie Cai bool ret = false; 156078884ef4SEddie Cai int size, i; 156178884ef4SEddie Cai FILE* outFile = fopen(name, "wb+"); 156278884ef4SEddie Cai if (!outFile) 156378884ef4SEddie Cai goto end; 156432268622SAndreas Färber printf("unpacking entry (%s)\n", name); 156578884ef4SEddie Cai fseek(inFile, entry->dataOffset, SEEK_SET); 156678884ef4SEddie Cai size = entry->dataSize; 156778884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 156878884ef4SEddie Cai goto end; 156978884ef4SEddie Cai if (entry->type == ENTRY_LOADER) { 157078884ef4SEddie Cai for(i=0; i<size/SMALL_PACKET; i++) 157178884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 157278884ef4SEddie Cai if (size % SMALL_PACKET) 157378884ef4SEddie Cai { 157478884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 157578884ef4SEddie Cai } 157678884ef4SEddie Cai } else { 157778884ef4SEddie Cai P_RC4(gBuf, size); 157878884ef4SEddie Cai } 157978884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 158078884ef4SEddie Cai goto end; 158178884ef4SEddie Cai ret = true; 158278884ef4SEddie Cai end: 158378884ef4SEddie Cai if (outFile) 158478884ef4SEddie Cai fclose(outFile); 158578884ef4SEddie Cai return ret; 158678884ef4SEddie Cai } 158778884ef4SEddie Cai 158878884ef4SEddie Cai bool unpackBoot(char* path) { 158978884ef4SEddie Cai bool ret = false; 159078884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 159178884ef4SEddie Cai int entryNum, i; 159278884ef4SEddie Cai char name[MAX_NAME_LEN]; 159378884ef4SEddie Cai rk_boot_entry* entrys; 159478884ef4SEddie Cai if (!inFile) { 159578884ef4SEddie Cai fprintf(stderr, "loader (%s) not found\n", path); 159678884ef4SEddie Cai goto end; 159778884ef4SEddie Cai } 159878884ef4SEddie Cai 159978884ef4SEddie Cai rk_boot_header hdr; 160078884ef4SEddie Cai if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 160132268622SAndreas Färber fprintf(stderr, "reading header failed\n"); 160278884ef4SEddie Cai goto end; 160378884ef4SEddie Cai } 160478884ef4SEddie Cai printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 160578884ef4SEddie Cai entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 160678884ef4SEddie Cai entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 160778884ef4SEddie Cai if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 160832268622SAndreas Färber fprintf(stderr, "reading data failed\n"); 160978884ef4SEddie Cai goto end; 161078884ef4SEddie Cai } 161178884ef4SEddie Cai 161278884ef4SEddie Cai printf("entry num: %d\n", entryNum); 161378884ef4SEddie Cai for (i=0; i<entryNum; i++) { 161478884ef4SEddie Cai wide2str(entrys[i].name, name, MAX_NAME_LEN); 161578884ef4SEddie Cai 161678884ef4SEddie Cai printf("entry: t=%d, name=%s, off=%d, size=%d\n", 161778884ef4SEddie Cai entrys[i].type, name, entrys[i].dataOffset, 161878884ef4SEddie Cai entrys[i].dataSize); 161978884ef4SEddie Cai if (!unpackEntry(entrys + i, name, inFile)) { 162032268622SAndreas Färber fprintf(stderr, "unpacking entry (%s) failed\n", name); 162178884ef4SEddie Cai goto end; 162278884ef4SEddie Cai } 162378884ef4SEddie Cai } 162478884ef4SEddie Cai printf("done\n"); 162578884ef4SEddie Cai ret = true; 162678884ef4SEddie Cai end: 162778884ef4SEddie Cai if (inFile) 162878884ef4SEddie Cai fclose(inFile); 162978884ef4SEddie Cai return ret; 163078884ef4SEddie Cai } 163178884ef4SEddie Cai 163276af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 163376af099aSliuyi { 163476af099aSliuyi if (!check_device_type(dev, RKUSB_MASKROM)) 163576af099aSliuyi return false; 163676af099aSliuyi CRKImage *pImage = NULL; 163776af099aSliuyi CRKBoot *pBoot = NULL; 163876af099aSliuyi bool bRet, bSuccess = false; 163976af099aSliuyi int iRet; 164076af099aSliuyi 164176af099aSliuyi pImage = new CRKImage(szLoader, bRet); 164276af099aSliuyi if (!bRet){ 164376af099aSliuyi ERROR_COLOR_ATTR; 164432268622SAndreas Färber printf("Opening loader failed, exiting download boot!"); 164576af099aSliuyi NORMAL_COLOR_ATTR; 164676af099aSliuyi printf("\r\n"); 164776af099aSliuyi return bSuccess; 164876af099aSliuyi } else { 164976af099aSliuyi pBoot = (CRKBoot *)pImage->m_bootObject; 165076af099aSliuyi CRKComm *pComm = NULL; 165176af099aSliuyi CRKDevice *pDevice = NULL; 165276af099aSliuyi 165376af099aSliuyi dev.emDeviceType = pBoot->SupportDevice; 165476af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 165576af099aSliuyi if (!bRet) { 165676af099aSliuyi if (pImage) 165776af099aSliuyi delete pImage; 165876af099aSliuyi ERROR_COLOR_ATTR; 165976af099aSliuyi printf("Creating Comm Object failed!"); 166076af099aSliuyi NORMAL_COLOR_ATTR; 166176af099aSliuyi printf("\r\n"); 166276af099aSliuyi return bSuccess; 166376af099aSliuyi } 166476af099aSliuyi 166576af099aSliuyi pDevice = new CRKDevice(dev); 166676af099aSliuyi if (!pDevice) { 166776af099aSliuyi if (pImage) 166876af099aSliuyi delete pImage; 166976af099aSliuyi if (pComm) 167076af099aSliuyi delete pComm; 167176af099aSliuyi ERROR_COLOR_ATTR; 167276af099aSliuyi printf("Creating device object failed!"); 167376af099aSliuyi NORMAL_COLOR_ATTR; 167476af099aSliuyi printf("\r\n"); 167576af099aSliuyi return bSuccess; 167676af099aSliuyi } 167776af099aSliuyi 167876af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 167932268622SAndreas Färber printf("Downloading bootloader...\r\n"); 168076af099aSliuyi iRet = pDevice->DownloadBoot(); 168176af099aSliuyi 168276af099aSliuyi CURSOR_MOVEUP_LINE(1); 168376af099aSliuyi CURSOR_DEL_LINE; 168476af099aSliuyi if (iRet == 0) { 168576af099aSliuyi bSuccess = true; 168632268622SAndreas Färber printf("Downloading bootloader succeeded.\r\n"); 168776af099aSliuyi } 168876af099aSliuyi else 168932268622SAndreas Färber printf("Downloading bootloader failed!\r\n"); 169076af099aSliuyi 169176af099aSliuyi if (pImage) 169276af099aSliuyi delete pImage; 169376af099aSliuyi if(pDevice) 169476af099aSliuyi delete pDevice; 169576af099aSliuyi } 169676af099aSliuyi return bSuccess; 169776af099aSliuyi } 1698c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1699c30d921cSKever Yang { 1700c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 1701c30d921cSKever Yang return false; 1702c30d921cSKever Yang CRKImage *pImage = NULL; 1703c30d921cSKever Yang CRKBoot *pBoot = NULL; 1704c30d921cSKever Yang CRKComm *pComm = NULL; 1705c30d921cSKever Yang bool bRet, bSuccess = false; 1706c30d921cSKever Yang int iRet; 1707c30d921cSKever Yang char index; 1708c30d921cSKever Yang USHORT usFlashDataSec, usFlashBootSec; 1709c30d921cSKever Yang DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1710c30d921cSKever Yang char loaderCodeName[] = "FlashBoot"; 1711c30d921cSKever Yang char loaderDataName[] = "FlashData"; 1712c30d921cSKever Yang PBYTE loaderCodeBuffer = NULL; 1713c30d921cSKever Yang PBYTE loaderDataBuffer = NULL; 1714c30d921cSKever Yang PBYTE pIDBData = NULL; 1715c30d921cSKever Yang pImage = new CRKImage(szLoader, bRet); 1716c30d921cSKever Yang if (!bRet){ 1717c30d921cSKever Yang ERROR_COLOR_ATTR; 171832268622SAndreas Färber printf("Opening loader failed, exiting upgrade loader!"); 1719c30d921cSKever Yang NORMAL_COLOR_ATTR; 1720c30d921cSKever Yang printf("\r\n"); 1721c30d921cSKever Yang goto Exit_UpgradeLoader; 1722c30d921cSKever Yang } else { 1723c30d921cSKever Yang pBoot = (CRKBoot *)pImage->m_bootObject; 1724c30d921cSKever Yang dev.emDeviceType = pBoot->SupportDevice; 1725c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1726c30d921cSKever Yang if (!bRet) { 1727c30d921cSKever Yang ERROR_COLOR_ATTR; 1728c30d921cSKever Yang printf("Creating Comm Object failed!"); 1729c30d921cSKever Yang NORMAL_COLOR_ATTR; 1730c30d921cSKever Yang printf("\r\n"); 1731c30d921cSKever Yang goto Exit_UpgradeLoader; 1732c30d921cSKever Yang } 1733c30d921cSKever Yang 173432268622SAndreas Färber printf("Upgrading loader...\r\n"); 1735c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1736c30d921cSKever Yang if (index == -1) { 1737c30d921cSKever Yang if (g_pLogObject) { 173832268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__); 1739c30d921cSKever Yang } 1740c30d921cSKever Yang goto Exit_UpgradeLoader; 1741c30d921cSKever Yang } 1742c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1743c30d921cSKever Yang if (!bRet) { 1744c30d921cSKever Yang if (g_pLogObject) { 174532268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__); 1746c30d921cSKever Yang } 1747c30d921cSKever Yang goto Exit_UpgradeLoader; 1748c30d921cSKever Yang } 1749c30d921cSKever Yang 1750c30d921cSKever Yang loaderCodeBuffer = new BYTE[dwLoaderSize]; 1751c30d921cSKever Yang memset(loaderCodeBuffer, 0, dwLoaderSize); 1752c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1753c30d921cSKever Yang if (g_pLogObject) { 175432268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__); 1755c30d921cSKever Yang } 1756c30d921cSKever Yang goto Exit_UpgradeLoader; 1757c30d921cSKever Yang } 1758c30d921cSKever Yang 1759c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1760c30d921cSKever Yang if (index == -1) { 1761c30d921cSKever Yang if (g_pLogObject) { 176232268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__); 1763c30d921cSKever Yang } 1764c30d921cSKever Yang delete []loaderCodeBuffer; 1765c30d921cSKever Yang return -4; 1766c30d921cSKever Yang } 1767c30d921cSKever Yang 1768c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1769c30d921cSKever Yang if (!bRet) { 1770c30d921cSKever Yang if (g_pLogObject) { 177132268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__); 1772c30d921cSKever Yang } 1773c30d921cSKever Yang goto Exit_UpgradeLoader; 1774c30d921cSKever Yang } 1775c30d921cSKever Yang 1776c30d921cSKever Yang loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1777c30d921cSKever Yang memset(loaderDataBuffer, 0, dwLoaderDataSize); 1778c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1779c30d921cSKever Yang if (g_pLogObject) { 178032268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__); 1781c30d921cSKever Yang } 1782c30d921cSKever Yang goto Exit_UpgradeLoader; 1783c30d921cSKever Yang } 1784c30d921cSKever Yang 1785c30d921cSKever Yang usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1786c30d921cSKever Yang usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1787c30d921cSKever Yang dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1788c30d921cSKever Yang pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1789c30d921cSKever Yang if (!pIDBData) { 1790c30d921cSKever Yang ERROR_COLOR_ATTR; 179132268622SAndreas Färber printf("Allocating memory failed!"); 1792c30d921cSKever Yang NORMAL_COLOR_ATTR; 1793c30d921cSKever Yang printf("\r\n"); 1794c30d921cSKever Yang goto Exit_UpgradeLoader; 1795c30d921cSKever Yang } 1796c30d921cSKever Yang memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1797b38fe5fcSliuyi iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag); 1798c30d921cSKever Yang if (iRet != 0) { 1799c30d921cSKever Yang ERROR_COLOR_ATTR; 180032268622SAndreas Färber printf("Making idblock failed!"); 1801c30d921cSKever Yang NORMAL_COLOR_ATTR; 1802c30d921cSKever Yang printf("\r\n"); 1803c30d921cSKever Yang goto Exit_UpgradeLoader; 1804c30d921cSKever Yang } 1805c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1806c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 1807c30d921cSKever Yang CURSOR_DEL_LINE; 1808c30d921cSKever Yang if (iRet == ERR_SUCCESS) { 1809b38fe5fcSliuyi //pComm->Reset_Usb_Device(); 1810c30d921cSKever Yang bSuccess = true; 181132268622SAndreas Färber printf("Upgrading loader succeeded.\r\n"); 1812c30d921cSKever Yang } else { 181332268622SAndreas Färber printf("Upgrading loader failed!\r\n"); 1814c30d921cSKever Yang goto Exit_UpgradeLoader; 1815c30d921cSKever Yang } 1816c30d921cSKever Yang } 1817c30d921cSKever Yang Exit_UpgradeLoader: 1818c30d921cSKever Yang if (pImage) 1819c30d921cSKever Yang delete pImage; 1820c30d921cSKever Yang if (pComm) 1821c30d921cSKever Yang delete pComm; 1822c30d921cSKever Yang if (loaderCodeBuffer) 1823c30d921cSKever Yang delete []loaderCodeBuffer; 1824c30d921cSKever Yang if (loaderDataBuffer) 1825c30d921cSKever Yang delete []loaderDataBuffer; 1826c30d921cSKever Yang if (pIDBData) 1827c30d921cSKever Yang delete []pIDBData; 1828c30d921cSKever Yang return bSuccess; 1829c30d921cSKever Yang } 1830c30d921cSKever Yang 183176af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 183276af099aSliuyi { 183376af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 183476af099aSliuyi return false; 183576af099aSliuyi CRKImage *pImage = NULL; 183676af099aSliuyi bool bRet, bSuccess = false; 183776af099aSliuyi int iRet; 183876af099aSliuyi CRKScan *pScan = NULL; 183976af099aSliuyi pScan = new CRKScan(); 184076af099aSliuyi pScan->SetVidPid(); 184176af099aSliuyi 184276af099aSliuyi CRKComm *pComm = NULL; 184376af099aSliuyi CRKDevice *pDevice = NULL; 184476af099aSliuyi 184576af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 184676af099aSliuyi if (!bRet) { 184776af099aSliuyi if (pScan) 184876af099aSliuyi delete pScan; 184976af099aSliuyi ERROR_COLOR_ATTR; 185076af099aSliuyi printf("Creating Comm Object failed!"); 185176af099aSliuyi NORMAL_COLOR_ATTR; 185276af099aSliuyi printf("\r\n"); 185376af099aSliuyi return bSuccess; 185476af099aSliuyi } 185576af099aSliuyi 185676af099aSliuyi pDevice = new CRKDevice(dev); 185776af099aSliuyi if (!pDevice) { 185876af099aSliuyi if (pComm) 185976af099aSliuyi delete pComm; 186076af099aSliuyi if (pScan) 186176af099aSliuyi delete pScan; 186276af099aSliuyi ERROR_COLOR_ATTR; 186376af099aSliuyi printf("Creating device object failed!"); 186476af099aSliuyi NORMAL_COLOR_ATTR; 186576af099aSliuyi printf("\r\n"); 186676af099aSliuyi return bSuccess; 186776af099aSliuyi } 186876af099aSliuyi 186976af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 187076af099aSliuyi pDevice->CallBackPointer = ProgressInfoProc; 187176af099aSliuyi 187232268622SAndreas Färber printf("Starting to erase flash...\r\n"); 187376af099aSliuyi iRet = pDevice->EraseAllBlocks(); 187476af099aSliuyi if (pDevice) 187576af099aSliuyi delete pDevice; 187676af099aSliuyi 187776af099aSliuyi if (iRet == 0) { 187876af099aSliuyi if (pScan) { 187976af099aSliuyi pScan->SetVidPid(); 188076af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 188176af099aSliuyi delete pScan; 188276af099aSliuyi } 188376af099aSliuyi CURSOR_MOVEUP_LINE(1); 188476af099aSliuyi CURSOR_DEL_LINE; 188576af099aSliuyi bSuccess = true; 188632268622SAndreas Färber printf("Erasing flash complete.\r\n"); 188776af099aSliuyi } 188876af099aSliuyi 188976af099aSliuyi return bSuccess; 189076af099aSliuyi } 189176af099aSliuyi 189276af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev) 189376af099aSliuyi { 189476af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 189576af099aSliuyi return false; 189676af099aSliuyi CRKUsbComm *pComm = NULL; 189776af099aSliuyi bool bRet, bSuccess = false; 189876af099aSliuyi int iRet; 189976af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 190076af099aSliuyi if (bRet) { 190176af099aSliuyi iRet = pComm->RKU_TestDeviceReady(); 190276af099aSliuyi if (iRet != ERR_SUCCESS) { 190376af099aSliuyi if (g_pLogObject) 190476af099aSliuyi g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 190532268622SAndreas Färber printf("Test Device failed!\r\n"); 190676af099aSliuyi } else { 190776af099aSliuyi bSuccess = true; 190876af099aSliuyi printf("Test Device OK.\r\n"); 190976af099aSliuyi } 191076af099aSliuyi } else { 191132268622SAndreas Färber printf("Test Device quit, creating comm object failed!\r\n"); 191276af099aSliuyi } 191376af099aSliuyi if (pComm) { 191476af099aSliuyi delete pComm; 191576af099aSliuyi pComm = NULL; 191676af099aSliuyi } 191776af099aSliuyi return bSuccess; 191876af099aSliuyi } 191976af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 192076af099aSliuyi { 192176af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 192276af099aSliuyi return false; 192376af099aSliuyi CRKUsbComm *pComm = NULL; 192476af099aSliuyi bool bRet, bSuccess = false; 192576af099aSliuyi int iRet; 192676af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 192776af099aSliuyi if (bRet) { 192876af099aSliuyi iRet = pComm->RKU_ResetDevice(subCode); 192976af099aSliuyi if (iRet != ERR_SUCCESS) { 193076af099aSliuyi if (g_pLogObject) 193176af099aSliuyi g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 193232268622SAndreas Färber printf("Reset Device failed!\r\n"); 193376af099aSliuyi } else { 193476af099aSliuyi bSuccess = true; 193576af099aSliuyi printf("Reset Device OK.\r\n"); 193676af099aSliuyi } 193776af099aSliuyi } else { 193832268622SAndreas Färber printf("Reset Device quit, creating comm object failed!\r\n"); 193976af099aSliuyi } 194076af099aSliuyi if (pComm) { 194176af099aSliuyi delete pComm; 194276af099aSliuyi pComm = NULL; 194376af099aSliuyi } 194476af099aSliuyi return bSuccess; 194576af099aSliuyi } 194676af099aSliuyi 194776af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 194876af099aSliuyi { 194976af099aSliuyi CRKUsbComm *pComm = NULL; 195076af099aSliuyi bool bRet, bSuccess = false; 195176af099aSliuyi int iRet; 195276af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 195376af099aSliuyi return bSuccess; 195476af099aSliuyi 195576af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 195676af099aSliuyi if (bRet) { 195776af099aSliuyi BYTE flashID[5]; 195876af099aSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 195976af099aSliuyi if (iRet != ERR_SUCCESS) { 196076af099aSliuyi if (g_pLogObject) 196176af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 196232268622SAndreas Färber printf("Reading flash ID failed!\r\n"); 196376af099aSliuyi } else { 196476af099aSliuyi printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 196576af099aSliuyi bSuccess = true; 196676af099aSliuyi } 196776af099aSliuyi } else { 196832268622SAndreas Färber printf("Read Flash ID quit, creating comm object failed!\r\n"); 196976af099aSliuyi } 197076af099aSliuyi if (pComm) { 197176af099aSliuyi delete pComm; 197276af099aSliuyi pComm = NULL; 197376af099aSliuyi } 197476af099aSliuyi return bSuccess; 197576af099aSliuyi } 197676af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 197776af099aSliuyi { 197876af099aSliuyi CRKUsbComm *pComm = NULL; 197976af099aSliuyi bool bRet, bSuccess = false; 198076af099aSliuyi int iRet; 198176af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 198276af099aSliuyi return bSuccess; 198376af099aSliuyi 198476af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 198576af099aSliuyi if (bRet) { 198676af099aSliuyi STRUCT_FLASHINFO_CMD info; 198776af099aSliuyi UINT uiRead; 198876af099aSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 198976af099aSliuyi if (iRet != ERR_SUCCESS) { 199076af099aSliuyi if (g_pLogObject) 199176af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 199232268622SAndreas Färber printf("Read Flash Info failed!\r\n"); 199376af099aSliuyi } else { 199476af099aSliuyi printf("Flash Info:\r\n"); 199576af099aSliuyi if (info.bManufCode <= 7) { 199676af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 199776af099aSliuyi } 199876af099aSliuyi else 199976af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 200076af099aSliuyi 200176af099aSliuyi printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 200276af099aSliuyi printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 200376af099aSliuyi printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 200476af099aSliuyi printf("\tECC Bits: %d\r\n", info.bECCBits); 200576af099aSliuyi printf("\tAccess Time: %d\r\n", info.bAccessTime); 200676af099aSliuyi printf("\tFlash CS: "); 200776af099aSliuyi for(int i = 0; i < 8; i++) { 200876af099aSliuyi if( info.bFlashCS & (1 << i) ) 200976af099aSliuyi printf("Flash<%d> ", i); 201076af099aSliuyi } 201176af099aSliuyi printf("\r\n"); 201276af099aSliuyi bSuccess = true; 201376af099aSliuyi } 201476af099aSliuyi }else { 201532268622SAndreas Färber printf("Read Flash Info quit, creating comm object failed!\r\n"); 201676af099aSliuyi } 201776af099aSliuyi if (pComm) { 201876af099aSliuyi delete pComm; 201976af099aSliuyi pComm = NULL; 202076af099aSliuyi } 202176af099aSliuyi return bSuccess; 202276af099aSliuyi } 202376af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 202476af099aSliuyi { 202576af099aSliuyi CRKUsbComm *pComm = NULL; 202676af099aSliuyi bool bRet, bSuccess = false; 202776af099aSliuyi int iRet; 202876af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 202976af099aSliuyi return bSuccess; 203076af099aSliuyi 203176af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 203276af099aSliuyi if (bRet) { 203376af099aSliuyi BYTE chipInfo[16]; 203476af099aSliuyi iRet = pComm->RKU_ReadChipInfo(chipInfo); 203576af099aSliuyi if (iRet != ERR_SUCCESS) { 203676af099aSliuyi if (g_pLogObject) 203776af099aSliuyi g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 203832268622SAndreas Färber printf("Read Chip Info failed!\r\n"); 203976af099aSliuyi } else { 204076af099aSliuyi string strChipInfo; 204176af099aSliuyi g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 204276af099aSliuyi printf("Chip Info: %s\r\n", strChipInfo.c_str()); 204376af099aSliuyi bSuccess = true; 204476af099aSliuyi } 204576af099aSliuyi } else { 204632268622SAndreas Färber printf("Read Chip Info quit, creating comm object failed!\r\n"); 204776af099aSliuyi } 204876af099aSliuyi if (pComm) { 204976af099aSliuyi delete pComm; 205076af099aSliuyi pComm = NULL; 205176af099aSliuyi } 205276af099aSliuyi return bSuccess; 205376af099aSliuyi } 205476af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 205576af099aSliuyi { 205676af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 205776af099aSliuyi return false; 205876af099aSliuyi CRKUsbComm *pComm = NULL; 205976af099aSliuyi FILE *file = NULL; 206076af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 206176af099aSliuyi int iRet; 206276af099aSliuyi UINT iTotalRead = 0,iRead = 0; 206376af099aSliuyi int nSectorSize = 512; 206476af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 206576af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 206676af099aSliuyi if (bRet) { 206776af099aSliuyi if(szFile) { 206876af099aSliuyi file = fopen(szFile, "wb+"); 206976af099aSliuyi if( !file ) { 207076af099aSliuyi printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 207176af099aSliuyi goto Exit_ReadLBA; 207276af099aSliuyi } 207376af099aSliuyi } 207476af099aSliuyi 207576af099aSliuyi while(uiLen > 0) { 207676af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 207776af099aSliuyi iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 207876af099aSliuyi iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 207976af099aSliuyi if(ERR_SUCCESS == iRet) { 208076af099aSliuyi uiLen -= iRead; 208176af099aSliuyi iTotalRead += iRead; 208276af099aSliuyi 208376af099aSliuyi if(szFile) { 208476af099aSliuyi fwrite(pBuf, 1, iRead * nSectorSize, file); 208576af099aSliuyi if (bFirst){ 208676af099aSliuyi if (iTotalRead >= 1024) 208732268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 208876af099aSliuyi else 208932268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 209076af099aSliuyi bFirst = false; 209176af099aSliuyi } else { 209276af099aSliuyi CURSOR_MOVEUP_LINE(1); 209376af099aSliuyi CURSOR_DEL_LINE; 209476af099aSliuyi if (iTotalRead >= 1024) 209532268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 209676af099aSliuyi else 209732268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 209876af099aSliuyi } 209976af099aSliuyi } 210076af099aSliuyi else 210176af099aSliuyi PrintData(pBuf, nSectorSize * iRead); 210276af099aSliuyi } else { 210376af099aSliuyi if (g_pLogObject) 210476af099aSliuyi g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 210576af099aSliuyi 210676af099aSliuyi printf("Read LBA failed!\r\n"); 210776af099aSliuyi goto Exit_ReadLBA; 210876af099aSliuyi } 210976af099aSliuyi } 211076af099aSliuyi bSuccess = true; 211176af099aSliuyi } else { 211232268622SAndreas Färber printf("Read LBA quit, creating comm object failed!\r\n"); 211376af099aSliuyi } 211476af099aSliuyi Exit_ReadLBA: 211576af099aSliuyi if (pComm) { 211676af099aSliuyi delete pComm; 211776af099aSliuyi pComm = NULL; 211876af099aSliuyi } 211976af099aSliuyi if (file) 212076af099aSliuyi fclose(file); 212176af099aSliuyi return bSuccess; 212276af099aSliuyi } 212376af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 212476af099aSliuyi { 212576af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 212676af099aSliuyi return false; 212776af099aSliuyi CRKUsbComm *pComm = NULL; 212876af099aSliuyi FILE *file = NULL; 212976af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 213076af099aSliuyi int iRet; 213176af099aSliuyi long long iTotalWrite = 0, iFileSize = 0; 213276af099aSliuyi UINT iWrite = 0, iRead = 0; 213376af099aSliuyi UINT uiLen; 213476af099aSliuyi int nSectorSize = 512; 213576af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 213676af099aSliuyi 213776af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 213876af099aSliuyi if (bRet) { 213976af099aSliuyi file = fopen(szFile, "rb"); 214076af099aSliuyi if( !file ) { 214176af099aSliuyi printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 214276af099aSliuyi goto Exit_WriteLBA; 214376af099aSliuyi } 214476af099aSliuyi 214576af099aSliuyi iRet = fseeko(file, 0, SEEK_END); 214676af099aSliuyi iFileSize = ftello(file); 214776af099aSliuyi fseeko(file, 0, SEEK_SET); 214876af099aSliuyi while(iTotalWrite < iFileSize) { 214976af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 215076af099aSliuyi iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 215176af099aSliuyi uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 215276af099aSliuyi iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 215376af099aSliuyi if(ERR_SUCCESS == iRet) { 215476af099aSliuyi uiBegin += uiLen; 215576af099aSliuyi iTotalWrite += iWrite; 215676af099aSliuyi if (bFirst) { 215776af099aSliuyi if (iTotalWrite >= 1024) 215876af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 215976af099aSliuyi else 216032268622SAndreas Färber printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 216176af099aSliuyi bFirst = false; 216276af099aSliuyi } else { 216376af099aSliuyi CURSOR_MOVEUP_LINE(1); 216476af099aSliuyi CURSOR_DEL_LINE; 216576af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 216676af099aSliuyi } 216776af099aSliuyi } else { 216876af099aSliuyi if (g_pLogObject) 216976af099aSliuyi g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 217076af099aSliuyi 217176af099aSliuyi printf("Write LBA failed!\r\n"); 217276af099aSliuyi goto Exit_WriteLBA; 217376af099aSliuyi } 217476af099aSliuyi } 217576af099aSliuyi bSuccess = true; 217676af099aSliuyi } else { 217732268622SAndreas Färber printf("Write LBA quit, creating comm object failed!\r\n"); 217876af099aSliuyi } 217976af099aSliuyi Exit_WriteLBA: 218076af099aSliuyi if (pComm) { 218176af099aSliuyi delete pComm; 218276af099aSliuyi pComm = NULL; 218376af099aSliuyi } 218476af099aSliuyi if (file) 218576af099aSliuyi fclose(file); 218676af099aSliuyi return bSuccess; 218776af099aSliuyi } 218876af099aSliuyi 218976af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems) 219076af099aSliuyi { 219176af099aSliuyi string strItem; 219276af099aSliuyi char szItem[100]; 219376af099aSliuyi char *pos = NULL, *pStart; 219476af099aSliuyi pStart = pszItems; 219576af099aSliuyi pos = strchr(pStart, ','); 219676af099aSliuyi while(pos != NULL) { 219776af099aSliuyi memset(szItem, 0, 100); 219876af099aSliuyi strncpy(szItem, pStart, pos - pStart); 219976af099aSliuyi strItem = szItem; 220076af099aSliuyi vecItems.push_back(strItem); 220176af099aSliuyi pStart = pos + 1; 220276af099aSliuyi if (*pStart == 0) 220376af099aSliuyi break; 220476af099aSliuyi pos = strchr(pStart, ','); 220576af099aSliuyi } 220676af099aSliuyi if (strlen(pStart) > 0) { 220776af099aSliuyi memset(szItem, 0, 100); 220876af099aSliuyi strncpy(szItem, pStart, strlen(pStart)); 220976af099aSliuyi strItem = szItem; 221076af099aSliuyi vecItems.push_back(strItem); 221176af099aSliuyi } 221276af099aSliuyi } 2213c30d921cSKever Yang 2214d71e8c20SEddie Cai void tag_spl(char *tag, char *spl) 2215d71e8c20SEddie Cai { 2216d71e8c20SEddie Cai FILE *file = NULL; 2217d71e8c20SEddie Cai int len; 2218d71e8c20SEddie Cai 2219d71e8c20SEddie Cai if(!tag || !spl) 2220d71e8c20SEddie Cai return; 2221d71e8c20SEddie Cai len = strlen(tag); 2222d71e8c20SEddie Cai printf("tag len=%d\n",len); 2223d71e8c20SEddie Cai file = fopen(spl, "rb"); 2224d71e8c20SEddie Cai if( !file ){ 2225d71e8c20SEddie Cai return; 2226d71e8c20SEddie Cai } 2227d71e8c20SEddie Cai int iFileSize; 2228d71e8c20SEddie Cai fseek(file, 0, SEEK_END); 2229d71e8c20SEddie Cai iFileSize = ftell(file); 2230d71e8c20SEddie Cai fseek(file, 0, SEEK_SET); 2231d71e8c20SEddie Cai char *Buf = NULL; 2232d71e8c20SEddie Cai Buf = new char[iFileSize + len + 1]; 2233d71e8c20SEddie Cai if (!Buf){ 2234d71e8c20SEddie Cai fclose(file); 2235d71e8c20SEddie Cai return; 2236d71e8c20SEddie Cai } 2237d71e8c20SEddie Cai memset(Buf, 0, iFileSize + 1); 2238d71e8c20SEddie Cai memcpy(Buf, tag, len); 2239d71e8c20SEddie Cai int iRead; 2240d71e8c20SEddie Cai iRead = fread(Buf+len, 1, iFileSize, file); 2241d71e8c20SEddie Cai if (iRead != iFileSize){ 2242d71e8c20SEddie Cai fclose(file); 2243d71e8c20SEddie Cai delete []Buf; 2244d71e8c20SEddie Cai return; 2245d71e8c20SEddie Cai } 2246d71e8c20SEddie Cai fclose(file); 2247d71e8c20SEddie Cai 2248d71e8c20SEddie Cai len = strlen(spl); 224932268622SAndreas Färber char *taggedspl = new char[len + 5]; 225032268622SAndreas Färber strcpy(taggedspl, spl); 225132268622SAndreas Färber strcpy(taggedspl + len, ".tag"); 225232268622SAndreas Färber taggedspl[len+4] = 0; 225332268622SAndreas Färber printf("Writing tagged spl to %s\n", taggedspl); 2254d71e8c20SEddie Cai 225532268622SAndreas Färber file = fopen(taggedspl, "wb"); 2256d71e8c20SEddie Cai if( !file ){ 225732268622SAndreas Färber delete []taggedspl; 2258d71e8c20SEddie Cai delete []Buf; 2259d71e8c20SEddie Cai return; 2260d71e8c20SEddie Cai } 2261d71e8c20SEddie Cai fwrite(Buf, 1, iFileSize+len, file); 2262d71e8c20SEddie Cai fclose(file); 226332268622SAndreas Färber delete []taggedspl; 2264d71e8c20SEddie Cai delete []Buf; 2265d71e8c20SEddie Cai printf("done\n"); 2266d71e8c20SEddie Cai return; 2267d71e8c20SEddie Cai } 2268d71e8c20SEddie Cai 226976af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan) 227076af099aSliuyi { 227176af099aSliuyi string strCmd; 227276af099aSliuyi strCmd = argv[1]; 227376af099aSliuyi ssize_t cnt; 227476af099aSliuyi bool bRet,bSuccess = false; 22758df2d64aSEddie Cai char *s; 22768df2d64aSEddie Cai int i, ret; 227776af099aSliuyi STRUCT_RKDEVICE_DESC dev; 227876af099aSliuyi 227976af099aSliuyi transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 22808df2d64aSEddie Cai s = (char*)strCmd.c_str(); 22818df2d64aSEddie Cai for(i = 0; i < (int)strlen(s); i++) 22828df2d64aSEddie Cai s[i] = toupper(s[i]); 228378884ef4SEddie Cai 22848df2d64aSEddie Cai if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 228576af099aSliuyi usage(); 228676af099aSliuyi return true; 22878df2d64aSEddie Cai } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2288c30d921cSKever Yang printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 228976af099aSliuyi return true; 229078884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 229178884ef4SEddie Cai mergeBoot(); 229278884ef4SEddie Cai 229378884ef4SEddie Cai return true; 229478884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 229578884ef4SEddie Cai string strLoader = argv[2]; 229678884ef4SEddie Cai 229778884ef4SEddie Cai unpackBoot((char*)strLoader.c_str()); 229878884ef4SEddie Cai return true; 2299d71e8c20SEddie Cai } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 2300d71e8c20SEddie Cai if (argc == 4) { 2301d71e8c20SEddie Cai string tag = argv[2]; 2302d71e8c20SEddie Cai string spl = argv[3]; 2303d71e8c20SEddie Cai printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 2304d71e8c20SEddie Cai tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 2305d71e8c20SEddie Cai return true; 2306d71e8c20SEddie Cai } 2307d71e8c20SEddie Cai printf("tagspl: parameter error\n"); 2308d71e8c20SEddie Cai usage(); 230976af099aSliuyi } 231076af099aSliuyi cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 231176af099aSliuyi if (cnt < 1) { 231276af099aSliuyi ERROR_COLOR_ATTR; 231332268622SAndreas Färber printf("Did not find any rockusb device, please plug device in!"); 231476af099aSliuyi NORMAL_COLOR_ATTR; 231576af099aSliuyi printf("\r\n"); 231676af099aSliuyi return bSuccess; 231776af099aSliuyi } else if (cnt > 1) { 231876af099aSliuyi ERROR_COLOR_ATTR; 231932268622SAndreas Färber printf("Found too many rockusb devices, please plug devices out!"); 232076af099aSliuyi NORMAL_COLOR_ATTR; 232176af099aSliuyi printf("\r\n"); 232276af099aSliuyi return bSuccess; 232376af099aSliuyi } 232476af099aSliuyi 232576af099aSliuyi bRet = pScan->GetDevice(dev, 0); 232676af099aSliuyi if (!bRet) { 232776af099aSliuyi ERROR_COLOR_ATTR; 232832268622SAndreas Färber printf("Getting information about rockusb device failed!"); 232976af099aSliuyi NORMAL_COLOR_ATTR; 233076af099aSliuyi printf("\r\n"); 233176af099aSliuyi return bSuccess; 233276af099aSliuyi } 233376af099aSliuyi 233476af099aSliuyi if(strcmp(strCmd.c_str(), "RD") == 0) { 233576af099aSliuyi if ((argc != 2) && (argc != 3)) 233676af099aSliuyi printf("Parameter of [RD] command is invalid, please check help!\r\n"); 233776af099aSliuyi else { 233876af099aSliuyi if (argc == 2) 233976af099aSliuyi bSuccess = reset_device(dev); 234076af099aSliuyi else { 234176af099aSliuyi UINT uiSubCode; 234276af099aSliuyi char *pszEnd; 234376af099aSliuyi uiSubCode = strtoul(argv[2], &pszEnd, 0); 234476af099aSliuyi if (*pszEnd) 234576af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 234676af099aSliuyi else { 234776af099aSliuyi if (uiSubCode <= 5) 234876af099aSliuyi bSuccess = reset_device(dev, uiSubCode); 234976af099aSliuyi else 235076af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 235176af099aSliuyi } 235276af099aSliuyi } 235376af099aSliuyi } 235476af099aSliuyi } else if(strcmp(strCmd.c_str(), "TD") == 0) { 235576af099aSliuyi bSuccess = test_device(dev); 235676af099aSliuyi } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 235776af099aSliuyi bSuccess = read_flash_id(dev); 235876af099aSliuyi } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 235976af099aSliuyi bSuccess = read_flash_info(dev); 236076af099aSliuyi } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 236176af099aSliuyi bSuccess = read_chip_info(dev); 236276af099aSliuyi } else if(strcmp(strCmd.c_str(), "DB") == 0) { 236376af099aSliuyi if (argc > 2) { 236476af099aSliuyi string strLoader; 236576af099aSliuyi strLoader = argv[2]; 236676af099aSliuyi bSuccess = download_boot(dev, (char *)strLoader.c_str()); 236776af099aSliuyi } else if (argc == 2) { 2368*c29e5f0fSliuyi ret = find_config_item(g_ConfigItemVec, "loader"); 236976af099aSliuyi if (ret == -1) 237032268622SAndreas Färber printf("Did not find loader item in config!\r\n"); 237176af099aSliuyi else 237276af099aSliuyi bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 237376af099aSliuyi } else 237476af099aSliuyi printf("Parameter of [DB] command is invalid, please check help!\r\n"); 2375c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2376c30d921cSKever Yang if (argc > 2) { 2377c30d921cSKever Yang string strParameter; 2378c30d921cSKever Yang strParameter = argv[2]; 2379c30d921cSKever Yang bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2380c30d921cSKever Yang } else 2381c30d921cSKever Yang printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 2382c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2383c30d921cSKever Yang if (argc > 2) { 2384c30d921cSKever Yang string strLoader; 2385c30d921cSKever Yang strLoader = argv[2]; 2386c30d921cSKever Yang bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2387c30d921cSKever Yang } else 2388c30d921cSKever Yang printf("Parameter of [UL] command is invalid, please check help!\r\n"); 238976af099aSliuyi } else if(strcmp(strCmd.c_str(), "EF") == 0) { 239076af099aSliuyi if (argc == 2) { 239176af099aSliuyi bSuccess = erase_flash(dev); 239276af099aSliuyi } else 239376af099aSliuyi printf("Parameter of [EF] command is invalid, please check help!\r\n"); 239476af099aSliuyi } else if(strcmp(strCmd.c_str(), "WL") == 0) { 239576af099aSliuyi if (argc == 4) { 239676af099aSliuyi UINT uiBegin; 239776af099aSliuyi char *pszEnd; 239876af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 239976af099aSliuyi if (*pszEnd) 240076af099aSliuyi printf("Begin is invalid, please check!\r\n"); 240176af099aSliuyi else 240276af099aSliuyi bSuccess = write_lba(dev, uiBegin, argv[3]); 240376af099aSliuyi } else 240476af099aSliuyi printf("Parameter of [WL] command is invalid, please check help!\r\n"); 240576af099aSliuyi } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 240676af099aSliuyi char *pszEnd; 240776af099aSliuyi UINT uiBegin, uiLen; 240876af099aSliuyi if (argc != 5) 240976af099aSliuyi printf("Parameter of [RL] command is invalid, please check help!\r\n"); 241076af099aSliuyi else { 241176af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 241276af099aSliuyi if (*pszEnd) 241376af099aSliuyi printf("Begin is invalid, please check!\r\n"); 241476af099aSliuyi else { 241576af099aSliuyi uiLen = strtoul(argv[3], &pszEnd, 0); 241676af099aSliuyi if (*pszEnd) 241776af099aSliuyi printf("Len is invalid, please check!\r\n"); 241876af099aSliuyi else { 241976af099aSliuyi bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 242076af099aSliuyi } 242176af099aSliuyi } 242276af099aSliuyi } 242376af099aSliuyi } else { 24249bc231bdSAndreas Färber printf("command is invalid!\r\n"); 24259bc231bdSAndreas Färber usage(); 242676af099aSliuyi } 242776af099aSliuyi return bSuccess; 242876af099aSliuyi } 242976af099aSliuyi 243076af099aSliuyi 243176af099aSliuyi int main(int argc, char* argv[]) 243276af099aSliuyi { 243376af099aSliuyi CRKScan *pScan = NULL; 243476af099aSliuyi int ret; 243576af099aSliuyi char szProgramProcPath[100]; 243676af099aSliuyi char szProgramDir[256]; 243776af099aSliuyi string strLogDir,strConfigFile; 243876af099aSliuyi struct stat statBuf; 243976af099aSliuyi 244076af099aSliuyi g_ConfigItemVec.clear(); 244176af099aSliuyi sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 244276af099aSliuyi if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 244376af099aSliuyi strcpy(szProgramDir, "."); 244476af099aSliuyi else { 244576af099aSliuyi char *pSlash; 244676af099aSliuyi pSlash = strrchr(szProgramDir, '/'); 244776af099aSliuyi if (pSlash) 244876af099aSliuyi *pSlash = '\0'; 244976af099aSliuyi } 245076af099aSliuyi strLogDir = szProgramDir; 245176af099aSliuyi strLogDir += "/log/"; 245276af099aSliuyi strConfigFile = szProgramDir; 245376af099aSliuyi strConfigFile += "/config.ini"; 245476af099aSliuyi if (opendir(strLogDir.c_str()) == NULL) 245576af099aSliuyi mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 2456e5ee8cc0Sliuyi g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 245776af099aSliuyi 245876af099aSliuyi if(stat(strConfigFile.c_str(), &statBuf) < 0) { 245976af099aSliuyi if (g_pLogObject) { 246076af099aSliuyi g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 246176af099aSliuyi } 246276af099aSliuyi } else if (S_ISREG(statBuf.st_mode)) { 246376af099aSliuyi parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 246476af099aSliuyi } 246576af099aSliuyi 246676af099aSliuyi ret = libusb_init(NULL); 246776af099aSliuyi if (ret < 0) { 246876af099aSliuyi if (g_pLogObject) { 246976af099aSliuyi g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 247076af099aSliuyi delete g_pLogObject; 247176af099aSliuyi } 247276af099aSliuyi return -1; 247376af099aSliuyi } 247476af099aSliuyi 247576af099aSliuyi pScan = new CRKScan(); 247676af099aSliuyi if (!pScan) { 247776af099aSliuyi if (g_pLogObject) { 247832268622SAndreas Färber g_pLogObject->Record("Error: failed to create object for searching device"); 247976af099aSliuyi delete g_pLogObject; 248076af099aSliuyi } 248176af099aSliuyi libusb_exit(NULL); 248276af099aSliuyi return -2; 248376af099aSliuyi } 248476af099aSliuyi pScan->SetVidPid(); 248576af099aSliuyi 248676af099aSliuyi if (argc == 1) 248776af099aSliuyi usage(); 248876af099aSliuyi else if (!handle_command(argc, argv, pScan)) 248976af099aSliuyi return -0xFF; 249076af099aSliuyi if (pScan) 249176af099aSliuyi delete pScan; 249276af099aSliuyi if (g_pLogObject) 249376af099aSliuyi delete g_pLogObject; 249476af099aSliuyi libusb_exit(NULL); 249576af099aSliuyi return 0; 249676af099aSliuyi } 2497