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"); 45ae4252f0Sliuyi printf("Help:\t\t\t-h or --help\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"); 533dc7e3ceSliuyi printf("PrintGPT:\t\tpgpt \r\n"); 54154ee062SEddie Cai printf("EraseFlash:\t\tef \r\n"); 55154ee062SEddie Cai printf("TestDevice:\t\ttd\r\n"); 56154ee062SEddie Cai printf("ResetDevice:\t\trd [subcode]\r\n"); 57154ee062SEddie Cai printf("ReadFlashID:\t\trid\r\n"); 58154ee062SEddie Cai printf("ReadFlashInfo:\t\trfi\r\n"); 59154ee062SEddie Cai printf("ReadChipInfo:\t\trci\r\n"); 6078884ef4SEddie Cai printf("PackBootLoader:\t\tpack\r\n"); 6178884ef4SEddie Cai printf("UnpackBootLoader:\tunpack <boot loader>\r\n"); 62d71e8c20SEddie Cai printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n"); 6376af099aSliuyi printf("-------------------------------------------------------\r\n\r\n"); 6476af099aSliuyi } 6576af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall) 6676af099aSliuyi { 6776af099aSliuyi string strInfoText=""; 6876af099aSliuyi char szText[256]; 6976af099aSliuyi switch (promptID) { 7076af099aSliuyi case TESTDEVICE_PROGRESS: 7132268622SAndreas Färber sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue); 7276af099aSliuyi strInfoText = szText; 7376af099aSliuyi break; 7476af099aSliuyi case LOWERFORMAT_PROGRESS: 7532268622SAndreas Färber sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue); 7676af099aSliuyi strInfoText = szText; 7776af099aSliuyi break; 7876af099aSliuyi case DOWNLOADIMAGE_PROGRESS: 7932268622SAndreas Färber sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 8076af099aSliuyi strInfoText = szText; 8176af099aSliuyi break; 8276af099aSliuyi case CHECKIMAGE_PROGRESS: 8332268622SAndreas Färber sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 8476af099aSliuyi strInfoText = szText; 8576af099aSliuyi break; 8676af099aSliuyi case TAGBADBLOCK_PROGRESS: 8732268622SAndreas Färber sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue); 8876af099aSliuyi strInfoText = szText; 8976af099aSliuyi break; 9076af099aSliuyi case TESTBLOCK_PROGRESS: 9132268622SAndreas Färber sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue); 9276af099aSliuyi strInfoText = szText; 9376af099aSliuyi break; 9476af099aSliuyi case ERASEFLASH_PROGRESS: 9532268622SAndreas Färber sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue); 9676af099aSliuyi strInfoText = szText; 9776af099aSliuyi break; 9876af099aSliuyi case ERASESYSTEM_PROGRESS: 9932268622SAndreas Färber sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue); 10076af099aSliuyi strInfoText = szText; 10176af099aSliuyi break; 10276af099aSliuyi case ERASEUSERDATA_PROGRESS: 10332268622SAndreas Färber sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue); 10476af099aSliuyi strInfoText = szText; 10576af099aSliuyi break; 10676af099aSliuyi } 10776af099aSliuyi if (strInfoText.size() > 0){ 10876af099aSliuyi CURSOR_MOVEUP_LINE(1); 10976af099aSliuyi CURSOR_DEL_LINE; 11076af099aSliuyi printf("%s\r\n", strInfoText.c_str()); 11176af099aSliuyi } 11276af099aSliuyi if (emCall == CALL_LAST) 11376af099aSliuyi deviceLayer = 0; 11476af099aSliuyi } 11576af099aSliuyi 11676af099aSliuyi char *strupr(char *szSrc) 11776af099aSliuyi { 11876af099aSliuyi char *p = szSrc; 11976af099aSliuyi while(*p){ 12076af099aSliuyi if ((*p >= 'a') && (*p <= 'z')) 12176af099aSliuyi *p = *p - 'a' + 'A'; 12276af099aSliuyi p++; 12376af099aSliuyi } 12476af099aSliuyi return szSrc; 12576af099aSliuyi } 12676af099aSliuyi void PrintData(PBYTE pData, int nSize) 12776af099aSliuyi { 12876af099aSliuyi char szPrint[17] = "\0"; 12976af099aSliuyi int i; 13076af099aSliuyi for( i = 0; i < nSize; i++){ 13176af099aSliuyi if(i % 16 == 0){ 13276af099aSliuyi if(i / 16 > 0) 13376af099aSliuyi printf(" %s\r\n", szPrint); 13476af099aSliuyi printf("%08d ", i / 16); 13576af099aSliuyi } 13676af099aSliuyi printf("%02X ", pData[i]); 13776af099aSliuyi szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.'; 13876af099aSliuyi } 13976af099aSliuyi if(i / 16 > 0) 14076af099aSliuyi printf(" %s\r\n", szPrint); 14176af099aSliuyi } 14276af099aSliuyi 14376af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest) 14476af099aSliuyi { 14576af099aSliuyi if (!pszSrc) 14676af099aSliuyi return false; 14776af099aSliuyi int nSrcLen = strlen(pszSrc); 14876af099aSliuyi int nDestLen = nSrcLen * 2; 14976af099aSliuyi 15076af099aSliuyi pszDest = NULL; 15176af099aSliuyi pszDest = new wchar_t[nDestLen]; 15276af099aSliuyi if (!pszDest) 15376af099aSliuyi return false; 15476af099aSliuyi nDestLen = nDestLen * sizeof(wchar_t); 15576af099aSliuyi memset(pszDest, 0, nDestLen); 15676af099aSliuyi int iRet; 15776af099aSliuyi iconv_t cd; 15876af099aSliuyi cd = iconv_open("UTF-32", "UTF-8"); 15976af099aSliuyi if((iconv_t)-1 == cd) { 16076af099aSliuyi delete []pszDest; 16176af099aSliuyi pszDest = NULL; 16276af099aSliuyi return false; 16376af099aSliuyi } 16476af099aSliuyi char *pIn, *pOut; 16576af099aSliuyi pIn = (char *)pszSrc; 16676af099aSliuyi pOut = (char *)pszDest; 16776af099aSliuyi 16876af099aSliuyi iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 16976af099aSliuyi 17076af099aSliuyi if(iRet == -1) { 17176af099aSliuyi delete []pszDest; 17276af099aSliuyi pszDest = NULL; 17376af099aSliuyi iconv_close(cd); 17476af099aSliuyi return false; 17576af099aSliuyi } 17676af099aSliuyi 17776af099aSliuyi iconv_close(cd); 17876af099aSliuyi 17976af099aSliuyi return true; 18076af099aSliuyi } 18176af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest) 18276af099aSliuyi { 18376af099aSliuyi if (!pszSrc) 18476af099aSliuyi return false; 18576af099aSliuyi int nSrcLen = wcslen(pszSrc); 18676af099aSliuyi int nDestLen = nSrcLen * 2; 18776af099aSliuyi nSrcLen = nSrcLen * sizeof(wchar_t); 18876af099aSliuyi pszDest = NULL; 18976af099aSliuyi pszDest = new char[nDestLen]; 19076af099aSliuyi if (!pszDest) 19176af099aSliuyi return false; 19276af099aSliuyi memset(pszDest, 0, nDestLen); 19376af099aSliuyi int iRet; 19476af099aSliuyi iconv_t cd; 19576af099aSliuyi cd = iconv_open("UTF-8", "UTF-32"); 19676af099aSliuyi 19776af099aSliuyi if((iconv_t)-1 == cd) { 19876af099aSliuyi delete []pszDest; 19976af099aSliuyi pszDest = NULL; 20076af099aSliuyi return false; 20176af099aSliuyi } 20276af099aSliuyi char *pIn, *pOut; 20376af099aSliuyi pIn = (char *)pszSrc; 20476af099aSliuyi pOut = (char *)pszDest; 20576af099aSliuyi iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 20676af099aSliuyi 20776af099aSliuyi if(iRet == -1) { 20876af099aSliuyi delete []pszDest; 20976af099aSliuyi pszDest = NULL; 21076af099aSliuyi iconv_close(cd); 21176af099aSliuyi return false; 21276af099aSliuyi } 21376af099aSliuyi 21476af099aSliuyi iconv_close(cd); 21576af099aSliuyi 21676af099aSliuyi return true; 21776af099aSliuyi } 218c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName) 21976af099aSliuyi { 22076af099aSliuyi unsigned int i; 221c29e5f0fSliuyi for(i = 0; i < vecItems.size(); i++){ 222c29e5f0fSliuyi if (strcasecmp(pszName, vecItems[i].szItemName) == 0){ 22376af099aSliuyi return i; 22476af099aSliuyi } 22576af099aSliuyi } 22676af099aSliuyi return -1; 22776af099aSliuyi } 228c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid) 229c29e5f0fSliuyi { 230c29e5f0fSliuyi unsigned int i; 231c29e5f0fSliuyi char value; 232c29e5f0fSliuyi memset(uuid, 0, 16); 233c29e5f0fSliuyi for (i =0; i < strUUid.size(); i++) { 234c29e5f0fSliuyi value = 0; 235c29e5f0fSliuyi if ((strUUid[i] >= '0')&&(strUUid[i] <= '9')) 236c29e5f0fSliuyi value = strUUid[i] - '0'; 237c29e5f0fSliuyi if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f')) 238c29e5f0fSliuyi value = strUUid[i] - 'a' + 10; 239c29e5f0fSliuyi if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F')) 240c29e5f0fSliuyi value = strUUid[i] - 'A' + 10; 241c29e5f0fSliuyi if ((i % 2) == 0) 242c29e5f0fSliuyi uuid[i / 2] += (value << 4); 243c29e5f0fSliuyi else 244c29e5f0fSliuyi uuid[i / 2] += value; 245c29e5f0fSliuyi } 246c29e5f0fSliuyi unsigned int *p32; 247c29e5f0fSliuyi unsigned short *p16; 248c29e5f0fSliuyi p32 = (unsigned int*)uuid; 249c29e5f0fSliuyi *p32 = cpu_to_be32(*p32); 250c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 4); 251c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 252c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 6); 253c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 254c29e5f0fSliuyi } 25576af099aSliuyi 25676af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 25776af099aSliuyi { 25876af099aSliuyi 25976af099aSliuyi stringstream configStream(pConfig); 26076af099aSliuyi string strLine, strItemName, strItemValue; 26176af099aSliuyi string::size_type line_size,pos; 26276af099aSliuyi STRUCT_CONFIG_ITEM item; 26376af099aSliuyi vecItem.clear(); 26476af099aSliuyi while (!configStream.eof()){ 26576af099aSliuyi getline(configStream, strLine); 26676af099aSliuyi line_size = strLine.size(); 26776af099aSliuyi if (line_size == 0) 26876af099aSliuyi continue; 26976af099aSliuyi if (strLine[line_size-1] == '\r'){ 27076af099aSliuyi strLine = strLine.substr(0, line_size-1); 27176af099aSliuyi } 272c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 273c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 274c30d921cSKever Yang if (strLine.size()==0 ) 275c30d921cSKever Yang continue; 276c30d921cSKever Yang if (strLine[0] == '#') 277c30d921cSKever Yang continue; 27876af099aSliuyi pos = strLine.find("="); 27976af099aSliuyi if (pos == string::npos){ 28076af099aSliuyi continue; 28176af099aSliuyi } 28276af099aSliuyi strItemName = strLine.substr(0, pos); 28376af099aSliuyi strItemValue = strLine.substr(pos + 1); 28476af099aSliuyi strItemName.erase(0, strItemName.find_first_not_of(" ")); 28576af099aSliuyi strItemName.erase(strItemName.find_last_not_of(" ") + 1); 28676af099aSliuyi strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 28776af099aSliuyi strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 28876af099aSliuyi if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 28976af099aSliuyi strcpy(item.szItemName, strItemName.c_str()); 29076af099aSliuyi strcpy(item.szItemValue, strItemValue.c_str()); 29176af099aSliuyi vecItem.push_back(item); 29276af099aSliuyi } 29376af099aSliuyi } 29476af099aSliuyi return true; 29576af099aSliuyi 29676af099aSliuyi } 29776af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 29876af099aSliuyi { 29976af099aSliuyi FILE *file = NULL; 30076af099aSliuyi file = fopen(pConfigFile, "rb"); 30176af099aSliuyi if( !file ){ 30276af099aSliuyi if (g_pLogObject) 30332268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile); 30476af099aSliuyi return false; 30576af099aSliuyi } 30676af099aSliuyi int iFileSize; 30776af099aSliuyi fseek(file, 0, SEEK_END); 30876af099aSliuyi iFileSize = ftell(file); 30976af099aSliuyi fseek(file, 0, SEEK_SET); 31076af099aSliuyi char *pConfigBuf = NULL; 31176af099aSliuyi pConfigBuf = new char[iFileSize + 1]; 31276af099aSliuyi if (!pConfigBuf){ 31376af099aSliuyi fclose(file); 31476af099aSliuyi return false; 31576af099aSliuyi } 31676af099aSliuyi memset(pConfigBuf, 0, iFileSize + 1); 31776af099aSliuyi int iRead; 31876af099aSliuyi iRead = fread(pConfigBuf, 1, iFileSize, file); 31976af099aSliuyi if (iRead != iFileSize){ 32076af099aSliuyi if (g_pLogObject) 32132268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize); 32276af099aSliuyi fclose(file); 32376af099aSliuyi delete []pConfigBuf; 32476af099aSliuyi return false; 32576af099aSliuyi } 32676af099aSliuyi fclose(file); 32776af099aSliuyi bool bRet; 32876af099aSliuyi bRet = parse_config(pConfigBuf, vecItem); 32976af099aSliuyi delete []pConfigBuf; 33076af099aSliuyi return bRet; 33176af099aSliuyi } 332c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 333c30d921cSKever Yang { 334c30d921cSKever Yang string::size_type pos,prevPos; 335c30d921cSKever Yang string strOffset,strLen; 336c30d921cSKever Yang int iCount; 337c30d921cSKever Yang prevPos = pos = 0; 338c30d921cSKever Yang if (strPartInfo.size() <= 0) { 339c30d921cSKever Yang return false; 340c30d921cSKever Yang } 341c30d921cSKever Yang pos = strPartInfo.find('@'); 342c30d921cSKever Yang if (pos == string::npos) { 343c30d921cSKever Yang return false; 344c30d921cSKever Yang } 345c30d921cSKever Yang strLen = strPartInfo.substr(prevPos, pos - prevPos); 346c30d921cSKever Yang strLen.erase(0, strLen.find_first_not_of(" ")); 347c30d921cSKever Yang strLen.erase(strLen.find_last_not_of(" ") + 1); 348c30d921cSKever Yang if (strchr(strLen.c_str(), '-')) { 349c30d921cSKever Yang uiLen = 0xFFFFFFFF; 350c30d921cSKever Yang } else { 351c30d921cSKever Yang iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 352c30d921cSKever Yang if (iCount != 1) { 353c30d921cSKever Yang return false; 354c30d921cSKever Yang } 355c30d921cSKever Yang } 356c30d921cSKever Yang 357c30d921cSKever Yang prevPos = pos + 1; 358c30d921cSKever Yang pos = strPartInfo.find('(',prevPos); 359c30d921cSKever Yang if (pos == string::npos) { 360c30d921cSKever Yang return false; 361c30d921cSKever Yang } 362c30d921cSKever Yang strOffset = strPartInfo.substr(prevPos, pos - prevPos); 363c30d921cSKever Yang strOffset.erase(0, strOffset.find_first_not_of(" ")); 364c30d921cSKever Yang strOffset.erase(strOffset.find_last_not_of(" ") + 1); 365c30d921cSKever Yang iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 366c30d921cSKever Yang if (iCount != 1) { 367c30d921cSKever Yang return false; 368c30d921cSKever Yang } 369c30d921cSKever Yang prevPos = pos + 1; 370c30d921cSKever Yang pos = strPartInfo.find(')', prevPos); 371c30d921cSKever Yang if (pos == string::npos) { 372c30d921cSKever Yang return false; 373c30d921cSKever Yang } 374c30d921cSKever Yang strName = strPartInfo.substr(prevPos, pos - prevPos); 375c30d921cSKever Yang strName.erase(0, strName.find_first_not_of(" ")); 376c30d921cSKever Yang strName.erase(strName.find_last_not_of(" ") + 1); 377c30d921cSKever Yang 378c30d921cSKever Yang return true; 379c30d921cSKever Yang } 380c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid) 381c29e5f0fSliuyi { 382c29e5f0fSliuyi string::size_type pos(0); 383c30d921cSKever Yang 384c29e5f0fSliuyi if (strUuidInfo.size() <= 0) { 385c29e5f0fSliuyi return false; 386c29e5f0fSliuyi } 387c29e5f0fSliuyi pos = strUuidInfo.find('='); 388c29e5f0fSliuyi if (pos == string::npos) { 389c29e5f0fSliuyi return false; 390c29e5f0fSliuyi } 391c29e5f0fSliuyi strName = strUuidInfo.substr(0, pos); 392c29e5f0fSliuyi strName.erase(0, strName.find_first_not_of(" ")); 393c29e5f0fSliuyi strName.erase(strName.find_last_not_of(" ") + 1); 394c29e5f0fSliuyi 395c29e5f0fSliuyi strUUid = strUuidInfo.substr(pos+1); 396c29e5f0fSliuyi strUUid.erase(0, strUUid.find_first_not_of(" ")); 397c29e5f0fSliuyi strUUid.erase(strUUid.find_last_not_of(" ") + 1); 398c29e5f0fSliuyi 399c29e5f0fSliuyi while(true) { 400c29e5f0fSliuyi pos = 0; 401c29e5f0fSliuyi if( (pos = strUUid.find("-")) != string::npos) 402c29e5f0fSliuyi strUUid.replace(pos,1,""); 403c29e5f0fSliuyi else 404c29e5f0fSliuyi break; 405c29e5f0fSliuyi } 406c29e5f0fSliuyi if (strUUid.size() != 32) 407c29e5f0fSliuyi return false; 408c29e5f0fSliuyi return true; 409c29e5f0fSliuyi } 410c29e5f0fSliuyi 411c29e5f0fSliuyi 412c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 413c30d921cSKever Yang { 414c30d921cSKever Yang stringstream paramStream(pParameter); 415c30d921cSKever Yang bool bRet,bFind = false; 416c29e5f0fSliuyi string strLine, strPartition, strPartInfo, strPartName, strUUid; 417c30d921cSKever Yang string::size_type line_size, pos, posColon, posComma; 418c30d921cSKever Yang UINT uiPartOffset, uiPartSize; 419c30d921cSKever Yang STRUCT_PARAM_ITEM item; 420c29e5f0fSliuyi STRUCT_CONFIG_ITEM uuid_item; 421c30d921cSKever Yang vecItem.clear(); 422c29e5f0fSliuyi vecUuidItem.clear(); 423c30d921cSKever Yang while (!paramStream.eof()) { 424c30d921cSKever Yang getline(paramStream,strLine); 425c30d921cSKever Yang line_size = strLine.size(); 426c30d921cSKever Yang if (line_size == 0) 427c30d921cSKever Yang continue; 428c30d921cSKever Yang if (strLine[line_size - 1] == '\r'){ 429c30d921cSKever Yang strLine = strLine.substr(0, line_size - 1); 430c30d921cSKever Yang } 431c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 432c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 433c30d921cSKever Yang if (strLine.size()==0 ) 434c30d921cSKever Yang continue; 435c30d921cSKever Yang if (strLine[0] == '#') 436c30d921cSKever Yang continue; 437c29e5f0fSliuyi pos = strLine.find("uuid:"); 438c29e5f0fSliuyi if (pos != string::npos) { 439c29e5f0fSliuyi strPartInfo = strLine.substr(pos+5); 440c29e5f0fSliuyi bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid); 441c29e5f0fSliuyi if (bRet) { 442c29e5f0fSliuyi strcpy(uuid_item.szItemName, strPartName.c_str()); 443c29e5f0fSliuyi string_to_uuid(strUUid,uuid_item.szItemValue); 444c29e5f0fSliuyi vecUuidItem.push_back(uuid_item); 445c29e5f0fSliuyi } 446c29e5f0fSliuyi continue; 447c29e5f0fSliuyi } 448c29e5f0fSliuyi 449c30d921cSKever Yang pos = strLine.find("mtdparts"); 450c30d921cSKever Yang if (pos == string::npos) { 451c30d921cSKever Yang continue; 452c30d921cSKever Yang } 453c30d921cSKever Yang bFind = true; 454c30d921cSKever Yang posColon = strLine.find(':', pos); 455c30d921cSKever Yang if (posColon == string::npos) { 456c30d921cSKever Yang continue; 457c30d921cSKever Yang } 458c30d921cSKever Yang strPartition = strLine.substr(posColon + 1); 459c30d921cSKever Yang pos = 0; 460c30d921cSKever Yang posComma = strPartition.find(',', pos); 461c30d921cSKever Yang while (posComma != string::npos) { 462c30d921cSKever Yang strPartInfo = strPartition.substr(pos, posComma - pos); 463c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 464c30d921cSKever Yang if (bRet) { 465c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 466c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 467c30d921cSKever Yang item.uiItemSize = uiPartSize; 468c30d921cSKever Yang vecItem.push_back(item); 469c30d921cSKever Yang } 470c30d921cSKever Yang pos = posComma + 1; 471c30d921cSKever Yang posComma = strPartition.find(',', pos); 472c30d921cSKever Yang } 473c30d921cSKever Yang strPartInfo = strPartition.substr(pos); 474c30d921cSKever Yang if (strPartInfo.size() > 0) { 475c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 476c30d921cSKever Yang if (bRet) { 477c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 478c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 479c30d921cSKever Yang item.uiItemSize = uiPartSize; 480c30d921cSKever Yang vecItem.push_back(item); 481c30d921cSKever Yang } 482c30d921cSKever Yang } 483c30d921cSKever Yang break; 484c30d921cSKever Yang } 485c30d921cSKever Yang return bFind; 486c30d921cSKever Yang 487c30d921cSKever Yang } 488c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 489c30d921cSKever Yang { 490c30d921cSKever Yang FILE *file = NULL; 491c30d921cSKever Yang file = fopen(pParamFile, "rb"); 492c30d921cSKever Yang if( !file ) { 493c30d921cSKever Yang if (g_pLogObject) 49432268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 495c30d921cSKever Yang return false; 496c30d921cSKever Yang } 497c30d921cSKever Yang int iFileSize; 498c30d921cSKever Yang fseek(file, 0, SEEK_END); 499c30d921cSKever Yang iFileSize = ftell(file); 500c30d921cSKever Yang fseek(file, 0, SEEK_SET); 501c30d921cSKever Yang char *pParamBuf = NULL; 502c30d921cSKever Yang pParamBuf = new char[iFileSize]; 503c30d921cSKever Yang if (!pParamBuf) { 504c30d921cSKever Yang fclose(file); 505c30d921cSKever Yang return false; 506c30d921cSKever Yang } 507c30d921cSKever Yang int iRead; 508c30d921cSKever Yang iRead = fread(pParamBuf, 1, iFileSize, file); 509c30d921cSKever Yang if (iRead != iFileSize) { 510c30d921cSKever Yang if (g_pLogObject) 51132268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize); 512c30d921cSKever Yang fclose(file); 513c30d921cSKever Yang delete []pParamBuf; 514c30d921cSKever Yang return false; 515c30d921cSKever Yang } 516c30d921cSKever Yang fclose(file); 517c30d921cSKever Yang bool bRet; 518c29e5f0fSliuyi bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem); 519c30d921cSKever Yang delete []pParamBuf; 520c30d921cSKever Yang return bRet; 521c30d921cSKever Yang } 5226ae612beSliuyi bool is_sparse_image(char *szImage) 5236ae612beSliuyi { 5246ae612beSliuyi FILE *file = NULL; 5256ae612beSliuyi sparse_header head; 5266ae612beSliuyi u32 uiRead; 5276ae612beSliuyi file = fopen(szImage, "rb"); 5286ae612beSliuyi if( !file ) { 5296ae612beSliuyi if (g_pLogObject) 5306ae612beSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage); 5316ae612beSliuyi return false; 5326ae612beSliuyi } 5336ae612beSliuyi uiRead = fread(&head, 1, sizeof(head), file); 5346ae612beSliuyi if (uiRead != sizeof(head)) { 5356ae612beSliuyi if (g_pLogObject) 5366ae612beSliuyi g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head)); 5376ae612beSliuyi fclose(file); 5386ae612beSliuyi return false; 5396ae612beSliuyi } 5406ae612beSliuyi fclose(file); 5416ae612beSliuyi if (head.magic!=SPARSE_HEADER_MAGIC) 5426ae612beSliuyi { 5436ae612beSliuyi return false; 5446ae612beSliuyi } 5456ae612beSliuyi return true; 5466ae612beSliuyi 5476ae612beSliuyi } 548c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin) 549c30d921cSKever Yang { 550c30d921cSKever Yang efi_guid_t id; 551c30d921cSKever Yang unsigned int *ptr = (unsigned int *)&id; 552c30d921cSKever Yang unsigned int i; 553c30d921cSKever Yang 554c30d921cSKever Yang /* Set all fields randomly */ 555c30d921cSKever Yang for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 556c30d921cSKever Yang *(ptr + i) = cpu_to_be32(rand()); 557c30d921cSKever Yang 558c30d921cSKever Yang id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 559c30d921cSKever Yang id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 560c30d921cSKever Yang 561c30d921cSKever Yang memcpy(uuid_bin, id.raw, sizeof(id)); 562c30d921cSKever Yang } 563c30d921cSKever Yang 564c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup) 565c29e5f0fSliuyi { 566c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 567c29e5f0fSliuyi gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE); 568c29e5f0fSliuyi u32 calc_crc32; 569c29e5f0fSliuyi u64 val; 570c29e5f0fSliuyi 571c29e5f0fSliuyi /* recalculate the values for the Backup GPT Header */ 572c29e5f0fSliuyi val = le64_to_cpu(gptMasterHead->my_lba); 573c29e5f0fSliuyi gptBackupHead->my_lba = gptMasterHead->alternate_lba; 574c29e5f0fSliuyi gptBackupHead->alternate_lba = cpu_to_le64(val); 575c29e5f0fSliuyi gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1); 576c29e5f0fSliuyi gptBackupHead->header_crc32 = 0; 577c29e5f0fSliuyi 578c29e5f0fSliuyi calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size)); 579c29e5f0fSliuyi gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32); 580c29e5f0fSliuyi } 5816ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end) 5826ae612beSliuyi { 5836ae612beSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 5846ae612beSliuyi gpt_entry *gptEntry = NULL; 5856ae612beSliuyi u32 i,j; 5866ae612beSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 5876ae612beSliuyi bool bFound = false; 5886ae612beSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 5896ae612beSliuyi 5906ae612beSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 5916ae612beSliuyi gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 5926ae612beSliuyi if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0) 5936ae612beSliuyi break; 5946ae612beSliuyi for (j = 0; j < strlen(pszName); j++) 5956ae612beSliuyi if (gptEntry->partition_name[j] != pszName[j]) 5966ae612beSliuyi break; 5976ae612beSliuyi if (gptEntry->partition_name[j] != 0) 5986ae612beSliuyi continue; 5996ae612beSliuyi if (j == strlen(pszName)) { 6006ae612beSliuyi bFound = true; 6016ae612beSliuyi break; 6026ae612beSliuyi } 6036ae612beSliuyi } 6046ae612beSliuyi if (bFound) { 6056ae612beSliuyi *lba = le64_to_cpu(gptEntry->starting_lba); 6066ae612beSliuyi *lba_end = le64_to_cpu(gptEntry->ending_lba); 6076ae612beSliuyi return true; 6086ae612beSliuyi } 6096ae612beSliuyi return false; 6106ae612beSliuyi } 611c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector) 612c29e5f0fSliuyi { 613c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 614c29e5f0fSliuyi gpt_entry *gptLastPartEntry = NULL; 615c29e5f0fSliuyi u32 i; 616c29e5f0fSliuyi u64 old_disksize; 617c29e5f0fSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 618c29e5f0fSliuyi 619c29e5f0fSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 620c29e5f0fSliuyi old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1; 621c29e5f0fSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 622c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 623c29e5f0fSliuyi if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0) 624c29e5f0fSliuyi break; 625c29e5f0fSliuyi } 626c29e5f0fSliuyi i--; 627c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry)); 628c29e5f0fSliuyi 629c29e5f0fSliuyi gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1); 630c29e5f0fSliuyi gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34); 631c29e5f0fSliuyi 632c29e5f0fSliuyi if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition 633c29e5f0fSliuyi gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34); 634c29e5f0fSliuyi gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 635c29e5f0fSliuyi } 636c29e5f0fSliuyi gptMasterHead->header_crc32 = 0; 637c29e5f0fSliuyi gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header))); 638c29e5f0fSliuyi memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS); 639c29e5f0fSliuyi memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE); 640c29e5f0fSliuyi prepare_gpt_backup(master, backup); 641c29e5f0fSliuyi 642c29e5f0fSliuyi } 643c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup) 644c29e5f0fSliuyi { 645c29e5f0fSliuyi FILE *file = NULL; 646c29e5f0fSliuyi file = fopen(pParamFile, "rb"); 647c29e5f0fSliuyi if( !file ) { 648c29e5f0fSliuyi if (g_pLogObject) 649c29e5f0fSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 650c29e5f0fSliuyi return false; 651c29e5f0fSliuyi } 652c29e5f0fSliuyi int iFileSize; 653c29e5f0fSliuyi fseek(file, 0, SEEK_END); 654c29e5f0fSliuyi iFileSize = ftell(file); 655c29e5f0fSliuyi fseek(file, 0, SEEK_SET); 656c29e5f0fSliuyi if (iFileSize != 67 * SECTOR_SIZE) { 657c29e5f0fSliuyi if (g_pLogObject) 658c29e5f0fSliuyi g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile); 659c29e5f0fSliuyi fclose(file); 660c29e5f0fSliuyi return false; 661c29e5f0fSliuyi } 662c29e5f0fSliuyi 663c29e5f0fSliuyi int iRead; 664c29e5f0fSliuyi iRead = fread(master, 1, 34 * SECTOR_SIZE, file); 665c29e5f0fSliuyi if (iRead != 34 * SECTOR_SIZE) { 666c29e5f0fSliuyi if (g_pLogObject) 667c29e5f0fSliuyi g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE); 668c29e5f0fSliuyi fclose(file); 669c29e5f0fSliuyi return false; 670c29e5f0fSliuyi } 671c29e5f0fSliuyi iRead = fread(backup, 1, 33 * SECTOR_SIZE, file); 672c29e5f0fSliuyi if (iRead != 33 * SECTOR_SIZE) { 673c29e5f0fSliuyi if (g_pLogObject) 674c29e5f0fSliuyi g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE); 675c29e5f0fSliuyi fclose(file); 676c29e5f0fSliuyi return false; 677c29e5f0fSliuyi } 678c29e5f0fSliuyi fclose(file); 679c29e5f0fSliuyi return true; 680c29e5f0fSliuyi } 681c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors) 682c30d921cSKever Yang { 683c30d921cSKever Yang legacy_mbr *mbr = (legacy_mbr *)gpt; 684c30d921cSKever Yang gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 685c30d921cSKever Yang gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 686c30d921cSKever Yang u32 i,j; 687c29e5f0fSliuyi int pos; 688c30d921cSKever Yang string strPartName; 689c30d921cSKever Yang string::size_type colonPos; 690c30d921cSKever Yang /*1.protective mbr*/ 691c30d921cSKever Yang memset(gpt, 0, SECTOR_SIZE); 692c30d921cSKever Yang mbr->signature = MSDOS_MBR_SIGNATURE; 693c30d921cSKever Yang mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 694c30d921cSKever Yang mbr->partition_record[0].start_sect = 1; 695c30d921cSKever Yang mbr->partition_record[0].nr_sects = (u32)-1; 696c30d921cSKever Yang /*2.gpt header*/ 697c30d921cSKever Yang memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 698c30d921cSKever Yang gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 699c30d921cSKever Yang gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 700c30d921cSKever Yang gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 701c30d921cSKever Yang gptHead->my_lba = cpu_to_le64(1); 702c30d921cSKever Yang gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 703c30d921cSKever Yang gptHead->first_usable_lba = cpu_to_le64(34); 704c30d921cSKever Yang gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 705c30d921cSKever Yang gptHead->partition_entry_lba = cpu_to_le64(2); 706c30d921cSKever Yang gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 707c30d921cSKever Yang gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 708c30d921cSKever Yang gptHead->header_crc32 = 0; 709c30d921cSKever Yang gptHead->partition_entry_array_crc32 = 0; 710c30d921cSKever Yang gen_rand_uuid(gptHead->disk_guid.raw); 711c30d921cSKever Yang 712c30d921cSKever Yang /*3.gpt partition entry*/ 713c30d921cSKever Yang memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 714c30d921cSKever Yang for (i = 0; i < vecParts.size(); i++) { 715c30d921cSKever Yang gen_rand_uuid(gptEntry->partition_type_guid.raw); 716c30d921cSKever Yang gen_rand_uuid(gptEntry->unique_partition_guid.raw); 717c30d921cSKever Yang gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 718c30d921cSKever Yang gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 719c30d921cSKever Yang gptEntry->attributes.raw = 0; 720c30d921cSKever Yang strPartName = vecParts[i].szItemName; 721c30d921cSKever Yang colonPos = strPartName.find_first_of(':'); 722c30d921cSKever Yang if (colonPos != string::npos) { 723c30d921cSKever Yang if (strPartName.find("bootable") != string::npos) 724c30d921cSKever Yang gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 725c29e5f0fSliuyi if (strPartName.find("grow") != string::npos) 726c29e5f0fSliuyi gptEntry->ending_lba = cpu_to_le64(diskSectors - 34); 727c30d921cSKever Yang strPartName = strPartName.substr(0, colonPos); 728c30d921cSKever Yang vecParts[i].szItemName[strPartName.size()] = 0; 729c30d921cSKever Yang } 730c30d921cSKever Yang for (j = 0; j < strlen(vecParts[i].szItemName); j++) 731c30d921cSKever Yang gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 732c29e5f0fSliuyi if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1) 733c29e5f0fSliuyi memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16); 734c30d921cSKever Yang gptEntry++; 735c30d921cSKever Yang } 736c30d921cSKever Yang 737c30d921cSKever Yang gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 738c30d921cSKever Yang gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 739c30d921cSKever Yang 740c30d921cSKever Yang } 741b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag) 742c30d921cSKever Yang { 743c30d921cSKever Yang PRK28_IDB_SEC0 pSec0; 744c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 745c30d921cSKever Yang pSec0 = (PRK28_IDB_SEC0)pSector; 746c30d921cSKever Yang 747c30d921cSKever Yang pSec0->dwTag = 0x0FF0AA55; 748b38fe5fcSliuyi pSec0->uiRc4Flag = rc4Flag; 749c30d921cSKever Yang pSec0->usBootCode1Offset = 0x4; 750c30d921cSKever Yang pSec0->usBootCode2Offset = 0x4; 751c30d921cSKever Yang pSec0->usBootDataSize = usFlashDataSec; 752c30d921cSKever Yang pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 753c30d921cSKever Yang return true; 754c30d921cSKever Yang } 755c30d921cSKever Yang 756c30d921cSKever Yang 757c30d921cSKever Yang bool MakeSector1(PBYTE pSector) 758c30d921cSKever Yang { 759c30d921cSKever Yang PRK28_IDB_SEC1 pSec1; 760c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 761c30d921cSKever Yang pSec1 = (PRK28_IDB_SEC1)pSector; 762c30d921cSKever Yang 763c30d921cSKever Yang pSec1->usSysReservedBlock = 0xC; 764c30d921cSKever Yang pSec1->usDisk0Size = 0xFFFF; 765c30d921cSKever Yang pSec1->uiChipTag = 0x38324B52; 766c30d921cSKever Yang return true; 767c30d921cSKever Yang } 768c30d921cSKever Yang 769c30d921cSKever Yang bool MakeSector2(PBYTE pSector) 770c30d921cSKever Yang { 771c30d921cSKever Yang PRK28_IDB_SEC2 pSec2; 772c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 773c30d921cSKever Yang pSec2 = (PRK28_IDB_SEC2)pSector; 774c30d921cSKever Yang 775c30d921cSKever Yang strcpy(pSec2->szVcTag, "VC"); 776c30d921cSKever Yang strcpy(pSec2->szCrcTag, "CRC"); 777c30d921cSKever Yang return true; 778c30d921cSKever Yang } 779c30d921cSKever Yang 780c30d921cSKever Yang bool MakeSector3(PBYTE pSector) 781c30d921cSKever Yang { 782c30d921cSKever Yang memset(pSector,0,SECTOR_SIZE); 783c30d921cSKever Yang return true; 784c30d921cSKever Yang } 785c30d921cSKever Yang 786b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag) 787c30d921cSKever Yang { 788c30d921cSKever Yang RK28_IDB_SEC0 sector0Info; 789c30d921cSKever Yang RK28_IDB_SEC1 sector1Info; 790c30d921cSKever Yang RK28_IDB_SEC2 sector2Info; 791c30d921cSKever Yang RK28_IDB_SEC3 sector3Info; 792c30d921cSKever Yang UINT i; 793b38fe5fcSliuyi MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag); 794c30d921cSKever Yang MakeSector1((PBYTE)§or1Info); 795c30d921cSKever Yang if (!MakeSector2((PBYTE)§or2Info)) { 796c30d921cSKever Yang return -6; 797c30d921cSKever Yang } 798c30d921cSKever Yang if (!MakeSector3((PBYTE)§or3Info)) { 799c30d921cSKever Yang return -7; 800c30d921cSKever Yang } 801c30d921cSKever Yang sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 802c30d921cSKever Yang sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 803c30d921cSKever Yang sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 804c30d921cSKever Yang 805c30d921cSKever Yang memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 806c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 807c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 808b38fe5fcSliuyi 809b38fe5fcSliuyi if (rc4Flag) { 810b38fe5fcSliuyi for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++) 811b38fe5fcSliuyi P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE); 812b38fe5fcSliuyi for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++) 813b38fe5fcSliuyi P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE); 814b38fe5fcSliuyi } 815b38fe5fcSliuyi 816c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 817c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 818c30d921cSKever Yang 819c30d921cSKever Yang sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 820c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 821c30d921cSKever Yang for(i = 0; i < 4; i++) { 822c30d921cSKever Yang if(i == 1) { 823c30d921cSKever Yang continue; 824c30d921cSKever Yang } else { 825c30d921cSKever Yang P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 826c30d921cSKever Yang } 827c30d921cSKever Yang } 828c30d921cSKever Yang return 0; 829c30d921cSKever Yang } 830c30d921cSKever Yang 831c30d921cSKever Yang 83276af099aSliuyi 83376af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 83476af099aSliuyi { 83506ea143eSKlaus Goger if (((UINT)dev.emUsbType & uiSupportType) == (UINT)dev.emUsbType) 83676af099aSliuyi return true; 83776af099aSliuyi else 83876af099aSliuyi { 83976af099aSliuyi ERROR_COLOR_ATTR; 84032268622SAndreas Färber printf("The device does not support this operation!"); 84176af099aSliuyi NORMAL_COLOR_ATTR; 84276af099aSliuyi printf("\r\n"); 84376af099aSliuyi return false; 84476af099aSliuyi } 84576af099aSliuyi } 846c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 847c30d921cSKever Yang { 848c30d921cSKever Yang u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 849c30d921cSKever Yang u32 total_size_sector; 850c30d921cSKever Yang CRKComm *pComm = NULL; 851c30d921cSKever Yang PARAM_ITEM_VECTOR vecItems; 852c29e5f0fSliuyi CONFIG_ITEM_VECTOR vecUuid; 853c30d921cSKever Yang int iRet; 854c30d921cSKever Yang bool bRet, bSuccess = false; 855c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 856c30d921cSKever Yang return false; 857c30d921cSKever Yang 858c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 859c30d921cSKever Yang if (!bRet) { 860c30d921cSKever Yang ERROR_COLOR_ATTR; 861c30d921cSKever Yang printf("Creating Comm Object failed!"); 862c30d921cSKever Yang NORMAL_COLOR_ATTR; 863c30d921cSKever Yang printf("\r\n"); 864c30d921cSKever Yang return bSuccess; 865c30d921cSKever Yang } 86632268622SAndreas Färber printf("Writing gpt...\r\n"); 867c30d921cSKever Yang //1.get flash info 868c30d921cSKever Yang iRet = pComm->RKU_ReadFlashInfo(flash_info); 869c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 870c30d921cSKever Yang ERROR_COLOR_ATTR; 871c30d921cSKever Yang printf("Reading Flash Info failed!"); 872c30d921cSKever Yang NORMAL_COLOR_ATTR; 873c30d921cSKever Yang printf("\r\n"); 874c30d921cSKever Yang return bSuccess; 875c30d921cSKever Yang } 876c30d921cSKever Yang total_size_sector = *(u32 *)flash_info; 877c29e5f0fSliuyi if (strstr(szParameter, ".img")) { 878c29e5f0fSliuyi if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) { 879c29e5f0fSliuyi ERROR_COLOR_ATTR; 880c29e5f0fSliuyi printf("Loading partition image failed!"); 881c29e5f0fSliuyi NORMAL_COLOR_ATTR; 882c29e5f0fSliuyi printf("\r\n"); 883c29e5f0fSliuyi return bSuccess; 884c29e5f0fSliuyi } 885c29e5f0fSliuyi update_gpt_disksize(master_gpt, backup_gpt, total_size_sector); 886c29e5f0fSliuyi } else { 887c30d921cSKever Yang //2.get partition from parameter 888c29e5f0fSliuyi bRet = parse_parameter_file(szParameter, vecItems, vecUuid); 889c30d921cSKever Yang if (!bRet) { 890c30d921cSKever Yang ERROR_COLOR_ATTR; 891c30d921cSKever Yang printf("Parsing parameter failed!"); 892c30d921cSKever Yang NORMAL_COLOR_ATTR; 893c30d921cSKever Yang printf("\r\n"); 894c30d921cSKever Yang return bSuccess; 895c30d921cSKever Yang } 896c29e5f0fSliuyi vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33; 897c30d921cSKever Yang //3.generate gpt info 898c29e5f0fSliuyi create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector); 899c30d921cSKever Yang memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 900c30d921cSKever Yang memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 901c29e5f0fSliuyi prepare_gpt_backup(master_gpt, backup_gpt); 902c29e5f0fSliuyi } 903c29e5f0fSliuyi 904c30d921cSKever Yang //4. write gpt 905c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 906c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 907c30d921cSKever Yang ERROR_COLOR_ATTR; 908c30d921cSKever Yang printf("Writing master gpt failed!"); 909c30d921cSKever Yang NORMAL_COLOR_ATTR; 910c30d921cSKever Yang printf("\r\n"); 911c30d921cSKever Yang return bSuccess; 912c30d921cSKever Yang } 913c29e5f0fSliuyi iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt); 914c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 915c30d921cSKever Yang ERROR_COLOR_ATTR; 916c30d921cSKever Yang printf("Writing backup gpt failed!"); 917c30d921cSKever Yang NORMAL_COLOR_ATTR; 918c30d921cSKever Yang printf("\r\n"); 919c30d921cSKever Yang return bSuccess; 920c30d921cSKever Yang } 921c29e5f0fSliuyi 922c30d921cSKever Yang bSuccess = true; 923c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 924c30d921cSKever Yang CURSOR_DEL_LINE; 92532268622SAndreas Färber printf("Writing gpt succeeded.\r\n"); 926c30d921cSKever Yang return bSuccess; 927c30d921cSKever Yang } 92876af099aSliuyi 92978884ef4SEddie Cai #include "boot_merger.h" 93078884ef4SEddie Cai #define ENTRY_ALIGN (2048) 93178884ef4SEddie Cai options gOpts; 93278884ef4SEddie Cai 93378884ef4SEddie Cai 93478884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 93578884ef4SEddie Cai char* gConfigPath; 93678884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE]; 93778884ef4SEddie Cai 93878884ef4SEddie Cai static inline void fixPath(char* path) { 93978884ef4SEddie Cai int i, len = strlen(path); 94078884ef4SEddie Cai for(i=0; i<len; i++) { 94178884ef4SEddie Cai if (path[i] == '\\') 94278884ef4SEddie Cai path[i] = '/'; 94378884ef4SEddie Cai else if (path[i] == '\r' || path[i] == '\n') 94478884ef4SEddie Cai path[i] = '\0'; 94578884ef4SEddie Cai } 94678884ef4SEddie Cai } 94778884ef4SEddie Cai 94878884ef4SEddie Cai static bool parseChip(FILE* file) { 94978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 95078884ef4SEddie Cai return false; 95178884ef4SEddie Cai } 95278884ef4SEddie Cai if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 95378884ef4SEddie Cai return false; 95478884ef4SEddie Cai } 95578884ef4SEddie Cai printf("chip: %s\n", gOpts.chip); 95678884ef4SEddie Cai return true; 95778884ef4SEddie Cai } 95878884ef4SEddie Cai 95978884ef4SEddie Cai static bool parseVersion(FILE* file) { 96078884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 96178884ef4SEddie Cai return false; 96278884ef4SEddie Cai } 96378884ef4SEddie Cai if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 96478884ef4SEddie Cai return false; 96578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 96678884ef4SEddie Cai return false; 96778884ef4SEddie Cai } 96878884ef4SEddie Cai if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 96978884ef4SEddie Cai return false; 97078884ef4SEddie Cai printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor); 97178884ef4SEddie Cai return true; 97278884ef4SEddie Cai } 97378884ef4SEddie Cai 97478884ef4SEddie Cai static bool parse471(FILE* file) { 97578884ef4SEddie Cai int i, index, pos; 97678884ef4SEddie Cai char buf[MAX_LINE_LEN]; 97778884ef4SEddie Cai 97878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 97978884ef4SEddie Cai return false; 98078884ef4SEddie Cai } 98178884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 98278884ef4SEddie Cai return false; 98378884ef4SEddie Cai printf("num: %d\n", gOpts.code471Num); 98478884ef4SEddie Cai if (!gOpts.code471Num) 98578884ef4SEddie Cai return true; 98678884ef4SEddie Cai if (gOpts.code471Num < 0) 98778884ef4SEddie Cai return false; 98878884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 98978884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 99078884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 99178884ef4SEddie Cai return false; 99278884ef4SEddie Cai } 99378884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 99478884ef4SEddie Cai != 2) 99578884ef4SEddie Cai return false; 99678884ef4SEddie Cai index--; 99778884ef4SEddie Cai fixPath(buf); 99878884ef4SEddie Cai strcpy((char*)gOpts.code471Path[index], buf); 99978884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code471Path[index]); 100078884ef4SEddie Cai } 100178884ef4SEddie Cai pos = ftell(file); 100278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 100378884ef4SEddie Cai return false; 100478884ef4SEddie Cai } 100578884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 100678884ef4SEddie Cai fseek(file, pos, SEEK_SET); 100778884ef4SEddie Cai printf("sleep: %d\n", gOpts.code471Sleep); 100878884ef4SEddie Cai return true; 100978884ef4SEddie Cai } 101078884ef4SEddie Cai 101178884ef4SEddie Cai static bool parse472(FILE* file) { 101278884ef4SEddie Cai int i, index, pos; 101378884ef4SEddie Cai char buf[MAX_LINE_LEN]; 101478884ef4SEddie Cai 101578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 101678884ef4SEddie Cai return false; 101778884ef4SEddie Cai } 101878884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 101978884ef4SEddie Cai return false; 102078884ef4SEddie Cai printf("num: %d\n", gOpts.code472Num); 102178884ef4SEddie Cai if (!gOpts.code472Num) 102278884ef4SEddie Cai return true; 102378884ef4SEddie Cai if (gOpts.code472Num < 0) 102478884ef4SEddie Cai return false; 102578884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 102678884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 102778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 102878884ef4SEddie Cai return false; 102978884ef4SEddie Cai } 103078884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 103178884ef4SEddie Cai != 2) 103278884ef4SEddie Cai return false; 103378884ef4SEddie Cai fixPath(buf); 103478884ef4SEddie Cai index--; 103578884ef4SEddie Cai strcpy((char*)gOpts.code472Path[index], buf); 103678884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code472Path[index]); 103778884ef4SEddie Cai } 103878884ef4SEddie Cai pos = ftell(file); 103978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 104078884ef4SEddie Cai return false; 104178884ef4SEddie Cai } 104278884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 104378884ef4SEddie Cai fseek(file, pos, SEEK_SET); 104478884ef4SEddie Cai printf("sleep: %d\n", gOpts.code472Sleep); 104578884ef4SEddie Cai return true; 104678884ef4SEddie Cai } 104778884ef4SEddie Cai 104878884ef4SEddie Cai static bool parseLoader(FILE* file) { 104978884ef4SEddie Cai int i, j, index, pos; 105078884ef4SEddie Cai char buf[MAX_LINE_LEN]; 105178884ef4SEddie Cai char buf2[MAX_LINE_LEN]; 105278884ef4SEddie Cai 105378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 105478884ef4SEddie Cai return false; 105578884ef4SEddie Cai } 105678884ef4SEddie Cai pos = ftell(file); 105778884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 105878884ef4SEddie Cai fseek(file, pos, SEEK_SET); 105978884ef4SEddie Cai if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 106078884ef4SEddie Cai return false; 106178884ef4SEddie Cai } 106278884ef4SEddie Cai } 106378884ef4SEddie Cai printf("num: %d\n", gOpts.loaderNum); 106478884ef4SEddie Cai if (!gOpts.loaderNum) 106578884ef4SEddie Cai return false; 106678884ef4SEddie Cai if (gOpts.loaderNum < 0) 106778884ef4SEddie Cai return false; 106878884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 106978884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 107078884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 107178884ef4SEddie Cai return false; 107278884ef4SEddie Cai } 107378884ef4SEddie Cai if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 107478884ef4SEddie Cai != 2) 107578884ef4SEddie Cai return false; 107678884ef4SEddie Cai strcpy(gOpts.loader[index].name, buf); 107778884ef4SEddie Cai printf("name%d: %s\n", index, gOpts.loader[index].name); 1078*544ec1d4SKlaus Goger index++; 107978884ef4SEddie Cai } 108078884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 108178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 108278884ef4SEddie Cai return false; 108378884ef4SEddie Cai } 108478884ef4SEddie Cai if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 108578884ef4SEddie Cai != 2) 108678884ef4SEddie Cai return false; 108778884ef4SEddie Cai for (j=0; j<gOpts.loaderNum; j++) { 108878884ef4SEddie Cai if (!strcmp(gOpts.loader[j].name, buf)) { 108978884ef4SEddie Cai fixPath(buf2); 109078884ef4SEddie Cai strcpy(gOpts.loader[j].path, buf2); 109178884ef4SEddie Cai printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 109278884ef4SEddie Cai break; 109378884ef4SEddie Cai } 109478884ef4SEddie Cai } 109578884ef4SEddie Cai if (j >= gOpts.loaderNum) { 109678884ef4SEddie Cai return false; 109778884ef4SEddie Cai } 109878884ef4SEddie Cai } 109978884ef4SEddie Cai return true; 110078884ef4SEddie Cai } 110178884ef4SEddie Cai 110278884ef4SEddie Cai static bool parseOut(FILE* file) { 110378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 110478884ef4SEddie Cai return false; 110578884ef4SEddie Cai } 110678884ef4SEddie Cai if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 110778884ef4SEddie Cai return false; 110878884ef4SEddie Cai fixPath(gOpts.outPath); 110978884ef4SEddie Cai printf("out: %s\n", gOpts.outPath); 111078884ef4SEddie Cai return true; 111178884ef4SEddie Cai } 111278884ef4SEddie Cai 111378884ef4SEddie Cai 111478884ef4SEddie Cai void printOpts(FILE* out) { 111578884ef4SEddie Cai int i; 111678884ef4SEddie Cai fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 111778884ef4SEddie Cai fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 111878884ef4SEddie Cai "=%d\n", gOpts.major, gOpts.minor); 111978884ef4SEddie Cai 112078884ef4SEddie Cai fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 112178884ef4SEddie Cai for (i=0 ;i<gOpts.code471Num ;i++) { 112278884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 112378884ef4SEddie Cai } 112478884ef4SEddie Cai if (gOpts.code471Sleep > 0) 112578884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 112678884ef4SEddie Cai 112778884ef4SEddie Cai fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 112878884ef4SEddie Cai for (i=0 ;i<gOpts.code472Num ;i++) { 112978884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 113078884ef4SEddie Cai } 113178884ef4SEddie Cai if (gOpts.code472Sleep > 0) 113278884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 113378884ef4SEddie Cai 113478884ef4SEddie Cai fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 113578884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 113678884ef4SEddie Cai fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 113778884ef4SEddie Cai } 113878884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 113978884ef4SEddie Cai fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 114078884ef4SEddie Cai } 114178884ef4SEddie Cai 114278884ef4SEddie Cai fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 114378884ef4SEddie Cai } 114478884ef4SEddie Cai 114578884ef4SEddie Cai static bool parseOpts(void) { 114678884ef4SEddie Cai bool ret = false; 114778884ef4SEddie Cai bool chipOk = false; 114878884ef4SEddie Cai bool versionOk = false; 114978884ef4SEddie Cai bool code471Ok = true; 115078884ef4SEddie Cai bool code472Ok = true; 115178884ef4SEddie Cai bool loaderOk = false; 115278884ef4SEddie Cai bool outOk = false; 115378884ef4SEddie Cai char buf[MAX_LINE_LEN]; 115478884ef4SEddie Cai 115578884ef4SEddie Cai char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 115678884ef4SEddie Cai FILE* file; 115778884ef4SEddie Cai file = fopen(configPath, "r"); 115878884ef4SEddie Cai if (!file) { 115978884ef4SEddie Cai fprintf(stderr, "config (%s) not found!\n", configPath); 116008c0d218SKlaus Goger if (strcmp(configPath, (char*)DEF_CONFIG_FILE) == 0) { 116178884ef4SEddie Cai file = fopen(DEF_CONFIG_FILE, "w"); 116278884ef4SEddie Cai if (file) { 116332268622SAndreas Färber fprintf(stderr, "creating defconfig\n"); 116478884ef4SEddie Cai printOpts(file); 116578884ef4SEddie Cai } 116678884ef4SEddie Cai } 116778884ef4SEddie Cai goto end; 116878884ef4SEddie Cai } 116978884ef4SEddie Cai 117032268622SAndreas Färber printf("Starting to parse...\n"); 117178884ef4SEddie Cai 117278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 117378884ef4SEddie Cai goto end; 117478884ef4SEddie Cai } 117578884ef4SEddie Cai while(fscanf(file, "%s", buf) == 1) { 117678884ef4SEddie Cai if (!strcmp(buf, SEC_CHIP)) { 117778884ef4SEddie Cai chipOk = parseChip(file); 117878884ef4SEddie Cai if (!chipOk) { 117978884ef4SEddie Cai printf("parseChip failed!\n"); 118078884ef4SEddie Cai goto end; 118178884ef4SEddie Cai } 118278884ef4SEddie Cai } else if (!strcmp(buf, SEC_VERSION)) { 118378884ef4SEddie Cai versionOk = parseVersion(file); 118478884ef4SEddie Cai if (!versionOk) { 118578884ef4SEddie Cai printf("parseVersion failed!\n"); 118678884ef4SEddie Cai goto end; 118778884ef4SEddie Cai } 118878884ef4SEddie Cai } else if (!strcmp(buf, SEC_471)) { 118978884ef4SEddie Cai code471Ok = parse471(file); 119078884ef4SEddie Cai if (!code471Ok) { 119178884ef4SEddie Cai printf("parse471 failed!\n"); 119278884ef4SEddie Cai goto end; 119378884ef4SEddie Cai } 119478884ef4SEddie Cai } else if (!strcmp(buf, SEC_472)) { 119578884ef4SEddie Cai code472Ok = parse472(file); 119678884ef4SEddie Cai if (!code472Ok) { 119778884ef4SEddie Cai printf("parse472 failed!\n"); 119878884ef4SEddie Cai goto end; 119978884ef4SEddie Cai } 120078884ef4SEddie Cai } else if (!strcmp(buf, SEC_LOADER)) { 120178884ef4SEddie Cai loaderOk = parseLoader(file); 120278884ef4SEddie Cai if (!loaderOk) { 120378884ef4SEddie Cai printf("parseLoader failed!\n"); 120478884ef4SEddie Cai goto end; 120578884ef4SEddie Cai } 120678884ef4SEddie Cai } else if (!strcmp(buf, SEC_OUT)) { 120778884ef4SEddie Cai outOk = parseOut(file); 120878884ef4SEddie Cai if (!outOk) { 120978884ef4SEddie Cai printf("parseOut failed!\n"); 121078884ef4SEddie Cai goto end; 121178884ef4SEddie Cai } 121278884ef4SEddie Cai } else if (buf[0] == '#') { 121378884ef4SEddie Cai continue; 121478884ef4SEddie Cai } else { 121578884ef4SEddie Cai printf("unknown sec: %s!\n", buf); 121678884ef4SEddie Cai goto end; 121778884ef4SEddie Cai } 121878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 121978884ef4SEddie Cai goto end; 122078884ef4SEddie Cai } 122178884ef4SEddie Cai } 122278884ef4SEddie Cai 122378884ef4SEddie Cai if (chipOk && versionOk && code471Ok && code472Ok 122478884ef4SEddie Cai && loaderOk && outOk) 122578884ef4SEddie Cai ret = true; 122678884ef4SEddie Cai end: 122778884ef4SEddie Cai if (file) 122878884ef4SEddie Cai fclose(file); 122978884ef4SEddie Cai return ret; 123078884ef4SEddie Cai } 123178884ef4SEddie Cai 123278884ef4SEddie Cai bool initOpts(void) { 123378884ef4SEddie Cai //set default opts 123478884ef4SEddie Cai gOpts.major = DEF_MAJOR; 123578884ef4SEddie Cai gOpts.minor = DEF_MINOR; 123678884ef4SEddie Cai strcpy(gOpts.chip, DEF_CHIP); 123778884ef4SEddie Cai gOpts.code471Sleep = DEF_CODE471_SLEEP; 123878884ef4SEddie Cai gOpts.code472Sleep = DEF_CODE472_SLEEP; 123978884ef4SEddie Cai gOpts.code471Num = DEF_CODE471_NUM; 124078884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 124178884ef4SEddie Cai strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 124278884ef4SEddie Cai gOpts.code472Num = DEF_CODE472_NUM; 124378884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 124478884ef4SEddie Cai strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 124578884ef4SEddie Cai gOpts.loaderNum = DEF_LOADER_NUM; 124678884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 124778884ef4SEddie Cai strcpy(gOpts.loader[0].name, DEF_LOADER0); 124878884ef4SEddie Cai strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 124978884ef4SEddie Cai strcpy(gOpts.loader[1].name, DEF_LOADER1); 125078884ef4SEddie Cai strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 125178884ef4SEddie Cai strcpy(gOpts.outPath, DEF_OUT_PATH); 125278884ef4SEddie Cai 125378884ef4SEddie Cai return parseOpts(); 125478884ef4SEddie Cai } 125578884ef4SEddie Cai 125678884ef4SEddie Cai /************merge code****************/ 125778884ef4SEddie Cai 125878884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) { 125978884ef4SEddie Cai uint8_t tmp[2] = {0}; 126078884ef4SEddie Cai int i; 126178884ef4SEddie Cai uint32_t ret; 126278884ef4SEddie Cai //if (value > 0xFFFF) { 126378884ef4SEddie Cai // return 0; 126478884ef4SEddie Cai //} 126578884ef4SEddie Cai for(i=0; i < 2; i++) { 126678884ef4SEddie Cai tmp[i] = (((value/10)%10)<<4) | (value%10); 126778884ef4SEddie Cai value /= 100; 126878884ef4SEddie Cai } 126978884ef4SEddie Cai ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 127078884ef4SEddie Cai 127178884ef4SEddie Cai printf("ret: %x\n",ret); 127278884ef4SEddie Cai return ret&0xFF; 127378884ef4SEddie Cai } 127478884ef4SEddie Cai 127578884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len) 127678884ef4SEddie Cai { 127778884ef4SEddie Cai int i; 127878884ef4SEddie Cai for (i = 0; i < len; i++) { 127978884ef4SEddie Cai wide[i] = (uint16_t) str[i]; 128078884ef4SEddie Cai } 128178884ef4SEddie Cai wide[len] = 0; 128278884ef4SEddie Cai } 128378884ef4SEddie Cai 128478884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) { 128578884ef4SEddie Cai char* end; 128678884ef4SEddie Cai char* start; 128778884ef4SEddie Cai int len; 128878884ef4SEddie Cai if (!path || !dst) 128978884ef4SEddie Cai return; 129078884ef4SEddie Cai start = strrchr(path, '/'); 129178884ef4SEddie Cai if (!start) 129278884ef4SEddie Cai start = path; 129378884ef4SEddie Cai else 129478884ef4SEddie Cai start++; 129578884ef4SEddie Cai end = strrchr(path, '.'); 1296641cfa16SEddie Cai if (!end || (end < start)) 129778884ef4SEddie Cai end = path + strlen(path); 129878884ef4SEddie Cai len = end - start; 129978884ef4SEddie Cai if (len >= MAX_NAME_LEN) 130078884ef4SEddie Cai len = MAX_NAME_LEN -1; 130178884ef4SEddie Cai str2wide(start, dst, len); 130278884ef4SEddie Cai 130378884ef4SEddie Cai 130478884ef4SEddie Cai char name[MAX_NAME_LEN]; 130578884ef4SEddie Cai memset(name, 0, sizeof(name)); 130678884ef4SEddie Cai memcpy(name, start, len); 130778884ef4SEddie Cai printf("path: %s, name: %s\n", path, name); 130878884ef4SEddie Cai 130978884ef4SEddie Cai } 131078884ef4SEddie Cai 131178884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) { 131278884ef4SEddie Cai struct stat st; 131378884ef4SEddie Cai if(stat(path, &st) < 0) 131478884ef4SEddie Cai return false; 131578884ef4SEddie Cai *size = st.st_size; 131678884ef4SEddie Cai printf("path: %s, size: %d\n", path, *size); 131778884ef4SEddie Cai return true; 131878884ef4SEddie Cai } 131978884ef4SEddie Cai 132078884ef4SEddie Cai static inline rk_time getTime(void) { 132178884ef4SEddie Cai rk_time rkTime; 132278884ef4SEddie Cai 132378884ef4SEddie Cai struct tm *tm; 132478884ef4SEddie Cai time_t tt = time(NULL); 132578884ef4SEddie Cai tm = localtime(&tt); 132678884ef4SEddie Cai rkTime.year = tm->tm_year + 1900; 132778884ef4SEddie Cai rkTime.month = tm->tm_mon + 1; 132878884ef4SEddie Cai rkTime.day = tm->tm_mday; 132978884ef4SEddie Cai rkTime.hour = tm->tm_hour; 133078884ef4SEddie Cai rkTime.minute = tm->tm_min; 133178884ef4SEddie Cai rkTime.second = tm->tm_sec; 133278884ef4SEddie Cai printf("%d-%d-%d %02d:%02d:%02d\n", 133378884ef4SEddie Cai rkTime.year, rkTime.month, rkTime.day, 133478884ef4SEddie Cai rkTime.hour, rkTime.minute, rkTime.second); 133578884ef4SEddie Cai return rkTime; 133678884ef4SEddie Cai } 133778884ef4SEddie Cai 133878884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) { 133978884ef4SEddie Cai bool ret = false; 134078884ef4SEddie Cai uint32_t size = 0, fixSize = 0; 134178884ef4SEddie Cai uint8_t* buf; 134278884ef4SEddie Cai 134378884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 134478884ef4SEddie Cai if (!inFile) 134578884ef4SEddie Cai goto end; 134678884ef4SEddie Cai 134778884ef4SEddie Cai if (!getFileSize(path, &size)) 134878884ef4SEddie Cai goto end; 134978884ef4SEddie Cai if (fix) { 135078884ef4SEddie Cai fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 135178884ef4SEddie Cai uint32_t tmp = fixSize % ENTRY_ALIGN; 135278884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 135378884ef4SEddie Cai fixSize +=tmp; 135478884ef4SEddie Cai memset(gBuf, 0, fixSize); 135578884ef4SEddie Cai } else { 135678884ef4SEddie Cai memset(gBuf, 0, size+ENTRY_ALIGN); 135778884ef4SEddie Cai } 135878884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 135978884ef4SEddie Cai goto end; 136078884ef4SEddie Cai 136178884ef4SEddie Cai if (fix) { 136278884ef4SEddie Cai 136378884ef4SEddie Cai buf = gBuf; 136478884ef4SEddie Cai size = fixSize; 136578884ef4SEddie Cai while(1) { 136678884ef4SEddie Cai P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 136778884ef4SEddie Cai buf += SMALL_PACKET; 136878884ef4SEddie Cai if (fixSize <= SMALL_PACKET) 136978884ef4SEddie Cai break; 137078884ef4SEddie Cai fixSize -= SMALL_PACKET; 137178884ef4SEddie Cai } 137278884ef4SEddie Cai } else { 137378884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 137478884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 137578884ef4SEddie Cai size +=tmp; 137678884ef4SEddie Cai P_RC4(gBuf, size); 137778884ef4SEddie Cai } 137878884ef4SEddie Cai 137978884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 138078884ef4SEddie Cai goto end; 138178884ef4SEddie Cai ret = true; 138278884ef4SEddie Cai end: 138378884ef4SEddie Cai if (inFile) 138478884ef4SEddie Cai fclose(inFile); 138578884ef4SEddie Cai if (!ret) 138632268622SAndreas Färber printf("writing entry (%s) failed\n", path); 138778884ef4SEddie Cai return ret; 138878884ef4SEddie Cai } 138978884ef4SEddie Cai 139078884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 139178884ef4SEddie Cai uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 139278884ef4SEddie Cai uint32_t size; 139378884ef4SEddie Cai rk_boot_entry entry; 139478884ef4SEddie Cai 139532268622SAndreas Färber printf("writing: %s\n", path); 1396641cfa16SEddie Cai memset(&entry, 0, sizeof(rk_boot_entry)); 139778884ef4SEddie Cai getName(fixName ? fixName: path, entry.name); 139878884ef4SEddie Cai entry.size = sizeof(rk_boot_entry); 139978884ef4SEddie Cai entry.type = type; 140078884ef4SEddie Cai entry.dataOffset = *offset; 140178884ef4SEddie Cai if (!getFileSize(path, &size)) { 140232268622SAndreas Färber printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path); 140378884ef4SEddie Cai return false; 140478884ef4SEddie Cai } 140578884ef4SEddie Cai if (fix) 140678884ef4SEddie Cai size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 140778884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 140878884ef4SEddie Cai size += tmp ? (ENTRY_ALIGN - tmp): 0; 140932268622SAndreas Färber printf("alignment size: %d\n", size); 141078884ef4SEddie Cai entry.dataSize = size; 141178884ef4SEddie Cai entry.dataDelay = delay; 141278884ef4SEddie Cai *offset += size; 141378884ef4SEddie Cai fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 141478884ef4SEddie Cai return true; 141578884ef4SEddie Cai } 141678884ef4SEddie Cai 141778884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) { 141878884ef4SEddie Cai char buffer[5]; 141978884ef4SEddie Cai memset(buffer, 0, sizeof(buffer)); 142078884ef4SEddie Cai snprintf(buffer, sizeof(buffer), "%s", chip); 142178884ef4SEddie Cai return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 142278884ef4SEddie Cai } 142378884ef4SEddie Cai 142478884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) { 142578884ef4SEddie Cai printf("chip: %s\n", chip); 142678884ef4SEddie Cai int chipType = RKNONE_DEVICE; 142778884ef4SEddie Cai if(!chip) { 142878884ef4SEddie Cai goto end; 142978884ef4SEddie Cai } 143078884ef4SEddie Cai if (!strcmp(chip, CHIP_RK28)) { 143178884ef4SEddie Cai chipType = RK28_DEVICE; 143278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK28)) { 143378884ef4SEddie Cai chipType = RK28_DEVICE; 143478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK281X)) { 143578884ef4SEddie Cai chipType = RK281X_DEVICE; 143678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKPANDA)) { 143778884ef4SEddie Cai chipType = RKPANDA_DEVICE; 143878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK27)) { 143978884ef4SEddie Cai chipType = RK27_DEVICE; 144078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKNANO)) { 144178884ef4SEddie Cai chipType = RKNANO_DEVICE; 144278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKSMART)) { 144378884ef4SEddie Cai chipType = RKSMART_DEVICE; 144478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCROWN)) { 144578884ef4SEddie Cai chipType = RKCROWN_DEVICE; 144678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 144778884ef4SEddie Cai chipType = RKCAYMAN_DEVICE; 144878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK29)) { 144978884ef4SEddie Cai chipType = RK29_DEVICE; 145078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK292X)) { 145178884ef4SEddie Cai chipType = RK292X_DEVICE; 145278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30)) { 145378884ef4SEddie Cai chipType = RK30_DEVICE; 145478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30B)) { 145578884ef4SEddie Cai chipType = RK30B_DEVICE; 145678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK31)) { 145778884ef4SEddie Cai chipType = RK31_DEVICE; 145878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK32)) { 145978884ef4SEddie Cai chipType = RK32_DEVICE; 146078884ef4SEddie Cai } else { 146178884ef4SEddie Cai chipType = convertChipType(chip + 2); 146278884ef4SEddie Cai } 146378884ef4SEddie Cai 146478884ef4SEddie Cai end: 146578884ef4SEddie Cai printf("type: 0x%x\n", chipType); 146678884ef4SEddie Cai if (chipType == RKNONE_DEVICE) { 146732268622SAndreas Färber printf("chip type not supported!\n"); 146878884ef4SEddie Cai } 146978884ef4SEddie Cai return chipType; 147078884ef4SEddie Cai } 147178884ef4SEddie Cai 147278884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) { 147378884ef4SEddie Cai memset(hdr, 0, sizeof(rk_boot_header)); 147478884ef4SEddie Cai hdr->tag = TAG; 147578884ef4SEddie Cai hdr->size = sizeof(rk_boot_header); 147678884ef4SEddie Cai hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 147778884ef4SEddie Cai hdr->mergerVersion = MERGER_VERSION; 147878884ef4SEddie Cai hdr->releaseTime = getTime(); 147978884ef4SEddie Cai hdr->chipType = getChipType(gOpts.chip); 148078884ef4SEddie Cai 148178884ef4SEddie Cai hdr->code471Num = gOpts.code471Num; 148278884ef4SEddie Cai hdr->code471Offset = sizeof(rk_boot_header); 148378884ef4SEddie Cai hdr->code471Size = sizeof(rk_boot_entry); 148478884ef4SEddie Cai 148578884ef4SEddie Cai hdr->code472Num = gOpts.code472Num; 148678884ef4SEddie Cai hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 148778884ef4SEddie Cai hdr->code472Size = sizeof(rk_boot_entry); 148878884ef4SEddie Cai 148978884ef4SEddie Cai hdr->loaderNum = gOpts.loaderNum; 149078884ef4SEddie Cai hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 149178884ef4SEddie Cai hdr->loaderSize = sizeof(rk_boot_entry); 149278884ef4SEddie Cai #ifndef USE_P_RC4 149378884ef4SEddie Cai hdr->rc4Flag = 1; 149478884ef4SEddie Cai #endif 149578884ef4SEddie Cai } 149678884ef4SEddie Cai 149778884ef4SEddie Cai static inline uint32_t getCrc(const char* path) { 149878884ef4SEddie Cai uint32_t size = 0; 149978884ef4SEddie Cai uint32_t crc = 0; 150078884ef4SEddie Cai 150178884ef4SEddie Cai FILE* file = fopen(path, "rb"); 150278884ef4SEddie Cai getFileSize(path, &size); 150378884ef4SEddie Cai if (!file) 150478884ef4SEddie Cai goto end; 150578884ef4SEddie Cai if (!fread(gBuf, size, 1, file)) 150678884ef4SEddie Cai goto end; 150778884ef4SEddie Cai crc = CRC_32(gBuf, size); 150878884ef4SEddie Cai printf("crc: 0x%08x\n", crc); 150978884ef4SEddie Cai end: 151078884ef4SEddie Cai if (file) 151178884ef4SEddie Cai fclose(file); 151278884ef4SEddie Cai return crc; 151378884ef4SEddie Cai } 151478884ef4SEddie Cai 151578884ef4SEddie Cai bool mergeBoot(void) { 151678884ef4SEddie Cai uint32_t dataOffset; 151778884ef4SEddie Cai bool ret = false; 151878884ef4SEddie Cai int i; 151978884ef4SEddie Cai FILE* outFile; 152078884ef4SEddie Cai uint32_t crc; 152178884ef4SEddie Cai rk_boot_header hdr; 152278884ef4SEddie Cai 152378884ef4SEddie Cai if (!initOpts()) 152478884ef4SEddie Cai return false; 152578884ef4SEddie Cai { 152678884ef4SEddie Cai char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 152778884ef4SEddie Cai char version[MAX_LINE_LEN]; 152878884ef4SEddie Cai snprintf(version, sizeof(version), "%s", gSubfix); 152978884ef4SEddie Cai if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 153078884ef4SEddie Cai subfix[0] = '\0'; 153178884ef4SEddie Cai } 153278884ef4SEddie Cai strcat(gOpts.outPath, version); 153378884ef4SEddie Cai printf("fix opt: %s\n", gOpts.outPath); 153478884ef4SEddie Cai } 153578884ef4SEddie Cai 153678884ef4SEddie Cai printf("---------------\nUSING CONFIG:\n"); 153778884ef4SEddie Cai printOpts(stdout); 153878884ef4SEddie Cai printf("---------------\n\n"); 153978884ef4SEddie Cai 154078884ef4SEddie Cai 154178884ef4SEddie Cai outFile = fopen(gOpts.outPath, "wb+"); 154278884ef4SEddie Cai if (!outFile) { 154332268622SAndreas Färber printf("Opening output file (%s) failed\n", gOpts.outPath); 154478884ef4SEddie Cai goto end; 154578884ef4SEddie Cai } 154678884ef4SEddie Cai 154778884ef4SEddie Cai getBoothdr(&hdr); 154832268622SAndreas Färber printf("Writing header...\n"); 154978884ef4SEddie Cai fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 155078884ef4SEddie Cai 155178884ef4SEddie Cai dataOffset = sizeof(rk_boot_header) + 155278884ef4SEddie Cai (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 155378884ef4SEddie Cai sizeof(rk_boot_entry); 155478884ef4SEddie Cai 155532268622SAndreas Färber printf("Writing code 471 entry...\n"); 155678884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 155778884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 155878884ef4SEddie Cai &dataOffset, NULL, false)) 155978884ef4SEddie Cai goto end; 156078884ef4SEddie Cai } 156132268622SAndreas Färber printf("Writing code 472 entry...\n"); 156278884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 156378884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 156478884ef4SEddie Cai &dataOffset, NULL, false)) 156578884ef4SEddie Cai goto end; 156678884ef4SEddie Cai } 156732268622SAndreas Färber printf("Writing loader entry...\n"); 156878884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 156978884ef4SEddie Cai if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 157078884ef4SEddie Cai &dataOffset, gOpts.loader[i].name, true)) 157178884ef4SEddie Cai goto end; 157278884ef4SEddie Cai } 157378884ef4SEddie Cai 157432268622SAndreas Färber printf("Writing code 471...\n"); 157578884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 157678884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 157778884ef4SEddie Cai goto end; 157878884ef4SEddie Cai } 157932268622SAndreas Färber printf("Writing code 472...\n"); 158078884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 158178884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 158278884ef4SEddie Cai goto end; 158378884ef4SEddie Cai } 158432268622SAndreas Färber printf("Writing loader...\n"); 158578884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 158678884ef4SEddie Cai if (!writeFile(outFile, gOpts.loader[i].path, true)) 158778884ef4SEddie Cai goto end; 158878884ef4SEddie Cai } 158978884ef4SEddie Cai fflush(outFile); 159078884ef4SEddie Cai 159132268622SAndreas Färber printf("Writing crc...\n"); 159278884ef4SEddie Cai crc = getCrc(gOpts.outPath); 159378884ef4SEddie Cai if (!fwrite(&crc, sizeof(crc), 1, outFile)) 159478884ef4SEddie Cai goto end; 159532268622SAndreas Färber printf("Done.\n"); 159678884ef4SEddie Cai ret = true; 159778884ef4SEddie Cai end: 159878884ef4SEddie Cai if (outFile) 159978884ef4SEddie Cai fclose(outFile); 160078884ef4SEddie Cai return ret; 160178884ef4SEddie Cai } 160278884ef4SEddie Cai 160378884ef4SEddie Cai /************merge code end************/ 160478884ef4SEddie Cai /************unpack code***************/ 160578884ef4SEddie Cai 160678884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len) 160778884ef4SEddie Cai { 160878884ef4SEddie Cai int i; 160978884ef4SEddie Cai for (i = 0; i < len; i++) { 161078884ef4SEddie Cai str[i] = (char) (wide[i] & 0xFF); 161178884ef4SEddie Cai } 161278884ef4SEddie Cai str[len] = 0; 161378884ef4SEddie Cai } 161478884ef4SEddie Cai 161578884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name, 161678884ef4SEddie Cai FILE* inFile) { 161778884ef4SEddie Cai bool ret = false; 161878884ef4SEddie Cai int size, i; 161978884ef4SEddie Cai FILE* outFile = fopen(name, "wb+"); 162078884ef4SEddie Cai if (!outFile) 162178884ef4SEddie Cai goto end; 162232268622SAndreas Färber printf("unpacking entry (%s)\n", name); 162378884ef4SEddie Cai fseek(inFile, entry->dataOffset, SEEK_SET); 162478884ef4SEddie Cai size = entry->dataSize; 162578884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 162678884ef4SEddie Cai goto end; 162778884ef4SEddie Cai if (entry->type == ENTRY_LOADER) { 162878884ef4SEddie Cai for(i=0; i<size/SMALL_PACKET; i++) 162978884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 163078884ef4SEddie Cai if (size % SMALL_PACKET) 163178884ef4SEddie Cai { 163278884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 163378884ef4SEddie Cai } 163478884ef4SEddie Cai } else { 163578884ef4SEddie Cai P_RC4(gBuf, size); 163678884ef4SEddie Cai } 163778884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 163878884ef4SEddie Cai goto end; 163978884ef4SEddie Cai ret = true; 164078884ef4SEddie Cai end: 164178884ef4SEddie Cai if (outFile) 164278884ef4SEddie Cai fclose(outFile); 164378884ef4SEddie Cai return ret; 164478884ef4SEddie Cai } 164578884ef4SEddie Cai 164678884ef4SEddie Cai bool unpackBoot(char* path) { 164778884ef4SEddie Cai bool ret = false; 164878884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 164978884ef4SEddie Cai int entryNum, i; 165078884ef4SEddie Cai char name[MAX_NAME_LEN]; 165178884ef4SEddie Cai rk_boot_entry* entrys; 165278884ef4SEddie Cai if (!inFile) { 165378884ef4SEddie Cai fprintf(stderr, "loader (%s) not found\n", path); 165478884ef4SEddie Cai goto end; 165578884ef4SEddie Cai } 165678884ef4SEddie Cai 165778884ef4SEddie Cai rk_boot_header hdr; 165878884ef4SEddie Cai if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 165932268622SAndreas Färber fprintf(stderr, "reading header failed\n"); 166078884ef4SEddie Cai goto end; 166178884ef4SEddie Cai } 166278884ef4SEddie Cai printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 166378884ef4SEddie Cai entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 166478884ef4SEddie Cai entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 166578884ef4SEddie Cai if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 166632268622SAndreas Färber fprintf(stderr, "reading data failed\n"); 166778884ef4SEddie Cai goto end; 166878884ef4SEddie Cai } 166978884ef4SEddie Cai 167078884ef4SEddie Cai printf("entry num: %d\n", entryNum); 167178884ef4SEddie Cai for (i=0; i<entryNum; i++) { 167278884ef4SEddie Cai wide2str(entrys[i].name, name, MAX_NAME_LEN); 167378884ef4SEddie Cai 167478884ef4SEddie Cai printf("entry: t=%d, name=%s, off=%d, size=%d\n", 167578884ef4SEddie Cai entrys[i].type, name, entrys[i].dataOffset, 167678884ef4SEddie Cai entrys[i].dataSize); 167778884ef4SEddie Cai if (!unpackEntry(entrys + i, name, inFile)) { 167832268622SAndreas Färber fprintf(stderr, "unpacking entry (%s) failed\n", name); 167978884ef4SEddie Cai goto end; 168078884ef4SEddie Cai } 168178884ef4SEddie Cai } 168278884ef4SEddie Cai printf("done\n"); 168378884ef4SEddie Cai ret = true; 168478884ef4SEddie Cai end: 168578884ef4SEddie Cai if (inFile) 168678884ef4SEddie Cai fclose(inFile); 168778884ef4SEddie Cai return ret; 168878884ef4SEddie Cai } 168978884ef4SEddie Cai 169076af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 169176af099aSliuyi { 169276af099aSliuyi if (!check_device_type(dev, RKUSB_MASKROM)) 169376af099aSliuyi return false; 169476af099aSliuyi CRKImage *pImage = NULL; 169576af099aSliuyi CRKBoot *pBoot = NULL; 169676af099aSliuyi bool bRet, bSuccess = false; 169776af099aSliuyi int iRet; 169876af099aSliuyi 169976af099aSliuyi pImage = new CRKImage(szLoader, bRet); 170076af099aSliuyi if (!bRet){ 170176af099aSliuyi ERROR_COLOR_ATTR; 170232268622SAndreas Färber printf("Opening loader failed, exiting download boot!"); 170376af099aSliuyi NORMAL_COLOR_ATTR; 170476af099aSliuyi printf("\r\n"); 170576af099aSliuyi return bSuccess; 170676af099aSliuyi } else { 170776af099aSliuyi pBoot = (CRKBoot *)pImage->m_bootObject; 170876af099aSliuyi CRKComm *pComm = NULL; 170976af099aSliuyi CRKDevice *pDevice = NULL; 171076af099aSliuyi 171176af099aSliuyi dev.emDeviceType = pBoot->SupportDevice; 171276af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 171376af099aSliuyi if (!bRet) { 171476af099aSliuyi if (pImage) 171576af099aSliuyi delete pImage; 171676af099aSliuyi ERROR_COLOR_ATTR; 171776af099aSliuyi printf("Creating Comm Object failed!"); 171876af099aSliuyi NORMAL_COLOR_ATTR; 171976af099aSliuyi printf("\r\n"); 172076af099aSliuyi return bSuccess; 172176af099aSliuyi } 172276af099aSliuyi 172376af099aSliuyi pDevice = new CRKDevice(dev); 172476af099aSliuyi if (!pDevice) { 172576af099aSliuyi if (pImage) 172676af099aSliuyi delete pImage; 172776af099aSliuyi if (pComm) 172876af099aSliuyi delete pComm; 172976af099aSliuyi ERROR_COLOR_ATTR; 173076af099aSliuyi printf("Creating device object failed!"); 173176af099aSliuyi NORMAL_COLOR_ATTR; 173276af099aSliuyi printf("\r\n"); 173376af099aSliuyi return bSuccess; 173476af099aSliuyi } 173576af099aSliuyi 173676af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 173732268622SAndreas Färber printf("Downloading bootloader...\r\n"); 173876af099aSliuyi iRet = pDevice->DownloadBoot(); 173976af099aSliuyi 174076af099aSliuyi CURSOR_MOVEUP_LINE(1); 174176af099aSliuyi CURSOR_DEL_LINE; 174276af099aSliuyi if (iRet == 0) { 174376af099aSliuyi bSuccess = true; 174432268622SAndreas Färber printf("Downloading bootloader succeeded.\r\n"); 174576af099aSliuyi } 174676af099aSliuyi else 174732268622SAndreas Färber printf("Downloading bootloader failed!\r\n"); 174876af099aSliuyi 174976af099aSliuyi if (pImage) 175076af099aSliuyi delete pImage; 175176af099aSliuyi if(pDevice) 175276af099aSliuyi delete pDevice; 175376af099aSliuyi } 175476af099aSliuyi return bSuccess; 175576af099aSliuyi } 1756c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1757c30d921cSKever Yang { 1758c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 1759c30d921cSKever Yang return false; 1760c30d921cSKever Yang CRKImage *pImage = NULL; 1761c30d921cSKever Yang CRKBoot *pBoot = NULL; 1762c30d921cSKever Yang CRKComm *pComm = NULL; 1763c30d921cSKever Yang bool bRet, bSuccess = false; 1764c30d921cSKever Yang int iRet; 1765c30d921cSKever Yang char index; 1766c30d921cSKever Yang USHORT usFlashDataSec, usFlashBootSec; 1767c30d921cSKever Yang DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1768c30d921cSKever Yang char loaderCodeName[] = "FlashBoot"; 1769c30d921cSKever Yang char loaderDataName[] = "FlashData"; 1770c30d921cSKever Yang PBYTE loaderCodeBuffer = NULL; 1771c30d921cSKever Yang PBYTE loaderDataBuffer = NULL; 1772c30d921cSKever Yang PBYTE pIDBData = NULL; 1773c30d921cSKever Yang pImage = new CRKImage(szLoader, bRet); 1774c30d921cSKever Yang if (!bRet){ 1775c30d921cSKever Yang ERROR_COLOR_ATTR; 177632268622SAndreas Färber printf("Opening loader failed, exiting upgrade loader!"); 1777c30d921cSKever Yang NORMAL_COLOR_ATTR; 1778c30d921cSKever Yang printf("\r\n"); 1779c30d921cSKever Yang goto Exit_UpgradeLoader; 1780c30d921cSKever Yang } else { 1781c30d921cSKever Yang pBoot = (CRKBoot *)pImage->m_bootObject; 1782c30d921cSKever Yang dev.emDeviceType = pBoot->SupportDevice; 1783c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1784c30d921cSKever Yang if (!bRet) { 1785c30d921cSKever Yang ERROR_COLOR_ATTR; 1786c30d921cSKever Yang printf("Creating Comm Object failed!"); 1787c30d921cSKever Yang NORMAL_COLOR_ATTR; 1788c30d921cSKever Yang printf("\r\n"); 1789c30d921cSKever Yang goto Exit_UpgradeLoader; 1790c30d921cSKever Yang } 1791c30d921cSKever Yang 179232268622SAndreas Färber printf("Upgrading loader...\r\n"); 1793c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1794c30d921cSKever Yang if (index == -1) { 1795c30d921cSKever Yang if (g_pLogObject) { 179632268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__); 1797c30d921cSKever Yang } 1798c30d921cSKever Yang goto Exit_UpgradeLoader; 1799c30d921cSKever Yang } 1800c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1801c30d921cSKever Yang if (!bRet) { 1802c30d921cSKever Yang if (g_pLogObject) { 180332268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__); 1804c30d921cSKever Yang } 1805c30d921cSKever Yang goto Exit_UpgradeLoader; 1806c30d921cSKever Yang } 1807c30d921cSKever Yang 1808c30d921cSKever Yang loaderCodeBuffer = new BYTE[dwLoaderSize]; 1809c30d921cSKever Yang memset(loaderCodeBuffer, 0, dwLoaderSize); 1810c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1811c30d921cSKever Yang if (g_pLogObject) { 181232268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__); 1813c30d921cSKever Yang } 1814c30d921cSKever Yang goto Exit_UpgradeLoader; 1815c30d921cSKever Yang } 1816c30d921cSKever Yang 1817c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1818c30d921cSKever Yang if (index == -1) { 1819c30d921cSKever Yang if (g_pLogObject) { 182032268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__); 1821c30d921cSKever Yang } 1822c30d921cSKever Yang delete []loaderCodeBuffer; 1823c30d921cSKever Yang return -4; 1824c30d921cSKever Yang } 1825c30d921cSKever Yang 1826c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1827c30d921cSKever Yang if (!bRet) { 1828c30d921cSKever Yang if (g_pLogObject) { 182932268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__); 1830c30d921cSKever Yang } 1831c30d921cSKever Yang goto Exit_UpgradeLoader; 1832c30d921cSKever Yang } 1833c30d921cSKever Yang 1834c30d921cSKever Yang loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1835c30d921cSKever Yang memset(loaderDataBuffer, 0, dwLoaderDataSize); 1836c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1837c30d921cSKever Yang if (g_pLogObject) { 183832268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__); 1839c30d921cSKever Yang } 1840c30d921cSKever Yang goto Exit_UpgradeLoader; 1841c30d921cSKever Yang } 1842c30d921cSKever Yang 1843c30d921cSKever Yang usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1844c30d921cSKever Yang usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1845c30d921cSKever Yang dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1846c30d921cSKever Yang pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1847c30d921cSKever Yang if (!pIDBData) { 1848c30d921cSKever Yang ERROR_COLOR_ATTR; 184932268622SAndreas Färber printf("Allocating memory failed!"); 1850c30d921cSKever Yang NORMAL_COLOR_ATTR; 1851c30d921cSKever Yang printf("\r\n"); 1852c30d921cSKever Yang goto Exit_UpgradeLoader; 1853c30d921cSKever Yang } 1854c30d921cSKever Yang memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1855b38fe5fcSliuyi iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag); 1856c30d921cSKever Yang if (iRet != 0) { 1857c30d921cSKever Yang ERROR_COLOR_ATTR; 185832268622SAndreas Färber printf("Making idblock failed!"); 1859c30d921cSKever Yang NORMAL_COLOR_ATTR; 1860c30d921cSKever Yang printf("\r\n"); 1861c30d921cSKever Yang goto Exit_UpgradeLoader; 1862c30d921cSKever Yang } 1863c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1864c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 1865c30d921cSKever Yang CURSOR_DEL_LINE; 1866c30d921cSKever Yang if (iRet == ERR_SUCCESS) { 1867b38fe5fcSliuyi //pComm->Reset_Usb_Device(); 1868c30d921cSKever Yang bSuccess = true; 186932268622SAndreas Färber printf("Upgrading loader succeeded.\r\n"); 1870c30d921cSKever Yang } else { 187132268622SAndreas Färber printf("Upgrading loader failed!\r\n"); 1872c30d921cSKever Yang goto Exit_UpgradeLoader; 1873c30d921cSKever Yang } 1874c30d921cSKever Yang } 1875c30d921cSKever Yang Exit_UpgradeLoader: 1876c30d921cSKever Yang if (pImage) 1877c30d921cSKever Yang delete pImage; 1878c30d921cSKever Yang if (pComm) 1879c30d921cSKever Yang delete pComm; 1880c30d921cSKever Yang if (loaderCodeBuffer) 1881c30d921cSKever Yang delete []loaderCodeBuffer; 1882c30d921cSKever Yang if (loaderDataBuffer) 1883c30d921cSKever Yang delete []loaderDataBuffer; 1884c30d921cSKever Yang if (pIDBData) 1885c30d921cSKever Yang delete []pIDBData; 1886c30d921cSKever Yang return bSuccess; 1887c30d921cSKever Yang } 18883dc7e3ceSliuyi bool print_gpt(STRUCT_RKDEVICE_DESC &dev) 18893dc7e3ceSliuyi { 18903dc7e3ceSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 18913dc7e3ceSliuyi return false; 18923dc7e3ceSliuyi u8 master_gpt[34 * SECTOR_SIZE]; 18933dc7e3ceSliuyi gpt_header *gptHead = (gpt_header *)(master_gpt + SECTOR_SIZE); 18943dc7e3ceSliuyi bool bRet, bSuccess = false; 18953dc7e3ceSliuyi int iRet; 18963dc7e3ceSliuyi gpt_entry *gptEntry = NULL; 18973dc7e3ceSliuyi u32 i,j; 18983dc7e3ceSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 18993dc7e3ceSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 19003dc7e3ceSliuyi CRKComm *pComm = NULL; 19013dc7e3ceSliuyi char partName[36]; 19023dc7e3ceSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 19033dc7e3ceSliuyi if (!bRet) { 19043dc7e3ceSliuyi ERROR_COLOR_ATTR; 19053dc7e3ceSliuyi printf("Creating Comm Object failed!"); 19063dc7e3ceSliuyi NORMAL_COLOR_ATTR; 19073dc7e3ceSliuyi printf("\r\n"); 19083dc7e3ceSliuyi return bSuccess; 19093dc7e3ceSliuyi } 19103dc7e3ceSliuyi iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt); 19113dc7e3ceSliuyi if(ERR_SUCCESS == iRet) { 19123dc7e3ceSliuyi if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 19133dc7e3ceSliuyi if (g_pLogObject) 19143dc7e3ceSliuyi g_pLogObject->Record("Error: invalid gpt signature"); 19153dc7e3ceSliuyi printf("Invalid GPT signature!\r\n"); 19163dc7e3ceSliuyi goto Exit_PrintGpt; 19173dc7e3ceSliuyi } 19183dc7e3ceSliuyi 19193dc7e3ceSliuyi } else { 19203dc7e3ceSliuyi if (g_pLogObject) 19213dc7e3ceSliuyi g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 19223dc7e3ceSliuyi printf("Read GPT failed!\r\n"); 19233dc7e3ceSliuyi goto Exit_PrintGpt; 19243dc7e3ceSliuyi } 19253dc7e3ceSliuyi 19263dc7e3ceSliuyi printf("**********GPT Info**********\r\n"); 19273dc7e3ceSliuyi printf("NO LBA Name \r\n"); 19283dc7e3ceSliuyi for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) { 19293dc7e3ceSliuyi gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 19303dc7e3ceSliuyi if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0) 19313dc7e3ceSliuyi break; 19323dc7e3ceSliuyi memset(partName, 0 , 36); 19333dc7e3ceSliuyi j = 0; 19343dc7e3ceSliuyi while (gptEntry->partition_name[j]) { 19353dc7e3ceSliuyi partName[j] = (char)gptEntry->partition_name[j]; 19363dc7e3ceSliuyi j++; 19373dc7e3ceSliuyi } 19383dc7e3ceSliuyi printf("%02d %08X %s\r\n", i, (u32)le64_to_cpu(gptEntry->starting_lba), partName); 19393dc7e3ceSliuyi } 19403dc7e3ceSliuyi bSuccess = true; 19413dc7e3ceSliuyi Exit_PrintGpt: 19423dc7e3ceSliuyi if (pComm) 19433dc7e3ceSliuyi delete pComm; 19443dc7e3ceSliuyi return bSuccess; 19453dc7e3ceSliuyi } 1946c30d921cSKever Yang 194776af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 194876af099aSliuyi { 194976af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 195076af099aSliuyi return false; 195176af099aSliuyi CRKImage *pImage = NULL; 195276af099aSliuyi bool bRet, bSuccess = false; 195376af099aSliuyi int iRet; 195476af099aSliuyi CRKScan *pScan = NULL; 195576af099aSliuyi pScan = new CRKScan(); 195676af099aSliuyi pScan->SetVidPid(); 195776af099aSliuyi 195876af099aSliuyi CRKComm *pComm = NULL; 195976af099aSliuyi CRKDevice *pDevice = NULL; 196076af099aSliuyi 196176af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 196276af099aSliuyi if (!bRet) { 196376af099aSliuyi if (pScan) 196476af099aSliuyi delete pScan; 196576af099aSliuyi ERROR_COLOR_ATTR; 196676af099aSliuyi printf("Creating Comm Object failed!"); 196776af099aSliuyi NORMAL_COLOR_ATTR; 196876af099aSliuyi printf("\r\n"); 196976af099aSliuyi return bSuccess; 197076af099aSliuyi } 197176af099aSliuyi 197276af099aSliuyi pDevice = new CRKDevice(dev); 197376af099aSliuyi if (!pDevice) { 197476af099aSliuyi if (pComm) 197576af099aSliuyi delete pComm; 197676af099aSliuyi if (pScan) 197776af099aSliuyi delete pScan; 197876af099aSliuyi ERROR_COLOR_ATTR; 197976af099aSliuyi printf("Creating device object failed!"); 198076af099aSliuyi NORMAL_COLOR_ATTR; 198176af099aSliuyi printf("\r\n"); 198276af099aSliuyi return bSuccess; 198376af099aSliuyi } 198476af099aSliuyi 198576af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 198676af099aSliuyi pDevice->CallBackPointer = ProgressInfoProc; 198776af099aSliuyi 198832268622SAndreas Färber printf("Starting to erase flash...\r\n"); 19896502326dSliuyi bRet = pDevice->GetFlashInfo(); 19906502326dSliuyi if (!bRet) { 19916502326dSliuyi if (pDevice) 19926502326dSliuyi delete pDevice; 19936502326dSliuyi if (pScan) 19946502326dSliuyi delete pScan; 19956502326dSliuyi ERROR_COLOR_ATTR; 19966502326dSliuyi printf("Getting flash info from device failed!"); 19976502326dSliuyi NORMAL_COLOR_ATTR; 19986502326dSliuyi printf("\r\n"); 19996502326dSliuyi return bSuccess; 20006502326dSliuyi } 200176af099aSliuyi iRet = pDevice->EraseAllBlocks(); 200276af099aSliuyi if (pDevice) 200376af099aSliuyi delete pDevice; 200476af099aSliuyi 200576af099aSliuyi if (iRet == 0) { 200676af099aSliuyi if (pScan) { 200776af099aSliuyi pScan->SetVidPid(); 200876af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 200976af099aSliuyi delete pScan; 201076af099aSliuyi } 201176af099aSliuyi CURSOR_MOVEUP_LINE(1); 201276af099aSliuyi CURSOR_DEL_LINE; 201376af099aSliuyi bSuccess = true; 201432268622SAndreas Färber printf("Erasing flash complete.\r\n"); 201576af099aSliuyi } 201676af099aSliuyi 201776af099aSliuyi return bSuccess; 201876af099aSliuyi } 201976af099aSliuyi 202076af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev) 202176af099aSliuyi { 202276af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 202376af099aSliuyi return false; 202476af099aSliuyi CRKUsbComm *pComm = NULL; 202576af099aSliuyi bool bRet, bSuccess = false; 202676af099aSliuyi int iRet; 202776af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 202876af099aSliuyi if (bRet) { 202976af099aSliuyi iRet = pComm->RKU_TestDeviceReady(); 203076af099aSliuyi if (iRet != ERR_SUCCESS) { 203176af099aSliuyi if (g_pLogObject) 203276af099aSliuyi g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 203332268622SAndreas Färber printf("Test Device failed!\r\n"); 203476af099aSliuyi } else { 203576af099aSliuyi bSuccess = true; 203676af099aSliuyi printf("Test Device OK.\r\n"); 203776af099aSliuyi } 203876af099aSliuyi } else { 203932268622SAndreas Färber printf("Test Device quit, creating comm object failed!\r\n"); 204076af099aSliuyi } 204176af099aSliuyi if (pComm) { 204276af099aSliuyi delete pComm; 204376af099aSliuyi pComm = NULL; 204476af099aSliuyi } 204576af099aSliuyi return bSuccess; 204676af099aSliuyi } 204776af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 204876af099aSliuyi { 204976af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 205076af099aSliuyi return false; 205176af099aSliuyi CRKUsbComm *pComm = NULL; 205276af099aSliuyi bool bRet, bSuccess = false; 205376af099aSliuyi int iRet; 205476af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 205576af099aSliuyi if (bRet) { 205676af099aSliuyi iRet = pComm->RKU_ResetDevice(subCode); 205776af099aSliuyi if (iRet != ERR_SUCCESS) { 205876af099aSliuyi if (g_pLogObject) 205976af099aSliuyi g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 206032268622SAndreas Färber printf("Reset Device failed!\r\n"); 206176af099aSliuyi } else { 206276af099aSliuyi bSuccess = true; 206376af099aSliuyi printf("Reset Device OK.\r\n"); 206476af099aSliuyi } 206576af099aSliuyi } else { 206632268622SAndreas Färber printf("Reset Device quit, creating comm object failed!\r\n"); 206776af099aSliuyi } 206876af099aSliuyi if (pComm) { 206976af099aSliuyi delete pComm; 207076af099aSliuyi pComm = NULL; 207176af099aSliuyi } 207276af099aSliuyi return bSuccess; 207376af099aSliuyi } 207476af099aSliuyi 207576af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 207676af099aSliuyi { 207776af099aSliuyi CRKUsbComm *pComm = NULL; 207876af099aSliuyi bool bRet, bSuccess = false; 207976af099aSliuyi int iRet; 208076af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 208176af099aSliuyi return bSuccess; 208276af099aSliuyi 208376af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 208476af099aSliuyi if (bRet) { 208576af099aSliuyi BYTE flashID[5]; 208676af099aSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 208776af099aSliuyi if (iRet != ERR_SUCCESS) { 208876af099aSliuyi if (g_pLogObject) 208976af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 209032268622SAndreas Färber printf("Reading flash ID failed!\r\n"); 209176af099aSliuyi } else { 209276af099aSliuyi printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 209376af099aSliuyi bSuccess = true; 209476af099aSliuyi } 209576af099aSliuyi } else { 209632268622SAndreas Färber printf("Read Flash ID quit, creating comm object failed!\r\n"); 209776af099aSliuyi } 209876af099aSliuyi if (pComm) { 209976af099aSliuyi delete pComm; 210076af099aSliuyi pComm = NULL; 210176af099aSliuyi } 210276af099aSliuyi return bSuccess; 210376af099aSliuyi } 210476af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 210576af099aSliuyi { 210676af099aSliuyi CRKUsbComm *pComm = NULL; 210776af099aSliuyi bool bRet, bSuccess = false; 210876af099aSliuyi int iRet; 210976af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 211076af099aSliuyi return bSuccess; 211176af099aSliuyi 211276af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 211376af099aSliuyi if (bRet) { 211476af099aSliuyi STRUCT_FLASHINFO_CMD info; 211576af099aSliuyi UINT uiRead; 211676af099aSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 211776af099aSliuyi if (iRet != ERR_SUCCESS) { 211876af099aSliuyi if (g_pLogObject) 211976af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 212032268622SAndreas Färber printf("Read Flash Info failed!\r\n"); 212176af099aSliuyi } else { 212276af099aSliuyi printf("Flash Info:\r\n"); 212376af099aSliuyi if (info.bManufCode <= 7) { 212476af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 212576af099aSliuyi } 212676af099aSliuyi else 212776af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 212876af099aSliuyi 212976af099aSliuyi printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 213076af099aSliuyi printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 213176af099aSliuyi printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 213276af099aSliuyi printf("\tECC Bits: %d\r\n", info.bECCBits); 213376af099aSliuyi printf("\tAccess Time: %d\r\n", info.bAccessTime); 213476af099aSliuyi printf("\tFlash CS: "); 213576af099aSliuyi for(int i = 0; i < 8; i++) { 213676af099aSliuyi if( info.bFlashCS & (1 << i) ) 213776af099aSliuyi printf("Flash<%d> ", i); 213876af099aSliuyi } 213976af099aSliuyi printf("\r\n"); 214076af099aSliuyi bSuccess = true; 214176af099aSliuyi } 214276af099aSliuyi }else { 214332268622SAndreas Färber printf("Read Flash Info quit, creating comm object failed!\r\n"); 214476af099aSliuyi } 214576af099aSliuyi if (pComm) { 214676af099aSliuyi delete pComm; 214776af099aSliuyi pComm = NULL; 214876af099aSliuyi } 214976af099aSliuyi return bSuccess; 215076af099aSliuyi } 215176af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 215276af099aSliuyi { 215376af099aSliuyi CRKUsbComm *pComm = NULL; 215476af099aSliuyi bool bRet, bSuccess = false; 215576af099aSliuyi int iRet; 215676af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 215776af099aSliuyi return bSuccess; 215876af099aSliuyi 215976af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 216076af099aSliuyi if (bRet) { 216176af099aSliuyi BYTE chipInfo[16]; 216276af099aSliuyi iRet = pComm->RKU_ReadChipInfo(chipInfo); 216376af099aSliuyi if (iRet != ERR_SUCCESS) { 216476af099aSliuyi if (g_pLogObject) 216576af099aSliuyi g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 216632268622SAndreas Färber printf("Read Chip Info failed!\r\n"); 216776af099aSliuyi } else { 216876af099aSliuyi string strChipInfo; 216976af099aSliuyi g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 217076af099aSliuyi printf("Chip Info: %s\r\n", strChipInfo.c_str()); 217176af099aSliuyi bSuccess = true; 217276af099aSliuyi } 217376af099aSliuyi } else { 217432268622SAndreas Färber printf("Read Chip Info quit, creating comm object failed!\r\n"); 217576af099aSliuyi } 217676af099aSliuyi if (pComm) { 217776af099aSliuyi delete pComm; 217876af099aSliuyi pComm = NULL; 217976af099aSliuyi } 218076af099aSliuyi return bSuccess; 218176af099aSliuyi } 21826ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt) 21836ae612beSliuyi { 21846ae612beSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 21856ae612beSliuyi return false; 21866ae612beSliuyi gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE); 21876ae612beSliuyi CRKUsbComm *pComm = NULL; 21886ae612beSliuyi bool bRet, bSuccess = false; 21896ae612beSliuyi int iRet; 21906ae612beSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 21916ae612beSliuyi if (bRet) { 21926ae612beSliuyi iRet = pComm->RKU_ReadLBA( 0, 34, pGpt); 21936ae612beSliuyi if(ERR_SUCCESS == iRet) { 21946ae612beSliuyi if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 21956ae612beSliuyi if (g_pLogObject) 21966ae612beSliuyi g_pLogObject->Record("Error: invalid gpt signature"); 21976ae612beSliuyi printf("Invalid GPT signature!\r\n"); 21986ae612beSliuyi goto Exit_ReadGPT; 21996ae612beSliuyi } 22006ae612beSliuyi 22016ae612beSliuyi } else { 22026ae612beSliuyi if (g_pLogObject) 22036ae612beSliuyi g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 22046ae612beSliuyi printf("Read GPT failed!\r\n"); 22056ae612beSliuyi goto Exit_ReadGPT; 22066ae612beSliuyi } 22076ae612beSliuyi bSuccess = true; 22086ae612beSliuyi } 22096ae612beSliuyi Exit_ReadGPT: 22106ae612beSliuyi if (pComm) { 22116ae612beSliuyi delete pComm; 22126ae612beSliuyi pComm = NULL; 22136ae612beSliuyi } 22146ae612beSliuyi return bSuccess; 22156ae612beSliuyi } 221676af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 221776af099aSliuyi { 221876af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 221976af099aSliuyi return false; 222076af099aSliuyi CRKUsbComm *pComm = NULL; 222176af099aSliuyi FILE *file = NULL; 222276af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 222376af099aSliuyi int iRet; 222476af099aSliuyi UINT iTotalRead = 0,iRead = 0; 222576af099aSliuyi int nSectorSize = 512; 222676af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 222776af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 222876af099aSliuyi if (bRet) { 222976af099aSliuyi if(szFile) { 223076af099aSliuyi file = fopen(szFile, "wb+"); 223176af099aSliuyi if( !file ) { 223276af099aSliuyi printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 223376af099aSliuyi goto Exit_ReadLBA; 223476af099aSliuyi } 223576af099aSliuyi } 223676af099aSliuyi 223776af099aSliuyi while(uiLen > 0) { 223876af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 223976af099aSliuyi iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 224076af099aSliuyi iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 224176af099aSliuyi if(ERR_SUCCESS == iRet) { 224276af099aSliuyi uiLen -= iRead; 224376af099aSliuyi iTotalRead += iRead; 224476af099aSliuyi 224576af099aSliuyi if(szFile) { 224676af099aSliuyi fwrite(pBuf, 1, iRead * nSectorSize, file); 224776af099aSliuyi if (bFirst){ 224876af099aSliuyi if (iTotalRead >= 1024) 224932268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 225076af099aSliuyi else 225132268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 225276af099aSliuyi bFirst = false; 225376af099aSliuyi } else { 225476af099aSliuyi CURSOR_MOVEUP_LINE(1); 225576af099aSliuyi CURSOR_DEL_LINE; 225676af099aSliuyi if (iTotalRead >= 1024) 225732268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 225876af099aSliuyi else 225932268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 226076af099aSliuyi } 226176af099aSliuyi } 226276af099aSliuyi else 226376af099aSliuyi PrintData(pBuf, nSectorSize * iRead); 226476af099aSliuyi } else { 226576af099aSliuyi if (g_pLogObject) 226676af099aSliuyi g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 226776af099aSliuyi 226876af099aSliuyi printf("Read LBA failed!\r\n"); 226976af099aSliuyi goto Exit_ReadLBA; 227076af099aSliuyi } 227176af099aSliuyi } 227276af099aSliuyi bSuccess = true; 227376af099aSliuyi } else { 227432268622SAndreas Färber printf("Read LBA quit, creating comm object failed!\r\n"); 227576af099aSliuyi } 227676af099aSliuyi Exit_ReadLBA: 227776af099aSliuyi if (pComm) { 227876af099aSliuyi delete pComm; 227976af099aSliuyi pComm = NULL; 228076af099aSliuyi } 228176af099aSliuyi if (file) 228276af099aSliuyi fclose(file); 228376af099aSliuyi return bSuccess; 228476af099aSliuyi } 22856ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize) 22866ae612beSliuyi { 2287ae4252f0Sliuyi UINT uiErase=1024*32; 22886ae612beSliuyi bool bSuccess = true; 22896ae612beSliuyi int iRet; 22906ae612beSliuyi while (uiSize) 22916ae612beSliuyi { 22926ae612beSliuyi if (uiSize>=uiErase) 22936ae612beSliuyi { 22946ae612beSliuyi iRet = pComm->RKU_EraseLBA(uiOffset,uiErase); 22956ae612beSliuyi uiSize -= uiErase; 22966ae612beSliuyi uiOffset += uiErase; 22976ae612beSliuyi } 22986ae612beSliuyi else 22996ae612beSliuyi { 23006ae612beSliuyi iRet = pComm->RKU_EraseLBA(uiOffset,uiSize); 23016ae612beSliuyi uiSize = 0; 23026ae612beSliuyi uiOffset += uiSize; 23036ae612beSliuyi } 23046ae612beSliuyi if (iRet!=ERR_SUCCESS) 23056ae612beSliuyi { 23066ae612beSliuyi if (g_pLogObject) 23076ae612beSliuyi { 23086ae612beSliuyi g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet); 23096ae612beSliuyi } 23106ae612beSliuyi bSuccess = false; 23116ae612beSliuyi break; 23126ae612beSliuyi } 23136ae612beSliuyi } 23146ae612beSliuyi return bSuccess; 23156ae612beSliuyi 23166ae612beSliuyi } 23176ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk) 23186ae612beSliuyi { 23196ae612beSliuyi UINT uiRead; 23206ae612beSliuyi uiRead = fread(&chunk, 1, sizeof(chunk_header), file); 23216ae612beSliuyi if (uiRead != sizeof(chunk_header)) { 23226ae612beSliuyi if (g_pLogObject) 23236ae612beSliuyi { 23246ae612beSliuyi g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno); 23256ae612beSliuyi } 23266ae612beSliuyi return false; 23276ae612beSliuyi } 23286ae612beSliuyi return true; 23296ae612beSliuyi } 23306ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize) 23316ae612beSliuyi { 23326ae612beSliuyi UINT uiRead; 23336ae612beSliuyi uiRead = fread(pBuf, 1, dwSize, file); 23346ae612beSliuyi if (uiRead!=dwSize) 23356ae612beSliuyi { 23366ae612beSliuyi if (g_pLogObject) 23376ae612beSliuyi { 23386ae612beSliuyi g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno); 23396ae612beSliuyi } 23406ae612beSliuyi return false; 23416ae612beSliuyi } 23426ae612beSliuyi return true; 23436ae612beSliuyi } 23446ae612beSliuyi 23456ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile) 23466ae612beSliuyi { 23476ae612beSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 23486ae612beSliuyi return false; 23496ae612beSliuyi CRKUsbComm *pComm = NULL; 23506ae612beSliuyi FILE *file = NULL; 23516ae612beSliuyi bool bRet, bSuccess = false, bFirst = true; 23526ae612beSliuyi int iRet; 23536ae612beSliuyi u64 iTotalWrite = 0, iFileSize = 0; 23546ae612beSliuyi UINT iRead = 0, uiTransferSec, curChunk, i; 23556ae612beSliuyi UINT dwChunkDataSize, dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc; 23566ae612beSliuyi BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA]; 23576ae612beSliuyi sparse_header header; 23586ae612beSliuyi chunk_header chunk; 23596ae612beSliuyi dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE; 23606ae612beSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 23616ae612beSliuyi if (bRet) { 2362ae4252f0Sliuyi 23636ae612beSliuyi file = fopen(szFile, "rb"); 23646ae612beSliuyi if( !file ) { 23656ae612beSliuyi printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile); 23666ae612beSliuyi goto Exit_WriteSparseLBA; 23676ae612beSliuyi } 23686ae612beSliuyi fseeko(file, 0, SEEK_SET); 23696ae612beSliuyi iRead = fread(&header, 1, sizeof(header), file); 23706ae612beSliuyi if (iRead != sizeof(sparse_header)) 23716ae612beSliuyi { 23726ae612beSliuyi if (g_pLogObject) 23736ae612beSliuyi { 23746ae612beSliuyi g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno); 23756ae612beSliuyi } 23766ae612beSliuyi goto Exit_WriteSparseLBA; 23776ae612beSliuyi } 23786ae612beSliuyi iFileSize = header.blk_sz * (u64)header.total_blks; 23796ae612beSliuyi iTotalWrite = 0; 23806ae612beSliuyi curChunk = 0; 2381ae4252f0Sliuyi if (uiSize==(u32)-1) 2382ae4252f0Sliuyi uiSize = ALIGN(iFileSize, SECTOR_SIZE); 2383ae4252f0Sliuyi bRet = erase_partition(pComm, uiBegin, uiSize); 2384ae4252f0Sliuyi if (!bRet) { 2385ae4252f0Sliuyi printf("%s failed, erase partition error\r\n", __func__); 2386ae4252f0Sliuyi goto Exit_WriteSparseLBA; 2387ae4252f0Sliuyi } 23886ae612beSliuyi while(curChunk < header.total_chunks) 23896ae612beSliuyi { 23906ae612beSliuyi if (!EatSparseChunk(file, chunk)) { 23916ae612beSliuyi goto Exit_WriteSparseLBA; 23926ae612beSliuyi } 23936ae612beSliuyi curChunk++; 23946ae612beSliuyi switch (chunk.chunk_type) { 23956ae612beSliuyi case CHUNK_TYPE_RAW: 23966ae612beSliuyi dwChunkDataSize = chunk.total_sz - sizeof(chunk_header); 23976ae612beSliuyi while (dwChunkDataSize) { 23986ae612beSliuyi memset(pBuf, 0, dwMaxReadWriteBytes); 23996ae612beSliuyi if (dwChunkDataSize >= dwMaxReadWriteBytes) { 24006ae612beSliuyi dwTransferBytes = dwMaxReadWriteBytes; 24016ae612beSliuyi uiTransferSec = DEFAULT_RW_LBA; 24026ae612beSliuyi } else { 24036ae612beSliuyi dwTransferBytes = dwChunkDataSize; 24046ae612beSliuyi uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 24056ae612beSliuyi } 24066ae612beSliuyi if (!EatSparseData(file, pBuf, dwTransferBytes)) { 24076ae612beSliuyi goto Exit_WriteSparseLBA; 24086ae612beSliuyi } 24096ae612beSliuyi iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 24106ae612beSliuyi if( ERR_SUCCESS == iRet ) { 24116ae612beSliuyi dwChunkDataSize -= dwTransferBytes; 24126ae612beSliuyi iTotalWrite += dwTransferBytes; 24136ae612beSliuyi uiBegin += uiTransferSec; 24146ae612beSliuyi } else { 24156ae612beSliuyi if (g_pLogObject) { 24166ae612beSliuyi g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)", __func__, iTotalWrite, iRet); 24176ae612beSliuyi } 24186ae612beSliuyi goto Exit_WriteSparseLBA; 24196ae612beSliuyi } 24206ae612beSliuyi if (bFirst) { 24216ae612beSliuyi if (iTotalWrite >= 1024) 24226ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 24236ae612beSliuyi else 24246ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 24256ae612beSliuyi bFirst = false; 24266ae612beSliuyi } else { 24276ae612beSliuyi CURSOR_MOVEUP_LINE(1); 24286ae612beSliuyi CURSOR_DEL_LINE; 24296ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 24306ae612beSliuyi } 24316ae612beSliuyi } 24326ae612beSliuyi break; 24336ae612beSliuyi case CHUNK_TYPE_FILL: 24346ae612beSliuyi dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 24356ae612beSliuyi if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) { 24366ae612beSliuyi goto Exit_WriteSparseLBA; 24376ae612beSliuyi } 24386ae612beSliuyi while (dwChunkDataSize) { 24396ae612beSliuyi memset(pBuf, 0, dwMaxReadWriteBytes); 24406ae612beSliuyi if (dwChunkDataSize >= dwMaxReadWriteBytes) { 24416ae612beSliuyi dwTransferBytes = dwMaxReadWriteBytes; 24426ae612beSliuyi uiTransferSec = DEFAULT_RW_LBA; 24436ae612beSliuyi } else { 24446ae612beSliuyi dwTransferBytes = dwChunkDataSize; 24456ae612beSliuyi uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 24466ae612beSliuyi } 24476ae612beSliuyi for (i = 0; i < dwTransferBytes / 4; i++) { 24486ae612beSliuyi *(DWORD *)(pBuf + i * 4) = dwFillByte; 24496ae612beSliuyi } 24506ae612beSliuyi iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 24516ae612beSliuyi if( ERR_SUCCESS == iRet ) { 24526ae612beSliuyi dwChunkDataSize -= dwTransferBytes; 24536ae612beSliuyi iTotalWrite += dwTransferBytes; 24546ae612beSliuyi uiBegin += uiTransferSec; 24556ae612beSliuyi } else { 24566ae612beSliuyi if (g_pLogObject) { 24576ae612beSliuyi g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet); 24586ae612beSliuyi } 24596ae612beSliuyi goto Exit_WriteSparseLBA; 24606ae612beSliuyi } 24616ae612beSliuyi if (bFirst) { 24626ae612beSliuyi if (iTotalWrite >= 1024) 24636ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 24646ae612beSliuyi else 24656ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 24666ae612beSliuyi bFirst = false; 24676ae612beSliuyi } else { 24686ae612beSliuyi CURSOR_MOVEUP_LINE(1); 24696ae612beSliuyi CURSOR_DEL_LINE; 24706ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 24716ae612beSliuyi } 24726ae612beSliuyi } 24736ae612beSliuyi break; 24746ae612beSliuyi case CHUNK_TYPE_DONT_CARE: 24756ae612beSliuyi dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 24766ae612beSliuyi iTotalWrite += dwChunkDataSize; 24776ae612beSliuyi uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1)); 24786ae612beSliuyi uiBegin += uiTransferSec; 24796ae612beSliuyi if (bFirst) { 24806ae612beSliuyi if (iTotalWrite >= 1024) 24816ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 24826ae612beSliuyi else 24836ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 24846ae612beSliuyi bFirst = false; 24856ae612beSliuyi } else { 24866ae612beSliuyi CURSOR_MOVEUP_LINE(1); 24876ae612beSliuyi CURSOR_DEL_LINE; 24886ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 24896ae612beSliuyi } 24906ae612beSliuyi break; 24916ae612beSliuyi case CHUNK_TYPE_CRC32: 24926ae612beSliuyi EatSparseData(file,(PBYTE)&dwCrc,4); 24936ae612beSliuyi break; 24946ae612beSliuyi } 24956ae612beSliuyi } 24966ae612beSliuyi bSuccess = true; 24976ae612beSliuyi } else { 24986ae612beSliuyi printf("Write LBA quit, creating comm object failed!\r\n"); 24996ae612beSliuyi } 25006ae612beSliuyi Exit_WriteSparseLBA: 25016ae612beSliuyi if (pComm) { 25026ae612beSliuyi delete pComm; 25036ae612beSliuyi pComm = NULL; 25046ae612beSliuyi } 25056ae612beSliuyi if (file) 25066ae612beSliuyi fclose(file); 25076ae612beSliuyi return bSuccess; 25086ae612beSliuyi 25096ae612beSliuyi } 25106ae612beSliuyi 251176af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 251276af099aSliuyi { 251376af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 251476af099aSliuyi return false; 251576af099aSliuyi CRKUsbComm *pComm = NULL; 251676af099aSliuyi FILE *file = NULL; 251776af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 251876af099aSliuyi int iRet; 251976af099aSliuyi long long iTotalWrite = 0, iFileSize = 0; 252076af099aSliuyi UINT iWrite = 0, iRead = 0; 252176af099aSliuyi UINT uiLen; 252276af099aSliuyi int nSectorSize = 512; 252376af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 252476af099aSliuyi 252576af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 252676af099aSliuyi if (bRet) { 252776af099aSliuyi file = fopen(szFile, "rb"); 252876af099aSliuyi if( !file ) { 252976af099aSliuyi printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 253076af099aSliuyi goto Exit_WriteLBA; 253176af099aSliuyi } 253276af099aSliuyi 253376af099aSliuyi iRet = fseeko(file, 0, SEEK_END); 253476af099aSliuyi iFileSize = ftello(file); 253576af099aSliuyi fseeko(file, 0, SEEK_SET); 253676af099aSliuyi while(iTotalWrite < iFileSize) { 253776af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 253876af099aSliuyi iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 253976af099aSliuyi uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 254076af099aSliuyi iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 254176af099aSliuyi if(ERR_SUCCESS == iRet) { 254276af099aSliuyi uiBegin += uiLen; 254376af099aSliuyi iTotalWrite += iWrite; 254476af099aSliuyi if (bFirst) { 254576af099aSliuyi if (iTotalWrite >= 1024) 254676af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 254776af099aSliuyi else 254832268622SAndreas Färber printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 254976af099aSliuyi bFirst = false; 255076af099aSliuyi } else { 255176af099aSliuyi CURSOR_MOVEUP_LINE(1); 255276af099aSliuyi CURSOR_DEL_LINE; 255376af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 255476af099aSliuyi } 255576af099aSliuyi } else { 255676af099aSliuyi if (g_pLogObject) 255776af099aSliuyi g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 255876af099aSliuyi 255976af099aSliuyi printf("Write LBA failed!\r\n"); 256076af099aSliuyi goto Exit_WriteLBA; 256176af099aSliuyi } 256276af099aSliuyi } 256376af099aSliuyi bSuccess = true; 256476af099aSliuyi } else { 256532268622SAndreas Färber printf("Write LBA quit, creating comm object failed!\r\n"); 256676af099aSliuyi } 256776af099aSliuyi Exit_WriteLBA: 256876af099aSliuyi if (pComm) { 256976af099aSliuyi delete pComm; 257076af099aSliuyi pComm = NULL; 257176af099aSliuyi } 257276af099aSliuyi if (file) 257376af099aSliuyi fclose(file); 257476af099aSliuyi return bSuccess; 257576af099aSliuyi } 257676af099aSliuyi 257776af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems) 257876af099aSliuyi { 257976af099aSliuyi string strItem; 258076af099aSliuyi char szItem[100]; 258176af099aSliuyi char *pos = NULL, *pStart; 258276af099aSliuyi pStart = pszItems; 258376af099aSliuyi pos = strchr(pStart, ','); 258476af099aSliuyi while(pos != NULL) { 258576af099aSliuyi memset(szItem, 0, 100); 258676af099aSliuyi strncpy(szItem, pStart, pos - pStart); 258776af099aSliuyi strItem = szItem; 258876af099aSliuyi vecItems.push_back(strItem); 258976af099aSliuyi pStart = pos + 1; 259076af099aSliuyi if (*pStart == 0) 259176af099aSliuyi break; 259276af099aSliuyi pos = strchr(pStart, ','); 259376af099aSliuyi } 259476af099aSliuyi if (strlen(pStart) > 0) { 259576af099aSliuyi memset(szItem, 0, 100); 259676af099aSliuyi strncpy(szItem, pStart, strlen(pStart)); 259776af099aSliuyi strItem = szItem; 259876af099aSliuyi vecItems.push_back(strItem); 259976af099aSliuyi } 260076af099aSliuyi } 2601c30d921cSKever Yang 2602d71e8c20SEddie Cai void tag_spl(char *tag, char *spl) 2603d71e8c20SEddie Cai { 2604d71e8c20SEddie Cai FILE *file = NULL; 2605d71e8c20SEddie Cai int len; 2606d71e8c20SEddie Cai 2607d71e8c20SEddie Cai if(!tag || !spl) 2608d71e8c20SEddie Cai return; 2609d71e8c20SEddie Cai len = strlen(tag); 2610d71e8c20SEddie Cai printf("tag len=%d\n",len); 2611d71e8c20SEddie Cai file = fopen(spl, "rb"); 2612d71e8c20SEddie Cai if( !file ){ 2613d71e8c20SEddie Cai return; 2614d71e8c20SEddie Cai } 2615d71e8c20SEddie Cai int iFileSize; 2616d71e8c20SEddie Cai fseek(file, 0, SEEK_END); 2617d71e8c20SEddie Cai iFileSize = ftell(file); 2618d71e8c20SEddie Cai fseek(file, 0, SEEK_SET); 2619d71e8c20SEddie Cai char *Buf = NULL; 2620d71e8c20SEddie Cai Buf = new char[iFileSize + len + 1]; 2621d71e8c20SEddie Cai if (!Buf){ 2622d71e8c20SEddie Cai fclose(file); 2623d71e8c20SEddie Cai return; 2624d71e8c20SEddie Cai } 2625d71e8c20SEddie Cai memset(Buf, 0, iFileSize + 1); 2626d71e8c20SEddie Cai memcpy(Buf, tag, len); 2627d71e8c20SEddie Cai int iRead; 2628d71e8c20SEddie Cai iRead = fread(Buf+len, 1, iFileSize, file); 2629d71e8c20SEddie Cai if (iRead != iFileSize){ 2630d71e8c20SEddie Cai fclose(file); 2631d71e8c20SEddie Cai delete []Buf; 2632d71e8c20SEddie Cai return; 2633d71e8c20SEddie Cai } 2634d71e8c20SEddie Cai fclose(file); 2635d71e8c20SEddie Cai 2636d71e8c20SEddie Cai len = strlen(spl); 263732268622SAndreas Färber char *taggedspl = new char[len + 5]; 263832268622SAndreas Färber strcpy(taggedspl, spl); 263932268622SAndreas Färber strcpy(taggedspl + len, ".tag"); 264032268622SAndreas Färber taggedspl[len+4] = 0; 264132268622SAndreas Färber printf("Writing tagged spl to %s\n", taggedspl); 2642d71e8c20SEddie Cai 264332268622SAndreas Färber file = fopen(taggedspl, "wb"); 2644d71e8c20SEddie Cai if( !file ){ 264532268622SAndreas Färber delete []taggedspl; 2646d71e8c20SEddie Cai delete []Buf; 2647d71e8c20SEddie Cai return; 2648d71e8c20SEddie Cai } 2649d71e8c20SEddie Cai fwrite(Buf, 1, iFileSize+len, file); 2650d71e8c20SEddie Cai fclose(file); 265132268622SAndreas Färber delete []taggedspl; 2652d71e8c20SEddie Cai delete []Buf; 2653d71e8c20SEddie Cai printf("done\n"); 2654d71e8c20SEddie Cai return; 2655d71e8c20SEddie Cai } 2656d71e8c20SEddie Cai 265776af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan) 265876af099aSliuyi { 265976af099aSliuyi string strCmd; 266076af099aSliuyi strCmd = argv[1]; 266176af099aSliuyi ssize_t cnt; 266276af099aSliuyi bool bRet,bSuccess = false; 26638df2d64aSEddie Cai char *s; 26648df2d64aSEddie Cai int i, ret; 266576af099aSliuyi STRUCT_RKDEVICE_DESC dev; 26666ae612beSliuyi u8 master_gpt[34 * SECTOR_SIZE]; 26676ae612beSliuyi u64 lba, lba_end; 266876af099aSliuyi 266976af099aSliuyi transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 26708df2d64aSEddie Cai s = (char*)strCmd.c_str(); 26718df2d64aSEddie Cai for(i = 0; i < (int)strlen(s); i++) 26728df2d64aSEddie Cai s[i] = toupper(s[i]); 267378884ef4SEddie Cai 26748df2d64aSEddie Cai if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 267576af099aSliuyi usage(); 267676af099aSliuyi return true; 26778df2d64aSEddie Cai } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2678c30d921cSKever Yang printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 267976af099aSliuyi return true; 268078884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 268178884ef4SEddie Cai mergeBoot(); 268278884ef4SEddie Cai 268378884ef4SEddie Cai return true; 268478884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 268578884ef4SEddie Cai string strLoader = argv[2]; 268678884ef4SEddie Cai 268778884ef4SEddie Cai unpackBoot((char*)strLoader.c_str()); 268878884ef4SEddie Cai return true; 2689d71e8c20SEddie Cai } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 2690d71e8c20SEddie Cai if (argc == 4) { 2691d71e8c20SEddie Cai string tag = argv[2]; 2692d71e8c20SEddie Cai string spl = argv[3]; 2693d71e8c20SEddie Cai printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 2694d71e8c20SEddie Cai tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 2695d71e8c20SEddie Cai return true; 2696d71e8c20SEddie Cai } 2697d71e8c20SEddie Cai printf("tagspl: parameter error\n"); 2698d71e8c20SEddie Cai usage(); 269976af099aSliuyi } 270076af099aSliuyi cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 270176af099aSliuyi if (cnt < 1) { 270276af099aSliuyi ERROR_COLOR_ATTR; 270332268622SAndreas Färber printf("Did not find any rockusb device, please plug device in!"); 270476af099aSliuyi NORMAL_COLOR_ATTR; 270576af099aSliuyi printf("\r\n"); 270676af099aSliuyi return bSuccess; 270776af099aSliuyi } else if (cnt > 1) { 270876af099aSliuyi ERROR_COLOR_ATTR; 270932268622SAndreas Färber printf("Found too many rockusb devices, please plug devices out!"); 271076af099aSliuyi NORMAL_COLOR_ATTR; 271176af099aSliuyi printf("\r\n"); 271276af099aSliuyi return bSuccess; 271376af099aSliuyi } 271476af099aSliuyi 271576af099aSliuyi bRet = pScan->GetDevice(dev, 0); 271676af099aSliuyi if (!bRet) { 271776af099aSliuyi ERROR_COLOR_ATTR; 271832268622SAndreas Färber printf("Getting information about rockusb device failed!"); 271976af099aSliuyi NORMAL_COLOR_ATTR; 272076af099aSliuyi printf("\r\n"); 272176af099aSliuyi return bSuccess; 272276af099aSliuyi } 272376af099aSliuyi 272476af099aSliuyi if(strcmp(strCmd.c_str(), "RD") == 0) { 272576af099aSliuyi if ((argc != 2) && (argc != 3)) 272676af099aSliuyi printf("Parameter of [RD] command is invalid, please check help!\r\n"); 272776af099aSliuyi else { 272876af099aSliuyi if (argc == 2) 272976af099aSliuyi bSuccess = reset_device(dev); 273076af099aSliuyi else { 273176af099aSliuyi UINT uiSubCode; 273276af099aSliuyi char *pszEnd; 273376af099aSliuyi uiSubCode = strtoul(argv[2], &pszEnd, 0); 273476af099aSliuyi if (*pszEnd) 273576af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 273676af099aSliuyi else { 273776af099aSliuyi if (uiSubCode <= 5) 273876af099aSliuyi bSuccess = reset_device(dev, uiSubCode); 273976af099aSliuyi else 274076af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 274176af099aSliuyi } 274276af099aSliuyi } 274376af099aSliuyi } 274476af099aSliuyi } else if(strcmp(strCmd.c_str(), "TD") == 0) { 274576af099aSliuyi bSuccess = test_device(dev); 274676af099aSliuyi } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 274776af099aSliuyi bSuccess = read_flash_id(dev); 274876af099aSliuyi } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 274976af099aSliuyi bSuccess = read_flash_info(dev); 275076af099aSliuyi } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 275176af099aSliuyi bSuccess = read_chip_info(dev); 275276af099aSliuyi } else if(strcmp(strCmd.c_str(), "DB") == 0) { 275376af099aSliuyi if (argc > 2) { 275476af099aSliuyi string strLoader; 275576af099aSliuyi strLoader = argv[2]; 275676af099aSliuyi bSuccess = download_boot(dev, (char *)strLoader.c_str()); 275776af099aSliuyi } else if (argc == 2) { 2758c29e5f0fSliuyi ret = find_config_item(g_ConfigItemVec, "loader"); 275976af099aSliuyi if (ret == -1) 276032268622SAndreas Färber printf("Did not find loader item in config!\r\n"); 276176af099aSliuyi else 276276af099aSliuyi bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 276376af099aSliuyi } else 276476af099aSliuyi printf("Parameter of [DB] command is invalid, please check help!\r\n"); 2765c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2766c30d921cSKever Yang if (argc > 2) { 2767c30d921cSKever Yang string strParameter; 2768c30d921cSKever Yang strParameter = argv[2]; 2769c30d921cSKever Yang bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2770c30d921cSKever Yang } else 2771c30d921cSKever Yang printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 2772c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2773c30d921cSKever Yang if (argc > 2) { 2774c30d921cSKever Yang string strLoader; 2775c30d921cSKever Yang strLoader = argv[2]; 2776c30d921cSKever Yang bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2777c30d921cSKever Yang } else 2778c30d921cSKever Yang printf("Parameter of [UL] command is invalid, please check help!\r\n"); 277976af099aSliuyi } else if(strcmp(strCmd.c_str(), "EF") == 0) { 278076af099aSliuyi if (argc == 2) { 278176af099aSliuyi bSuccess = erase_flash(dev); 278276af099aSliuyi } else 278376af099aSliuyi printf("Parameter of [EF] command is invalid, please check help!\r\n"); 278476af099aSliuyi } else if(strcmp(strCmd.c_str(), "WL") == 0) { 278576af099aSliuyi if (argc == 4) { 278676af099aSliuyi UINT uiBegin; 278776af099aSliuyi char *pszEnd; 278876af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 278976af099aSliuyi if (*pszEnd) 279076af099aSliuyi printf("Begin is invalid, please check!\r\n"); 2791ae4252f0Sliuyi else { 2792ae4252f0Sliuyi if (is_sparse_image(argv[3])) 2793ae4252f0Sliuyi bSuccess = write_sparse_lba(dev, (u32)uiBegin, (u32)-1, argv[3]); 279476af099aSliuyi else 2795ae4252f0Sliuyi bSuccess = write_lba(dev, (u32)uiBegin, argv[3]); 2796ae4252f0Sliuyi } 279776af099aSliuyi } else 279876af099aSliuyi printf("Parameter of [WL] command is invalid, please check help!\r\n"); 27996ae612beSliuyi } else if(strcmp(strCmd.c_str(), "WLX") == 0) { 28006ae612beSliuyi if (argc == 4) { 28016ae612beSliuyi bRet = read_gpt(dev, master_gpt); 28026ae612beSliuyi if (bRet) { 28036ae612beSliuyi bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end); 28046ae612beSliuyi if (bRet) { 28056ae612beSliuyi if (is_sparse_image(argv[3])) 28066ae612beSliuyi bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]); 28076ae612beSliuyi else 28086ae612beSliuyi bSuccess = write_lba(dev, (u32)lba, argv[3]); 28096ae612beSliuyi } else 28106ae612beSliuyi printf("No found %s partition\r\n", argv[2]); 28116ae612beSliuyi } 28126ae612beSliuyi } else 28136ae612beSliuyi printf("Parameter of [WLX] command is invalid, please check help!\r\n"); 281476af099aSliuyi } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 281576af099aSliuyi char *pszEnd; 281676af099aSliuyi UINT uiBegin, uiLen; 281776af099aSliuyi if (argc != 5) 281876af099aSliuyi printf("Parameter of [RL] command is invalid, please check help!\r\n"); 281976af099aSliuyi else { 282076af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 282176af099aSliuyi if (*pszEnd) 282276af099aSliuyi printf("Begin is invalid, please check!\r\n"); 282376af099aSliuyi else { 282476af099aSliuyi uiLen = strtoul(argv[3], &pszEnd, 0); 282576af099aSliuyi if (*pszEnd) 282676af099aSliuyi printf("Len is invalid, please check!\r\n"); 282776af099aSliuyi else { 282876af099aSliuyi bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 282976af099aSliuyi } 283076af099aSliuyi } 283176af099aSliuyi } 28323dc7e3ceSliuyi } else if(strcmp(strCmd.c_str(), "PGPT") == 0) { 28333dc7e3ceSliuyi if (argc == 2) { 28343dc7e3ceSliuyi bSuccess = print_gpt(dev); 28353dc7e3ceSliuyi } else 28363dc7e3ceSliuyi printf("Parameter of [PGPT] command is invalid, please check help!\r\n"); 283776af099aSliuyi } else { 28389bc231bdSAndreas Färber printf("command is invalid!\r\n"); 28399bc231bdSAndreas Färber usage(); 284076af099aSliuyi } 284176af099aSliuyi return bSuccess; 284276af099aSliuyi } 284376af099aSliuyi 284476af099aSliuyi 284576af099aSliuyi int main(int argc, char* argv[]) 284676af099aSliuyi { 284776af099aSliuyi CRKScan *pScan = NULL; 284876af099aSliuyi int ret; 284976af099aSliuyi char szProgramProcPath[100]; 285076af099aSliuyi char szProgramDir[256]; 285176af099aSliuyi string strLogDir,strConfigFile; 285276af099aSliuyi struct stat statBuf; 285376af099aSliuyi 285476af099aSliuyi g_ConfigItemVec.clear(); 285576af099aSliuyi sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 285676af099aSliuyi if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 285776af099aSliuyi strcpy(szProgramDir, "."); 285876af099aSliuyi else { 285976af099aSliuyi char *pSlash; 286076af099aSliuyi pSlash = strrchr(szProgramDir, '/'); 286176af099aSliuyi if (pSlash) 286276af099aSliuyi *pSlash = '\0'; 286376af099aSliuyi } 286476af099aSliuyi strLogDir = szProgramDir; 286576af099aSliuyi strLogDir += "/log/"; 286676af099aSliuyi strConfigFile = szProgramDir; 286776af099aSliuyi strConfigFile += "/config.ini"; 286876af099aSliuyi if (opendir(strLogDir.c_str()) == NULL) 286976af099aSliuyi mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 2870e5ee8cc0Sliuyi g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 287176af099aSliuyi 287276af099aSliuyi if(stat(strConfigFile.c_str(), &statBuf) < 0) { 287376af099aSliuyi if (g_pLogObject) { 287476af099aSliuyi g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 287576af099aSliuyi } 287676af099aSliuyi } else if (S_ISREG(statBuf.st_mode)) { 287776af099aSliuyi parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 287876af099aSliuyi } 287976af099aSliuyi 288076af099aSliuyi ret = libusb_init(NULL); 288176af099aSliuyi if (ret < 0) { 288276af099aSliuyi if (g_pLogObject) { 288376af099aSliuyi g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 288476af099aSliuyi delete g_pLogObject; 288576af099aSliuyi } 288676af099aSliuyi return -1; 288776af099aSliuyi } 288876af099aSliuyi 288976af099aSliuyi pScan = new CRKScan(); 289076af099aSliuyi if (!pScan) { 289176af099aSliuyi if (g_pLogObject) { 289232268622SAndreas Färber g_pLogObject->Record("Error: failed to create object for searching device"); 289376af099aSliuyi delete g_pLogObject; 289476af099aSliuyi } 289576af099aSliuyi libusb_exit(NULL); 289676af099aSliuyi return -2; 289776af099aSliuyi } 289876af099aSliuyi pScan->SetVidPid(); 289976af099aSliuyi 290076af099aSliuyi if (argc == 1) 290176af099aSliuyi usage(); 290276af099aSliuyi else if (!handle_command(argc, argv, pScan)) 290376af099aSliuyi return -0xFF; 290476af099aSliuyi if (pScan) 290576af099aSliuyi delete pScan; 290676af099aSliuyi if (g_pLogObject) 290776af099aSliuyi delete g_pLogObject; 290876af099aSliuyi libusb_exit(NULL); 290976af099aSliuyi return 0; 291076af099aSliuyi } 2911