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"); 516ae612beSliuyi printf("WriteLBA:\t\twlx <PartitionName> <File>\r\n"); 52154ee062SEddie Cai printf("WriteGPT:\t\tgpt <gpt partition table>\r\n"); 53154ee062SEddie Cai printf("EraseFlash:\t\tef \r\n"); 54154ee062SEddie Cai printf("TestDevice:\t\ttd\r\n"); 55154ee062SEddie Cai printf("ResetDevice:\t\trd [subcode]\r\n"); 56154ee062SEddie Cai printf("ReadFlashID:\t\trid\r\n"); 57154ee062SEddie Cai printf("ReadFlashInfo:\t\trfi\r\n"); 58154ee062SEddie Cai printf("ReadChipInfo:\t\trci\r\n"); 5978884ef4SEddie Cai printf("PackBootLoader:\t\tpack\r\n"); 6078884ef4SEddie Cai printf("UnpackBootLoader:\tunpack <boot loader>\r\n"); 61d71e8c20SEddie Cai printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n"); 6276af099aSliuyi printf("-------------------------------------------------------\r\n\r\n"); 6376af099aSliuyi } 6476af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall) 6576af099aSliuyi { 6676af099aSliuyi string strInfoText=""; 6776af099aSliuyi char szText[256]; 6876af099aSliuyi switch (promptID) { 6976af099aSliuyi case TESTDEVICE_PROGRESS: 7032268622SAndreas Färber sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue); 7176af099aSliuyi strInfoText = szText; 7276af099aSliuyi break; 7376af099aSliuyi case LOWERFORMAT_PROGRESS: 7432268622SAndreas Färber sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue); 7576af099aSliuyi strInfoText = szText; 7676af099aSliuyi break; 7776af099aSliuyi case DOWNLOADIMAGE_PROGRESS: 7832268622SAndreas Färber sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 7976af099aSliuyi strInfoText = szText; 8076af099aSliuyi break; 8176af099aSliuyi case CHECKIMAGE_PROGRESS: 8232268622SAndreas Färber sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 8376af099aSliuyi strInfoText = szText; 8476af099aSliuyi break; 8576af099aSliuyi case TAGBADBLOCK_PROGRESS: 8632268622SAndreas Färber sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue); 8776af099aSliuyi strInfoText = szText; 8876af099aSliuyi break; 8976af099aSliuyi case TESTBLOCK_PROGRESS: 9032268622SAndreas Färber sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue); 9176af099aSliuyi strInfoText = szText; 9276af099aSliuyi break; 9376af099aSliuyi case ERASEFLASH_PROGRESS: 9432268622SAndreas Färber sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue); 9576af099aSliuyi strInfoText = szText; 9676af099aSliuyi break; 9776af099aSliuyi case ERASESYSTEM_PROGRESS: 9832268622SAndreas Färber sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue); 9976af099aSliuyi strInfoText = szText; 10076af099aSliuyi break; 10176af099aSliuyi case ERASEUSERDATA_PROGRESS: 10232268622SAndreas Färber sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue); 10376af099aSliuyi strInfoText = szText; 10476af099aSliuyi break; 10576af099aSliuyi } 10676af099aSliuyi if (strInfoText.size() > 0){ 10776af099aSliuyi CURSOR_MOVEUP_LINE(1); 10876af099aSliuyi CURSOR_DEL_LINE; 10976af099aSliuyi printf("%s\r\n", strInfoText.c_str()); 11076af099aSliuyi } 11176af099aSliuyi if (emCall == CALL_LAST) 11276af099aSliuyi deviceLayer = 0; 11376af099aSliuyi } 11476af099aSliuyi 11576af099aSliuyi char *strupr(char *szSrc) 11676af099aSliuyi { 11776af099aSliuyi char *p = szSrc; 11876af099aSliuyi while(*p){ 11976af099aSliuyi if ((*p >= 'a') && (*p <= 'z')) 12076af099aSliuyi *p = *p - 'a' + 'A'; 12176af099aSliuyi p++; 12276af099aSliuyi } 12376af099aSliuyi return szSrc; 12476af099aSliuyi } 12576af099aSliuyi void PrintData(PBYTE pData, int nSize) 12676af099aSliuyi { 12776af099aSliuyi char szPrint[17] = "\0"; 12876af099aSliuyi int i; 12976af099aSliuyi for( i = 0; i < nSize; i++){ 13076af099aSliuyi if(i % 16 == 0){ 13176af099aSliuyi if(i / 16 > 0) 13276af099aSliuyi printf(" %s\r\n", szPrint); 13376af099aSliuyi printf("%08d ", i / 16); 13476af099aSliuyi } 13576af099aSliuyi printf("%02X ", pData[i]); 13676af099aSliuyi szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.'; 13776af099aSliuyi } 13876af099aSliuyi if(i / 16 > 0) 13976af099aSliuyi printf(" %s\r\n", szPrint); 14076af099aSliuyi } 14176af099aSliuyi 14276af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest) 14376af099aSliuyi { 14476af099aSliuyi if (!pszSrc) 14576af099aSliuyi return false; 14676af099aSliuyi int nSrcLen = strlen(pszSrc); 14776af099aSliuyi int nDestLen = nSrcLen * 2; 14876af099aSliuyi 14976af099aSliuyi pszDest = NULL; 15076af099aSliuyi pszDest = new wchar_t[nDestLen]; 15176af099aSliuyi if (!pszDest) 15276af099aSliuyi return false; 15376af099aSliuyi nDestLen = nDestLen * sizeof(wchar_t); 15476af099aSliuyi memset(pszDest, 0, nDestLen); 15576af099aSliuyi int iRet; 15676af099aSliuyi iconv_t cd; 15776af099aSliuyi cd = iconv_open("UTF-32", "UTF-8"); 15876af099aSliuyi if((iconv_t)-1 == cd) { 15976af099aSliuyi delete []pszDest; 16076af099aSliuyi pszDest = NULL; 16176af099aSliuyi return false; 16276af099aSliuyi } 16376af099aSliuyi char *pIn, *pOut; 16476af099aSliuyi pIn = (char *)pszSrc; 16576af099aSliuyi pOut = (char *)pszDest; 16676af099aSliuyi 16776af099aSliuyi iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 16876af099aSliuyi 16976af099aSliuyi if(iRet == -1) { 17076af099aSliuyi delete []pszDest; 17176af099aSliuyi pszDest = NULL; 17276af099aSliuyi iconv_close(cd); 17376af099aSliuyi return false; 17476af099aSliuyi } 17576af099aSliuyi 17676af099aSliuyi iconv_close(cd); 17776af099aSliuyi 17876af099aSliuyi return true; 17976af099aSliuyi } 18076af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest) 18176af099aSliuyi { 18276af099aSliuyi if (!pszSrc) 18376af099aSliuyi return false; 18476af099aSliuyi int nSrcLen = wcslen(pszSrc); 18576af099aSliuyi int nDestLen = nSrcLen * 2; 18676af099aSliuyi nSrcLen = nSrcLen * sizeof(wchar_t); 18776af099aSliuyi pszDest = NULL; 18876af099aSliuyi pszDest = new char[nDestLen]; 18976af099aSliuyi if (!pszDest) 19076af099aSliuyi return false; 19176af099aSliuyi memset(pszDest, 0, nDestLen); 19276af099aSliuyi int iRet; 19376af099aSliuyi iconv_t cd; 19476af099aSliuyi cd = iconv_open("UTF-8", "UTF-32"); 19576af099aSliuyi 19676af099aSliuyi if((iconv_t)-1 == cd) { 19776af099aSliuyi delete []pszDest; 19876af099aSliuyi pszDest = NULL; 19976af099aSliuyi return false; 20076af099aSliuyi } 20176af099aSliuyi char *pIn, *pOut; 20276af099aSliuyi pIn = (char *)pszSrc; 20376af099aSliuyi pOut = (char *)pszDest; 20476af099aSliuyi iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 20576af099aSliuyi 20676af099aSliuyi if(iRet == -1) { 20776af099aSliuyi delete []pszDest; 20876af099aSliuyi pszDest = NULL; 20976af099aSliuyi iconv_close(cd); 21076af099aSliuyi return false; 21176af099aSliuyi } 21276af099aSliuyi 21376af099aSliuyi iconv_close(cd); 21476af099aSliuyi 21576af099aSliuyi return true; 21676af099aSliuyi } 217c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName) 21876af099aSliuyi { 21976af099aSliuyi unsigned int i; 220c29e5f0fSliuyi for(i = 0; i < vecItems.size(); i++){ 221c29e5f0fSliuyi if (strcasecmp(pszName, vecItems[i].szItemName) == 0){ 22276af099aSliuyi return i; 22376af099aSliuyi } 22476af099aSliuyi } 22576af099aSliuyi return -1; 22676af099aSliuyi } 227c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid) 228c29e5f0fSliuyi { 229c29e5f0fSliuyi unsigned int i; 230c29e5f0fSliuyi char value; 231c29e5f0fSliuyi memset(uuid, 0, 16); 232c29e5f0fSliuyi for (i =0; i < strUUid.size(); i++) { 233c29e5f0fSliuyi value = 0; 234c29e5f0fSliuyi if ((strUUid[i] >= '0')&&(strUUid[i] <= '9')) 235c29e5f0fSliuyi value = strUUid[i] - '0'; 236c29e5f0fSliuyi if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f')) 237c29e5f0fSliuyi value = strUUid[i] - 'a' + 10; 238c29e5f0fSliuyi if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F')) 239c29e5f0fSliuyi value = strUUid[i] - 'A' + 10; 240c29e5f0fSliuyi if ((i % 2) == 0) 241c29e5f0fSliuyi uuid[i / 2] += (value << 4); 242c29e5f0fSliuyi else 243c29e5f0fSliuyi uuid[i / 2] += value; 244c29e5f0fSliuyi } 245c29e5f0fSliuyi unsigned int *p32; 246c29e5f0fSliuyi unsigned short *p16; 247c29e5f0fSliuyi p32 = (unsigned int*)uuid; 248c29e5f0fSliuyi *p32 = cpu_to_be32(*p32); 249c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 4); 250c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 251c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 6); 252c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 253c29e5f0fSliuyi } 25476af099aSliuyi 25576af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 25676af099aSliuyi { 25776af099aSliuyi 25876af099aSliuyi stringstream configStream(pConfig); 25976af099aSliuyi string strLine, strItemName, strItemValue; 26076af099aSliuyi string::size_type line_size,pos; 26176af099aSliuyi STRUCT_CONFIG_ITEM item; 26276af099aSliuyi vecItem.clear(); 26376af099aSliuyi while (!configStream.eof()){ 26476af099aSliuyi getline(configStream, strLine); 26576af099aSliuyi line_size = strLine.size(); 26676af099aSliuyi if (line_size == 0) 26776af099aSliuyi continue; 26876af099aSliuyi if (strLine[line_size-1] == '\r'){ 26976af099aSliuyi strLine = strLine.substr(0, line_size-1); 27076af099aSliuyi } 271c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 272c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 273c30d921cSKever Yang if (strLine.size()==0 ) 274c30d921cSKever Yang continue; 275c30d921cSKever Yang if (strLine[0] == '#') 276c30d921cSKever Yang continue; 27776af099aSliuyi pos = strLine.find("="); 27876af099aSliuyi if (pos == string::npos){ 27976af099aSliuyi continue; 28076af099aSliuyi } 28176af099aSliuyi strItemName = strLine.substr(0, pos); 28276af099aSliuyi strItemValue = strLine.substr(pos + 1); 28376af099aSliuyi strItemName.erase(0, strItemName.find_first_not_of(" ")); 28476af099aSliuyi strItemName.erase(strItemName.find_last_not_of(" ") + 1); 28576af099aSliuyi strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 28676af099aSliuyi strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 28776af099aSliuyi if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 28876af099aSliuyi strcpy(item.szItemName, strItemName.c_str()); 28976af099aSliuyi strcpy(item.szItemValue, strItemValue.c_str()); 29076af099aSliuyi vecItem.push_back(item); 29176af099aSliuyi } 29276af099aSliuyi } 29376af099aSliuyi return true; 29476af099aSliuyi 29576af099aSliuyi } 29676af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 29776af099aSliuyi { 29876af099aSliuyi FILE *file = NULL; 29976af099aSliuyi file = fopen(pConfigFile, "rb"); 30076af099aSliuyi if( !file ){ 30176af099aSliuyi if (g_pLogObject) 30232268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile); 30376af099aSliuyi return false; 30476af099aSliuyi } 30576af099aSliuyi int iFileSize; 30676af099aSliuyi fseek(file, 0, SEEK_END); 30776af099aSliuyi iFileSize = ftell(file); 30876af099aSliuyi fseek(file, 0, SEEK_SET); 30976af099aSliuyi char *pConfigBuf = NULL; 31076af099aSliuyi pConfigBuf = new char[iFileSize + 1]; 31176af099aSliuyi if (!pConfigBuf){ 31276af099aSliuyi fclose(file); 31376af099aSliuyi return false; 31476af099aSliuyi } 31576af099aSliuyi memset(pConfigBuf, 0, iFileSize + 1); 31676af099aSliuyi int iRead; 31776af099aSliuyi iRead = fread(pConfigBuf, 1, iFileSize, file); 31876af099aSliuyi if (iRead != iFileSize){ 31976af099aSliuyi if (g_pLogObject) 32032268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize); 32176af099aSliuyi fclose(file); 32276af099aSliuyi delete []pConfigBuf; 32376af099aSliuyi return false; 32476af099aSliuyi } 32576af099aSliuyi fclose(file); 32676af099aSliuyi bool bRet; 32776af099aSliuyi bRet = parse_config(pConfigBuf, vecItem); 32876af099aSliuyi delete []pConfigBuf; 32976af099aSliuyi return bRet; 33076af099aSliuyi } 331c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 332c30d921cSKever Yang { 333c30d921cSKever Yang string::size_type pos,prevPos; 334c30d921cSKever Yang string strOffset,strLen; 335c30d921cSKever Yang int iCount; 336c30d921cSKever Yang prevPos = pos = 0; 337c30d921cSKever Yang if (strPartInfo.size() <= 0) { 338c30d921cSKever Yang return false; 339c30d921cSKever Yang } 340c30d921cSKever Yang pos = strPartInfo.find('@'); 341c30d921cSKever Yang if (pos == string::npos) { 342c30d921cSKever Yang return false; 343c30d921cSKever Yang } 344c30d921cSKever Yang strLen = strPartInfo.substr(prevPos, pos - prevPos); 345c30d921cSKever Yang strLen.erase(0, strLen.find_first_not_of(" ")); 346c30d921cSKever Yang strLen.erase(strLen.find_last_not_of(" ") + 1); 347c30d921cSKever Yang if (strchr(strLen.c_str(), '-')) { 348c30d921cSKever Yang uiLen = 0xFFFFFFFF; 349c30d921cSKever Yang } else { 350c30d921cSKever Yang iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 351c30d921cSKever Yang if (iCount != 1) { 352c30d921cSKever Yang return false; 353c30d921cSKever Yang } 354c30d921cSKever Yang } 355c30d921cSKever Yang 356c30d921cSKever Yang prevPos = pos + 1; 357c30d921cSKever Yang pos = strPartInfo.find('(',prevPos); 358c30d921cSKever Yang if (pos == string::npos) { 359c30d921cSKever Yang return false; 360c30d921cSKever Yang } 361c30d921cSKever Yang strOffset = strPartInfo.substr(prevPos, pos - prevPos); 362c30d921cSKever Yang strOffset.erase(0, strOffset.find_first_not_of(" ")); 363c30d921cSKever Yang strOffset.erase(strOffset.find_last_not_of(" ") + 1); 364c30d921cSKever Yang iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 365c30d921cSKever Yang if (iCount != 1) { 366c30d921cSKever Yang return false; 367c30d921cSKever Yang } 368c30d921cSKever Yang prevPos = pos + 1; 369c30d921cSKever Yang pos = strPartInfo.find(')', prevPos); 370c30d921cSKever Yang if (pos == string::npos) { 371c30d921cSKever Yang return false; 372c30d921cSKever Yang } 373c30d921cSKever Yang strName = strPartInfo.substr(prevPos, pos - prevPos); 374c30d921cSKever Yang strName.erase(0, strName.find_first_not_of(" ")); 375c30d921cSKever Yang strName.erase(strName.find_last_not_of(" ") + 1); 376c30d921cSKever Yang 377c30d921cSKever Yang return true; 378c30d921cSKever Yang } 379c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid) 380c29e5f0fSliuyi { 381c29e5f0fSliuyi string::size_type pos(0); 382c30d921cSKever Yang 383c29e5f0fSliuyi if (strUuidInfo.size() <= 0) { 384c29e5f0fSliuyi return false; 385c29e5f0fSliuyi } 386c29e5f0fSliuyi pos = strUuidInfo.find('='); 387c29e5f0fSliuyi if (pos == string::npos) { 388c29e5f0fSliuyi return false; 389c29e5f0fSliuyi } 390c29e5f0fSliuyi strName = strUuidInfo.substr(0, pos); 391c29e5f0fSliuyi strName.erase(0, strName.find_first_not_of(" ")); 392c29e5f0fSliuyi strName.erase(strName.find_last_not_of(" ") + 1); 393c29e5f0fSliuyi 394c29e5f0fSliuyi strUUid = strUuidInfo.substr(pos+1); 395c29e5f0fSliuyi strUUid.erase(0, strUUid.find_first_not_of(" ")); 396c29e5f0fSliuyi strUUid.erase(strUUid.find_last_not_of(" ") + 1); 397c29e5f0fSliuyi 398c29e5f0fSliuyi while(true) { 399c29e5f0fSliuyi pos = 0; 400c29e5f0fSliuyi if( (pos = strUUid.find("-")) != string::npos) 401c29e5f0fSliuyi strUUid.replace(pos,1,""); 402c29e5f0fSliuyi else 403c29e5f0fSliuyi break; 404c29e5f0fSliuyi } 405c29e5f0fSliuyi if (strUUid.size() != 32) 406c29e5f0fSliuyi return false; 407c29e5f0fSliuyi return true; 408c29e5f0fSliuyi } 409c29e5f0fSliuyi 410c29e5f0fSliuyi 411c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 412c30d921cSKever Yang { 413c30d921cSKever Yang stringstream paramStream(pParameter); 414c30d921cSKever Yang bool bRet,bFind = false; 415c29e5f0fSliuyi string strLine, strPartition, strPartInfo, strPartName, strUUid; 416c30d921cSKever Yang string::size_type line_size, pos, posColon, posComma; 417c30d921cSKever Yang UINT uiPartOffset, uiPartSize; 418c30d921cSKever Yang STRUCT_PARAM_ITEM item; 419c29e5f0fSliuyi STRUCT_CONFIG_ITEM uuid_item; 420c30d921cSKever Yang vecItem.clear(); 421c29e5f0fSliuyi vecUuidItem.clear(); 422c30d921cSKever Yang while (!paramStream.eof()) { 423c30d921cSKever Yang getline(paramStream,strLine); 424c30d921cSKever Yang line_size = strLine.size(); 425c30d921cSKever Yang if (line_size == 0) 426c30d921cSKever Yang continue; 427c30d921cSKever Yang if (strLine[line_size - 1] == '\r'){ 428c30d921cSKever Yang strLine = strLine.substr(0, line_size - 1); 429c30d921cSKever Yang } 430c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 431c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 432c30d921cSKever Yang if (strLine.size()==0 ) 433c30d921cSKever Yang continue; 434c30d921cSKever Yang if (strLine[0] == '#') 435c30d921cSKever Yang continue; 436c29e5f0fSliuyi pos = strLine.find("uuid:"); 437c29e5f0fSliuyi if (pos != string::npos) { 438c29e5f0fSliuyi strPartInfo = strLine.substr(pos+5); 439c29e5f0fSliuyi bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid); 440c29e5f0fSliuyi if (bRet) { 441c29e5f0fSliuyi strcpy(uuid_item.szItemName, strPartName.c_str()); 442c29e5f0fSliuyi string_to_uuid(strUUid,uuid_item.szItemValue); 443c29e5f0fSliuyi vecUuidItem.push_back(uuid_item); 444c29e5f0fSliuyi } 445c29e5f0fSliuyi continue; 446c29e5f0fSliuyi } 447c29e5f0fSliuyi 448c30d921cSKever Yang pos = strLine.find("mtdparts"); 449c30d921cSKever Yang if (pos == string::npos) { 450c30d921cSKever Yang continue; 451c30d921cSKever Yang } 452c30d921cSKever Yang bFind = true; 453c30d921cSKever Yang posColon = strLine.find(':', pos); 454c30d921cSKever Yang if (posColon == string::npos) { 455c30d921cSKever Yang continue; 456c30d921cSKever Yang } 457c30d921cSKever Yang strPartition = strLine.substr(posColon + 1); 458c30d921cSKever Yang pos = 0; 459c30d921cSKever Yang posComma = strPartition.find(',', pos); 460c30d921cSKever Yang while (posComma != string::npos) { 461c30d921cSKever Yang strPartInfo = strPartition.substr(pos, posComma - pos); 462c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 463c30d921cSKever Yang if (bRet) { 464c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 465c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 466c30d921cSKever Yang item.uiItemSize = uiPartSize; 467c30d921cSKever Yang vecItem.push_back(item); 468c30d921cSKever Yang } 469c30d921cSKever Yang pos = posComma + 1; 470c30d921cSKever Yang posComma = strPartition.find(',', pos); 471c30d921cSKever Yang } 472c30d921cSKever Yang strPartInfo = strPartition.substr(pos); 473c30d921cSKever Yang if (strPartInfo.size() > 0) { 474c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 475c30d921cSKever Yang if (bRet) { 476c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 477c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 478c30d921cSKever Yang item.uiItemSize = uiPartSize; 479c30d921cSKever Yang vecItem.push_back(item); 480c30d921cSKever Yang } 481c30d921cSKever Yang } 482c30d921cSKever Yang break; 483c30d921cSKever Yang } 484c30d921cSKever Yang return bFind; 485c30d921cSKever Yang 486c30d921cSKever Yang } 487c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 488c30d921cSKever Yang { 489c30d921cSKever Yang FILE *file = NULL; 490c30d921cSKever Yang file = fopen(pParamFile, "rb"); 491c30d921cSKever Yang if( !file ) { 492c30d921cSKever Yang if (g_pLogObject) 49332268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 494c30d921cSKever Yang return false; 495c30d921cSKever Yang } 496c30d921cSKever Yang int iFileSize; 497c30d921cSKever Yang fseek(file, 0, SEEK_END); 498c30d921cSKever Yang iFileSize = ftell(file); 499c30d921cSKever Yang fseek(file, 0, SEEK_SET); 500c30d921cSKever Yang char *pParamBuf = NULL; 501c30d921cSKever Yang pParamBuf = new char[iFileSize]; 502c30d921cSKever Yang if (!pParamBuf) { 503c30d921cSKever Yang fclose(file); 504c30d921cSKever Yang return false; 505c30d921cSKever Yang } 506c30d921cSKever Yang int iRead; 507c30d921cSKever Yang iRead = fread(pParamBuf, 1, iFileSize, file); 508c30d921cSKever Yang if (iRead != iFileSize) { 509c30d921cSKever Yang if (g_pLogObject) 51032268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize); 511c30d921cSKever Yang fclose(file); 512c30d921cSKever Yang delete []pParamBuf; 513c30d921cSKever Yang return false; 514c30d921cSKever Yang } 515c30d921cSKever Yang fclose(file); 516c30d921cSKever Yang bool bRet; 517c29e5f0fSliuyi bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem); 518c30d921cSKever Yang delete []pParamBuf; 519c30d921cSKever Yang return bRet; 520c30d921cSKever Yang } 5216ae612beSliuyi bool is_sparse_image(char *szImage) 5226ae612beSliuyi { 5236ae612beSliuyi FILE *file = NULL; 5246ae612beSliuyi sparse_header head; 5256ae612beSliuyi u32 uiRead; 5266ae612beSliuyi file = fopen(szImage, "rb"); 5276ae612beSliuyi if( !file ) { 5286ae612beSliuyi if (g_pLogObject) 5296ae612beSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage); 5306ae612beSliuyi return false; 5316ae612beSliuyi } 5326ae612beSliuyi uiRead = fread(&head, 1, sizeof(head), file); 5336ae612beSliuyi if (uiRead != sizeof(head)) { 5346ae612beSliuyi if (g_pLogObject) 5356ae612beSliuyi g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head)); 5366ae612beSliuyi fclose(file); 5376ae612beSliuyi return false; 5386ae612beSliuyi } 5396ae612beSliuyi fclose(file); 5406ae612beSliuyi if (head.magic!=SPARSE_HEADER_MAGIC) 5416ae612beSliuyi { 5426ae612beSliuyi return false; 5436ae612beSliuyi } 5446ae612beSliuyi return true; 5456ae612beSliuyi 5466ae612beSliuyi } 547c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin) 548c30d921cSKever Yang { 549c30d921cSKever Yang efi_guid_t id; 550c30d921cSKever Yang unsigned int *ptr = (unsigned int *)&id; 551c30d921cSKever Yang unsigned int i; 552c30d921cSKever Yang 553c30d921cSKever Yang /* Set all fields randomly */ 554c30d921cSKever Yang for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 555c30d921cSKever Yang *(ptr + i) = cpu_to_be32(rand()); 556c30d921cSKever Yang 557c30d921cSKever Yang id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 558c30d921cSKever Yang id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 559c30d921cSKever Yang 560c30d921cSKever Yang memcpy(uuid_bin, id.raw, sizeof(id)); 561c30d921cSKever Yang } 562c30d921cSKever Yang 563c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup) 564c29e5f0fSliuyi { 565c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 566c29e5f0fSliuyi gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE); 567c29e5f0fSliuyi u32 calc_crc32; 568c29e5f0fSliuyi u64 val; 569c29e5f0fSliuyi 570c29e5f0fSliuyi /* recalculate the values for the Backup GPT Header */ 571c29e5f0fSliuyi val = le64_to_cpu(gptMasterHead->my_lba); 572c29e5f0fSliuyi gptBackupHead->my_lba = gptMasterHead->alternate_lba; 573c29e5f0fSliuyi gptBackupHead->alternate_lba = cpu_to_le64(val); 574c29e5f0fSliuyi gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1); 575c29e5f0fSliuyi gptBackupHead->header_crc32 = 0; 576c29e5f0fSliuyi 577c29e5f0fSliuyi calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size)); 578c29e5f0fSliuyi gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32); 579c29e5f0fSliuyi } 5806ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end) 5816ae612beSliuyi { 5826ae612beSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 5836ae612beSliuyi gpt_entry *gptEntry = NULL; 5846ae612beSliuyi u32 i,j; 5856ae612beSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 5866ae612beSliuyi bool bFound = false; 5876ae612beSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 5886ae612beSliuyi 5896ae612beSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 5906ae612beSliuyi gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 5916ae612beSliuyi if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0) 5926ae612beSliuyi break; 5936ae612beSliuyi for (j = 0; j < strlen(pszName); j++) 5946ae612beSliuyi if (gptEntry->partition_name[j] != pszName[j]) 5956ae612beSliuyi break; 5966ae612beSliuyi if (gptEntry->partition_name[j] != 0) 5976ae612beSliuyi continue; 5986ae612beSliuyi if (j == strlen(pszName)) { 5996ae612beSliuyi bFound = true; 6006ae612beSliuyi break; 6016ae612beSliuyi } 6026ae612beSliuyi } 6036ae612beSliuyi if (bFound) { 6046ae612beSliuyi *lba = le64_to_cpu(gptEntry->starting_lba); 6056ae612beSliuyi *lba_end = le64_to_cpu(gptEntry->ending_lba); 6066ae612beSliuyi return true; 6076ae612beSliuyi } 6086ae612beSliuyi return false; 6096ae612beSliuyi } 610c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector) 611c29e5f0fSliuyi { 612c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 613c29e5f0fSliuyi gpt_entry *gptLastPartEntry = NULL; 614c29e5f0fSliuyi u32 i; 615c29e5f0fSliuyi u64 old_disksize; 616c29e5f0fSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 617c29e5f0fSliuyi 618c29e5f0fSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 619c29e5f0fSliuyi old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1; 620c29e5f0fSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 621c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 622c29e5f0fSliuyi if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0) 623c29e5f0fSliuyi break; 624c29e5f0fSliuyi } 625c29e5f0fSliuyi i--; 626c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry)); 627c29e5f0fSliuyi 628c29e5f0fSliuyi gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1); 629c29e5f0fSliuyi gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34); 630c29e5f0fSliuyi 631c29e5f0fSliuyi if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition 632c29e5f0fSliuyi gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34); 633c29e5f0fSliuyi gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 634c29e5f0fSliuyi } 635c29e5f0fSliuyi gptMasterHead->header_crc32 = 0; 636c29e5f0fSliuyi gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header))); 637c29e5f0fSliuyi memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS); 638c29e5f0fSliuyi memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE); 639c29e5f0fSliuyi prepare_gpt_backup(master, backup); 640c29e5f0fSliuyi 641c29e5f0fSliuyi } 642c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup) 643c29e5f0fSliuyi { 644c29e5f0fSliuyi FILE *file = NULL; 645c29e5f0fSliuyi file = fopen(pParamFile, "rb"); 646c29e5f0fSliuyi if( !file ) { 647c29e5f0fSliuyi if (g_pLogObject) 648c29e5f0fSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 649c29e5f0fSliuyi return false; 650c29e5f0fSliuyi } 651c29e5f0fSliuyi int iFileSize; 652c29e5f0fSliuyi fseek(file, 0, SEEK_END); 653c29e5f0fSliuyi iFileSize = ftell(file); 654c29e5f0fSliuyi fseek(file, 0, SEEK_SET); 655c29e5f0fSliuyi if (iFileSize != 67 * SECTOR_SIZE) { 656c29e5f0fSliuyi if (g_pLogObject) 657c29e5f0fSliuyi g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile); 658c29e5f0fSliuyi fclose(file); 659c29e5f0fSliuyi return false; 660c29e5f0fSliuyi } 661c29e5f0fSliuyi 662c29e5f0fSliuyi int iRead; 663c29e5f0fSliuyi iRead = fread(master, 1, 34 * SECTOR_SIZE, file); 664c29e5f0fSliuyi if (iRead != 34 * SECTOR_SIZE) { 665c29e5f0fSliuyi if (g_pLogObject) 666c29e5f0fSliuyi g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE); 667c29e5f0fSliuyi fclose(file); 668c29e5f0fSliuyi return false; 669c29e5f0fSliuyi } 670c29e5f0fSliuyi iRead = fread(backup, 1, 33 * SECTOR_SIZE, file); 671c29e5f0fSliuyi if (iRead != 33 * SECTOR_SIZE) { 672c29e5f0fSliuyi if (g_pLogObject) 673c29e5f0fSliuyi g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE); 674c29e5f0fSliuyi fclose(file); 675c29e5f0fSliuyi return false; 676c29e5f0fSliuyi } 677c29e5f0fSliuyi fclose(file); 678c29e5f0fSliuyi return true; 679c29e5f0fSliuyi } 680c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors) 681c30d921cSKever Yang { 682c30d921cSKever Yang legacy_mbr *mbr = (legacy_mbr *)gpt; 683c30d921cSKever Yang gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 684c30d921cSKever Yang gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 685c30d921cSKever Yang u32 i,j; 686c29e5f0fSliuyi int pos; 687c30d921cSKever Yang string strPartName; 688c30d921cSKever Yang string::size_type colonPos; 689c30d921cSKever Yang /*1.protective mbr*/ 690c30d921cSKever Yang memset(gpt, 0, SECTOR_SIZE); 691c30d921cSKever Yang mbr->signature = MSDOS_MBR_SIGNATURE; 692c30d921cSKever Yang mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 693c30d921cSKever Yang mbr->partition_record[0].start_sect = 1; 694c30d921cSKever Yang mbr->partition_record[0].nr_sects = (u32)-1; 695c30d921cSKever Yang /*2.gpt header*/ 696c30d921cSKever Yang memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 697c30d921cSKever Yang gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 698c30d921cSKever Yang gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 699c30d921cSKever Yang gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 700c30d921cSKever Yang gptHead->my_lba = cpu_to_le64(1); 701c30d921cSKever Yang gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 702c30d921cSKever Yang gptHead->first_usable_lba = cpu_to_le64(34); 703c30d921cSKever Yang gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 704c30d921cSKever Yang gptHead->partition_entry_lba = cpu_to_le64(2); 705c30d921cSKever Yang gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 706c30d921cSKever Yang gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 707c30d921cSKever Yang gptHead->header_crc32 = 0; 708c30d921cSKever Yang gptHead->partition_entry_array_crc32 = 0; 709c30d921cSKever Yang gen_rand_uuid(gptHead->disk_guid.raw); 710c30d921cSKever Yang 711c30d921cSKever Yang /*3.gpt partition entry*/ 712c30d921cSKever Yang memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 713c30d921cSKever Yang for (i = 0; i < vecParts.size(); i++) { 714c30d921cSKever Yang gen_rand_uuid(gptEntry->partition_type_guid.raw); 715c30d921cSKever Yang gen_rand_uuid(gptEntry->unique_partition_guid.raw); 716c30d921cSKever Yang gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 717c30d921cSKever Yang gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 718c30d921cSKever Yang gptEntry->attributes.raw = 0; 719c30d921cSKever Yang strPartName = vecParts[i].szItemName; 720c30d921cSKever Yang colonPos = strPartName.find_first_of(':'); 721c30d921cSKever Yang if (colonPos != string::npos) { 722c30d921cSKever Yang if (strPartName.find("bootable") != string::npos) 723c30d921cSKever Yang gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 724c29e5f0fSliuyi if (strPartName.find("grow") != string::npos) 725c29e5f0fSliuyi gptEntry->ending_lba = cpu_to_le64(diskSectors - 34); 726c30d921cSKever Yang strPartName = strPartName.substr(0, colonPos); 727c30d921cSKever Yang vecParts[i].szItemName[strPartName.size()] = 0; 728c30d921cSKever Yang } 729c30d921cSKever Yang for (j = 0; j < strlen(vecParts[i].szItemName); j++) 730c30d921cSKever Yang gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 731c29e5f0fSliuyi if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1) 732c29e5f0fSliuyi memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16); 733c30d921cSKever Yang gptEntry++; 734c30d921cSKever Yang } 735c30d921cSKever Yang 736c30d921cSKever Yang gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 737c30d921cSKever Yang gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 738c30d921cSKever Yang 739c30d921cSKever Yang } 740b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag) 741c30d921cSKever Yang { 742c30d921cSKever Yang PRK28_IDB_SEC0 pSec0; 743c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 744c30d921cSKever Yang pSec0 = (PRK28_IDB_SEC0)pSector; 745c30d921cSKever Yang 746c30d921cSKever Yang pSec0->dwTag = 0x0FF0AA55; 747b38fe5fcSliuyi pSec0->uiRc4Flag = rc4Flag; 748c30d921cSKever Yang pSec0->usBootCode1Offset = 0x4; 749c30d921cSKever Yang pSec0->usBootCode2Offset = 0x4; 750c30d921cSKever Yang pSec0->usBootDataSize = usFlashDataSec; 751c30d921cSKever Yang pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 752c30d921cSKever Yang return true; 753c30d921cSKever Yang } 754c30d921cSKever Yang 755c30d921cSKever Yang 756c30d921cSKever Yang bool MakeSector1(PBYTE pSector) 757c30d921cSKever Yang { 758c30d921cSKever Yang PRK28_IDB_SEC1 pSec1; 759c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 760c30d921cSKever Yang pSec1 = (PRK28_IDB_SEC1)pSector; 761c30d921cSKever Yang 762c30d921cSKever Yang pSec1->usSysReservedBlock = 0xC; 763c30d921cSKever Yang pSec1->usDisk0Size = 0xFFFF; 764c30d921cSKever Yang pSec1->uiChipTag = 0x38324B52; 765c30d921cSKever Yang return true; 766c30d921cSKever Yang } 767c30d921cSKever Yang 768c30d921cSKever Yang bool MakeSector2(PBYTE pSector) 769c30d921cSKever Yang { 770c30d921cSKever Yang PRK28_IDB_SEC2 pSec2; 771c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 772c30d921cSKever Yang pSec2 = (PRK28_IDB_SEC2)pSector; 773c30d921cSKever Yang 774c30d921cSKever Yang strcpy(pSec2->szVcTag, "VC"); 775c30d921cSKever Yang strcpy(pSec2->szCrcTag, "CRC"); 776c30d921cSKever Yang return true; 777c30d921cSKever Yang } 778c30d921cSKever Yang 779c30d921cSKever Yang bool MakeSector3(PBYTE pSector) 780c30d921cSKever Yang { 781c30d921cSKever Yang memset(pSector,0,SECTOR_SIZE); 782c30d921cSKever Yang return true; 783c30d921cSKever Yang } 784c30d921cSKever Yang 785b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag) 786c30d921cSKever Yang { 787c30d921cSKever Yang RK28_IDB_SEC0 sector0Info; 788c30d921cSKever Yang RK28_IDB_SEC1 sector1Info; 789c30d921cSKever Yang RK28_IDB_SEC2 sector2Info; 790c30d921cSKever Yang RK28_IDB_SEC3 sector3Info; 791c30d921cSKever Yang UINT i; 792b38fe5fcSliuyi MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag); 793c30d921cSKever Yang MakeSector1((PBYTE)§or1Info); 794c30d921cSKever Yang if (!MakeSector2((PBYTE)§or2Info)) { 795c30d921cSKever Yang return -6; 796c30d921cSKever Yang } 797c30d921cSKever Yang if (!MakeSector3((PBYTE)§or3Info)) { 798c30d921cSKever Yang return -7; 799c30d921cSKever Yang } 800c30d921cSKever Yang sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 801c30d921cSKever Yang sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 802c30d921cSKever Yang sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 803c30d921cSKever Yang 804c30d921cSKever Yang memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 805c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 806c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 807b38fe5fcSliuyi 808b38fe5fcSliuyi if (rc4Flag) { 809b38fe5fcSliuyi for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++) 810b38fe5fcSliuyi P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE); 811b38fe5fcSliuyi for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++) 812b38fe5fcSliuyi P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE); 813b38fe5fcSliuyi } 814b38fe5fcSliuyi 815c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 816c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 817c30d921cSKever Yang 818c30d921cSKever Yang sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 819c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 820c30d921cSKever Yang for(i = 0; i < 4; i++) { 821c30d921cSKever Yang if(i == 1) { 822c30d921cSKever Yang continue; 823c30d921cSKever Yang } else { 824c30d921cSKever Yang P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 825c30d921cSKever Yang } 826c30d921cSKever Yang } 827c30d921cSKever Yang return 0; 828c30d921cSKever Yang } 829c30d921cSKever Yang 830c30d921cSKever Yang 83176af099aSliuyi 83276af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 83376af099aSliuyi { 83476af099aSliuyi if ((dev.emUsbType & uiSupportType) == dev.emUsbType) 83576af099aSliuyi return true; 83676af099aSliuyi else 83776af099aSliuyi { 83876af099aSliuyi ERROR_COLOR_ATTR; 83932268622SAndreas Färber printf("The device does not support this operation!"); 84076af099aSliuyi NORMAL_COLOR_ATTR; 84176af099aSliuyi printf("\r\n"); 84276af099aSliuyi return false; 84376af099aSliuyi } 84476af099aSliuyi } 845c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 846c30d921cSKever Yang { 847c30d921cSKever Yang u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 848c30d921cSKever Yang u32 total_size_sector; 849c30d921cSKever Yang CRKComm *pComm = NULL; 850c30d921cSKever Yang PARAM_ITEM_VECTOR vecItems; 851c29e5f0fSliuyi CONFIG_ITEM_VECTOR vecUuid; 852c30d921cSKever Yang int iRet; 853c30d921cSKever Yang bool bRet, bSuccess = false; 854c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 855c30d921cSKever Yang return false; 856c30d921cSKever Yang 857c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 858c30d921cSKever Yang if (!bRet) { 859c30d921cSKever Yang ERROR_COLOR_ATTR; 860c30d921cSKever Yang printf("Creating Comm Object failed!"); 861c30d921cSKever Yang NORMAL_COLOR_ATTR; 862c30d921cSKever Yang printf("\r\n"); 863c30d921cSKever Yang return bSuccess; 864c30d921cSKever Yang } 86532268622SAndreas Färber printf("Writing gpt...\r\n"); 866c30d921cSKever Yang //1.get flash info 867c30d921cSKever Yang iRet = pComm->RKU_ReadFlashInfo(flash_info); 868c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 869c30d921cSKever Yang ERROR_COLOR_ATTR; 870c30d921cSKever Yang printf("Reading Flash Info failed!"); 871c30d921cSKever Yang NORMAL_COLOR_ATTR; 872c30d921cSKever Yang printf("\r\n"); 873c30d921cSKever Yang return bSuccess; 874c30d921cSKever Yang } 875c30d921cSKever Yang total_size_sector = *(u32 *)flash_info; 876c29e5f0fSliuyi if (strstr(szParameter, ".img")) { 877c29e5f0fSliuyi if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) { 878c29e5f0fSliuyi ERROR_COLOR_ATTR; 879c29e5f0fSliuyi printf("Loading partition image failed!"); 880c29e5f0fSliuyi NORMAL_COLOR_ATTR; 881c29e5f0fSliuyi printf("\r\n"); 882c29e5f0fSliuyi return bSuccess; 883c29e5f0fSliuyi } 884c29e5f0fSliuyi update_gpt_disksize(master_gpt, backup_gpt, total_size_sector); 885c29e5f0fSliuyi } else { 886c30d921cSKever Yang //2.get partition from parameter 887c29e5f0fSliuyi bRet = parse_parameter_file(szParameter, vecItems, vecUuid); 888c30d921cSKever Yang if (!bRet) { 889c30d921cSKever Yang ERROR_COLOR_ATTR; 890c30d921cSKever Yang printf("Parsing parameter failed!"); 891c30d921cSKever Yang NORMAL_COLOR_ATTR; 892c30d921cSKever Yang printf("\r\n"); 893c30d921cSKever Yang return bSuccess; 894c30d921cSKever Yang } 895c29e5f0fSliuyi vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33; 896c30d921cSKever Yang //3.generate gpt info 897c29e5f0fSliuyi create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector); 898c30d921cSKever Yang memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 899c30d921cSKever Yang memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 900c29e5f0fSliuyi prepare_gpt_backup(master_gpt, backup_gpt); 901c29e5f0fSliuyi } 902c29e5f0fSliuyi 903c30d921cSKever Yang //4. write gpt 904c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 905c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 906c30d921cSKever Yang ERROR_COLOR_ATTR; 907c30d921cSKever Yang printf("Writing master gpt failed!"); 908c30d921cSKever Yang NORMAL_COLOR_ATTR; 909c30d921cSKever Yang printf("\r\n"); 910c30d921cSKever Yang return bSuccess; 911c30d921cSKever Yang } 912c29e5f0fSliuyi iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt); 913c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 914c30d921cSKever Yang ERROR_COLOR_ATTR; 915c30d921cSKever Yang printf("Writing backup gpt failed!"); 916c30d921cSKever Yang NORMAL_COLOR_ATTR; 917c30d921cSKever Yang printf("\r\n"); 918c30d921cSKever Yang return bSuccess; 919c30d921cSKever Yang } 920c29e5f0fSliuyi 921c30d921cSKever Yang bSuccess = true; 922c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 923c30d921cSKever Yang CURSOR_DEL_LINE; 92432268622SAndreas Färber printf("Writing gpt succeeded.\r\n"); 925c30d921cSKever Yang return bSuccess; 926c30d921cSKever Yang } 92776af099aSliuyi 92878884ef4SEddie Cai #include "boot_merger.h" 92978884ef4SEddie Cai #define ENTRY_ALIGN (2048) 93078884ef4SEddie Cai options gOpts; 93178884ef4SEddie Cai 93278884ef4SEddie Cai 93378884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 93478884ef4SEddie Cai char* gConfigPath; 93578884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE]; 93678884ef4SEddie Cai 93778884ef4SEddie Cai static inline void fixPath(char* path) { 93878884ef4SEddie Cai int i, len = strlen(path); 93978884ef4SEddie Cai for(i=0; i<len; i++) { 94078884ef4SEddie Cai if (path[i] == '\\') 94178884ef4SEddie Cai path[i] = '/'; 94278884ef4SEddie Cai else if (path[i] == '\r' || path[i] == '\n') 94378884ef4SEddie Cai path[i] = '\0'; 94478884ef4SEddie Cai } 94578884ef4SEddie Cai } 94678884ef4SEddie Cai 94778884ef4SEddie Cai static bool parseChip(FILE* file) { 94878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 94978884ef4SEddie Cai return false; 95078884ef4SEddie Cai } 95178884ef4SEddie Cai if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 95278884ef4SEddie Cai return false; 95378884ef4SEddie Cai } 95478884ef4SEddie Cai printf("chip: %s\n", gOpts.chip); 95578884ef4SEddie Cai return true; 95678884ef4SEddie Cai } 95778884ef4SEddie Cai 95878884ef4SEddie Cai static bool parseVersion(FILE* file) { 95978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 96078884ef4SEddie Cai return false; 96178884ef4SEddie Cai } 96278884ef4SEddie Cai if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 96378884ef4SEddie Cai return false; 96478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 96578884ef4SEddie Cai return false; 96678884ef4SEddie Cai } 96778884ef4SEddie Cai if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 96878884ef4SEddie Cai return false; 96978884ef4SEddie Cai printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor); 97078884ef4SEddie Cai return true; 97178884ef4SEddie Cai } 97278884ef4SEddie Cai 97378884ef4SEddie Cai static bool parse471(FILE* file) { 97478884ef4SEddie Cai int i, index, pos; 97578884ef4SEddie Cai char buf[MAX_LINE_LEN]; 97678884ef4SEddie Cai 97778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 97878884ef4SEddie Cai return false; 97978884ef4SEddie Cai } 98078884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 98178884ef4SEddie Cai return false; 98278884ef4SEddie Cai printf("num: %d\n", gOpts.code471Num); 98378884ef4SEddie Cai if (!gOpts.code471Num) 98478884ef4SEddie Cai return true; 98578884ef4SEddie Cai if (gOpts.code471Num < 0) 98678884ef4SEddie Cai return false; 98778884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 98878884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 98978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 99078884ef4SEddie Cai return false; 99178884ef4SEddie Cai } 99278884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 99378884ef4SEddie Cai != 2) 99478884ef4SEddie Cai return false; 99578884ef4SEddie Cai index--; 99678884ef4SEddie Cai fixPath(buf); 99778884ef4SEddie Cai strcpy((char*)gOpts.code471Path[index], buf); 99878884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code471Path[index]); 99978884ef4SEddie Cai } 100078884ef4SEddie Cai pos = ftell(file); 100178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 100278884ef4SEddie Cai return false; 100378884ef4SEddie Cai } 100478884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 100578884ef4SEddie Cai fseek(file, pos, SEEK_SET); 100678884ef4SEddie Cai printf("sleep: %d\n", gOpts.code471Sleep); 100778884ef4SEddie Cai return true; 100878884ef4SEddie Cai } 100978884ef4SEddie Cai 101078884ef4SEddie Cai static bool parse472(FILE* file) { 101178884ef4SEddie Cai int i, index, pos; 101278884ef4SEddie Cai char buf[MAX_LINE_LEN]; 101378884ef4SEddie Cai 101478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 101578884ef4SEddie Cai return false; 101678884ef4SEddie Cai } 101778884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 101878884ef4SEddie Cai return false; 101978884ef4SEddie Cai printf("num: %d\n", gOpts.code472Num); 102078884ef4SEddie Cai if (!gOpts.code472Num) 102178884ef4SEddie Cai return true; 102278884ef4SEddie Cai if (gOpts.code472Num < 0) 102378884ef4SEddie Cai return false; 102478884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 102578884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 102678884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 102778884ef4SEddie Cai return false; 102878884ef4SEddie Cai } 102978884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 103078884ef4SEddie Cai != 2) 103178884ef4SEddie Cai return false; 103278884ef4SEddie Cai fixPath(buf); 103378884ef4SEddie Cai index--; 103478884ef4SEddie Cai strcpy((char*)gOpts.code472Path[index], buf); 103578884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code472Path[index]); 103678884ef4SEddie Cai } 103778884ef4SEddie Cai pos = ftell(file); 103878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 103978884ef4SEddie Cai return false; 104078884ef4SEddie Cai } 104178884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 104278884ef4SEddie Cai fseek(file, pos, SEEK_SET); 104378884ef4SEddie Cai printf("sleep: %d\n", gOpts.code472Sleep); 104478884ef4SEddie Cai return true; 104578884ef4SEddie Cai } 104678884ef4SEddie Cai 104778884ef4SEddie Cai static bool parseLoader(FILE* file) { 104878884ef4SEddie Cai int i, j, index, pos; 104978884ef4SEddie Cai char buf[MAX_LINE_LEN]; 105078884ef4SEddie Cai char buf2[MAX_LINE_LEN]; 105178884ef4SEddie Cai 105278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 105378884ef4SEddie Cai return false; 105478884ef4SEddie Cai } 105578884ef4SEddie Cai pos = ftell(file); 105678884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 105778884ef4SEddie Cai fseek(file, pos, SEEK_SET); 105878884ef4SEddie Cai if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 105978884ef4SEddie Cai return false; 106078884ef4SEddie Cai } 106178884ef4SEddie Cai } 106278884ef4SEddie Cai printf("num: %d\n", gOpts.loaderNum); 106378884ef4SEddie Cai if (!gOpts.loaderNum) 106478884ef4SEddie Cai return false; 106578884ef4SEddie Cai if (gOpts.loaderNum < 0) 106678884ef4SEddie Cai return false; 106778884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 106878884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 106978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 107078884ef4SEddie Cai return false; 107178884ef4SEddie Cai } 107278884ef4SEddie Cai if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 107378884ef4SEddie Cai != 2) 107478884ef4SEddie Cai return false; 107578884ef4SEddie Cai index--; 107678884ef4SEddie Cai strcpy(gOpts.loader[index].name, buf); 107778884ef4SEddie Cai printf("name%d: %s\n", index, gOpts.loader[index].name); 107878884ef4SEddie Cai } 107978884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 108078884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 108178884ef4SEddie Cai return false; 108278884ef4SEddie Cai } 108378884ef4SEddie Cai if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 108478884ef4SEddie Cai != 2) 108578884ef4SEddie Cai return false; 108678884ef4SEddie Cai for (j=0; j<gOpts.loaderNum; j++) { 108778884ef4SEddie Cai if (!strcmp(gOpts.loader[j].name, buf)) { 108878884ef4SEddie Cai fixPath(buf2); 108978884ef4SEddie Cai strcpy(gOpts.loader[j].path, buf2); 109078884ef4SEddie Cai printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 109178884ef4SEddie Cai break; 109278884ef4SEddie Cai } 109378884ef4SEddie Cai } 109478884ef4SEddie Cai if (j >= gOpts.loaderNum) { 109578884ef4SEddie Cai return false; 109678884ef4SEddie Cai } 109778884ef4SEddie Cai } 109878884ef4SEddie Cai return true; 109978884ef4SEddie Cai } 110078884ef4SEddie Cai 110178884ef4SEddie Cai static bool parseOut(FILE* file) { 110278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 110378884ef4SEddie Cai return false; 110478884ef4SEddie Cai } 110578884ef4SEddie Cai if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 110678884ef4SEddie Cai return false; 110778884ef4SEddie Cai fixPath(gOpts.outPath); 110878884ef4SEddie Cai printf("out: %s\n", gOpts.outPath); 110978884ef4SEddie Cai return true; 111078884ef4SEddie Cai } 111178884ef4SEddie Cai 111278884ef4SEddie Cai 111378884ef4SEddie Cai void printOpts(FILE* out) { 111478884ef4SEddie Cai int i; 111578884ef4SEddie Cai fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 111678884ef4SEddie Cai fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 111778884ef4SEddie Cai "=%d\n", gOpts.major, gOpts.minor); 111878884ef4SEddie Cai 111978884ef4SEddie Cai fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 112078884ef4SEddie Cai for (i=0 ;i<gOpts.code471Num ;i++) { 112178884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 112278884ef4SEddie Cai } 112378884ef4SEddie Cai if (gOpts.code471Sleep > 0) 112478884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 112578884ef4SEddie Cai 112678884ef4SEddie Cai fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 112778884ef4SEddie Cai for (i=0 ;i<gOpts.code472Num ;i++) { 112878884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 112978884ef4SEddie Cai } 113078884ef4SEddie Cai if (gOpts.code472Sleep > 0) 113178884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 113278884ef4SEddie Cai 113378884ef4SEddie Cai fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 113478884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 113578884ef4SEddie Cai fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 113678884ef4SEddie Cai } 113778884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 113878884ef4SEddie Cai fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 113978884ef4SEddie Cai } 114078884ef4SEddie Cai 114178884ef4SEddie Cai fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 114278884ef4SEddie Cai } 114378884ef4SEddie Cai 114478884ef4SEddie Cai static bool parseOpts(void) { 114578884ef4SEddie Cai bool ret = false; 114678884ef4SEddie Cai bool chipOk = false; 114778884ef4SEddie Cai bool versionOk = false; 114878884ef4SEddie Cai bool code471Ok = true; 114978884ef4SEddie Cai bool code472Ok = true; 115078884ef4SEddie Cai bool loaderOk = false; 115178884ef4SEddie Cai bool outOk = false; 115278884ef4SEddie Cai char buf[MAX_LINE_LEN]; 115378884ef4SEddie Cai 115478884ef4SEddie Cai char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 115578884ef4SEddie Cai FILE* file; 115678884ef4SEddie Cai file = fopen(configPath, "r"); 115778884ef4SEddie Cai if (!file) { 115878884ef4SEddie Cai fprintf(stderr, "config (%s) not found!\n", configPath); 115978884ef4SEddie Cai if (configPath == (char*)DEF_CONFIG_FILE) { 116078884ef4SEddie Cai file = fopen(DEF_CONFIG_FILE, "w"); 116178884ef4SEddie Cai if (file) { 116232268622SAndreas Färber fprintf(stderr, "creating defconfig\n"); 116378884ef4SEddie Cai printOpts(file); 116478884ef4SEddie Cai } 116578884ef4SEddie Cai } 116678884ef4SEddie Cai goto end; 116778884ef4SEddie Cai } 116878884ef4SEddie Cai 116932268622SAndreas Färber printf("Starting to parse...\n"); 117078884ef4SEddie Cai 117178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 117278884ef4SEddie Cai goto end; 117378884ef4SEddie Cai } 117478884ef4SEddie Cai while(fscanf(file, "%s", buf) == 1) { 117578884ef4SEddie Cai if (!strcmp(buf, SEC_CHIP)) { 117678884ef4SEddie Cai chipOk = parseChip(file); 117778884ef4SEddie Cai if (!chipOk) { 117878884ef4SEddie Cai printf("parseChip failed!\n"); 117978884ef4SEddie Cai goto end; 118078884ef4SEddie Cai } 118178884ef4SEddie Cai } else if (!strcmp(buf, SEC_VERSION)) { 118278884ef4SEddie Cai versionOk = parseVersion(file); 118378884ef4SEddie Cai if (!versionOk) { 118478884ef4SEddie Cai printf("parseVersion failed!\n"); 118578884ef4SEddie Cai goto end; 118678884ef4SEddie Cai } 118778884ef4SEddie Cai } else if (!strcmp(buf, SEC_471)) { 118878884ef4SEddie Cai code471Ok = parse471(file); 118978884ef4SEddie Cai if (!code471Ok) { 119078884ef4SEddie Cai printf("parse471 failed!\n"); 119178884ef4SEddie Cai goto end; 119278884ef4SEddie Cai } 119378884ef4SEddie Cai } else if (!strcmp(buf, SEC_472)) { 119478884ef4SEddie Cai code472Ok = parse472(file); 119578884ef4SEddie Cai if (!code472Ok) { 119678884ef4SEddie Cai printf("parse472 failed!\n"); 119778884ef4SEddie Cai goto end; 119878884ef4SEddie Cai } 119978884ef4SEddie Cai } else if (!strcmp(buf, SEC_LOADER)) { 120078884ef4SEddie Cai loaderOk = parseLoader(file); 120178884ef4SEddie Cai if (!loaderOk) { 120278884ef4SEddie Cai printf("parseLoader failed!\n"); 120378884ef4SEddie Cai goto end; 120478884ef4SEddie Cai } 120578884ef4SEddie Cai } else if (!strcmp(buf, SEC_OUT)) { 120678884ef4SEddie Cai outOk = parseOut(file); 120778884ef4SEddie Cai if (!outOk) { 120878884ef4SEddie Cai printf("parseOut failed!\n"); 120978884ef4SEddie Cai goto end; 121078884ef4SEddie Cai } 121178884ef4SEddie Cai } else if (buf[0] == '#') { 121278884ef4SEddie Cai continue; 121378884ef4SEddie Cai } else { 121478884ef4SEddie Cai printf("unknown sec: %s!\n", buf); 121578884ef4SEddie Cai goto end; 121678884ef4SEddie Cai } 121778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 121878884ef4SEddie Cai goto end; 121978884ef4SEddie Cai } 122078884ef4SEddie Cai } 122178884ef4SEddie Cai 122278884ef4SEddie Cai if (chipOk && versionOk && code471Ok && code472Ok 122378884ef4SEddie Cai && loaderOk && outOk) 122478884ef4SEddie Cai ret = true; 122578884ef4SEddie Cai end: 122678884ef4SEddie Cai if (file) 122778884ef4SEddie Cai fclose(file); 122878884ef4SEddie Cai return ret; 122978884ef4SEddie Cai } 123078884ef4SEddie Cai 123178884ef4SEddie Cai bool initOpts(void) { 123278884ef4SEddie Cai //set default opts 123378884ef4SEddie Cai gOpts.major = DEF_MAJOR; 123478884ef4SEddie Cai gOpts.minor = DEF_MINOR; 123578884ef4SEddie Cai strcpy(gOpts.chip, DEF_CHIP); 123678884ef4SEddie Cai gOpts.code471Sleep = DEF_CODE471_SLEEP; 123778884ef4SEddie Cai gOpts.code472Sleep = DEF_CODE472_SLEEP; 123878884ef4SEddie Cai gOpts.code471Num = DEF_CODE471_NUM; 123978884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 124078884ef4SEddie Cai strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 124178884ef4SEddie Cai gOpts.code472Num = DEF_CODE472_NUM; 124278884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 124378884ef4SEddie Cai strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 124478884ef4SEddie Cai gOpts.loaderNum = DEF_LOADER_NUM; 124578884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 124678884ef4SEddie Cai strcpy(gOpts.loader[0].name, DEF_LOADER0); 124778884ef4SEddie Cai strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 124878884ef4SEddie Cai strcpy(gOpts.loader[1].name, DEF_LOADER1); 124978884ef4SEddie Cai strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 125078884ef4SEddie Cai strcpy(gOpts.outPath, DEF_OUT_PATH); 125178884ef4SEddie Cai 125278884ef4SEddie Cai return parseOpts(); 125378884ef4SEddie Cai } 125478884ef4SEddie Cai 125578884ef4SEddie Cai /************merge code****************/ 125678884ef4SEddie Cai 125778884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) { 125878884ef4SEddie Cai uint8_t tmp[2] = {0}; 125978884ef4SEddie Cai int i; 126078884ef4SEddie Cai uint32_t ret; 126178884ef4SEddie Cai //if (value > 0xFFFF) { 126278884ef4SEddie Cai // return 0; 126378884ef4SEddie Cai //} 126478884ef4SEddie Cai for(i=0; i < 2; i++) { 126578884ef4SEddie Cai tmp[i] = (((value/10)%10)<<4) | (value%10); 126678884ef4SEddie Cai value /= 100; 126778884ef4SEddie Cai } 126878884ef4SEddie Cai ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 126978884ef4SEddie Cai 127078884ef4SEddie Cai printf("ret: %x\n",ret); 127178884ef4SEddie Cai return ret&0xFF; 127278884ef4SEddie Cai } 127378884ef4SEddie Cai 127478884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len) 127578884ef4SEddie Cai { 127678884ef4SEddie Cai int i; 127778884ef4SEddie Cai for (i = 0; i < len; i++) { 127878884ef4SEddie Cai wide[i] = (uint16_t) str[i]; 127978884ef4SEddie Cai } 128078884ef4SEddie Cai wide[len] = 0; 128178884ef4SEddie Cai } 128278884ef4SEddie Cai 128378884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) { 128478884ef4SEddie Cai char* end; 128578884ef4SEddie Cai char* start; 128678884ef4SEddie Cai int len; 128778884ef4SEddie Cai if (!path || !dst) 128878884ef4SEddie Cai return; 128978884ef4SEddie Cai start = strrchr(path, '/'); 129078884ef4SEddie Cai if (!start) 129178884ef4SEddie Cai start = path; 129278884ef4SEddie Cai else 129378884ef4SEddie Cai start++; 129478884ef4SEddie Cai end = strrchr(path, '.'); 1295641cfa16SEddie Cai if (!end || (end < start)) 129678884ef4SEddie Cai end = path + strlen(path); 129778884ef4SEddie Cai len = end - start; 129878884ef4SEddie Cai if (len >= MAX_NAME_LEN) 129978884ef4SEddie Cai len = MAX_NAME_LEN -1; 130078884ef4SEddie Cai str2wide(start, dst, len); 130178884ef4SEddie Cai 130278884ef4SEddie Cai 130378884ef4SEddie Cai char name[MAX_NAME_LEN]; 130478884ef4SEddie Cai memset(name, 0, sizeof(name)); 130578884ef4SEddie Cai memcpy(name, start, len); 130678884ef4SEddie Cai printf("path: %s, name: %s\n", path, name); 130778884ef4SEddie Cai 130878884ef4SEddie Cai } 130978884ef4SEddie Cai 131078884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) { 131178884ef4SEddie Cai struct stat st; 131278884ef4SEddie Cai if(stat(path, &st) < 0) 131378884ef4SEddie Cai return false; 131478884ef4SEddie Cai *size = st.st_size; 131578884ef4SEddie Cai printf("path: %s, size: %d\n", path, *size); 131678884ef4SEddie Cai return true; 131778884ef4SEddie Cai } 131878884ef4SEddie Cai 131978884ef4SEddie Cai static inline rk_time getTime(void) { 132078884ef4SEddie Cai rk_time rkTime; 132178884ef4SEddie Cai 132278884ef4SEddie Cai struct tm *tm; 132378884ef4SEddie Cai time_t tt = time(NULL); 132478884ef4SEddie Cai tm = localtime(&tt); 132578884ef4SEddie Cai rkTime.year = tm->tm_year + 1900; 132678884ef4SEddie Cai rkTime.month = tm->tm_mon + 1; 132778884ef4SEddie Cai rkTime.day = tm->tm_mday; 132878884ef4SEddie Cai rkTime.hour = tm->tm_hour; 132978884ef4SEddie Cai rkTime.minute = tm->tm_min; 133078884ef4SEddie Cai rkTime.second = tm->tm_sec; 133178884ef4SEddie Cai printf("%d-%d-%d %02d:%02d:%02d\n", 133278884ef4SEddie Cai rkTime.year, rkTime.month, rkTime.day, 133378884ef4SEddie Cai rkTime.hour, rkTime.minute, rkTime.second); 133478884ef4SEddie Cai return rkTime; 133578884ef4SEddie Cai } 133678884ef4SEddie Cai 133778884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) { 133878884ef4SEddie Cai bool ret = false; 133978884ef4SEddie Cai uint32_t size = 0, fixSize = 0; 134078884ef4SEddie Cai uint8_t* buf; 134178884ef4SEddie Cai 134278884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 134378884ef4SEddie Cai if (!inFile) 134478884ef4SEddie Cai goto end; 134578884ef4SEddie Cai 134678884ef4SEddie Cai if (!getFileSize(path, &size)) 134778884ef4SEddie Cai goto end; 134878884ef4SEddie Cai if (fix) { 134978884ef4SEddie Cai fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 135078884ef4SEddie Cai uint32_t tmp = fixSize % ENTRY_ALIGN; 135178884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 135278884ef4SEddie Cai fixSize +=tmp; 135378884ef4SEddie Cai memset(gBuf, 0, fixSize); 135478884ef4SEddie Cai } else { 135578884ef4SEddie Cai memset(gBuf, 0, size+ENTRY_ALIGN); 135678884ef4SEddie Cai } 135778884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 135878884ef4SEddie Cai goto end; 135978884ef4SEddie Cai 136078884ef4SEddie Cai if (fix) { 136178884ef4SEddie Cai 136278884ef4SEddie Cai buf = gBuf; 136378884ef4SEddie Cai size = fixSize; 136478884ef4SEddie Cai while(1) { 136578884ef4SEddie Cai P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 136678884ef4SEddie Cai buf += SMALL_PACKET; 136778884ef4SEddie Cai if (fixSize <= SMALL_PACKET) 136878884ef4SEddie Cai break; 136978884ef4SEddie Cai fixSize -= SMALL_PACKET; 137078884ef4SEddie Cai } 137178884ef4SEddie Cai } else { 137278884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 137378884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 137478884ef4SEddie Cai size +=tmp; 137578884ef4SEddie Cai P_RC4(gBuf, size); 137678884ef4SEddie Cai } 137778884ef4SEddie Cai 137878884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 137978884ef4SEddie Cai goto end; 138078884ef4SEddie Cai ret = true; 138178884ef4SEddie Cai end: 138278884ef4SEddie Cai if (inFile) 138378884ef4SEddie Cai fclose(inFile); 138478884ef4SEddie Cai if (!ret) 138532268622SAndreas Färber printf("writing entry (%s) failed\n", path); 138678884ef4SEddie Cai return ret; 138778884ef4SEddie Cai } 138878884ef4SEddie Cai 138978884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 139078884ef4SEddie Cai uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 139178884ef4SEddie Cai uint32_t size; 139278884ef4SEddie Cai rk_boot_entry entry; 139378884ef4SEddie Cai 139432268622SAndreas Färber printf("writing: %s\n", path); 1395641cfa16SEddie Cai memset(&entry, 0, sizeof(rk_boot_entry)); 139678884ef4SEddie Cai getName(fixName ? fixName: path, entry.name); 139778884ef4SEddie Cai entry.size = sizeof(rk_boot_entry); 139878884ef4SEddie Cai entry.type = type; 139978884ef4SEddie Cai entry.dataOffset = *offset; 140078884ef4SEddie Cai if (!getFileSize(path, &size)) { 140132268622SAndreas Färber printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path); 140278884ef4SEddie Cai return false; 140378884ef4SEddie Cai } 140478884ef4SEddie Cai if (fix) 140578884ef4SEddie Cai size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 140678884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 140778884ef4SEddie Cai size += tmp ? (ENTRY_ALIGN - tmp): 0; 140832268622SAndreas Färber printf("alignment size: %d\n", size); 140978884ef4SEddie Cai entry.dataSize = size; 141078884ef4SEddie Cai entry.dataDelay = delay; 141178884ef4SEddie Cai *offset += size; 141278884ef4SEddie Cai fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 141378884ef4SEddie Cai return true; 141478884ef4SEddie Cai } 141578884ef4SEddie Cai 141678884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) { 141778884ef4SEddie Cai char buffer[5]; 141878884ef4SEddie Cai memset(buffer, 0, sizeof(buffer)); 141978884ef4SEddie Cai snprintf(buffer, sizeof(buffer), "%s", chip); 142078884ef4SEddie Cai return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 142178884ef4SEddie Cai } 142278884ef4SEddie Cai 142378884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) { 142478884ef4SEddie Cai printf("chip: %s\n", chip); 142578884ef4SEddie Cai int chipType = RKNONE_DEVICE; 142678884ef4SEddie Cai if(!chip) { 142778884ef4SEddie Cai goto end; 142878884ef4SEddie Cai } 142978884ef4SEddie Cai if (!strcmp(chip, CHIP_RK28)) { 143078884ef4SEddie Cai chipType = RK28_DEVICE; 143178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK28)) { 143278884ef4SEddie Cai chipType = RK28_DEVICE; 143378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK281X)) { 143478884ef4SEddie Cai chipType = RK281X_DEVICE; 143578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKPANDA)) { 143678884ef4SEddie Cai chipType = RKPANDA_DEVICE; 143778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK27)) { 143878884ef4SEddie Cai chipType = RK27_DEVICE; 143978884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKNANO)) { 144078884ef4SEddie Cai chipType = RKNANO_DEVICE; 144178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKSMART)) { 144278884ef4SEddie Cai chipType = RKSMART_DEVICE; 144378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCROWN)) { 144478884ef4SEddie Cai chipType = RKCROWN_DEVICE; 144578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 144678884ef4SEddie Cai chipType = RKCAYMAN_DEVICE; 144778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK29)) { 144878884ef4SEddie Cai chipType = RK29_DEVICE; 144978884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK292X)) { 145078884ef4SEddie Cai chipType = RK292X_DEVICE; 145178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30)) { 145278884ef4SEddie Cai chipType = RK30_DEVICE; 145378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30B)) { 145478884ef4SEddie Cai chipType = RK30B_DEVICE; 145578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK31)) { 145678884ef4SEddie Cai chipType = RK31_DEVICE; 145778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK32)) { 145878884ef4SEddie Cai chipType = RK32_DEVICE; 145978884ef4SEddie Cai } else { 146078884ef4SEddie Cai chipType = convertChipType(chip + 2); 146178884ef4SEddie Cai } 146278884ef4SEddie Cai 146378884ef4SEddie Cai end: 146478884ef4SEddie Cai printf("type: 0x%x\n", chipType); 146578884ef4SEddie Cai if (chipType == RKNONE_DEVICE) { 146632268622SAndreas Färber printf("chip type not supported!\n"); 146778884ef4SEddie Cai } 146878884ef4SEddie Cai return chipType; 146978884ef4SEddie Cai } 147078884ef4SEddie Cai 147178884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) { 147278884ef4SEddie Cai memset(hdr, 0, sizeof(rk_boot_header)); 147378884ef4SEddie Cai hdr->tag = TAG; 147478884ef4SEddie Cai hdr->size = sizeof(rk_boot_header); 147578884ef4SEddie Cai hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 147678884ef4SEddie Cai hdr->mergerVersion = MERGER_VERSION; 147778884ef4SEddie Cai hdr->releaseTime = getTime(); 147878884ef4SEddie Cai hdr->chipType = getChipType(gOpts.chip); 147978884ef4SEddie Cai 148078884ef4SEddie Cai hdr->code471Num = gOpts.code471Num; 148178884ef4SEddie Cai hdr->code471Offset = sizeof(rk_boot_header); 148278884ef4SEddie Cai hdr->code471Size = sizeof(rk_boot_entry); 148378884ef4SEddie Cai 148478884ef4SEddie Cai hdr->code472Num = gOpts.code472Num; 148578884ef4SEddie Cai hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 148678884ef4SEddie Cai hdr->code472Size = sizeof(rk_boot_entry); 148778884ef4SEddie Cai 148878884ef4SEddie Cai hdr->loaderNum = gOpts.loaderNum; 148978884ef4SEddie Cai hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 149078884ef4SEddie Cai hdr->loaderSize = sizeof(rk_boot_entry); 149178884ef4SEddie Cai #ifndef USE_P_RC4 149278884ef4SEddie Cai hdr->rc4Flag = 1; 149378884ef4SEddie Cai #endif 149478884ef4SEddie Cai } 149578884ef4SEddie Cai 149678884ef4SEddie Cai static inline uint32_t getCrc(const char* path) { 149778884ef4SEddie Cai uint32_t size = 0; 149878884ef4SEddie Cai uint32_t crc = 0; 149978884ef4SEddie Cai 150078884ef4SEddie Cai FILE* file = fopen(path, "rb"); 150178884ef4SEddie Cai getFileSize(path, &size); 150278884ef4SEddie Cai if (!file) 150378884ef4SEddie Cai goto end; 150478884ef4SEddie Cai if (!fread(gBuf, size, 1, file)) 150578884ef4SEddie Cai goto end; 150678884ef4SEddie Cai crc = CRC_32(gBuf, size); 150778884ef4SEddie Cai printf("crc: 0x%08x\n", crc); 150878884ef4SEddie Cai end: 150978884ef4SEddie Cai if (file) 151078884ef4SEddie Cai fclose(file); 151178884ef4SEddie Cai return crc; 151278884ef4SEddie Cai } 151378884ef4SEddie Cai 151478884ef4SEddie Cai bool mergeBoot(void) { 151578884ef4SEddie Cai uint32_t dataOffset; 151678884ef4SEddie Cai bool ret = false; 151778884ef4SEddie Cai int i; 151878884ef4SEddie Cai FILE* outFile; 151978884ef4SEddie Cai uint32_t crc; 152078884ef4SEddie Cai rk_boot_header hdr; 152178884ef4SEddie Cai 152278884ef4SEddie Cai if (!initOpts()) 152378884ef4SEddie Cai return false; 152478884ef4SEddie Cai { 152578884ef4SEddie Cai char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 152678884ef4SEddie Cai char version[MAX_LINE_LEN]; 152778884ef4SEddie Cai snprintf(version, sizeof(version), "%s", gSubfix); 152878884ef4SEddie Cai if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 152978884ef4SEddie Cai subfix[0] = '\0'; 153078884ef4SEddie Cai } 153178884ef4SEddie Cai strcat(gOpts.outPath, version); 153278884ef4SEddie Cai printf("fix opt: %s\n", gOpts.outPath); 153378884ef4SEddie Cai } 153478884ef4SEddie Cai 153578884ef4SEddie Cai printf("---------------\nUSING CONFIG:\n"); 153678884ef4SEddie Cai printOpts(stdout); 153778884ef4SEddie Cai printf("---------------\n\n"); 153878884ef4SEddie Cai 153978884ef4SEddie Cai 154078884ef4SEddie Cai outFile = fopen(gOpts.outPath, "wb+"); 154178884ef4SEddie Cai if (!outFile) { 154232268622SAndreas Färber printf("Opening output file (%s) failed\n", gOpts.outPath); 154378884ef4SEddie Cai goto end; 154478884ef4SEddie Cai } 154578884ef4SEddie Cai 154678884ef4SEddie Cai getBoothdr(&hdr); 154732268622SAndreas Färber printf("Writing header...\n"); 154878884ef4SEddie Cai fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 154978884ef4SEddie Cai 155078884ef4SEddie Cai dataOffset = sizeof(rk_boot_header) + 155178884ef4SEddie Cai (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 155278884ef4SEddie Cai sizeof(rk_boot_entry); 155378884ef4SEddie Cai 155432268622SAndreas Färber printf("Writing code 471 entry...\n"); 155578884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 155678884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 155778884ef4SEddie Cai &dataOffset, NULL, false)) 155878884ef4SEddie Cai goto end; 155978884ef4SEddie Cai } 156032268622SAndreas Färber printf("Writing code 472 entry...\n"); 156178884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 156278884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 156378884ef4SEddie Cai &dataOffset, NULL, false)) 156478884ef4SEddie Cai goto end; 156578884ef4SEddie Cai } 156632268622SAndreas Färber printf("Writing loader entry...\n"); 156778884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 156878884ef4SEddie Cai if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 156978884ef4SEddie Cai &dataOffset, gOpts.loader[i].name, true)) 157078884ef4SEddie Cai goto end; 157178884ef4SEddie Cai } 157278884ef4SEddie Cai 157332268622SAndreas Färber printf("Writing code 471...\n"); 157478884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 157578884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 157678884ef4SEddie Cai goto end; 157778884ef4SEddie Cai } 157832268622SAndreas Färber printf("Writing code 472...\n"); 157978884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 158078884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 158178884ef4SEddie Cai goto end; 158278884ef4SEddie Cai } 158332268622SAndreas Färber printf("Writing loader...\n"); 158478884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 158578884ef4SEddie Cai if (!writeFile(outFile, gOpts.loader[i].path, true)) 158678884ef4SEddie Cai goto end; 158778884ef4SEddie Cai } 158878884ef4SEddie Cai fflush(outFile); 158978884ef4SEddie Cai 159032268622SAndreas Färber printf("Writing crc...\n"); 159178884ef4SEddie Cai crc = getCrc(gOpts.outPath); 159278884ef4SEddie Cai if (!fwrite(&crc, sizeof(crc), 1, outFile)) 159378884ef4SEddie Cai goto end; 159432268622SAndreas Färber printf("Done.\n"); 159578884ef4SEddie Cai ret = true; 159678884ef4SEddie Cai end: 159778884ef4SEddie Cai if (outFile) 159878884ef4SEddie Cai fclose(outFile); 159978884ef4SEddie Cai return ret; 160078884ef4SEddie Cai } 160178884ef4SEddie Cai 160278884ef4SEddie Cai /************merge code end************/ 160378884ef4SEddie Cai /************unpack code***************/ 160478884ef4SEddie Cai 160578884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len) 160678884ef4SEddie Cai { 160778884ef4SEddie Cai int i; 160878884ef4SEddie Cai for (i = 0; i < len; i++) { 160978884ef4SEddie Cai str[i] = (char) (wide[i] & 0xFF); 161078884ef4SEddie Cai } 161178884ef4SEddie Cai str[len] = 0; 161278884ef4SEddie Cai } 161378884ef4SEddie Cai 161478884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name, 161578884ef4SEddie Cai FILE* inFile) { 161678884ef4SEddie Cai bool ret = false; 161778884ef4SEddie Cai int size, i; 161878884ef4SEddie Cai FILE* outFile = fopen(name, "wb+"); 161978884ef4SEddie Cai if (!outFile) 162078884ef4SEddie Cai goto end; 162132268622SAndreas Färber printf("unpacking entry (%s)\n", name); 162278884ef4SEddie Cai fseek(inFile, entry->dataOffset, SEEK_SET); 162378884ef4SEddie Cai size = entry->dataSize; 162478884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 162578884ef4SEddie Cai goto end; 162678884ef4SEddie Cai if (entry->type == ENTRY_LOADER) { 162778884ef4SEddie Cai for(i=0; i<size/SMALL_PACKET; i++) 162878884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 162978884ef4SEddie Cai if (size % SMALL_PACKET) 163078884ef4SEddie Cai { 163178884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 163278884ef4SEddie Cai } 163378884ef4SEddie Cai } else { 163478884ef4SEddie Cai P_RC4(gBuf, size); 163578884ef4SEddie Cai } 163678884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 163778884ef4SEddie Cai goto end; 163878884ef4SEddie Cai ret = true; 163978884ef4SEddie Cai end: 164078884ef4SEddie Cai if (outFile) 164178884ef4SEddie Cai fclose(outFile); 164278884ef4SEddie Cai return ret; 164378884ef4SEddie Cai } 164478884ef4SEddie Cai 164578884ef4SEddie Cai bool unpackBoot(char* path) { 164678884ef4SEddie Cai bool ret = false; 164778884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 164878884ef4SEddie Cai int entryNum, i; 164978884ef4SEddie Cai char name[MAX_NAME_LEN]; 165078884ef4SEddie Cai rk_boot_entry* entrys; 165178884ef4SEddie Cai if (!inFile) { 165278884ef4SEddie Cai fprintf(stderr, "loader (%s) not found\n", path); 165378884ef4SEddie Cai goto end; 165478884ef4SEddie Cai } 165578884ef4SEddie Cai 165678884ef4SEddie Cai rk_boot_header hdr; 165778884ef4SEddie Cai if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 165832268622SAndreas Färber fprintf(stderr, "reading header failed\n"); 165978884ef4SEddie Cai goto end; 166078884ef4SEddie Cai } 166178884ef4SEddie Cai printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 166278884ef4SEddie Cai entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 166378884ef4SEddie Cai entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 166478884ef4SEddie Cai if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 166532268622SAndreas Färber fprintf(stderr, "reading data failed\n"); 166678884ef4SEddie Cai goto end; 166778884ef4SEddie Cai } 166878884ef4SEddie Cai 166978884ef4SEddie Cai printf("entry num: %d\n", entryNum); 167078884ef4SEddie Cai for (i=0; i<entryNum; i++) { 167178884ef4SEddie Cai wide2str(entrys[i].name, name, MAX_NAME_LEN); 167278884ef4SEddie Cai 167378884ef4SEddie Cai printf("entry: t=%d, name=%s, off=%d, size=%d\n", 167478884ef4SEddie Cai entrys[i].type, name, entrys[i].dataOffset, 167578884ef4SEddie Cai entrys[i].dataSize); 167678884ef4SEddie Cai if (!unpackEntry(entrys + i, name, inFile)) { 167732268622SAndreas Färber fprintf(stderr, "unpacking entry (%s) failed\n", name); 167878884ef4SEddie Cai goto end; 167978884ef4SEddie Cai } 168078884ef4SEddie Cai } 168178884ef4SEddie Cai printf("done\n"); 168278884ef4SEddie Cai ret = true; 168378884ef4SEddie Cai end: 168478884ef4SEddie Cai if (inFile) 168578884ef4SEddie Cai fclose(inFile); 168678884ef4SEddie Cai return ret; 168778884ef4SEddie Cai } 168878884ef4SEddie Cai 168976af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 169076af099aSliuyi { 169176af099aSliuyi if (!check_device_type(dev, RKUSB_MASKROM)) 169276af099aSliuyi return false; 169376af099aSliuyi CRKImage *pImage = NULL; 169476af099aSliuyi CRKBoot *pBoot = NULL; 169576af099aSliuyi bool bRet, bSuccess = false; 169676af099aSliuyi int iRet; 169776af099aSliuyi 169876af099aSliuyi pImage = new CRKImage(szLoader, bRet); 169976af099aSliuyi if (!bRet){ 170076af099aSliuyi ERROR_COLOR_ATTR; 170132268622SAndreas Färber printf("Opening loader failed, exiting download boot!"); 170276af099aSliuyi NORMAL_COLOR_ATTR; 170376af099aSliuyi printf("\r\n"); 170476af099aSliuyi return bSuccess; 170576af099aSliuyi } else { 170676af099aSliuyi pBoot = (CRKBoot *)pImage->m_bootObject; 170776af099aSliuyi CRKComm *pComm = NULL; 170876af099aSliuyi CRKDevice *pDevice = NULL; 170976af099aSliuyi 171076af099aSliuyi dev.emDeviceType = pBoot->SupportDevice; 171176af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 171276af099aSliuyi if (!bRet) { 171376af099aSliuyi if (pImage) 171476af099aSliuyi delete pImage; 171576af099aSliuyi ERROR_COLOR_ATTR; 171676af099aSliuyi printf("Creating Comm Object failed!"); 171776af099aSliuyi NORMAL_COLOR_ATTR; 171876af099aSliuyi printf("\r\n"); 171976af099aSliuyi return bSuccess; 172076af099aSliuyi } 172176af099aSliuyi 172276af099aSliuyi pDevice = new CRKDevice(dev); 172376af099aSliuyi if (!pDevice) { 172476af099aSliuyi if (pImage) 172576af099aSliuyi delete pImage; 172676af099aSliuyi if (pComm) 172776af099aSliuyi delete pComm; 172876af099aSliuyi ERROR_COLOR_ATTR; 172976af099aSliuyi printf("Creating device object failed!"); 173076af099aSliuyi NORMAL_COLOR_ATTR; 173176af099aSliuyi printf("\r\n"); 173276af099aSliuyi return bSuccess; 173376af099aSliuyi } 173476af099aSliuyi 173576af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 173632268622SAndreas Färber printf("Downloading bootloader...\r\n"); 173776af099aSliuyi iRet = pDevice->DownloadBoot(); 173876af099aSliuyi 173976af099aSliuyi CURSOR_MOVEUP_LINE(1); 174076af099aSliuyi CURSOR_DEL_LINE; 174176af099aSliuyi if (iRet == 0) { 174276af099aSliuyi bSuccess = true; 174332268622SAndreas Färber printf("Downloading bootloader succeeded.\r\n"); 174476af099aSliuyi } 174576af099aSliuyi else 174632268622SAndreas Färber printf("Downloading bootloader failed!\r\n"); 174776af099aSliuyi 174876af099aSliuyi if (pImage) 174976af099aSliuyi delete pImage; 175076af099aSliuyi if(pDevice) 175176af099aSliuyi delete pDevice; 175276af099aSliuyi } 175376af099aSliuyi return bSuccess; 175476af099aSliuyi } 1755c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1756c30d921cSKever Yang { 1757c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 1758c30d921cSKever Yang return false; 1759c30d921cSKever Yang CRKImage *pImage = NULL; 1760c30d921cSKever Yang CRKBoot *pBoot = NULL; 1761c30d921cSKever Yang CRKComm *pComm = NULL; 1762c30d921cSKever Yang bool bRet, bSuccess = false; 1763c30d921cSKever Yang int iRet; 1764c30d921cSKever Yang char index; 1765c30d921cSKever Yang USHORT usFlashDataSec, usFlashBootSec; 1766c30d921cSKever Yang DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1767c30d921cSKever Yang char loaderCodeName[] = "FlashBoot"; 1768c30d921cSKever Yang char loaderDataName[] = "FlashData"; 1769c30d921cSKever Yang PBYTE loaderCodeBuffer = NULL; 1770c30d921cSKever Yang PBYTE loaderDataBuffer = NULL; 1771c30d921cSKever Yang PBYTE pIDBData = NULL; 1772c30d921cSKever Yang pImage = new CRKImage(szLoader, bRet); 1773c30d921cSKever Yang if (!bRet){ 1774c30d921cSKever Yang ERROR_COLOR_ATTR; 177532268622SAndreas Färber printf("Opening loader failed, exiting upgrade loader!"); 1776c30d921cSKever Yang NORMAL_COLOR_ATTR; 1777c30d921cSKever Yang printf("\r\n"); 1778c30d921cSKever Yang goto Exit_UpgradeLoader; 1779c30d921cSKever Yang } else { 1780c30d921cSKever Yang pBoot = (CRKBoot *)pImage->m_bootObject; 1781c30d921cSKever Yang dev.emDeviceType = pBoot->SupportDevice; 1782c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1783c30d921cSKever Yang if (!bRet) { 1784c30d921cSKever Yang ERROR_COLOR_ATTR; 1785c30d921cSKever Yang printf("Creating Comm Object failed!"); 1786c30d921cSKever Yang NORMAL_COLOR_ATTR; 1787c30d921cSKever Yang printf("\r\n"); 1788c30d921cSKever Yang goto Exit_UpgradeLoader; 1789c30d921cSKever Yang } 1790c30d921cSKever Yang 179132268622SAndreas Färber printf("Upgrading loader...\r\n"); 1792c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1793c30d921cSKever Yang if (index == -1) { 1794c30d921cSKever Yang if (g_pLogObject) { 179532268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__); 1796c30d921cSKever Yang } 1797c30d921cSKever Yang goto Exit_UpgradeLoader; 1798c30d921cSKever Yang } 1799c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1800c30d921cSKever Yang if (!bRet) { 1801c30d921cSKever Yang if (g_pLogObject) { 180232268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__); 1803c30d921cSKever Yang } 1804c30d921cSKever Yang goto Exit_UpgradeLoader; 1805c30d921cSKever Yang } 1806c30d921cSKever Yang 1807c30d921cSKever Yang loaderCodeBuffer = new BYTE[dwLoaderSize]; 1808c30d921cSKever Yang memset(loaderCodeBuffer, 0, dwLoaderSize); 1809c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1810c30d921cSKever Yang if (g_pLogObject) { 181132268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__); 1812c30d921cSKever Yang } 1813c30d921cSKever Yang goto Exit_UpgradeLoader; 1814c30d921cSKever Yang } 1815c30d921cSKever Yang 1816c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1817c30d921cSKever Yang if (index == -1) { 1818c30d921cSKever Yang if (g_pLogObject) { 181932268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__); 1820c30d921cSKever Yang } 1821c30d921cSKever Yang delete []loaderCodeBuffer; 1822c30d921cSKever Yang return -4; 1823c30d921cSKever Yang } 1824c30d921cSKever Yang 1825c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1826c30d921cSKever Yang if (!bRet) { 1827c30d921cSKever Yang if (g_pLogObject) { 182832268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__); 1829c30d921cSKever Yang } 1830c30d921cSKever Yang goto Exit_UpgradeLoader; 1831c30d921cSKever Yang } 1832c30d921cSKever Yang 1833c30d921cSKever Yang loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1834c30d921cSKever Yang memset(loaderDataBuffer, 0, dwLoaderDataSize); 1835c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1836c30d921cSKever Yang if (g_pLogObject) { 183732268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__); 1838c30d921cSKever Yang } 1839c30d921cSKever Yang goto Exit_UpgradeLoader; 1840c30d921cSKever Yang } 1841c30d921cSKever Yang 1842c30d921cSKever Yang usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1843c30d921cSKever Yang usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1844c30d921cSKever Yang dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1845c30d921cSKever Yang pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1846c30d921cSKever Yang if (!pIDBData) { 1847c30d921cSKever Yang ERROR_COLOR_ATTR; 184832268622SAndreas Färber printf("Allocating memory failed!"); 1849c30d921cSKever Yang NORMAL_COLOR_ATTR; 1850c30d921cSKever Yang printf("\r\n"); 1851c30d921cSKever Yang goto Exit_UpgradeLoader; 1852c30d921cSKever Yang } 1853c30d921cSKever Yang memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1854b38fe5fcSliuyi iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag); 1855c30d921cSKever Yang if (iRet != 0) { 1856c30d921cSKever Yang ERROR_COLOR_ATTR; 185732268622SAndreas Färber printf("Making idblock failed!"); 1858c30d921cSKever Yang NORMAL_COLOR_ATTR; 1859c30d921cSKever Yang printf("\r\n"); 1860c30d921cSKever Yang goto Exit_UpgradeLoader; 1861c30d921cSKever Yang } 1862c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1863c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 1864c30d921cSKever Yang CURSOR_DEL_LINE; 1865c30d921cSKever Yang if (iRet == ERR_SUCCESS) { 1866b38fe5fcSliuyi //pComm->Reset_Usb_Device(); 1867c30d921cSKever Yang bSuccess = true; 186832268622SAndreas Färber printf("Upgrading loader succeeded.\r\n"); 1869c30d921cSKever Yang } else { 187032268622SAndreas Färber printf("Upgrading loader failed!\r\n"); 1871c30d921cSKever Yang goto Exit_UpgradeLoader; 1872c30d921cSKever Yang } 1873c30d921cSKever Yang } 1874c30d921cSKever Yang Exit_UpgradeLoader: 1875c30d921cSKever Yang if (pImage) 1876c30d921cSKever Yang delete pImage; 1877c30d921cSKever Yang if (pComm) 1878c30d921cSKever Yang delete pComm; 1879c30d921cSKever Yang if (loaderCodeBuffer) 1880c30d921cSKever Yang delete []loaderCodeBuffer; 1881c30d921cSKever Yang if (loaderDataBuffer) 1882c30d921cSKever Yang delete []loaderDataBuffer; 1883c30d921cSKever Yang if (pIDBData) 1884c30d921cSKever Yang delete []pIDBData; 1885c30d921cSKever Yang return bSuccess; 1886c30d921cSKever Yang } 1887c30d921cSKever Yang 188876af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 188976af099aSliuyi { 189076af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 189176af099aSliuyi return false; 189276af099aSliuyi CRKImage *pImage = NULL; 189376af099aSliuyi bool bRet, bSuccess = false; 189476af099aSliuyi int iRet; 189576af099aSliuyi CRKScan *pScan = NULL; 189676af099aSliuyi pScan = new CRKScan(); 189776af099aSliuyi pScan->SetVidPid(); 189876af099aSliuyi 189976af099aSliuyi CRKComm *pComm = NULL; 190076af099aSliuyi CRKDevice *pDevice = NULL; 190176af099aSliuyi 190276af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 190376af099aSliuyi if (!bRet) { 190476af099aSliuyi if (pScan) 190576af099aSliuyi delete pScan; 190676af099aSliuyi ERROR_COLOR_ATTR; 190776af099aSliuyi printf("Creating Comm Object failed!"); 190876af099aSliuyi NORMAL_COLOR_ATTR; 190976af099aSliuyi printf("\r\n"); 191076af099aSliuyi return bSuccess; 191176af099aSliuyi } 191276af099aSliuyi 191376af099aSliuyi pDevice = new CRKDevice(dev); 191476af099aSliuyi if (!pDevice) { 191576af099aSliuyi if (pComm) 191676af099aSliuyi delete pComm; 191776af099aSliuyi if (pScan) 191876af099aSliuyi delete pScan; 191976af099aSliuyi ERROR_COLOR_ATTR; 192076af099aSliuyi printf("Creating device object failed!"); 192176af099aSliuyi NORMAL_COLOR_ATTR; 192276af099aSliuyi printf("\r\n"); 192376af099aSliuyi return bSuccess; 192476af099aSliuyi } 192576af099aSliuyi 192676af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 192776af099aSliuyi pDevice->CallBackPointer = ProgressInfoProc; 192876af099aSliuyi 192932268622SAndreas Färber printf("Starting to erase flash...\r\n"); 1930*6502326dSliuyi bRet = pDevice->GetFlashInfo(); 1931*6502326dSliuyi if (!bRet) { 1932*6502326dSliuyi if (pDevice) 1933*6502326dSliuyi delete pDevice; 1934*6502326dSliuyi if (pScan) 1935*6502326dSliuyi delete pScan; 1936*6502326dSliuyi ERROR_COLOR_ATTR; 1937*6502326dSliuyi printf("Getting flash info from device failed!"); 1938*6502326dSliuyi NORMAL_COLOR_ATTR; 1939*6502326dSliuyi printf("\r\n"); 1940*6502326dSliuyi return bSuccess; 1941*6502326dSliuyi } 194276af099aSliuyi iRet = pDevice->EraseAllBlocks(); 194376af099aSliuyi if (pDevice) 194476af099aSliuyi delete pDevice; 194576af099aSliuyi 194676af099aSliuyi if (iRet == 0) { 194776af099aSliuyi if (pScan) { 194876af099aSliuyi pScan->SetVidPid(); 194976af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 195076af099aSliuyi delete pScan; 195176af099aSliuyi } 195276af099aSliuyi CURSOR_MOVEUP_LINE(1); 195376af099aSliuyi CURSOR_DEL_LINE; 195476af099aSliuyi bSuccess = true; 195532268622SAndreas Färber printf("Erasing flash complete.\r\n"); 195676af099aSliuyi } 195776af099aSliuyi 195876af099aSliuyi return bSuccess; 195976af099aSliuyi } 196076af099aSliuyi 196176af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev) 196276af099aSliuyi { 196376af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 196476af099aSliuyi return false; 196576af099aSliuyi CRKUsbComm *pComm = NULL; 196676af099aSliuyi bool bRet, bSuccess = false; 196776af099aSliuyi int iRet; 196876af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 196976af099aSliuyi if (bRet) { 197076af099aSliuyi iRet = pComm->RKU_TestDeviceReady(); 197176af099aSliuyi if (iRet != ERR_SUCCESS) { 197276af099aSliuyi if (g_pLogObject) 197376af099aSliuyi g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 197432268622SAndreas Färber printf("Test Device failed!\r\n"); 197576af099aSliuyi } else { 197676af099aSliuyi bSuccess = true; 197776af099aSliuyi printf("Test Device OK.\r\n"); 197876af099aSliuyi } 197976af099aSliuyi } else { 198032268622SAndreas Färber printf("Test Device quit, creating comm object failed!\r\n"); 198176af099aSliuyi } 198276af099aSliuyi if (pComm) { 198376af099aSliuyi delete pComm; 198476af099aSliuyi pComm = NULL; 198576af099aSliuyi } 198676af099aSliuyi return bSuccess; 198776af099aSliuyi } 198876af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 198976af099aSliuyi { 199076af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 199176af099aSliuyi return false; 199276af099aSliuyi CRKUsbComm *pComm = NULL; 199376af099aSliuyi bool bRet, bSuccess = false; 199476af099aSliuyi int iRet; 199576af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 199676af099aSliuyi if (bRet) { 199776af099aSliuyi iRet = pComm->RKU_ResetDevice(subCode); 199876af099aSliuyi if (iRet != ERR_SUCCESS) { 199976af099aSliuyi if (g_pLogObject) 200076af099aSliuyi g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 200132268622SAndreas Färber printf("Reset Device failed!\r\n"); 200276af099aSliuyi } else { 200376af099aSliuyi bSuccess = true; 200476af099aSliuyi printf("Reset Device OK.\r\n"); 200576af099aSliuyi } 200676af099aSliuyi } else { 200732268622SAndreas Färber printf("Reset Device quit, creating comm object failed!\r\n"); 200876af099aSliuyi } 200976af099aSliuyi if (pComm) { 201076af099aSliuyi delete pComm; 201176af099aSliuyi pComm = NULL; 201276af099aSliuyi } 201376af099aSliuyi return bSuccess; 201476af099aSliuyi } 201576af099aSliuyi 201676af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 201776af099aSliuyi { 201876af099aSliuyi CRKUsbComm *pComm = NULL; 201976af099aSliuyi bool bRet, bSuccess = false; 202076af099aSliuyi int iRet; 202176af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 202276af099aSliuyi return bSuccess; 202376af099aSliuyi 202476af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 202576af099aSliuyi if (bRet) { 202676af099aSliuyi BYTE flashID[5]; 202776af099aSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 202876af099aSliuyi if (iRet != ERR_SUCCESS) { 202976af099aSliuyi if (g_pLogObject) 203076af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 203132268622SAndreas Färber printf("Reading flash ID failed!\r\n"); 203276af099aSliuyi } else { 203376af099aSliuyi printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 203476af099aSliuyi bSuccess = true; 203576af099aSliuyi } 203676af099aSliuyi } else { 203732268622SAndreas Färber printf("Read Flash ID quit, creating comm object failed!\r\n"); 203876af099aSliuyi } 203976af099aSliuyi if (pComm) { 204076af099aSliuyi delete pComm; 204176af099aSliuyi pComm = NULL; 204276af099aSliuyi } 204376af099aSliuyi return bSuccess; 204476af099aSliuyi } 204576af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 204676af099aSliuyi { 204776af099aSliuyi CRKUsbComm *pComm = NULL; 204876af099aSliuyi bool bRet, bSuccess = false; 204976af099aSliuyi int iRet; 205076af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 205176af099aSliuyi return bSuccess; 205276af099aSliuyi 205376af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 205476af099aSliuyi if (bRet) { 205576af099aSliuyi STRUCT_FLASHINFO_CMD info; 205676af099aSliuyi UINT uiRead; 205776af099aSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 205876af099aSliuyi if (iRet != ERR_SUCCESS) { 205976af099aSliuyi if (g_pLogObject) 206076af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 206132268622SAndreas Färber printf("Read Flash Info failed!\r\n"); 206276af099aSliuyi } else { 206376af099aSliuyi printf("Flash Info:\r\n"); 206476af099aSliuyi if (info.bManufCode <= 7) { 206576af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 206676af099aSliuyi } 206776af099aSliuyi else 206876af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 206976af099aSliuyi 207076af099aSliuyi printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 207176af099aSliuyi printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 207276af099aSliuyi printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 207376af099aSliuyi printf("\tECC Bits: %d\r\n", info.bECCBits); 207476af099aSliuyi printf("\tAccess Time: %d\r\n", info.bAccessTime); 207576af099aSliuyi printf("\tFlash CS: "); 207676af099aSliuyi for(int i = 0; i < 8; i++) { 207776af099aSliuyi if( info.bFlashCS & (1 << i) ) 207876af099aSliuyi printf("Flash<%d> ", i); 207976af099aSliuyi } 208076af099aSliuyi printf("\r\n"); 208176af099aSliuyi bSuccess = true; 208276af099aSliuyi } 208376af099aSliuyi }else { 208432268622SAndreas Färber printf("Read Flash Info quit, creating comm object failed!\r\n"); 208576af099aSliuyi } 208676af099aSliuyi if (pComm) { 208776af099aSliuyi delete pComm; 208876af099aSliuyi pComm = NULL; 208976af099aSliuyi } 209076af099aSliuyi return bSuccess; 209176af099aSliuyi } 209276af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 209376af099aSliuyi { 209476af099aSliuyi CRKUsbComm *pComm = NULL; 209576af099aSliuyi bool bRet, bSuccess = false; 209676af099aSliuyi int iRet; 209776af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 209876af099aSliuyi return bSuccess; 209976af099aSliuyi 210076af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 210176af099aSliuyi if (bRet) { 210276af099aSliuyi BYTE chipInfo[16]; 210376af099aSliuyi iRet = pComm->RKU_ReadChipInfo(chipInfo); 210476af099aSliuyi if (iRet != ERR_SUCCESS) { 210576af099aSliuyi if (g_pLogObject) 210676af099aSliuyi g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 210732268622SAndreas Färber printf("Read Chip Info failed!\r\n"); 210876af099aSliuyi } else { 210976af099aSliuyi string strChipInfo; 211076af099aSliuyi g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 211176af099aSliuyi printf("Chip Info: %s\r\n", strChipInfo.c_str()); 211276af099aSliuyi bSuccess = true; 211376af099aSliuyi } 211476af099aSliuyi } else { 211532268622SAndreas Färber printf("Read Chip Info quit, creating comm object failed!\r\n"); 211676af099aSliuyi } 211776af099aSliuyi if (pComm) { 211876af099aSliuyi delete pComm; 211976af099aSliuyi pComm = NULL; 212076af099aSliuyi } 212176af099aSliuyi return bSuccess; 212276af099aSliuyi } 21236ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt) 21246ae612beSliuyi { 21256ae612beSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 21266ae612beSliuyi return false; 21276ae612beSliuyi gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE); 21286ae612beSliuyi CRKUsbComm *pComm = NULL; 21296ae612beSliuyi bool bRet, bSuccess = false; 21306ae612beSliuyi int iRet; 21316ae612beSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 21326ae612beSliuyi if (bRet) { 21336ae612beSliuyi iRet = pComm->RKU_ReadLBA( 0, 34, pGpt); 21346ae612beSliuyi if(ERR_SUCCESS == iRet) { 21356ae612beSliuyi if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 21366ae612beSliuyi if (g_pLogObject) 21376ae612beSliuyi g_pLogObject->Record("Error: invalid gpt signature"); 21386ae612beSliuyi printf("Invalid GPT signature!\r\n"); 21396ae612beSliuyi goto Exit_ReadGPT; 21406ae612beSliuyi } 21416ae612beSliuyi 21426ae612beSliuyi } else { 21436ae612beSliuyi if (g_pLogObject) 21446ae612beSliuyi g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 21456ae612beSliuyi printf("Read GPT failed!\r\n"); 21466ae612beSliuyi goto Exit_ReadGPT; 21476ae612beSliuyi } 21486ae612beSliuyi bSuccess = true; 21496ae612beSliuyi } 21506ae612beSliuyi Exit_ReadGPT: 21516ae612beSliuyi if (pComm) { 21526ae612beSliuyi delete pComm; 21536ae612beSliuyi pComm = NULL; 21546ae612beSliuyi } 21556ae612beSliuyi return bSuccess; 21566ae612beSliuyi } 215776af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 215876af099aSliuyi { 215976af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 216076af099aSliuyi return false; 216176af099aSliuyi CRKUsbComm *pComm = NULL; 216276af099aSliuyi FILE *file = NULL; 216376af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 216476af099aSliuyi int iRet; 216576af099aSliuyi UINT iTotalRead = 0,iRead = 0; 216676af099aSliuyi int nSectorSize = 512; 216776af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 216876af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 216976af099aSliuyi if (bRet) { 217076af099aSliuyi if(szFile) { 217176af099aSliuyi file = fopen(szFile, "wb+"); 217276af099aSliuyi if( !file ) { 217376af099aSliuyi printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 217476af099aSliuyi goto Exit_ReadLBA; 217576af099aSliuyi } 217676af099aSliuyi } 217776af099aSliuyi 217876af099aSliuyi while(uiLen > 0) { 217976af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 218076af099aSliuyi iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 218176af099aSliuyi iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 218276af099aSliuyi if(ERR_SUCCESS == iRet) { 218376af099aSliuyi uiLen -= iRead; 218476af099aSliuyi iTotalRead += iRead; 218576af099aSliuyi 218676af099aSliuyi if(szFile) { 218776af099aSliuyi fwrite(pBuf, 1, iRead * nSectorSize, file); 218876af099aSliuyi if (bFirst){ 218976af099aSliuyi if (iTotalRead >= 1024) 219032268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 219176af099aSliuyi else 219232268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 219376af099aSliuyi bFirst = false; 219476af099aSliuyi } else { 219576af099aSliuyi CURSOR_MOVEUP_LINE(1); 219676af099aSliuyi CURSOR_DEL_LINE; 219776af099aSliuyi if (iTotalRead >= 1024) 219832268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 219976af099aSliuyi else 220032268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 220176af099aSliuyi } 220276af099aSliuyi } 220376af099aSliuyi else 220476af099aSliuyi PrintData(pBuf, nSectorSize * iRead); 220576af099aSliuyi } else { 220676af099aSliuyi if (g_pLogObject) 220776af099aSliuyi g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 220876af099aSliuyi 220976af099aSliuyi printf("Read LBA failed!\r\n"); 221076af099aSliuyi goto Exit_ReadLBA; 221176af099aSliuyi } 221276af099aSliuyi } 221376af099aSliuyi bSuccess = true; 221476af099aSliuyi } else { 221532268622SAndreas Färber printf("Read LBA quit, creating comm object failed!\r\n"); 221676af099aSliuyi } 221776af099aSliuyi Exit_ReadLBA: 221876af099aSliuyi if (pComm) { 221976af099aSliuyi delete pComm; 222076af099aSliuyi pComm = NULL; 222176af099aSliuyi } 222276af099aSliuyi if (file) 222376af099aSliuyi fclose(file); 222476af099aSliuyi return bSuccess; 222576af099aSliuyi } 22266ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize) 22276ae612beSliuyi { 22286ae612beSliuyi UINT uiErase=2048*64; 22296ae612beSliuyi bool bSuccess = true; 22306ae612beSliuyi int iRet; 22316ae612beSliuyi while (uiSize) 22326ae612beSliuyi { 22336ae612beSliuyi if (uiSize>=uiErase) 22346ae612beSliuyi { 22356ae612beSliuyi iRet = pComm->RKU_EraseLBA(uiOffset,uiErase); 22366ae612beSliuyi uiSize -= uiErase; 22376ae612beSliuyi uiOffset += uiErase; 22386ae612beSliuyi } 22396ae612beSliuyi else 22406ae612beSliuyi { 22416ae612beSliuyi iRet = pComm->RKU_EraseLBA(uiOffset,uiSize); 22426ae612beSliuyi uiSize = 0; 22436ae612beSliuyi uiOffset += uiSize; 22446ae612beSliuyi } 22456ae612beSliuyi if (iRet!=ERR_SUCCESS) 22466ae612beSliuyi { 22476ae612beSliuyi if (g_pLogObject) 22486ae612beSliuyi { 22496ae612beSliuyi g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet); 22506ae612beSliuyi } 22516ae612beSliuyi bSuccess = false; 22526ae612beSliuyi break; 22536ae612beSliuyi } 22546ae612beSliuyi } 22556ae612beSliuyi return bSuccess; 22566ae612beSliuyi 22576ae612beSliuyi } 22586ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk) 22596ae612beSliuyi { 22606ae612beSliuyi UINT uiRead; 22616ae612beSliuyi uiRead = fread(&chunk, 1, sizeof(chunk_header), file); 22626ae612beSliuyi if (uiRead != sizeof(chunk_header)) { 22636ae612beSliuyi if (g_pLogObject) 22646ae612beSliuyi { 22656ae612beSliuyi g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno); 22666ae612beSliuyi } 22676ae612beSliuyi return false; 22686ae612beSliuyi } 22696ae612beSliuyi return true; 22706ae612beSliuyi } 22716ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize) 22726ae612beSliuyi { 22736ae612beSliuyi UINT uiRead; 22746ae612beSliuyi uiRead = fread(pBuf, 1, dwSize, file); 22756ae612beSliuyi if (uiRead!=dwSize) 22766ae612beSliuyi { 22776ae612beSliuyi if (g_pLogObject) 22786ae612beSliuyi { 22796ae612beSliuyi g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno); 22806ae612beSliuyi } 22816ae612beSliuyi return false; 22826ae612beSliuyi } 22836ae612beSliuyi return true; 22846ae612beSliuyi } 22856ae612beSliuyi 22866ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile) 22876ae612beSliuyi { 22886ae612beSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 22896ae612beSliuyi return false; 22906ae612beSliuyi CRKUsbComm *pComm = NULL; 22916ae612beSliuyi FILE *file = NULL; 22926ae612beSliuyi bool bRet, bSuccess = false, bFirst = true; 22936ae612beSliuyi int iRet; 22946ae612beSliuyi u64 iTotalWrite = 0, iFileSize = 0; 22956ae612beSliuyi UINT iRead = 0, uiTransferSec, curChunk, i; 22966ae612beSliuyi UINT dwChunkDataSize, dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc; 22976ae612beSliuyi BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA]; 22986ae612beSliuyi sparse_header header; 22996ae612beSliuyi chunk_header chunk; 23006ae612beSliuyi dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE; 23016ae612beSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 23026ae612beSliuyi if (bRet) { 23036ae612beSliuyi bRet = erase_partition(pComm, uiBegin, uiSize); 23046ae612beSliuyi if (!bRet) { 23056ae612beSliuyi printf("%s failed, erase partition error\r\n", __func__); 23066ae612beSliuyi goto Exit_WriteSparseLBA; 23076ae612beSliuyi } 23086ae612beSliuyi file = fopen(szFile, "rb"); 23096ae612beSliuyi if( !file ) { 23106ae612beSliuyi printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile); 23116ae612beSliuyi goto Exit_WriteSparseLBA; 23126ae612beSliuyi } 23136ae612beSliuyi fseeko(file, 0, SEEK_SET); 23146ae612beSliuyi iRead = fread(&header, 1, sizeof(header), file); 23156ae612beSliuyi if (iRead != sizeof(sparse_header)) 23166ae612beSliuyi { 23176ae612beSliuyi if (g_pLogObject) 23186ae612beSliuyi { 23196ae612beSliuyi g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno); 23206ae612beSliuyi } 23216ae612beSliuyi goto Exit_WriteSparseLBA; 23226ae612beSliuyi } 23236ae612beSliuyi iFileSize = header.blk_sz * (u64)header.total_blks; 23246ae612beSliuyi iTotalWrite = 0; 23256ae612beSliuyi curChunk = 0; 23266ae612beSliuyi 23276ae612beSliuyi while(curChunk < header.total_chunks) 23286ae612beSliuyi { 23296ae612beSliuyi if (!EatSparseChunk(file, chunk)) { 23306ae612beSliuyi goto Exit_WriteSparseLBA; 23316ae612beSliuyi } 23326ae612beSliuyi curChunk++; 23336ae612beSliuyi switch (chunk.chunk_type) { 23346ae612beSliuyi case CHUNK_TYPE_RAW: 23356ae612beSliuyi dwChunkDataSize = chunk.total_sz - sizeof(chunk_header); 23366ae612beSliuyi while (dwChunkDataSize) { 23376ae612beSliuyi memset(pBuf, 0, dwMaxReadWriteBytes); 23386ae612beSliuyi if (dwChunkDataSize >= dwMaxReadWriteBytes) { 23396ae612beSliuyi dwTransferBytes = dwMaxReadWriteBytes; 23406ae612beSliuyi uiTransferSec = DEFAULT_RW_LBA; 23416ae612beSliuyi } else { 23426ae612beSliuyi dwTransferBytes = dwChunkDataSize; 23436ae612beSliuyi uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 23446ae612beSliuyi } 23456ae612beSliuyi if (!EatSparseData(file, pBuf, dwTransferBytes)) { 23466ae612beSliuyi goto Exit_WriteSparseLBA; 23476ae612beSliuyi } 23486ae612beSliuyi iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 23496ae612beSliuyi if( ERR_SUCCESS == iRet ) { 23506ae612beSliuyi dwChunkDataSize -= dwTransferBytes; 23516ae612beSliuyi iTotalWrite += dwTransferBytes; 23526ae612beSliuyi uiBegin += uiTransferSec; 23536ae612beSliuyi } else { 23546ae612beSliuyi if (g_pLogObject) { 23556ae612beSliuyi g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)", __func__, iTotalWrite, iRet); 23566ae612beSliuyi } 23576ae612beSliuyi goto Exit_WriteSparseLBA; 23586ae612beSliuyi } 23596ae612beSliuyi if (bFirst) { 23606ae612beSliuyi if (iTotalWrite >= 1024) 23616ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 23626ae612beSliuyi else 23636ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 23646ae612beSliuyi bFirst = false; 23656ae612beSliuyi } else { 23666ae612beSliuyi CURSOR_MOVEUP_LINE(1); 23676ae612beSliuyi CURSOR_DEL_LINE; 23686ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 23696ae612beSliuyi } 23706ae612beSliuyi } 23716ae612beSliuyi break; 23726ae612beSliuyi case CHUNK_TYPE_FILL: 23736ae612beSliuyi dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 23746ae612beSliuyi if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) { 23756ae612beSliuyi goto Exit_WriteSparseLBA; 23766ae612beSliuyi } 23776ae612beSliuyi while (dwChunkDataSize) { 23786ae612beSliuyi memset(pBuf, 0, dwMaxReadWriteBytes); 23796ae612beSliuyi if (dwChunkDataSize >= dwMaxReadWriteBytes) { 23806ae612beSliuyi dwTransferBytes = dwMaxReadWriteBytes; 23816ae612beSliuyi uiTransferSec = DEFAULT_RW_LBA; 23826ae612beSliuyi } else { 23836ae612beSliuyi dwTransferBytes = dwChunkDataSize; 23846ae612beSliuyi uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 23856ae612beSliuyi } 23866ae612beSliuyi for (i = 0; i < dwTransferBytes / 4; i++) { 23876ae612beSliuyi *(DWORD *)(pBuf + i * 4) = dwFillByte; 23886ae612beSliuyi } 23896ae612beSliuyi iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 23906ae612beSliuyi if( ERR_SUCCESS == iRet ) { 23916ae612beSliuyi dwChunkDataSize -= dwTransferBytes; 23926ae612beSliuyi iTotalWrite += dwTransferBytes; 23936ae612beSliuyi uiBegin += uiTransferSec; 23946ae612beSliuyi } else { 23956ae612beSliuyi if (g_pLogObject) { 23966ae612beSliuyi g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet); 23976ae612beSliuyi } 23986ae612beSliuyi goto Exit_WriteSparseLBA; 23996ae612beSliuyi } 24006ae612beSliuyi if (bFirst) { 24016ae612beSliuyi if (iTotalWrite >= 1024) 24026ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 24036ae612beSliuyi else 24046ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 24056ae612beSliuyi bFirst = false; 24066ae612beSliuyi } else { 24076ae612beSliuyi CURSOR_MOVEUP_LINE(1); 24086ae612beSliuyi CURSOR_DEL_LINE; 24096ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 24106ae612beSliuyi } 24116ae612beSliuyi } 24126ae612beSliuyi break; 24136ae612beSliuyi case CHUNK_TYPE_DONT_CARE: 24146ae612beSliuyi dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 24156ae612beSliuyi iTotalWrite += dwChunkDataSize; 24166ae612beSliuyi uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1)); 24176ae612beSliuyi uiBegin += uiTransferSec; 24186ae612beSliuyi if (bFirst) { 24196ae612beSliuyi if (iTotalWrite >= 1024) 24206ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 24216ae612beSliuyi else 24226ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 24236ae612beSliuyi bFirst = false; 24246ae612beSliuyi } else { 24256ae612beSliuyi CURSOR_MOVEUP_LINE(1); 24266ae612beSliuyi CURSOR_DEL_LINE; 24276ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 24286ae612beSliuyi } 24296ae612beSliuyi break; 24306ae612beSliuyi case CHUNK_TYPE_CRC32: 24316ae612beSliuyi EatSparseData(file,(PBYTE)&dwCrc,4); 24326ae612beSliuyi break; 24336ae612beSliuyi } 24346ae612beSliuyi } 24356ae612beSliuyi bSuccess = true; 24366ae612beSliuyi } else { 24376ae612beSliuyi printf("Write LBA quit, creating comm object failed!\r\n"); 24386ae612beSliuyi } 24396ae612beSliuyi Exit_WriteSparseLBA: 24406ae612beSliuyi if (pComm) { 24416ae612beSliuyi delete pComm; 24426ae612beSliuyi pComm = NULL; 24436ae612beSliuyi } 24446ae612beSliuyi if (file) 24456ae612beSliuyi fclose(file); 24466ae612beSliuyi return bSuccess; 24476ae612beSliuyi 24486ae612beSliuyi } 24496ae612beSliuyi 245076af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 245176af099aSliuyi { 245276af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 245376af099aSliuyi return false; 245476af099aSliuyi CRKUsbComm *pComm = NULL; 245576af099aSliuyi FILE *file = NULL; 245676af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 245776af099aSliuyi int iRet; 245876af099aSliuyi long long iTotalWrite = 0, iFileSize = 0; 245976af099aSliuyi UINT iWrite = 0, iRead = 0; 246076af099aSliuyi UINT uiLen; 246176af099aSliuyi int nSectorSize = 512; 246276af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 246376af099aSliuyi 246476af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 246576af099aSliuyi if (bRet) { 246676af099aSliuyi file = fopen(szFile, "rb"); 246776af099aSliuyi if( !file ) { 246876af099aSliuyi printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 246976af099aSliuyi goto Exit_WriteLBA; 247076af099aSliuyi } 247176af099aSliuyi 247276af099aSliuyi iRet = fseeko(file, 0, SEEK_END); 247376af099aSliuyi iFileSize = ftello(file); 247476af099aSliuyi fseeko(file, 0, SEEK_SET); 247576af099aSliuyi while(iTotalWrite < iFileSize) { 247676af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 247776af099aSliuyi iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 247876af099aSliuyi uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 247976af099aSliuyi iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 248076af099aSliuyi if(ERR_SUCCESS == iRet) { 248176af099aSliuyi uiBegin += uiLen; 248276af099aSliuyi iTotalWrite += iWrite; 248376af099aSliuyi if (bFirst) { 248476af099aSliuyi if (iTotalWrite >= 1024) 248576af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 248676af099aSliuyi else 248732268622SAndreas Färber printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 248876af099aSliuyi bFirst = false; 248976af099aSliuyi } else { 249076af099aSliuyi CURSOR_MOVEUP_LINE(1); 249176af099aSliuyi CURSOR_DEL_LINE; 249276af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 249376af099aSliuyi } 249476af099aSliuyi } else { 249576af099aSliuyi if (g_pLogObject) 249676af099aSliuyi g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 249776af099aSliuyi 249876af099aSliuyi printf("Write LBA failed!\r\n"); 249976af099aSliuyi goto Exit_WriteLBA; 250076af099aSliuyi } 250176af099aSliuyi } 250276af099aSliuyi bSuccess = true; 250376af099aSliuyi } else { 250432268622SAndreas Färber printf("Write LBA quit, creating comm object failed!\r\n"); 250576af099aSliuyi } 250676af099aSliuyi Exit_WriteLBA: 250776af099aSliuyi if (pComm) { 250876af099aSliuyi delete pComm; 250976af099aSliuyi pComm = NULL; 251076af099aSliuyi } 251176af099aSliuyi if (file) 251276af099aSliuyi fclose(file); 251376af099aSliuyi return bSuccess; 251476af099aSliuyi } 251576af099aSliuyi 251676af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems) 251776af099aSliuyi { 251876af099aSliuyi string strItem; 251976af099aSliuyi char szItem[100]; 252076af099aSliuyi char *pos = NULL, *pStart; 252176af099aSliuyi pStart = pszItems; 252276af099aSliuyi pos = strchr(pStart, ','); 252376af099aSliuyi while(pos != NULL) { 252476af099aSliuyi memset(szItem, 0, 100); 252576af099aSliuyi strncpy(szItem, pStart, pos - pStart); 252676af099aSliuyi strItem = szItem; 252776af099aSliuyi vecItems.push_back(strItem); 252876af099aSliuyi pStart = pos + 1; 252976af099aSliuyi if (*pStart == 0) 253076af099aSliuyi break; 253176af099aSliuyi pos = strchr(pStart, ','); 253276af099aSliuyi } 253376af099aSliuyi if (strlen(pStart) > 0) { 253476af099aSliuyi memset(szItem, 0, 100); 253576af099aSliuyi strncpy(szItem, pStart, strlen(pStart)); 253676af099aSliuyi strItem = szItem; 253776af099aSliuyi vecItems.push_back(strItem); 253876af099aSliuyi } 253976af099aSliuyi } 2540c30d921cSKever Yang 2541d71e8c20SEddie Cai void tag_spl(char *tag, char *spl) 2542d71e8c20SEddie Cai { 2543d71e8c20SEddie Cai FILE *file = NULL; 2544d71e8c20SEddie Cai int len; 2545d71e8c20SEddie Cai 2546d71e8c20SEddie Cai if(!tag || !spl) 2547d71e8c20SEddie Cai return; 2548d71e8c20SEddie Cai len = strlen(tag); 2549d71e8c20SEddie Cai printf("tag len=%d\n",len); 2550d71e8c20SEddie Cai file = fopen(spl, "rb"); 2551d71e8c20SEddie Cai if( !file ){ 2552d71e8c20SEddie Cai return; 2553d71e8c20SEddie Cai } 2554d71e8c20SEddie Cai int iFileSize; 2555d71e8c20SEddie Cai fseek(file, 0, SEEK_END); 2556d71e8c20SEddie Cai iFileSize = ftell(file); 2557d71e8c20SEddie Cai fseek(file, 0, SEEK_SET); 2558d71e8c20SEddie Cai char *Buf = NULL; 2559d71e8c20SEddie Cai Buf = new char[iFileSize + len + 1]; 2560d71e8c20SEddie Cai if (!Buf){ 2561d71e8c20SEddie Cai fclose(file); 2562d71e8c20SEddie Cai return; 2563d71e8c20SEddie Cai } 2564d71e8c20SEddie Cai memset(Buf, 0, iFileSize + 1); 2565d71e8c20SEddie Cai memcpy(Buf, tag, len); 2566d71e8c20SEddie Cai int iRead; 2567d71e8c20SEddie Cai iRead = fread(Buf+len, 1, iFileSize, file); 2568d71e8c20SEddie Cai if (iRead != iFileSize){ 2569d71e8c20SEddie Cai fclose(file); 2570d71e8c20SEddie Cai delete []Buf; 2571d71e8c20SEddie Cai return; 2572d71e8c20SEddie Cai } 2573d71e8c20SEddie Cai fclose(file); 2574d71e8c20SEddie Cai 2575d71e8c20SEddie Cai len = strlen(spl); 257632268622SAndreas Färber char *taggedspl = new char[len + 5]; 257732268622SAndreas Färber strcpy(taggedspl, spl); 257832268622SAndreas Färber strcpy(taggedspl + len, ".tag"); 257932268622SAndreas Färber taggedspl[len+4] = 0; 258032268622SAndreas Färber printf("Writing tagged spl to %s\n", taggedspl); 2581d71e8c20SEddie Cai 258232268622SAndreas Färber file = fopen(taggedspl, "wb"); 2583d71e8c20SEddie Cai if( !file ){ 258432268622SAndreas Färber delete []taggedspl; 2585d71e8c20SEddie Cai delete []Buf; 2586d71e8c20SEddie Cai return; 2587d71e8c20SEddie Cai } 2588d71e8c20SEddie Cai fwrite(Buf, 1, iFileSize+len, file); 2589d71e8c20SEddie Cai fclose(file); 259032268622SAndreas Färber delete []taggedspl; 2591d71e8c20SEddie Cai delete []Buf; 2592d71e8c20SEddie Cai printf("done\n"); 2593d71e8c20SEddie Cai return; 2594d71e8c20SEddie Cai } 2595d71e8c20SEddie Cai 259676af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan) 259776af099aSliuyi { 259876af099aSliuyi string strCmd; 259976af099aSliuyi strCmd = argv[1]; 260076af099aSliuyi ssize_t cnt; 260176af099aSliuyi bool bRet,bSuccess = false; 26028df2d64aSEddie Cai char *s; 26038df2d64aSEddie Cai int i, ret; 260476af099aSliuyi STRUCT_RKDEVICE_DESC dev; 26056ae612beSliuyi u8 master_gpt[34 * SECTOR_SIZE]; 26066ae612beSliuyi u64 lba, lba_end; 260776af099aSliuyi 260876af099aSliuyi transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 26098df2d64aSEddie Cai s = (char*)strCmd.c_str(); 26108df2d64aSEddie Cai for(i = 0; i < (int)strlen(s); i++) 26118df2d64aSEddie Cai s[i] = toupper(s[i]); 261278884ef4SEddie Cai 26138df2d64aSEddie Cai if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 261476af099aSliuyi usage(); 261576af099aSliuyi return true; 26168df2d64aSEddie Cai } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2617c30d921cSKever Yang printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 261876af099aSliuyi return true; 261978884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 262078884ef4SEddie Cai mergeBoot(); 262178884ef4SEddie Cai 262278884ef4SEddie Cai return true; 262378884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 262478884ef4SEddie Cai string strLoader = argv[2]; 262578884ef4SEddie Cai 262678884ef4SEddie Cai unpackBoot((char*)strLoader.c_str()); 262778884ef4SEddie Cai return true; 2628d71e8c20SEddie Cai } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 2629d71e8c20SEddie Cai if (argc == 4) { 2630d71e8c20SEddie Cai string tag = argv[2]; 2631d71e8c20SEddie Cai string spl = argv[3]; 2632d71e8c20SEddie Cai printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 2633d71e8c20SEddie Cai tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 2634d71e8c20SEddie Cai return true; 2635d71e8c20SEddie Cai } 2636d71e8c20SEddie Cai printf("tagspl: parameter error\n"); 2637d71e8c20SEddie Cai usage(); 263876af099aSliuyi } 263976af099aSliuyi cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 264076af099aSliuyi if (cnt < 1) { 264176af099aSliuyi ERROR_COLOR_ATTR; 264232268622SAndreas Färber printf("Did not find any rockusb device, please plug device in!"); 264376af099aSliuyi NORMAL_COLOR_ATTR; 264476af099aSliuyi printf("\r\n"); 264576af099aSliuyi return bSuccess; 264676af099aSliuyi } else if (cnt > 1) { 264776af099aSliuyi ERROR_COLOR_ATTR; 264832268622SAndreas Färber printf("Found too many rockusb devices, please plug devices out!"); 264976af099aSliuyi NORMAL_COLOR_ATTR; 265076af099aSliuyi printf("\r\n"); 265176af099aSliuyi return bSuccess; 265276af099aSliuyi } 265376af099aSliuyi 265476af099aSliuyi bRet = pScan->GetDevice(dev, 0); 265576af099aSliuyi if (!bRet) { 265676af099aSliuyi ERROR_COLOR_ATTR; 265732268622SAndreas Färber printf("Getting information about rockusb device failed!"); 265876af099aSliuyi NORMAL_COLOR_ATTR; 265976af099aSliuyi printf("\r\n"); 266076af099aSliuyi return bSuccess; 266176af099aSliuyi } 266276af099aSliuyi 266376af099aSliuyi if(strcmp(strCmd.c_str(), "RD") == 0) { 266476af099aSliuyi if ((argc != 2) && (argc != 3)) 266576af099aSliuyi printf("Parameter of [RD] command is invalid, please check help!\r\n"); 266676af099aSliuyi else { 266776af099aSliuyi if (argc == 2) 266876af099aSliuyi bSuccess = reset_device(dev); 266976af099aSliuyi else { 267076af099aSliuyi UINT uiSubCode; 267176af099aSliuyi char *pszEnd; 267276af099aSliuyi uiSubCode = strtoul(argv[2], &pszEnd, 0); 267376af099aSliuyi if (*pszEnd) 267476af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 267576af099aSliuyi else { 267676af099aSliuyi if (uiSubCode <= 5) 267776af099aSliuyi bSuccess = reset_device(dev, uiSubCode); 267876af099aSliuyi else 267976af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 268076af099aSliuyi } 268176af099aSliuyi } 268276af099aSliuyi } 268376af099aSliuyi } else if(strcmp(strCmd.c_str(), "TD") == 0) { 268476af099aSliuyi bSuccess = test_device(dev); 268576af099aSliuyi } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 268676af099aSliuyi bSuccess = read_flash_id(dev); 268776af099aSliuyi } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 268876af099aSliuyi bSuccess = read_flash_info(dev); 268976af099aSliuyi } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 269076af099aSliuyi bSuccess = read_chip_info(dev); 269176af099aSliuyi } else if(strcmp(strCmd.c_str(), "DB") == 0) { 269276af099aSliuyi if (argc > 2) { 269376af099aSliuyi string strLoader; 269476af099aSliuyi strLoader = argv[2]; 269576af099aSliuyi bSuccess = download_boot(dev, (char *)strLoader.c_str()); 269676af099aSliuyi } else if (argc == 2) { 2697c29e5f0fSliuyi ret = find_config_item(g_ConfigItemVec, "loader"); 269876af099aSliuyi if (ret == -1) 269932268622SAndreas Färber printf("Did not find loader item in config!\r\n"); 270076af099aSliuyi else 270176af099aSliuyi bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 270276af099aSliuyi } else 270376af099aSliuyi printf("Parameter of [DB] command is invalid, please check help!\r\n"); 2704c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2705c30d921cSKever Yang if (argc > 2) { 2706c30d921cSKever Yang string strParameter; 2707c30d921cSKever Yang strParameter = argv[2]; 2708c30d921cSKever Yang bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2709c30d921cSKever Yang } else 2710c30d921cSKever Yang printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 2711c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2712c30d921cSKever Yang if (argc > 2) { 2713c30d921cSKever Yang string strLoader; 2714c30d921cSKever Yang strLoader = argv[2]; 2715c30d921cSKever Yang bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2716c30d921cSKever Yang } else 2717c30d921cSKever Yang printf("Parameter of [UL] command is invalid, please check help!\r\n"); 271876af099aSliuyi } else if(strcmp(strCmd.c_str(), "EF") == 0) { 271976af099aSliuyi if (argc == 2) { 272076af099aSliuyi bSuccess = erase_flash(dev); 272176af099aSliuyi } else 272276af099aSliuyi printf("Parameter of [EF] command is invalid, please check help!\r\n"); 272376af099aSliuyi } else if(strcmp(strCmd.c_str(), "WL") == 0) { 272476af099aSliuyi if (argc == 4) { 272576af099aSliuyi UINT uiBegin; 272676af099aSliuyi char *pszEnd; 272776af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 272876af099aSliuyi if (*pszEnd) 272976af099aSliuyi printf("Begin is invalid, please check!\r\n"); 273076af099aSliuyi else 273176af099aSliuyi bSuccess = write_lba(dev, uiBegin, argv[3]); 273276af099aSliuyi } else 273376af099aSliuyi printf("Parameter of [WL] command is invalid, please check help!\r\n"); 27346ae612beSliuyi } else if(strcmp(strCmd.c_str(), "WLX") == 0) { 27356ae612beSliuyi if (argc == 4) { 27366ae612beSliuyi bRet = read_gpt(dev, master_gpt); 27376ae612beSliuyi if (bRet) { 27386ae612beSliuyi bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end); 27396ae612beSliuyi if (bRet) { 27406ae612beSliuyi if (is_sparse_image(argv[3])) 27416ae612beSliuyi bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]); 27426ae612beSliuyi else 27436ae612beSliuyi bSuccess = write_lba(dev, (u32)lba, argv[3]); 27446ae612beSliuyi } else 27456ae612beSliuyi printf("No found %s partition\r\n", argv[2]); 27466ae612beSliuyi } 27476ae612beSliuyi } else 27486ae612beSliuyi printf("Parameter of [WLX] command is invalid, please check help!\r\n"); 274976af099aSliuyi } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 275076af099aSliuyi char *pszEnd; 275176af099aSliuyi UINT uiBegin, uiLen; 275276af099aSliuyi if (argc != 5) 275376af099aSliuyi printf("Parameter of [RL] command is invalid, please check help!\r\n"); 275476af099aSliuyi else { 275576af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 275676af099aSliuyi if (*pszEnd) 275776af099aSliuyi printf("Begin is invalid, please check!\r\n"); 275876af099aSliuyi else { 275976af099aSliuyi uiLen = strtoul(argv[3], &pszEnd, 0); 276076af099aSliuyi if (*pszEnd) 276176af099aSliuyi printf("Len is invalid, please check!\r\n"); 276276af099aSliuyi else { 276376af099aSliuyi bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 276476af099aSliuyi } 276576af099aSliuyi } 276676af099aSliuyi } 276776af099aSliuyi } else { 27689bc231bdSAndreas Färber printf("command is invalid!\r\n"); 27699bc231bdSAndreas Färber usage(); 277076af099aSliuyi } 277176af099aSliuyi return bSuccess; 277276af099aSliuyi } 277376af099aSliuyi 277476af099aSliuyi 277576af099aSliuyi int main(int argc, char* argv[]) 277676af099aSliuyi { 277776af099aSliuyi CRKScan *pScan = NULL; 277876af099aSliuyi int ret; 277976af099aSliuyi char szProgramProcPath[100]; 278076af099aSliuyi char szProgramDir[256]; 278176af099aSliuyi string strLogDir,strConfigFile; 278276af099aSliuyi struct stat statBuf; 278376af099aSliuyi 278476af099aSliuyi g_ConfigItemVec.clear(); 278576af099aSliuyi sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 278676af099aSliuyi if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 278776af099aSliuyi strcpy(szProgramDir, "."); 278876af099aSliuyi else { 278976af099aSliuyi char *pSlash; 279076af099aSliuyi pSlash = strrchr(szProgramDir, '/'); 279176af099aSliuyi if (pSlash) 279276af099aSliuyi *pSlash = '\0'; 279376af099aSliuyi } 279476af099aSliuyi strLogDir = szProgramDir; 279576af099aSliuyi strLogDir += "/log/"; 279676af099aSliuyi strConfigFile = szProgramDir; 279776af099aSliuyi strConfigFile += "/config.ini"; 279876af099aSliuyi if (opendir(strLogDir.c_str()) == NULL) 279976af099aSliuyi mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 2800e5ee8cc0Sliuyi g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 280176af099aSliuyi 280276af099aSliuyi if(stat(strConfigFile.c_str(), &statBuf) < 0) { 280376af099aSliuyi if (g_pLogObject) { 280476af099aSliuyi g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 280576af099aSliuyi } 280676af099aSliuyi } else if (S_ISREG(statBuf.st_mode)) { 280776af099aSliuyi parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 280876af099aSliuyi } 280976af099aSliuyi 281076af099aSliuyi ret = libusb_init(NULL); 281176af099aSliuyi if (ret < 0) { 281276af099aSliuyi if (g_pLogObject) { 281376af099aSliuyi g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 281476af099aSliuyi delete g_pLogObject; 281576af099aSliuyi } 281676af099aSliuyi return -1; 281776af099aSliuyi } 281876af099aSliuyi 281976af099aSliuyi pScan = new CRKScan(); 282076af099aSliuyi if (!pScan) { 282176af099aSliuyi if (g_pLogObject) { 282232268622SAndreas Färber g_pLogObject->Record("Error: failed to create object for searching device"); 282376af099aSliuyi delete g_pLogObject; 282476af099aSliuyi } 282576af099aSliuyi libusb_exit(NULL); 282676af099aSliuyi return -2; 282776af099aSliuyi } 282876af099aSliuyi pScan->SetVidPid(); 282976af099aSliuyi 283076af099aSliuyi if (argc == 1) 283176af099aSliuyi usage(); 283276af099aSliuyi else if (!handle_command(argc, argv, pScan)) 283376af099aSliuyi return -0xFF; 283476af099aSliuyi if (pScan) 283576af099aSliuyi delete pScan; 283676af099aSliuyi if (g_pLogObject) 283776af099aSliuyi delete g_pLogObject; 283876af099aSliuyi libusb_exit(NULL); 283976af099aSliuyi return 0; 284076af099aSliuyi } 2841