176af099aSliuyi /* 276af099aSliuyi * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 376af099aSliuyi * Seth Liu 2017.03.01 476af099aSliuyi * 576af099aSliuyi * SPDX-License-Identifier: GPL-2.0+ 676af099aSliuyi */ 776af099aSliuyi 876af099aSliuyi #include <unistd.h> 976af099aSliuyi #include <dirent.h> 10c30d921cSKever Yang #include "config.h" 1176af099aSliuyi #include "DefineHeader.h" 12c30d921cSKever Yang #include "gpt.h" 1376af099aSliuyi #include "RKLog.h" 1476af099aSliuyi #include "RKScan.h" 1576af099aSliuyi #include "RKComm.h" 1676af099aSliuyi #include "RKDevice.h" 1776af099aSliuyi #include "RKImage.h" 1876af099aSliuyi extern const char *szManufName[]; 1976af099aSliuyi CRKLog *g_pLogObject=NULL; 2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec; 2176af099aSliuyi #define DEFAULT_RW_LBA 128 2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n) 2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B) 2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B) 2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B) 2676af099aSliuyi #define ERROR_COLOR_ATTR printf("%c[30;41m", 0x1B); 273601cc08SAndreas Färber #define NORMAL_COLOR_ATTR printf("%c[0m", 0x1B); 28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize); 29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize); 30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len); 31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len); 32c30d921cSKever Yang /* 33c30d921cSKever Yang u8 test_gpt_head[] = { 34c30d921cSKever Yang 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00, 35c30d921cSKever Yang 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36c30d921cSKever Yang 0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37c30d921cSKever Yang 0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B, 38c30d921cSKever Yang 0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39c30d921cSKever Yang 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08}; 40c30d921cSKever Yang */ 41c30d921cSKever Yang 4276af099aSliuyi void usage() 4376af099aSliuyi { 4476af099aSliuyi printf("\r\n---------------------Tool Usage ---------------------\r\n"); 45154ee062SEddie Cai printf("Help:\t\t\t-h or --version\r\n"); 46154ee062SEddie Cai printf("Version:\t\t-v or --version\r\n"); 47154ee062SEddie Cai printf("DownloadBoot:\t\tdb <Loader>\r\n"); 48154ee062SEddie Cai printf("UpgradeLoader:\t\tul <Loader>\r\n"); 49154ee062SEddie Cai printf("ReadLBA:\t\trl <BeginSec> <SectorLen> <File>\r\n"); 50154ee062SEddie Cai printf("WriteLBA:\t\twl <BeginSec> <File>\r\n"); 51*6ae612beSliuyi printf("WriteLBA:\t\twlx <PartitionName> <File>\r\n"); 52154ee062SEddie Cai printf("WriteGPT:\t\tgpt <gpt partition table>\r\n"); 53154ee062SEddie Cai printf("EraseFlash:\t\tef \r\n"); 54154ee062SEddie Cai printf("TestDevice:\t\ttd\r\n"); 55154ee062SEddie Cai printf("ResetDevice:\t\trd [subcode]\r\n"); 56154ee062SEddie Cai printf("ReadFlashID:\t\trid\r\n"); 57154ee062SEddie Cai printf("ReadFlashInfo:\t\trfi\r\n"); 58154ee062SEddie Cai printf("ReadChipInfo:\t\trci\r\n"); 5978884ef4SEddie Cai printf("PackBootLoader:\t\tpack\r\n"); 6078884ef4SEddie Cai printf("UnpackBootLoader:\tunpack <boot loader>\r\n"); 61d71e8c20SEddie Cai printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n"); 6276af099aSliuyi printf("-------------------------------------------------------\r\n\r\n"); 6376af099aSliuyi } 6476af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall) 6576af099aSliuyi { 6676af099aSliuyi string strInfoText=""; 6776af099aSliuyi char szText[256]; 6876af099aSliuyi switch (promptID) { 6976af099aSliuyi case TESTDEVICE_PROGRESS: 7032268622SAndreas Färber sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue); 7176af099aSliuyi strInfoText = szText; 7276af099aSliuyi break; 7376af099aSliuyi case LOWERFORMAT_PROGRESS: 7432268622SAndreas Färber sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue); 7576af099aSliuyi strInfoText = szText; 7676af099aSliuyi break; 7776af099aSliuyi case DOWNLOADIMAGE_PROGRESS: 7832268622SAndreas Färber sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 7976af099aSliuyi strInfoText = szText; 8076af099aSliuyi break; 8176af099aSliuyi case CHECKIMAGE_PROGRESS: 8232268622SAndreas Färber sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 8376af099aSliuyi strInfoText = szText; 8476af099aSliuyi break; 8576af099aSliuyi case TAGBADBLOCK_PROGRESS: 8632268622SAndreas Färber sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue); 8776af099aSliuyi strInfoText = szText; 8876af099aSliuyi break; 8976af099aSliuyi case TESTBLOCK_PROGRESS: 9032268622SAndreas Färber sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue); 9176af099aSliuyi strInfoText = szText; 9276af099aSliuyi break; 9376af099aSliuyi case ERASEFLASH_PROGRESS: 9432268622SAndreas Färber sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue); 9576af099aSliuyi strInfoText = szText; 9676af099aSliuyi break; 9776af099aSliuyi case ERASESYSTEM_PROGRESS: 9832268622SAndreas Färber sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue); 9976af099aSliuyi strInfoText = szText; 10076af099aSliuyi break; 10176af099aSliuyi case ERASEUSERDATA_PROGRESS: 10232268622SAndreas Färber sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue); 10376af099aSliuyi strInfoText = szText; 10476af099aSliuyi break; 10576af099aSliuyi } 10676af099aSliuyi if (strInfoText.size() > 0){ 10776af099aSliuyi CURSOR_MOVEUP_LINE(1); 10876af099aSliuyi CURSOR_DEL_LINE; 10976af099aSliuyi printf("%s\r\n", strInfoText.c_str()); 11076af099aSliuyi } 11176af099aSliuyi if (emCall == CALL_LAST) 11276af099aSliuyi deviceLayer = 0; 11376af099aSliuyi } 11476af099aSliuyi 11576af099aSliuyi char *strupr(char *szSrc) 11676af099aSliuyi { 11776af099aSliuyi char *p = szSrc; 11876af099aSliuyi while(*p){ 11976af099aSliuyi if ((*p >= 'a') && (*p <= 'z')) 12076af099aSliuyi *p = *p - 'a' + 'A'; 12176af099aSliuyi p++; 12276af099aSliuyi } 12376af099aSliuyi return szSrc; 12476af099aSliuyi } 12576af099aSliuyi void PrintData(PBYTE pData, int nSize) 12676af099aSliuyi { 12776af099aSliuyi char szPrint[17] = "\0"; 12876af099aSliuyi int i; 12976af099aSliuyi for( i = 0; i < nSize; i++){ 13076af099aSliuyi if(i % 16 == 0){ 13176af099aSliuyi if(i / 16 > 0) 13276af099aSliuyi printf(" %s\r\n", szPrint); 13376af099aSliuyi printf("%08d ", i / 16); 13476af099aSliuyi } 13576af099aSliuyi printf("%02X ", pData[i]); 13676af099aSliuyi szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.'; 13776af099aSliuyi } 13876af099aSliuyi if(i / 16 > 0) 13976af099aSliuyi printf(" %s\r\n", szPrint); 14076af099aSliuyi } 14176af099aSliuyi 14276af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest) 14376af099aSliuyi { 14476af099aSliuyi if (!pszSrc) 14576af099aSliuyi return false; 14676af099aSliuyi int nSrcLen = strlen(pszSrc); 14776af099aSliuyi int nDestLen = nSrcLen * 2; 14876af099aSliuyi 14976af099aSliuyi pszDest = NULL; 15076af099aSliuyi pszDest = new wchar_t[nDestLen]; 15176af099aSliuyi if (!pszDest) 15276af099aSliuyi return false; 15376af099aSliuyi nDestLen = nDestLen * sizeof(wchar_t); 15476af099aSliuyi memset(pszDest, 0, nDestLen); 15576af099aSliuyi int iRet; 15676af099aSliuyi iconv_t cd; 15776af099aSliuyi cd = iconv_open("UTF-32", "UTF-8"); 15876af099aSliuyi if((iconv_t)-1 == cd) { 15976af099aSliuyi delete []pszDest; 16076af099aSliuyi pszDest = NULL; 16176af099aSliuyi return false; 16276af099aSliuyi } 16376af099aSliuyi char *pIn, *pOut; 16476af099aSliuyi pIn = (char *)pszSrc; 16576af099aSliuyi pOut = (char *)pszDest; 16676af099aSliuyi 16776af099aSliuyi iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 16876af099aSliuyi 16976af099aSliuyi if(iRet == -1) { 17076af099aSliuyi delete []pszDest; 17176af099aSliuyi pszDest = NULL; 17276af099aSliuyi iconv_close(cd); 17376af099aSliuyi return false; 17476af099aSliuyi } 17576af099aSliuyi 17676af099aSliuyi iconv_close(cd); 17776af099aSliuyi 17876af099aSliuyi return true; 17976af099aSliuyi } 18076af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest) 18176af099aSliuyi { 18276af099aSliuyi if (!pszSrc) 18376af099aSliuyi return false; 18476af099aSliuyi int nSrcLen = wcslen(pszSrc); 18576af099aSliuyi int nDestLen = nSrcLen * 2; 18676af099aSliuyi nSrcLen = nSrcLen * sizeof(wchar_t); 18776af099aSliuyi pszDest = NULL; 18876af099aSliuyi pszDest = new char[nDestLen]; 18976af099aSliuyi if (!pszDest) 19076af099aSliuyi return false; 19176af099aSliuyi memset(pszDest, 0, nDestLen); 19276af099aSliuyi int iRet; 19376af099aSliuyi iconv_t cd; 19476af099aSliuyi cd = iconv_open("UTF-8", "UTF-32"); 19576af099aSliuyi 19676af099aSliuyi if((iconv_t)-1 == cd) { 19776af099aSliuyi delete []pszDest; 19876af099aSliuyi pszDest = NULL; 19976af099aSliuyi return false; 20076af099aSliuyi } 20176af099aSliuyi char *pIn, *pOut; 20276af099aSliuyi pIn = (char *)pszSrc; 20376af099aSliuyi pOut = (char *)pszDest; 20476af099aSliuyi iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 20576af099aSliuyi 20676af099aSliuyi if(iRet == -1) { 20776af099aSliuyi delete []pszDest; 20876af099aSliuyi pszDest = NULL; 20976af099aSliuyi iconv_close(cd); 21076af099aSliuyi return false; 21176af099aSliuyi } 21276af099aSliuyi 21376af099aSliuyi iconv_close(cd); 21476af099aSliuyi 21576af099aSliuyi return true; 21676af099aSliuyi } 217c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName) 21876af099aSliuyi { 21976af099aSliuyi unsigned int i; 220c29e5f0fSliuyi for(i = 0; i < vecItems.size(); i++){ 221c29e5f0fSliuyi if (strcasecmp(pszName, vecItems[i].szItemName) == 0){ 22276af099aSliuyi return i; 22376af099aSliuyi } 22476af099aSliuyi } 22576af099aSliuyi return -1; 22676af099aSliuyi } 227c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid) 228c29e5f0fSliuyi { 229c29e5f0fSliuyi unsigned int i; 230c29e5f0fSliuyi char value; 231c29e5f0fSliuyi memset(uuid, 0, 16); 232c29e5f0fSliuyi for (i =0; i < strUUid.size(); i++) { 233c29e5f0fSliuyi value = 0; 234c29e5f0fSliuyi if ((strUUid[i] >= '0')&&(strUUid[i] <= '9')) 235c29e5f0fSliuyi value = strUUid[i] - '0'; 236c29e5f0fSliuyi if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f')) 237c29e5f0fSliuyi value = strUUid[i] - 'a' + 10; 238c29e5f0fSliuyi if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F')) 239c29e5f0fSliuyi value = strUUid[i] - 'A' + 10; 240c29e5f0fSliuyi if ((i % 2) == 0) 241c29e5f0fSliuyi uuid[i / 2] += (value << 4); 242c29e5f0fSliuyi else 243c29e5f0fSliuyi uuid[i / 2] += value; 244c29e5f0fSliuyi } 245c29e5f0fSliuyi unsigned int *p32; 246c29e5f0fSliuyi unsigned short *p16; 247c29e5f0fSliuyi p32 = (unsigned int*)uuid; 248c29e5f0fSliuyi *p32 = cpu_to_be32(*p32); 249c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 4); 250c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 251c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 6); 252c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 253c29e5f0fSliuyi } 25476af099aSliuyi 25576af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 25676af099aSliuyi { 25776af099aSliuyi 25876af099aSliuyi stringstream configStream(pConfig); 25976af099aSliuyi string strLine, strItemName, strItemValue; 26076af099aSliuyi string::size_type line_size,pos; 26176af099aSliuyi STRUCT_CONFIG_ITEM item; 26276af099aSliuyi vecItem.clear(); 26376af099aSliuyi while (!configStream.eof()){ 26476af099aSliuyi getline(configStream, strLine); 26576af099aSliuyi line_size = strLine.size(); 26676af099aSliuyi if (line_size == 0) 26776af099aSliuyi continue; 26876af099aSliuyi if (strLine[line_size-1] == '\r'){ 26976af099aSliuyi strLine = strLine.substr(0, line_size-1); 27076af099aSliuyi } 271c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 272c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 273c30d921cSKever Yang if (strLine.size()==0 ) 274c30d921cSKever Yang continue; 275c30d921cSKever Yang if (strLine[0] == '#') 276c30d921cSKever Yang continue; 27776af099aSliuyi pos = strLine.find("="); 27876af099aSliuyi if (pos == string::npos){ 27976af099aSliuyi continue; 28076af099aSliuyi } 28176af099aSliuyi strItemName = strLine.substr(0, pos); 28276af099aSliuyi strItemValue = strLine.substr(pos + 1); 28376af099aSliuyi strItemName.erase(0, strItemName.find_first_not_of(" ")); 28476af099aSliuyi strItemName.erase(strItemName.find_last_not_of(" ") + 1); 28576af099aSliuyi strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 28676af099aSliuyi strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 28776af099aSliuyi if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 28876af099aSliuyi strcpy(item.szItemName, strItemName.c_str()); 28976af099aSliuyi strcpy(item.szItemValue, strItemValue.c_str()); 29076af099aSliuyi vecItem.push_back(item); 29176af099aSliuyi } 29276af099aSliuyi } 29376af099aSliuyi return true; 29476af099aSliuyi 29576af099aSliuyi } 29676af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 29776af099aSliuyi { 29876af099aSliuyi FILE *file = NULL; 29976af099aSliuyi file = fopen(pConfigFile, "rb"); 30076af099aSliuyi if( !file ){ 30176af099aSliuyi if (g_pLogObject) 30232268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile); 30376af099aSliuyi return false; 30476af099aSliuyi } 30576af099aSliuyi int iFileSize; 30676af099aSliuyi fseek(file, 0, SEEK_END); 30776af099aSliuyi iFileSize = ftell(file); 30876af099aSliuyi fseek(file, 0, SEEK_SET); 30976af099aSliuyi char *pConfigBuf = NULL; 31076af099aSliuyi pConfigBuf = new char[iFileSize + 1]; 31176af099aSliuyi if (!pConfigBuf){ 31276af099aSliuyi fclose(file); 31376af099aSliuyi return false; 31476af099aSliuyi } 31576af099aSliuyi memset(pConfigBuf, 0, iFileSize + 1); 31676af099aSliuyi int iRead; 31776af099aSliuyi iRead = fread(pConfigBuf, 1, iFileSize, file); 31876af099aSliuyi if (iRead != iFileSize){ 31976af099aSliuyi if (g_pLogObject) 32032268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize); 32176af099aSliuyi fclose(file); 32276af099aSliuyi delete []pConfigBuf; 32376af099aSliuyi return false; 32476af099aSliuyi } 32576af099aSliuyi fclose(file); 32676af099aSliuyi bool bRet; 32776af099aSliuyi bRet = parse_config(pConfigBuf, vecItem); 32876af099aSliuyi delete []pConfigBuf; 32976af099aSliuyi return bRet; 33076af099aSliuyi } 331c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 332c30d921cSKever Yang { 333c30d921cSKever Yang string::size_type pos,prevPos; 334c30d921cSKever Yang string strOffset,strLen; 335c30d921cSKever Yang int iCount; 336c30d921cSKever Yang prevPos = pos = 0; 337c30d921cSKever Yang if (strPartInfo.size() <= 0) { 338c30d921cSKever Yang return false; 339c30d921cSKever Yang } 340c30d921cSKever Yang pos = strPartInfo.find('@'); 341c30d921cSKever Yang if (pos == string::npos) { 342c30d921cSKever Yang return false; 343c30d921cSKever Yang } 344c30d921cSKever Yang strLen = strPartInfo.substr(prevPos, pos - prevPos); 345c30d921cSKever Yang strLen.erase(0, strLen.find_first_not_of(" ")); 346c30d921cSKever Yang strLen.erase(strLen.find_last_not_of(" ") + 1); 347c30d921cSKever Yang if (strchr(strLen.c_str(), '-')) { 348c30d921cSKever Yang uiLen = 0xFFFFFFFF; 349c30d921cSKever Yang } else { 350c30d921cSKever Yang iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 351c30d921cSKever Yang if (iCount != 1) { 352c30d921cSKever Yang return false; 353c30d921cSKever Yang } 354c30d921cSKever Yang } 355c30d921cSKever Yang 356c30d921cSKever Yang prevPos = pos + 1; 357c30d921cSKever Yang pos = strPartInfo.find('(',prevPos); 358c30d921cSKever Yang if (pos == string::npos) { 359c30d921cSKever Yang return false; 360c30d921cSKever Yang } 361c30d921cSKever Yang strOffset = strPartInfo.substr(prevPos, pos - prevPos); 362c30d921cSKever Yang strOffset.erase(0, strOffset.find_first_not_of(" ")); 363c30d921cSKever Yang strOffset.erase(strOffset.find_last_not_of(" ") + 1); 364c30d921cSKever Yang iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 365c30d921cSKever Yang if (iCount != 1) { 366c30d921cSKever Yang return false; 367c30d921cSKever Yang } 368c30d921cSKever Yang prevPos = pos + 1; 369c30d921cSKever Yang pos = strPartInfo.find(')', prevPos); 370c30d921cSKever Yang if (pos == string::npos) { 371c30d921cSKever Yang return false; 372c30d921cSKever Yang } 373c30d921cSKever Yang strName = strPartInfo.substr(prevPos, pos - prevPos); 374c30d921cSKever Yang strName.erase(0, strName.find_first_not_of(" ")); 375c30d921cSKever Yang strName.erase(strName.find_last_not_of(" ") + 1); 376c30d921cSKever Yang 377c30d921cSKever Yang return true; 378c30d921cSKever Yang } 379c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid) 380c29e5f0fSliuyi { 381c29e5f0fSliuyi string::size_type pos(0); 382c30d921cSKever Yang 383c29e5f0fSliuyi if (strUuidInfo.size() <= 0) { 384c29e5f0fSliuyi return false; 385c29e5f0fSliuyi } 386c29e5f0fSliuyi pos = strUuidInfo.find('='); 387c29e5f0fSliuyi if (pos == string::npos) { 388c29e5f0fSliuyi return false; 389c29e5f0fSliuyi } 390c29e5f0fSliuyi strName = strUuidInfo.substr(0, pos); 391c29e5f0fSliuyi strName.erase(0, strName.find_first_not_of(" ")); 392c29e5f0fSliuyi strName.erase(strName.find_last_not_of(" ") + 1); 393c29e5f0fSliuyi 394c29e5f0fSliuyi strUUid = strUuidInfo.substr(pos+1); 395c29e5f0fSliuyi strUUid.erase(0, strUUid.find_first_not_of(" ")); 396c29e5f0fSliuyi strUUid.erase(strUUid.find_last_not_of(" ") + 1); 397c29e5f0fSliuyi 398c29e5f0fSliuyi while(true) { 399c29e5f0fSliuyi pos = 0; 400c29e5f0fSliuyi if( (pos = strUUid.find("-")) != string::npos) 401c29e5f0fSliuyi strUUid.replace(pos,1,""); 402c29e5f0fSliuyi else 403c29e5f0fSliuyi break; 404c29e5f0fSliuyi } 405c29e5f0fSliuyi if (strUUid.size() != 32) 406c29e5f0fSliuyi return false; 407c29e5f0fSliuyi return true; 408c29e5f0fSliuyi } 409c29e5f0fSliuyi 410c29e5f0fSliuyi 411c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 412c30d921cSKever Yang { 413c30d921cSKever Yang stringstream paramStream(pParameter); 414c30d921cSKever Yang bool bRet,bFind = false; 415c29e5f0fSliuyi string strLine, strPartition, strPartInfo, strPartName, strUUid; 416c30d921cSKever Yang string::size_type line_size, pos, posColon, posComma; 417c30d921cSKever Yang UINT uiPartOffset, uiPartSize; 418c30d921cSKever Yang STRUCT_PARAM_ITEM item; 419c29e5f0fSliuyi STRUCT_CONFIG_ITEM uuid_item; 420c30d921cSKever Yang vecItem.clear(); 421c29e5f0fSliuyi vecUuidItem.clear(); 422c30d921cSKever Yang while (!paramStream.eof()) { 423c30d921cSKever Yang getline(paramStream,strLine); 424c30d921cSKever Yang line_size = strLine.size(); 425c30d921cSKever Yang if (line_size == 0) 426c30d921cSKever Yang continue; 427c30d921cSKever Yang if (strLine[line_size - 1] == '\r'){ 428c30d921cSKever Yang strLine = strLine.substr(0, line_size - 1); 429c30d921cSKever Yang } 430c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 431c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 432c30d921cSKever Yang if (strLine.size()==0 ) 433c30d921cSKever Yang continue; 434c30d921cSKever Yang if (strLine[0] == '#') 435c30d921cSKever Yang continue; 436c29e5f0fSliuyi pos = strLine.find("uuid:"); 437c29e5f0fSliuyi if (pos != string::npos) { 438c29e5f0fSliuyi strPartInfo = strLine.substr(pos+5); 439c29e5f0fSliuyi bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid); 440c29e5f0fSliuyi if (bRet) { 441c29e5f0fSliuyi strcpy(uuid_item.szItemName, strPartName.c_str()); 442c29e5f0fSliuyi string_to_uuid(strUUid,uuid_item.szItemValue); 443c29e5f0fSliuyi vecUuidItem.push_back(uuid_item); 444c29e5f0fSliuyi } 445c29e5f0fSliuyi continue; 446c29e5f0fSliuyi } 447c29e5f0fSliuyi 448c30d921cSKever Yang pos = strLine.find("mtdparts"); 449c30d921cSKever Yang if (pos == string::npos) { 450c30d921cSKever Yang continue; 451c30d921cSKever Yang } 452c30d921cSKever Yang bFind = true; 453c30d921cSKever Yang posColon = strLine.find(':', pos); 454c30d921cSKever Yang if (posColon == string::npos) { 455c30d921cSKever Yang continue; 456c30d921cSKever Yang } 457c30d921cSKever Yang strPartition = strLine.substr(posColon + 1); 458c30d921cSKever Yang pos = 0; 459c30d921cSKever Yang posComma = strPartition.find(',', pos); 460c30d921cSKever Yang while (posComma != string::npos) { 461c30d921cSKever Yang strPartInfo = strPartition.substr(pos, posComma - pos); 462c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 463c30d921cSKever Yang if (bRet) { 464c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 465c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 466c30d921cSKever Yang item.uiItemSize = uiPartSize; 467c30d921cSKever Yang vecItem.push_back(item); 468c30d921cSKever Yang } 469c30d921cSKever Yang pos = posComma + 1; 470c30d921cSKever Yang posComma = strPartition.find(',', pos); 471c30d921cSKever Yang } 472c30d921cSKever Yang strPartInfo = strPartition.substr(pos); 473c30d921cSKever Yang if (strPartInfo.size() > 0) { 474c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 475c30d921cSKever Yang if (bRet) { 476c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 477c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 478c30d921cSKever Yang item.uiItemSize = uiPartSize; 479c30d921cSKever Yang vecItem.push_back(item); 480c30d921cSKever Yang } 481c30d921cSKever Yang } 482c30d921cSKever Yang break; 483c30d921cSKever Yang } 484c30d921cSKever Yang return bFind; 485c30d921cSKever Yang 486c30d921cSKever Yang } 487c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 488c30d921cSKever Yang { 489c30d921cSKever Yang FILE *file = NULL; 490c30d921cSKever Yang file = fopen(pParamFile, "rb"); 491c30d921cSKever Yang if( !file ) { 492c30d921cSKever Yang if (g_pLogObject) 49332268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 494c30d921cSKever Yang return false; 495c30d921cSKever Yang } 496c30d921cSKever Yang int iFileSize; 497c30d921cSKever Yang fseek(file, 0, SEEK_END); 498c30d921cSKever Yang iFileSize = ftell(file); 499c30d921cSKever Yang fseek(file, 0, SEEK_SET); 500c30d921cSKever Yang char *pParamBuf = NULL; 501c30d921cSKever Yang pParamBuf = new char[iFileSize]; 502c30d921cSKever Yang if (!pParamBuf) { 503c30d921cSKever Yang fclose(file); 504c30d921cSKever Yang return false; 505c30d921cSKever Yang } 506c30d921cSKever Yang int iRead; 507c30d921cSKever Yang iRead = fread(pParamBuf, 1, iFileSize, file); 508c30d921cSKever Yang if (iRead != iFileSize) { 509c30d921cSKever Yang if (g_pLogObject) 51032268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize); 511c30d921cSKever Yang fclose(file); 512c30d921cSKever Yang delete []pParamBuf; 513c30d921cSKever Yang return false; 514c30d921cSKever Yang } 515c30d921cSKever Yang fclose(file); 516c30d921cSKever Yang bool bRet; 517c29e5f0fSliuyi bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem); 518c30d921cSKever Yang delete []pParamBuf; 519c30d921cSKever Yang return bRet; 520c30d921cSKever Yang } 521*6ae612beSliuyi bool is_sparse_image(char *szImage) 522*6ae612beSliuyi { 523*6ae612beSliuyi FILE *file = NULL; 524*6ae612beSliuyi sparse_header head; 525*6ae612beSliuyi u32 uiRead; 526*6ae612beSliuyi file = fopen(szImage, "rb"); 527*6ae612beSliuyi if( !file ) { 528*6ae612beSliuyi if (g_pLogObject) 529*6ae612beSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage); 530*6ae612beSliuyi return false; 531*6ae612beSliuyi } 532*6ae612beSliuyi uiRead = fread(&head, 1, sizeof(head), file); 533*6ae612beSliuyi if (uiRead != sizeof(head)) { 534*6ae612beSliuyi if (g_pLogObject) 535*6ae612beSliuyi g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head)); 536*6ae612beSliuyi fclose(file); 537*6ae612beSliuyi return false; 538*6ae612beSliuyi } 539*6ae612beSliuyi fclose(file); 540*6ae612beSliuyi if (head.magic!=SPARSE_HEADER_MAGIC) 541*6ae612beSliuyi { 542*6ae612beSliuyi return false; 543*6ae612beSliuyi } 544*6ae612beSliuyi return true; 545*6ae612beSliuyi 546*6ae612beSliuyi } 547c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin) 548c30d921cSKever Yang { 549c30d921cSKever Yang efi_guid_t id; 550c30d921cSKever Yang unsigned int *ptr = (unsigned int *)&id; 551c30d921cSKever Yang unsigned int i; 552c30d921cSKever Yang 553c30d921cSKever Yang /* Set all fields randomly */ 554c30d921cSKever Yang for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 555c30d921cSKever Yang *(ptr + i) = cpu_to_be32(rand()); 556c30d921cSKever Yang 557c30d921cSKever Yang id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 558c30d921cSKever Yang id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 559c30d921cSKever Yang 560c30d921cSKever Yang memcpy(uuid_bin, id.raw, sizeof(id)); 561c30d921cSKever Yang } 562c30d921cSKever Yang 563c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup) 564c29e5f0fSliuyi { 565c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 566c29e5f0fSliuyi gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE); 567c29e5f0fSliuyi u32 calc_crc32; 568c29e5f0fSliuyi u64 val; 569c29e5f0fSliuyi 570c29e5f0fSliuyi /* recalculate the values for the Backup GPT Header */ 571c29e5f0fSliuyi val = le64_to_cpu(gptMasterHead->my_lba); 572c29e5f0fSliuyi gptBackupHead->my_lba = gptMasterHead->alternate_lba; 573c29e5f0fSliuyi gptBackupHead->alternate_lba = cpu_to_le64(val); 574c29e5f0fSliuyi gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1); 575c29e5f0fSliuyi gptBackupHead->header_crc32 = 0; 576c29e5f0fSliuyi 577c29e5f0fSliuyi calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size)); 578c29e5f0fSliuyi gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32); 579c29e5f0fSliuyi } 580*6ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end) 581*6ae612beSliuyi { 582*6ae612beSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 583*6ae612beSliuyi gpt_entry *gptEntry = NULL; 584*6ae612beSliuyi u32 i,j; 585*6ae612beSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 586*6ae612beSliuyi bool bFound = false; 587*6ae612beSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 588*6ae612beSliuyi 589*6ae612beSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 590*6ae612beSliuyi gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 591*6ae612beSliuyi if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0) 592*6ae612beSliuyi break; 593*6ae612beSliuyi for (j = 0; j < strlen(pszName); j++) 594*6ae612beSliuyi if (gptEntry->partition_name[j] != pszName[j]) 595*6ae612beSliuyi break; 596*6ae612beSliuyi if (gptEntry->partition_name[j] != 0) 597*6ae612beSliuyi continue; 598*6ae612beSliuyi if (j == strlen(pszName)) { 599*6ae612beSliuyi bFound = true; 600*6ae612beSliuyi break; 601*6ae612beSliuyi } 602*6ae612beSliuyi } 603*6ae612beSliuyi if (bFound) { 604*6ae612beSliuyi *lba = le64_to_cpu(gptEntry->starting_lba); 605*6ae612beSliuyi *lba_end = le64_to_cpu(gptEntry->ending_lba); 606*6ae612beSliuyi return true; 607*6ae612beSliuyi } 608*6ae612beSliuyi return false; 609*6ae612beSliuyi } 610c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector) 611c29e5f0fSliuyi { 612c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 613c29e5f0fSliuyi gpt_entry *gptLastPartEntry = NULL; 614c29e5f0fSliuyi u32 i; 615c29e5f0fSliuyi u64 old_disksize; 616c29e5f0fSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 617c29e5f0fSliuyi 618c29e5f0fSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 619c29e5f0fSliuyi old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1; 620c29e5f0fSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 621c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 622c29e5f0fSliuyi if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0) 623c29e5f0fSliuyi break; 624c29e5f0fSliuyi } 625c29e5f0fSliuyi i--; 626c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry)); 627c29e5f0fSliuyi 628c29e5f0fSliuyi gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1); 629c29e5f0fSliuyi gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34); 630c29e5f0fSliuyi 631c29e5f0fSliuyi if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition 632c29e5f0fSliuyi gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34); 633c29e5f0fSliuyi gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 634c29e5f0fSliuyi } 635c29e5f0fSliuyi gptMasterHead->header_crc32 = 0; 636c29e5f0fSliuyi gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header))); 637c29e5f0fSliuyi memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS); 638c29e5f0fSliuyi memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE); 639c29e5f0fSliuyi prepare_gpt_backup(master, backup); 640c29e5f0fSliuyi 641c29e5f0fSliuyi } 642c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup) 643c29e5f0fSliuyi { 644c29e5f0fSliuyi FILE *file = NULL; 645c29e5f0fSliuyi file = fopen(pParamFile, "rb"); 646c29e5f0fSliuyi if( !file ) { 647c29e5f0fSliuyi if (g_pLogObject) 648c29e5f0fSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 649c29e5f0fSliuyi return false; 650c29e5f0fSliuyi } 651c29e5f0fSliuyi int iFileSize; 652c29e5f0fSliuyi fseek(file, 0, SEEK_END); 653c29e5f0fSliuyi iFileSize = ftell(file); 654c29e5f0fSliuyi fseek(file, 0, SEEK_SET); 655c29e5f0fSliuyi if (iFileSize != 67 * SECTOR_SIZE) { 656c29e5f0fSliuyi if (g_pLogObject) 657c29e5f0fSliuyi g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile); 658c29e5f0fSliuyi fclose(file); 659c29e5f0fSliuyi return false; 660c29e5f0fSliuyi } 661c29e5f0fSliuyi 662c29e5f0fSliuyi int iRead; 663c29e5f0fSliuyi iRead = fread(master, 1, 34 * SECTOR_SIZE, file); 664c29e5f0fSliuyi if (iRead != 34 * SECTOR_SIZE) { 665c29e5f0fSliuyi if (g_pLogObject) 666c29e5f0fSliuyi g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE); 667c29e5f0fSliuyi fclose(file); 668c29e5f0fSliuyi return false; 669c29e5f0fSliuyi } 670c29e5f0fSliuyi iRead = fread(backup, 1, 33 * SECTOR_SIZE, file); 671c29e5f0fSliuyi if (iRead != 33 * SECTOR_SIZE) { 672c29e5f0fSliuyi if (g_pLogObject) 673c29e5f0fSliuyi g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE); 674c29e5f0fSliuyi fclose(file); 675c29e5f0fSliuyi return false; 676c29e5f0fSliuyi } 677c29e5f0fSliuyi fclose(file); 678c29e5f0fSliuyi return true; 679c29e5f0fSliuyi } 680c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors) 681c30d921cSKever Yang { 682c30d921cSKever Yang legacy_mbr *mbr = (legacy_mbr *)gpt; 683c30d921cSKever Yang gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 684c30d921cSKever Yang gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 685c30d921cSKever Yang u32 i,j; 686c29e5f0fSliuyi int pos; 687c30d921cSKever Yang string strPartName; 688c30d921cSKever Yang string::size_type colonPos; 689c30d921cSKever Yang /*1.protective mbr*/ 690c30d921cSKever Yang memset(gpt, 0, SECTOR_SIZE); 691c30d921cSKever Yang mbr->signature = MSDOS_MBR_SIGNATURE; 692c30d921cSKever Yang mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 693c30d921cSKever Yang mbr->partition_record[0].start_sect = 1; 694c30d921cSKever Yang mbr->partition_record[0].nr_sects = (u32)-1; 695c30d921cSKever Yang /*2.gpt header*/ 696c30d921cSKever Yang memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 697c30d921cSKever Yang gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 698c30d921cSKever Yang gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 699c30d921cSKever Yang gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 700c30d921cSKever Yang gptHead->my_lba = cpu_to_le64(1); 701c30d921cSKever Yang gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 702c30d921cSKever Yang gptHead->first_usable_lba = cpu_to_le64(34); 703c30d921cSKever Yang gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 704c30d921cSKever Yang gptHead->partition_entry_lba = cpu_to_le64(2); 705c30d921cSKever Yang gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 706c30d921cSKever Yang gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 707c30d921cSKever Yang gptHead->header_crc32 = 0; 708c30d921cSKever Yang gptHead->partition_entry_array_crc32 = 0; 709c30d921cSKever Yang gen_rand_uuid(gptHead->disk_guid.raw); 710c30d921cSKever Yang 711c30d921cSKever Yang /*3.gpt partition entry*/ 712c30d921cSKever Yang memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 713c30d921cSKever Yang for (i = 0; i < vecParts.size(); i++) { 714c30d921cSKever Yang gen_rand_uuid(gptEntry->partition_type_guid.raw); 715c30d921cSKever Yang gen_rand_uuid(gptEntry->unique_partition_guid.raw); 716c30d921cSKever Yang gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 717c30d921cSKever Yang gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 718c30d921cSKever Yang gptEntry->attributes.raw = 0; 719c30d921cSKever Yang strPartName = vecParts[i].szItemName; 720c30d921cSKever Yang colonPos = strPartName.find_first_of(':'); 721c30d921cSKever Yang if (colonPos != string::npos) { 722c30d921cSKever Yang if (strPartName.find("bootable") != string::npos) 723c30d921cSKever Yang gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 724c29e5f0fSliuyi if (strPartName.find("grow") != string::npos) 725c29e5f0fSliuyi gptEntry->ending_lba = cpu_to_le64(diskSectors - 34); 726c30d921cSKever Yang strPartName = strPartName.substr(0, colonPos); 727c30d921cSKever Yang vecParts[i].szItemName[strPartName.size()] = 0; 728c30d921cSKever Yang } 729c30d921cSKever Yang for (j = 0; j < strlen(vecParts[i].szItemName); j++) 730c30d921cSKever Yang gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 731c29e5f0fSliuyi if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1) 732c29e5f0fSliuyi memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16); 733c30d921cSKever Yang gptEntry++; 734c30d921cSKever Yang } 735c30d921cSKever Yang 736c30d921cSKever Yang gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 737c30d921cSKever Yang gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 738c30d921cSKever Yang 739c30d921cSKever Yang } 740b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag) 741c30d921cSKever Yang { 742c30d921cSKever Yang PRK28_IDB_SEC0 pSec0; 743c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 744c30d921cSKever Yang pSec0 = (PRK28_IDB_SEC0)pSector; 745c30d921cSKever Yang 746c30d921cSKever Yang pSec0->dwTag = 0x0FF0AA55; 747b38fe5fcSliuyi pSec0->uiRc4Flag = rc4Flag; 748c30d921cSKever Yang pSec0->usBootCode1Offset = 0x4; 749c30d921cSKever Yang pSec0->usBootCode2Offset = 0x4; 750c30d921cSKever Yang pSec0->usBootDataSize = usFlashDataSec; 751c30d921cSKever Yang pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 752c30d921cSKever Yang return true; 753c30d921cSKever Yang } 754c30d921cSKever Yang 755c30d921cSKever Yang 756c30d921cSKever Yang bool MakeSector1(PBYTE pSector) 757c30d921cSKever Yang { 758c30d921cSKever Yang PRK28_IDB_SEC1 pSec1; 759c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 760c30d921cSKever Yang pSec1 = (PRK28_IDB_SEC1)pSector; 761c30d921cSKever Yang 762c30d921cSKever Yang pSec1->usSysReservedBlock = 0xC; 763c30d921cSKever Yang pSec1->usDisk0Size = 0xFFFF; 764c30d921cSKever Yang pSec1->uiChipTag = 0x38324B52; 765c30d921cSKever Yang return true; 766c30d921cSKever Yang } 767c30d921cSKever Yang 768c30d921cSKever Yang bool MakeSector2(PBYTE pSector) 769c30d921cSKever Yang { 770c30d921cSKever Yang PRK28_IDB_SEC2 pSec2; 771c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 772c30d921cSKever Yang pSec2 = (PRK28_IDB_SEC2)pSector; 773c30d921cSKever Yang 774c30d921cSKever Yang strcpy(pSec2->szVcTag, "VC"); 775c30d921cSKever Yang strcpy(pSec2->szCrcTag, "CRC"); 776c30d921cSKever Yang return true; 777c30d921cSKever Yang } 778c30d921cSKever Yang 779c30d921cSKever Yang bool MakeSector3(PBYTE pSector) 780c30d921cSKever Yang { 781c30d921cSKever Yang memset(pSector,0,SECTOR_SIZE); 782c30d921cSKever Yang return true; 783c30d921cSKever Yang } 784c30d921cSKever Yang 785b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag) 786c30d921cSKever Yang { 787c30d921cSKever Yang RK28_IDB_SEC0 sector0Info; 788c30d921cSKever Yang RK28_IDB_SEC1 sector1Info; 789c30d921cSKever Yang RK28_IDB_SEC2 sector2Info; 790c30d921cSKever Yang RK28_IDB_SEC3 sector3Info; 791c30d921cSKever Yang UINT i; 792b38fe5fcSliuyi MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag); 793c30d921cSKever Yang MakeSector1((PBYTE)§or1Info); 794c30d921cSKever Yang if (!MakeSector2((PBYTE)§or2Info)) { 795c30d921cSKever Yang return -6; 796c30d921cSKever Yang } 797c30d921cSKever Yang if (!MakeSector3((PBYTE)§or3Info)) { 798c30d921cSKever Yang return -7; 799c30d921cSKever Yang } 800c30d921cSKever Yang sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 801c30d921cSKever Yang sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 802c30d921cSKever Yang sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 803c30d921cSKever Yang 804c30d921cSKever Yang memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 805c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 806c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 807b38fe5fcSliuyi 808b38fe5fcSliuyi if (rc4Flag) { 809b38fe5fcSliuyi for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++) 810b38fe5fcSliuyi P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE); 811b38fe5fcSliuyi for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++) 812b38fe5fcSliuyi P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE); 813b38fe5fcSliuyi } 814b38fe5fcSliuyi 815c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 816c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 817c30d921cSKever Yang 818c30d921cSKever Yang sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 819c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 820c30d921cSKever Yang for(i = 0; i < 4; i++) { 821c30d921cSKever Yang if(i == 1) { 822c30d921cSKever Yang continue; 823c30d921cSKever Yang } else { 824c30d921cSKever Yang P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 825c30d921cSKever Yang } 826c30d921cSKever Yang } 827c30d921cSKever Yang return 0; 828c30d921cSKever Yang } 829c30d921cSKever Yang 830c30d921cSKever Yang 83176af099aSliuyi 83276af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 83376af099aSliuyi { 83476af099aSliuyi if ((dev.emUsbType & uiSupportType) == dev.emUsbType) 83576af099aSliuyi return true; 83676af099aSliuyi else 83776af099aSliuyi { 83876af099aSliuyi ERROR_COLOR_ATTR; 83932268622SAndreas Färber printf("The device does not support this operation!"); 84076af099aSliuyi NORMAL_COLOR_ATTR; 84176af099aSliuyi printf("\r\n"); 84276af099aSliuyi return false; 84376af099aSliuyi } 84476af099aSliuyi } 845c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 846c30d921cSKever Yang { 847c30d921cSKever Yang u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 848c30d921cSKever Yang u32 total_size_sector; 849c30d921cSKever Yang CRKComm *pComm = NULL; 850c30d921cSKever Yang PARAM_ITEM_VECTOR vecItems; 851c29e5f0fSliuyi CONFIG_ITEM_VECTOR vecUuid; 852c30d921cSKever Yang int iRet; 853c30d921cSKever Yang bool bRet, bSuccess = false; 854c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 855c30d921cSKever Yang return false; 856c30d921cSKever Yang 857c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 858c30d921cSKever Yang if (!bRet) { 859c30d921cSKever Yang ERROR_COLOR_ATTR; 860c30d921cSKever Yang printf("Creating Comm Object failed!"); 861c30d921cSKever Yang NORMAL_COLOR_ATTR; 862c30d921cSKever Yang printf("\r\n"); 863c30d921cSKever Yang return bSuccess; 864c30d921cSKever Yang } 86532268622SAndreas Färber printf("Writing gpt...\r\n"); 866c30d921cSKever Yang //1.get flash info 867c30d921cSKever Yang iRet = pComm->RKU_ReadFlashInfo(flash_info); 868c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 869c30d921cSKever Yang ERROR_COLOR_ATTR; 870c30d921cSKever Yang printf("Reading Flash Info failed!"); 871c30d921cSKever Yang NORMAL_COLOR_ATTR; 872c30d921cSKever Yang printf("\r\n"); 873c30d921cSKever Yang return bSuccess; 874c30d921cSKever Yang } 875c30d921cSKever Yang total_size_sector = *(u32 *)flash_info; 876c29e5f0fSliuyi if (strstr(szParameter, ".img")) { 877c29e5f0fSliuyi if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) { 878c29e5f0fSliuyi ERROR_COLOR_ATTR; 879c29e5f0fSliuyi printf("Loading partition image failed!"); 880c29e5f0fSliuyi NORMAL_COLOR_ATTR; 881c29e5f0fSliuyi printf("\r\n"); 882c29e5f0fSliuyi return bSuccess; 883c29e5f0fSliuyi } 884c29e5f0fSliuyi update_gpt_disksize(master_gpt, backup_gpt, total_size_sector); 885c29e5f0fSliuyi } else { 886c30d921cSKever Yang //2.get partition from parameter 887c29e5f0fSliuyi bRet = parse_parameter_file(szParameter, vecItems, vecUuid); 888c30d921cSKever Yang if (!bRet) { 889c30d921cSKever Yang ERROR_COLOR_ATTR; 890c30d921cSKever Yang printf("Parsing parameter failed!"); 891c30d921cSKever Yang NORMAL_COLOR_ATTR; 892c30d921cSKever Yang printf("\r\n"); 893c30d921cSKever Yang return bSuccess; 894c30d921cSKever Yang } 895c29e5f0fSliuyi vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33; 896c30d921cSKever Yang //3.generate gpt info 897c29e5f0fSliuyi create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector); 898c30d921cSKever Yang memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 899c30d921cSKever Yang memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 900c29e5f0fSliuyi prepare_gpt_backup(master_gpt, backup_gpt); 901c29e5f0fSliuyi } 902c29e5f0fSliuyi 903c30d921cSKever Yang //4. write gpt 904c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 905c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 906c30d921cSKever Yang ERROR_COLOR_ATTR; 907c30d921cSKever Yang printf("Writing master gpt failed!"); 908c30d921cSKever Yang NORMAL_COLOR_ATTR; 909c30d921cSKever Yang printf("\r\n"); 910c30d921cSKever Yang return bSuccess; 911c30d921cSKever Yang } 912c29e5f0fSliuyi iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt); 913c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 914c30d921cSKever Yang ERROR_COLOR_ATTR; 915c30d921cSKever Yang printf("Writing backup gpt failed!"); 916c30d921cSKever Yang NORMAL_COLOR_ATTR; 917c30d921cSKever Yang printf("\r\n"); 918c30d921cSKever Yang return bSuccess; 919c30d921cSKever Yang } 920c29e5f0fSliuyi 921c30d921cSKever Yang bSuccess = true; 922c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 923c30d921cSKever Yang CURSOR_DEL_LINE; 92432268622SAndreas Färber printf("Writing gpt succeeded.\r\n"); 925c30d921cSKever Yang return bSuccess; 926c30d921cSKever Yang } 92776af099aSliuyi 92878884ef4SEddie Cai #include "boot_merger.h" 92978884ef4SEddie Cai #define ENTRY_ALIGN (2048) 93078884ef4SEddie Cai options gOpts; 93178884ef4SEddie Cai 93278884ef4SEddie Cai 93378884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 93478884ef4SEddie Cai char* gConfigPath; 93578884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE]; 93678884ef4SEddie Cai 93778884ef4SEddie Cai static inline void fixPath(char* path) { 93878884ef4SEddie Cai int i, len = strlen(path); 93978884ef4SEddie Cai for(i=0; i<len; i++) { 94078884ef4SEddie Cai if (path[i] == '\\') 94178884ef4SEddie Cai path[i] = '/'; 94278884ef4SEddie Cai else if (path[i] == '\r' || path[i] == '\n') 94378884ef4SEddie Cai path[i] = '\0'; 94478884ef4SEddie Cai } 94578884ef4SEddie Cai } 94678884ef4SEddie Cai 94778884ef4SEddie Cai static bool parseChip(FILE* file) { 94878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 94978884ef4SEddie Cai return false; 95078884ef4SEddie Cai } 95178884ef4SEddie Cai if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 95278884ef4SEddie Cai return false; 95378884ef4SEddie Cai } 95478884ef4SEddie Cai printf("chip: %s\n", gOpts.chip); 95578884ef4SEddie Cai return true; 95678884ef4SEddie Cai } 95778884ef4SEddie Cai 95878884ef4SEddie Cai static bool parseVersion(FILE* file) { 95978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 96078884ef4SEddie Cai return false; 96178884ef4SEddie Cai } 96278884ef4SEddie Cai if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 96378884ef4SEddie Cai return false; 96478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 96578884ef4SEddie Cai return false; 96678884ef4SEddie Cai } 96778884ef4SEddie Cai if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 96878884ef4SEddie Cai return false; 96978884ef4SEddie Cai printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor); 97078884ef4SEddie Cai return true; 97178884ef4SEddie Cai } 97278884ef4SEddie Cai 97378884ef4SEddie Cai static bool parse471(FILE* file) { 97478884ef4SEddie Cai int i, index, pos; 97578884ef4SEddie Cai char buf[MAX_LINE_LEN]; 97678884ef4SEddie Cai 97778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 97878884ef4SEddie Cai return false; 97978884ef4SEddie Cai } 98078884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 98178884ef4SEddie Cai return false; 98278884ef4SEddie Cai printf("num: %d\n", gOpts.code471Num); 98378884ef4SEddie Cai if (!gOpts.code471Num) 98478884ef4SEddie Cai return true; 98578884ef4SEddie Cai if (gOpts.code471Num < 0) 98678884ef4SEddie Cai return false; 98778884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 98878884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 98978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 99078884ef4SEddie Cai return false; 99178884ef4SEddie Cai } 99278884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 99378884ef4SEddie Cai != 2) 99478884ef4SEddie Cai return false; 99578884ef4SEddie Cai index--; 99678884ef4SEddie Cai fixPath(buf); 99778884ef4SEddie Cai strcpy((char*)gOpts.code471Path[index], buf); 99878884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code471Path[index]); 99978884ef4SEddie Cai } 100078884ef4SEddie Cai pos = ftell(file); 100178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 100278884ef4SEddie Cai return false; 100378884ef4SEddie Cai } 100478884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 100578884ef4SEddie Cai fseek(file, pos, SEEK_SET); 100678884ef4SEddie Cai printf("sleep: %d\n", gOpts.code471Sleep); 100778884ef4SEddie Cai return true; 100878884ef4SEddie Cai } 100978884ef4SEddie Cai 101078884ef4SEddie Cai static bool parse472(FILE* file) { 101178884ef4SEddie Cai int i, index, pos; 101278884ef4SEddie Cai char buf[MAX_LINE_LEN]; 101378884ef4SEddie Cai 101478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 101578884ef4SEddie Cai return false; 101678884ef4SEddie Cai } 101778884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 101878884ef4SEddie Cai return false; 101978884ef4SEddie Cai printf("num: %d\n", gOpts.code472Num); 102078884ef4SEddie Cai if (!gOpts.code472Num) 102178884ef4SEddie Cai return true; 102278884ef4SEddie Cai if (gOpts.code472Num < 0) 102378884ef4SEddie Cai return false; 102478884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 102578884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 102678884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 102778884ef4SEddie Cai return false; 102878884ef4SEddie Cai } 102978884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 103078884ef4SEddie Cai != 2) 103178884ef4SEddie Cai return false; 103278884ef4SEddie Cai fixPath(buf); 103378884ef4SEddie Cai index--; 103478884ef4SEddie Cai strcpy((char*)gOpts.code472Path[index], buf); 103578884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code472Path[index]); 103678884ef4SEddie Cai } 103778884ef4SEddie Cai pos = ftell(file); 103878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 103978884ef4SEddie Cai return false; 104078884ef4SEddie Cai } 104178884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 104278884ef4SEddie Cai fseek(file, pos, SEEK_SET); 104378884ef4SEddie Cai printf("sleep: %d\n", gOpts.code472Sleep); 104478884ef4SEddie Cai return true; 104578884ef4SEddie Cai } 104678884ef4SEddie Cai 104778884ef4SEddie Cai static bool parseLoader(FILE* file) { 104878884ef4SEddie Cai int i, j, index, pos; 104978884ef4SEddie Cai char buf[MAX_LINE_LEN]; 105078884ef4SEddie Cai char buf2[MAX_LINE_LEN]; 105178884ef4SEddie Cai 105278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 105378884ef4SEddie Cai return false; 105478884ef4SEddie Cai } 105578884ef4SEddie Cai pos = ftell(file); 105678884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 105778884ef4SEddie Cai fseek(file, pos, SEEK_SET); 105878884ef4SEddie Cai if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 105978884ef4SEddie Cai return false; 106078884ef4SEddie Cai } 106178884ef4SEddie Cai } 106278884ef4SEddie Cai printf("num: %d\n", gOpts.loaderNum); 106378884ef4SEddie Cai if (!gOpts.loaderNum) 106478884ef4SEddie Cai return false; 106578884ef4SEddie Cai if (gOpts.loaderNum < 0) 106678884ef4SEddie Cai return false; 106778884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 106878884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 106978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 107078884ef4SEddie Cai return false; 107178884ef4SEddie Cai } 107278884ef4SEddie Cai if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 107378884ef4SEddie Cai != 2) 107478884ef4SEddie Cai return false; 107578884ef4SEddie Cai index--; 107678884ef4SEddie Cai strcpy(gOpts.loader[index].name, buf); 107778884ef4SEddie Cai printf("name%d: %s\n", index, gOpts.loader[index].name); 107878884ef4SEddie Cai } 107978884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 108078884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 108178884ef4SEddie Cai return false; 108278884ef4SEddie Cai } 108378884ef4SEddie Cai if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 108478884ef4SEddie Cai != 2) 108578884ef4SEddie Cai return false; 108678884ef4SEddie Cai for (j=0; j<gOpts.loaderNum; j++) { 108778884ef4SEddie Cai if (!strcmp(gOpts.loader[j].name, buf)) { 108878884ef4SEddie Cai fixPath(buf2); 108978884ef4SEddie Cai strcpy(gOpts.loader[j].path, buf2); 109078884ef4SEddie Cai printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 109178884ef4SEddie Cai break; 109278884ef4SEddie Cai } 109378884ef4SEddie Cai } 109478884ef4SEddie Cai if (j >= gOpts.loaderNum) { 109578884ef4SEddie Cai return false; 109678884ef4SEddie Cai } 109778884ef4SEddie Cai } 109878884ef4SEddie Cai return true; 109978884ef4SEddie Cai } 110078884ef4SEddie Cai 110178884ef4SEddie Cai static bool parseOut(FILE* file) { 110278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 110378884ef4SEddie Cai return false; 110478884ef4SEddie Cai } 110578884ef4SEddie Cai if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 110678884ef4SEddie Cai return false; 110778884ef4SEddie Cai fixPath(gOpts.outPath); 110878884ef4SEddie Cai printf("out: %s\n", gOpts.outPath); 110978884ef4SEddie Cai return true; 111078884ef4SEddie Cai } 111178884ef4SEddie Cai 111278884ef4SEddie Cai 111378884ef4SEddie Cai void printOpts(FILE* out) { 111478884ef4SEddie Cai int i; 111578884ef4SEddie Cai fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 111678884ef4SEddie Cai fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 111778884ef4SEddie Cai "=%d\n", gOpts.major, gOpts.minor); 111878884ef4SEddie Cai 111978884ef4SEddie Cai fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 112078884ef4SEddie Cai for (i=0 ;i<gOpts.code471Num ;i++) { 112178884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 112278884ef4SEddie Cai } 112378884ef4SEddie Cai if (gOpts.code471Sleep > 0) 112478884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 112578884ef4SEddie Cai 112678884ef4SEddie Cai fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 112778884ef4SEddie Cai for (i=0 ;i<gOpts.code472Num ;i++) { 112878884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 112978884ef4SEddie Cai } 113078884ef4SEddie Cai if (gOpts.code472Sleep > 0) 113178884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 113278884ef4SEddie Cai 113378884ef4SEddie Cai fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 113478884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 113578884ef4SEddie Cai fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 113678884ef4SEddie Cai } 113778884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 113878884ef4SEddie Cai fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 113978884ef4SEddie Cai } 114078884ef4SEddie Cai 114178884ef4SEddie Cai fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 114278884ef4SEddie Cai } 114378884ef4SEddie Cai 114478884ef4SEddie Cai static bool parseOpts(void) { 114578884ef4SEddie Cai bool ret = false; 114678884ef4SEddie Cai bool chipOk = false; 114778884ef4SEddie Cai bool versionOk = false; 114878884ef4SEddie Cai bool code471Ok = true; 114978884ef4SEddie Cai bool code472Ok = true; 115078884ef4SEddie Cai bool loaderOk = false; 115178884ef4SEddie Cai bool outOk = false; 115278884ef4SEddie Cai char buf[MAX_LINE_LEN]; 115378884ef4SEddie Cai 115478884ef4SEddie Cai char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 115578884ef4SEddie Cai FILE* file; 115678884ef4SEddie Cai file = fopen(configPath, "r"); 115778884ef4SEddie Cai if (!file) { 115878884ef4SEddie Cai fprintf(stderr, "config (%s) not found!\n", configPath); 115978884ef4SEddie Cai if (configPath == (char*)DEF_CONFIG_FILE) { 116078884ef4SEddie Cai file = fopen(DEF_CONFIG_FILE, "w"); 116178884ef4SEddie Cai if (file) { 116232268622SAndreas Färber fprintf(stderr, "creating defconfig\n"); 116378884ef4SEddie Cai printOpts(file); 116478884ef4SEddie Cai } 116578884ef4SEddie Cai } 116678884ef4SEddie Cai goto end; 116778884ef4SEddie Cai } 116878884ef4SEddie Cai 116932268622SAndreas Färber printf("Starting to parse...\n"); 117078884ef4SEddie Cai 117178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 117278884ef4SEddie Cai goto end; 117378884ef4SEddie Cai } 117478884ef4SEddie Cai while(fscanf(file, "%s", buf) == 1) { 117578884ef4SEddie Cai if (!strcmp(buf, SEC_CHIP)) { 117678884ef4SEddie Cai chipOk = parseChip(file); 117778884ef4SEddie Cai if (!chipOk) { 117878884ef4SEddie Cai printf("parseChip failed!\n"); 117978884ef4SEddie Cai goto end; 118078884ef4SEddie Cai } 118178884ef4SEddie Cai } else if (!strcmp(buf, SEC_VERSION)) { 118278884ef4SEddie Cai versionOk = parseVersion(file); 118378884ef4SEddie Cai if (!versionOk) { 118478884ef4SEddie Cai printf("parseVersion failed!\n"); 118578884ef4SEddie Cai goto end; 118678884ef4SEddie Cai } 118778884ef4SEddie Cai } else if (!strcmp(buf, SEC_471)) { 118878884ef4SEddie Cai code471Ok = parse471(file); 118978884ef4SEddie Cai if (!code471Ok) { 119078884ef4SEddie Cai printf("parse471 failed!\n"); 119178884ef4SEddie Cai goto end; 119278884ef4SEddie Cai } 119378884ef4SEddie Cai } else if (!strcmp(buf, SEC_472)) { 119478884ef4SEddie Cai code472Ok = parse472(file); 119578884ef4SEddie Cai if (!code472Ok) { 119678884ef4SEddie Cai printf("parse472 failed!\n"); 119778884ef4SEddie Cai goto end; 119878884ef4SEddie Cai } 119978884ef4SEddie Cai } else if (!strcmp(buf, SEC_LOADER)) { 120078884ef4SEddie Cai loaderOk = parseLoader(file); 120178884ef4SEddie Cai if (!loaderOk) { 120278884ef4SEddie Cai printf("parseLoader failed!\n"); 120378884ef4SEddie Cai goto end; 120478884ef4SEddie Cai } 120578884ef4SEddie Cai } else if (!strcmp(buf, SEC_OUT)) { 120678884ef4SEddie Cai outOk = parseOut(file); 120778884ef4SEddie Cai if (!outOk) { 120878884ef4SEddie Cai printf("parseOut failed!\n"); 120978884ef4SEddie Cai goto end; 121078884ef4SEddie Cai } 121178884ef4SEddie Cai } else if (buf[0] == '#') { 121278884ef4SEddie Cai continue; 121378884ef4SEddie Cai } else { 121478884ef4SEddie Cai printf("unknown sec: %s!\n", buf); 121578884ef4SEddie Cai goto end; 121678884ef4SEddie Cai } 121778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 121878884ef4SEddie Cai goto end; 121978884ef4SEddie Cai } 122078884ef4SEddie Cai } 122178884ef4SEddie Cai 122278884ef4SEddie Cai if (chipOk && versionOk && code471Ok && code472Ok 122378884ef4SEddie Cai && loaderOk && outOk) 122478884ef4SEddie Cai ret = true; 122578884ef4SEddie Cai end: 122678884ef4SEddie Cai if (file) 122778884ef4SEddie Cai fclose(file); 122878884ef4SEddie Cai return ret; 122978884ef4SEddie Cai } 123078884ef4SEddie Cai 123178884ef4SEddie Cai bool initOpts(void) { 123278884ef4SEddie Cai //set default opts 123378884ef4SEddie Cai gOpts.major = DEF_MAJOR; 123478884ef4SEddie Cai gOpts.minor = DEF_MINOR; 123578884ef4SEddie Cai strcpy(gOpts.chip, DEF_CHIP); 123678884ef4SEddie Cai gOpts.code471Sleep = DEF_CODE471_SLEEP; 123778884ef4SEddie Cai gOpts.code472Sleep = DEF_CODE472_SLEEP; 123878884ef4SEddie Cai gOpts.code471Num = DEF_CODE471_NUM; 123978884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 124078884ef4SEddie Cai strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 124178884ef4SEddie Cai gOpts.code472Num = DEF_CODE472_NUM; 124278884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 124378884ef4SEddie Cai strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 124478884ef4SEddie Cai gOpts.loaderNum = DEF_LOADER_NUM; 124578884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 124678884ef4SEddie Cai strcpy(gOpts.loader[0].name, DEF_LOADER0); 124778884ef4SEddie Cai strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 124878884ef4SEddie Cai strcpy(gOpts.loader[1].name, DEF_LOADER1); 124978884ef4SEddie Cai strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 125078884ef4SEddie Cai strcpy(gOpts.outPath, DEF_OUT_PATH); 125178884ef4SEddie Cai 125278884ef4SEddie Cai return parseOpts(); 125378884ef4SEddie Cai } 125478884ef4SEddie Cai 125578884ef4SEddie Cai /************merge code****************/ 125678884ef4SEddie Cai 125778884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) { 125878884ef4SEddie Cai uint8_t tmp[2] = {0}; 125978884ef4SEddie Cai int i; 126078884ef4SEddie Cai uint32_t ret; 126178884ef4SEddie Cai //if (value > 0xFFFF) { 126278884ef4SEddie Cai // return 0; 126378884ef4SEddie Cai //} 126478884ef4SEddie Cai for(i=0; i < 2; i++) { 126578884ef4SEddie Cai tmp[i] = (((value/10)%10)<<4) | (value%10); 126678884ef4SEddie Cai value /= 100; 126778884ef4SEddie Cai } 126878884ef4SEddie Cai ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 126978884ef4SEddie Cai 127078884ef4SEddie Cai printf("ret: %x\n",ret); 127178884ef4SEddie Cai return ret&0xFF; 127278884ef4SEddie Cai } 127378884ef4SEddie Cai 127478884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len) 127578884ef4SEddie Cai { 127678884ef4SEddie Cai int i; 127778884ef4SEddie Cai for (i = 0; i < len; i++) { 127878884ef4SEddie Cai wide[i] = (uint16_t) str[i]; 127978884ef4SEddie Cai } 128078884ef4SEddie Cai wide[len] = 0; 128178884ef4SEddie Cai } 128278884ef4SEddie Cai 128378884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) { 128478884ef4SEddie Cai char* end; 128578884ef4SEddie Cai char* start; 128678884ef4SEddie Cai int len; 128778884ef4SEddie Cai if (!path || !dst) 128878884ef4SEddie Cai return; 128978884ef4SEddie Cai start = strrchr(path, '/'); 129078884ef4SEddie Cai if (!start) 129178884ef4SEddie Cai start = path; 129278884ef4SEddie Cai else 129378884ef4SEddie Cai start++; 129478884ef4SEddie Cai end = strrchr(path, '.'); 1295641cfa16SEddie Cai if (!end || (end < start)) 129678884ef4SEddie Cai end = path + strlen(path); 129778884ef4SEddie Cai len = end - start; 129878884ef4SEddie Cai if (len >= MAX_NAME_LEN) 129978884ef4SEddie Cai len = MAX_NAME_LEN -1; 130078884ef4SEddie Cai str2wide(start, dst, len); 130178884ef4SEddie Cai 130278884ef4SEddie Cai 130378884ef4SEddie Cai char name[MAX_NAME_LEN]; 130478884ef4SEddie Cai memset(name, 0, sizeof(name)); 130578884ef4SEddie Cai memcpy(name, start, len); 130678884ef4SEddie Cai printf("path: %s, name: %s\n", path, name); 130778884ef4SEddie Cai 130878884ef4SEddie Cai } 130978884ef4SEddie Cai 131078884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) { 131178884ef4SEddie Cai struct stat st; 131278884ef4SEddie Cai if(stat(path, &st) < 0) 131378884ef4SEddie Cai return false; 131478884ef4SEddie Cai *size = st.st_size; 131578884ef4SEddie Cai printf("path: %s, size: %d\n", path, *size); 131678884ef4SEddie Cai return true; 131778884ef4SEddie Cai } 131878884ef4SEddie Cai 131978884ef4SEddie Cai static inline rk_time getTime(void) { 132078884ef4SEddie Cai rk_time rkTime; 132178884ef4SEddie Cai 132278884ef4SEddie Cai struct tm *tm; 132378884ef4SEddie Cai time_t tt = time(NULL); 132478884ef4SEddie Cai tm = localtime(&tt); 132578884ef4SEddie Cai rkTime.year = tm->tm_year + 1900; 132678884ef4SEddie Cai rkTime.month = tm->tm_mon + 1; 132778884ef4SEddie Cai rkTime.day = tm->tm_mday; 132878884ef4SEddie Cai rkTime.hour = tm->tm_hour; 132978884ef4SEddie Cai rkTime.minute = tm->tm_min; 133078884ef4SEddie Cai rkTime.second = tm->tm_sec; 133178884ef4SEddie Cai printf("%d-%d-%d %02d:%02d:%02d\n", 133278884ef4SEddie Cai rkTime.year, rkTime.month, rkTime.day, 133378884ef4SEddie Cai rkTime.hour, rkTime.minute, rkTime.second); 133478884ef4SEddie Cai return rkTime; 133578884ef4SEddie Cai } 133678884ef4SEddie Cai 133778884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) { 133878884ef4SEddie Cai bool ret = false; 133978884ef4SEddie Cai uint32_t size = 0, fixSize = 0; 134078884ef4SEddie Cai uint8_t* buf; 134178884ef4SEddie Cai 134278884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 134378884ef4SEddie Cai if (!inFile) 134478884ef4SEddie Cai goto end; 134578884ef4SEddie Cai 134678884ef4SEddie Cai if (!getFileSize(path, &size)) 134778884ef4SEddie Cai goto end; 134878884ef4SEddie Cai if (fix) { 134978884ef4SEddie Cai fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 135078884ef4SEddie Cai uint32_t tmp = fixSize % ENTRY_ALIGN; 135178884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 135278884ef4SEddie Cai fixSize +=tmp; 135378884ef4SEddie Cai memset(gBuf, 0, fixSize); 135478884ef4SEddie Cai } else { 135578884ef4SEddie Cai memset(gBuf, 0, size+ENTRY_ALIGN); 135678884ef4SEddie Cai } 135778884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 135878884ef4SEddie Cai goto end; 135978884ef4SEddie Cai 136078884ef4SEddie Cai if (fix) { 136178884ef4SEddie Cai 136278884ef4SEddie Cai buf = gBuf; 136378884ef4SEddie Cai size = fixSize; 136478884ef4SEddie Cai while(1) { 136578884ef4SEddie Cai P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 136678884ef4SEddie Cai buf += SMALL_PACKET; 136778884ef4SEddie Cai if (fixSize <= SMALL_PACKET) 136878884ef4SEddie Cai break; 136978884ef4SEddie Cai fixSize -= SMALL_PACKET; 137078884ef4SEddie Cai } 137178884ef4SEddie Cai } else { 137278884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 137378884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 137478884ef4SEddie Cai size +=tmp; 137578884ef4SEddie Cai P_RC4(gBuf, size); 137678884ef4SEddie Cai } 137778884ef4SEddie Cai 137878884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 137978884ef4SEddie Cai goto end; 138078884ef4SEddie Cai ret = true; 138178884ef4SEddie Cai end: 138278884ef4SEddie Cai if (inFile) 138378884ef4SEddie Cai fclose(inFile); 138478884ef4SEddie Cai if (!ret) 138532268622SAndreas Färber printf("writing entry (%s) failed\n", path); 138678884ef4SEddie Cai return ret; 138778884ef4SEddie Cai } 138878884ef4SEddie Cai 138978884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 139078884ef4SEddie Cai uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 139178884ef4SEddie Cai uint32_t size; 139278884ef4SEddie Cai rk_boot_entry entry; 139378884ef4SEddie Cai 139432268622SAndreas Färber printf("writing: %s\n", path); 1395641cfa16SEddie Cai memset(&entry, 0, sizeof(rk_boot_entry)); 139678884ef4SEddie Cai getName(fixName ? fixName: path, entry.name); 139778884ef4SEddie Cai entry.size = sizeof(rk_boot_entry); 139878884ef4SEddie Cai entry.type = type; 139978884ef4SEddie Cai entry.dataOffset = *offset; 140078884ef4SEddie Cai if (!getFileSize(path, &size)) { 140132268622SAndreas Färber printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path); 140278884ef4SEddie Cai return false; 140378884ef4SEddie Cai } 140478884ef4SEddie Cai if (fix) 140578884ef4SEddie Cai size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 140678884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 140778884ef4SEddie Cai size += tmp ? (ENTRY_ALIGN - tmp): 0; 140832268622SAndreas Färber printf("alignment size: %d\n", size); 140978884ef4SEddie Cai entry.dataSize = size; 141078884ef4SEddie Cai entry.dataDelay = delay; 141178884ef4SEddie Cai *offset += size; 141278884ef4SEddie Cai fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 141378884ef4SEddie Cai return true; 141478884ef4SEddie Cai } 141578884ef4SEddie Cai 141678884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) { 141778884ef4SEddie Cai char buffer[5]; 141878884ef4SEddie Cai memset(buffer, 0, sizeof(buffer)); 141978884ef4SEddie Cai snprintf(buffer, sizeof(buffer), "%s", chip); 142078884ef4SEddie Cai return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 142178884ef4SEddie Cai } 142278884ef4SEddie Cai 142378884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) { 142478884ef4SEddie Cai printf("chip: %s\n", chip); 142578884ef4SEddie Cai int chipType = RKNONE_DEVICE; 142678884ef4SEddie Cai if(!chip) { 142778884ef4SEddie Cai goto end; 142878884ef4SEddie Cai } 142978884ef4SEddie Cai if (!strcmp(chip, CHIP_RK28)) { 143078884ef4SEddie Cai chipType = RK28_DEVICE; 143178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK28)) { 143278884ef4SEddie Cai chipType = RK28_DEVICE; 143378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK281X)) { 143478884ef4SEddie Cai chipType = RK281X_DEVICE; 143578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKPANDA)) { 143678884ef4SEddie Cai chipType = RKPANDA_DEVICE; 143778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK27)) { 143878884ef4SEddie Cai chipType = RK27_DEVICE; 143978884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKNANO)) { 144078884ef4SEddie Cai chipType = RKNANO_DEVICE; 144178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKSMART)) { 144278884ef4SEddie Cai chipType = RKSMART_DEVICE; 144378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCROWN)) { 144478884ef4SEddie Cai chipType = RKCROWN_DEVICE; 144578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 144678884ef4SEddie Cai chipType = RKCAYMAN_DEVICE; 144778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK29)) { 144878884ef4SEddie Cai chipType = RK29_DEVICE; 144978884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK292X)) { 145078884ef4SEddie Cai chipType = RK292X_DEVICE; 145178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30)) { 145278884ef4SEddie Cai chipType = RK30_DEVICE; 145378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30B)) { 145478884ef4SEddie Cai chipType = RK30B_DEVICE; 145578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK31)) { 145678884ef4SEddie Cai chipType = RK31_DEVICE; 145778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK32)) { 145878884ef4SEddie Cai chipType = RK32_DEVICE; 145978884ef4SEddie Cai } else { 146078884ef4SEddie Cai chipType = convertChipType(chip + 2); 146178884ef4SEddie Cai } 146278884ef4SEddie Cai 146378884ef4SEddie Cai end: 146478884ef4SEddie Cai printf("type: 0x%x\n", chipType); 146578884ef4SEddie Cai if (chipType == RKNONE_DEVICE) { 146632268622SAndreas Färber printf("chip type not supported!\n"); 146778884ef4SEddie Cai } 146878884ef4SEddie Cai return chipType; 146978884ef4SEddie Cai } 147078884ef4SEddie Cai 147178884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) { 147278884ef4SEddie Cai memset(hdr, 0, sizeof(rk_boot_header)); 147378884ef4SEddie Cai hdr->tag = TAG; 147478884ef4SEddie Cai hdr->size = sizeof(rk_boot_header); 147578884ef4SEddie Cai hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 147678884ef4SEddie Cai hdr->mergerVersion = MERGER_VERSION; 147778884ef4SEddie Cai hdr->releaseTime = getTime(); 147878884ef4SEddie Cai hdr->chipType = getChipType(gOpts.chip); 147978884ef4SEddie Cai 148078884ef4SEddie Cai hdr->code471Num = gOpts.code471Num; 148178884ef4SEddie Cai hdr->code471Offset = sizeof(rk_boot_header); 148278884ef4SEddie Cai hdr->code471Size = sizeof(rk_boot_entry); 148378884ef4SEddie Cai 148478884ef4SEddie Cai hdr->code472Num = gOpts.code472Num; 148578884ef4SEddie Cai hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 148678884ef4SEddie Cai hdr->code472Size = sizeof(rk_boot_entry); 148778884ef4SEddie Cai 148878884ef4SEddie Cai hdr->loaderNum = gOpts.loaderNum; 148978884ef4SEddie Cai hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 149078884ef4SEddie Cai hdr->loaderSize = sizeof(rk_boot_entry); 149178884ef4SEddie Cai #ifndef USE_P_RC4 149278884ef4SEddie Cai hdr->rc4Flag = 1; 149378884ef4SEddie Cai #endif 149478884ef4SEddie Cai } 149578884ef4SEddie Cai 149678884ef4SEddie Cai static inline uint32_t getCrc(const char* path) { 149778884ef4SEddie Cai uint32_t size = 0; 149878884ef4SEddie Cai uint32_t crc = 0; 149978884ef4SEddie Cai 150078884ef4SEddie Cai FILE* file = fopen(path, "rb"); 150178884ef4SEddie Cai getFileSize(path, &size); 150278884ef4SEddie Cai if (!file) 150378884ef4SEddie Cai goto end; 150478884ef4SEddie Cai if (!fread(gBuf, size, 1, file)) 150578884ef4SEddie Cai goto end; 150678884ef4SEddie Cai crc = CRC_32(gBuf, size); 150778884ef4SEddie Cai printf("crc: 0x%08x\n", crc); 150878884ef4SEddie Cai end: 150978884ef4SEddie Cai if (file) 151078884ef4SEddie Cai fclose(file); 151178884ef4SEddie Cai return crc; 151278884ef4SEddie Cai } 151378884ef4SEddie Cai 151478884ef4SEddie Cai bool mergeBoot(void) { 151578884ef4SEddie Cai uint32_t dataOffset; 151678884ef4SEddie Cai bool ret = false; 151778884ef4SEddie Cai int i; 151878884ef4SEddie Cai FILE* outFile; 151978884ef4SEddie Cai uint32_t crc; 152078884ef4SEddie Cai rk_boot_header hdr; 152178884ef4SEddie Cai 152278884ef4SEddie Cai if (!initOpts()) 152378884ef4SEddie Cai return false; 152478884ef4SEddie Cai { 152578884ef4SEddie Cai char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 152678884ef4SEddie Cai char version[MAX_LINE_LEN]; 152778884ef4SEddie Cai snprintf(version, sizeof(version), "%s", gSubfix); 152878884ef4SEddie Cai if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 152978884ef4SEddie Cai subfix[0] = '\0'; 153078884ef4SEddie Cai } 153178884ef4SEddie Cai strcat(gOpts.outPath, version); 153278884ef4SEddie Cai printf("fix opt: %s\n", gOpts.outPath); 153378884ef4SEddie Cai } 153478884ef4SEddie Cai 153578884ef4SEddie Cai printf("---------------\nUSING CONFIG:\n"); 153678884ef4SEddie Cai printOpts(stdout); 153778884ef4SEddie Cai printf("---------------\n\n"); 153878884ef4SEddie Cai 153978884ef4SEddie Cai 154078884ef4SEddie Cai outFile = fopen(gOpts.outPath, "wb+"); 154178884ef4SEddie Cai if (!outFile) { 154232268622SAndreas Färber printf("Opening output file (%s) failed\n", gOpts.outPath); 154378884ef4SEddie Cai goto end; 154478884ef4SEddie Cai } 154578884ef4SEddie Cai 154678884ef4SEddie Cai getBoothdr(&hdr); 154732268622SAndreas Färber printf("Writing header...\n"); 154878884ef4SEddie Cai fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 154978884ef4SEddie Cai 155078884ef4SEddie Cai dataOffset = sizeof(rk_boot_header) + 155178884ef4SEddie Cai (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 155278884ef4SEddie Cai sizeof(rk_boot_entry); 155378884ef4SEddie Cai 155432268622SAndreas Färber printf("Writing code 471 entry...\n"); 155578884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 155678884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 155778884ef4SEddie Cai &dataOffset, NULL, false)) 155878884ef4SEddie Cai goto end; 155978884ef4SEddie Cai } 156032268622SAndreas Färber printf("Writing code 472 entry...\n"); 156178884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 156278884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 156378884ef4SEddie Cai &dataOffset, NULL, false)) 156478884ef4SEddie Cai goto end; 156578884ef4SEddie Cai } 156632268622SAndreas Färber printf("Writing loader entry...\n"); 156778884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 156878884ef4SEddie Cai if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 156978884ef4SEddie Cai &dataOffset, gOpts.loader[i].name, true)) 157078884ef4SEddie Cai goto end; 157178884ef4SEddie Cai } 157278884ef4SEddie Cai 157332268622SAndreas Färber printf("Writing code 471...\n"); 157478884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 157578884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 157678884ef4SEddie Cai goto end; 157778884ef4SEddie Cai } 157832268622SAndreas Färber printf("Writing code 472...\n"); 157978884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 158078884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 158178884ef4SEddie Cai goto end; 158278884ef4SEddie Cai } 158332268622SAndreas Färber printf("Writing loader...\n"); 158478884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 158578884ef4SEddie Cai if (!writeFile(outFile, gOpts.loader[i].path, true)) 158678884ef4SEddie Cai goto end; 158778884ef4SEddie Cai } 158878884ef4SEddie Cai fflush(outFile); 158978884ef4SEddie Cai 159032268622SAndreas Färber printf("Writing crc...\n"); 159178884ef4SEddie Cai crc = getCrc(gOpts.outPath); 159278884ef4SEddie Cai if (!fwrite(&crc, sizeof(crc), 1, outFile)) 159378884ef4SEddie Cai goto end; 159432268622SAndreas Färber printf("Done.\n"); 159578884ef4SEddie Cai ret = true; 159678884ef4SEddie Cai end: 159778884ef4SEddie Cai if (outFile) 159878884ef4SEddie Cai fclose(outFile); 159978884ef4SEddie Cai return ret; 160078884ef4SEddie Cai } 160178884ef4SEddie Cai 160278884ef4SEddie Cai /************merge code end************/ 160378884ef4SEddie Cai /************unpack code***************/ 160478884ef4SEddie Cai 160578884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len) 160678884ef4SEddie Cai { 160778884ef4SEddie Cai int i; 160878884ef4SEddie Cai for (i = 0; i < len; i++) { 160978884ef4SEddie Cai str[i] = (char) (wide[i] & 0xFF); 161078884ef4SEddie Cai } 161178884ef4SEddie Cai str[len] = 0; 161278884ef4SEddie Cai } 161378884ef4SEddie Cai 161478884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name, 161578884ef4SEddie Cai FILE* inFile) { 161678884ef4SEddie Cai bool ret = false; 161778884ef4SEddie Cai int size, i; 161878884ef4SEddie Cai FILE* outFile = fopen(name, "wb+"); 161978884ef4SEddie Cai if (!outFile) 162078884ef4SEddie Cai goto end; 162132268622SAndreas Färber printf("unpacking entry (%s)\n", name); 162278884ef4SEddie Cai fseek(inFile, entry->dataOffset, SEEK_SET); 162378884ef4SEddie Cai size = entry->dataSize; 162478884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 162578884ef4SEddie Cai goto end; 162678884ef4SEddie Cai if (entry->type == ENTRY_LOADER) { 162778884ef4SEddie Cai for(i=0; i<size/SMALL_PACKET; i++) 162878884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 162978884ef4SEddie Cai if (size % SMALL_PACKET) 163078884ef4SEddie Cai { 163178884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 163278884ef4SEddie Cai } 163378884ef4SEddie Cai } else { 163478884ef4SEddie Cai P_RC4(gBuf, size); 163578884ef4SEddie Cai } 163678884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 163778884ef4SEddie Cai goto end; 163878884ef4SEddie Cai ret = true; 163978884ef4SEddie Cai end: 164078884ef4SEddie Cai if (outFile) 164178884ef4SEddie Cai fclose(outFile); 164278884ef4SEddie Cai return ret; 164378884ef4SEddie Cai } 164478884ef4SEddie Cai 164578884ef4SEddie Cai bool unpackBoot(char* path) { 164678884ef4SEddie Cai bool ret = false; 164778884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 164878884ef4SEddie Cai int entryNum, i; 164978884ef4SEddie Cai char name[MAX_NAME_LEN]; 165078884ef4SEddie Cai rk_boot_entry* entrys; 165178884ef4SEddie Cai if (!inFile) { 165278884ef4SEddie Cai fprintf(stderr, "loader (%s) not found\n", path); 165378884ef4SEddie Cai goto end; 165478884ef4SEddie Cai } 165578884ef4SEddie Cai 165678884ef4SEddie Cai rk_boot_header hdr; 165778884ef4SEddie Cai if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 165832268622SAndreas Färber fprintf(stderr, "reading header failed\n"); 165978884ef4SEddie Cai goto end; 166078884ef4SEddie Cai } 166178884ef4SEddie Cai printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 166278884ef4SEddie Cai entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 166378884ef4SEddie Cai entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 166478884ef4SEddie Cai if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 166532268622SAndreas Färber fprintf(stderr, "reading data failed\n"); 166678884ef4SEddie Cai goto end; 166778884ef4SEddie Cai } 166878884ef4SEddie Cai 166978884ef4SEddie Cai printf("entry num: %d\n", entryNum); 167078884ef4SEddie Cai for (i=0; i<entryNum; i++) { 167178884ef4SEddie Cai wide2str(entrys[i].name, name, MAX_NAME_LEN); 167278884ef4SEddie Cai 167378884ef4SEddie Cai printf("entry: t=%d, name=%s, off=%d, size=%d\n", 167478884ef4SEddie Cai entrys[i].type, name, entrys[i].dataOffset, 167578884ef4SEddie Cai entrys[i].dataSize); 167678884ef4SEddie Cai if (!unpackEntry(entrys + i, name, inFile)) { 167732268622SAndreas Färber fprintf(stderr, "unpacking entry (%s) failed\n", name); 167878884ef4SEddie Cai goto end; 167978884ef4SEddie Cai } 168078884ef4SEddie Cai } 168178884ef4SEddie Cai printf("done\n"); 168278884ef4SEddie Cai ret = true; 168378884ef4SEddie Cai end: 168478884ef4SEddie Cai if (inFile) 168578884ef4SEddie Cai fclose(inFile); 168678884ef4SEddie Cai return ret; 168778884ef4SEddie Cai } 168878884ef4SEddie Cai 168976af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 169076af099aSliuyi { 169176af099aSliuyi if (!check_device_type(dev, RKUSB_MASKROM)) 169276af099aSliuyi return false; 169376af099aSliuyi CRKImage *pImage = NULL; 169476af099aSliuyi CRKBoot *pBoot = NULL; 169576af099aSliuyi bool bRet, bSuccess = false; 169676af099aSliuyi int iRet; 169776af099aSliuyi 169876af099aSliuyi pImage = new CRKImage(szLoader, bRet); 169976af099aSliuyi if (!bRet){ 170076af099aSliuyi ERROR_COLOR_ATTR; 170132268622SAndreas Färber printf("Opening loader failed, exiting download boot!"); 170276af099aSliuyi NORMAL_COLOR_ATTR; 170376af099aSliuyi printf("\r\n"); 170476af099aSliuyi return bSuccess; 170576af099aSliuyi } else { 170676af099aSliuyi pBoot = (CRKBoot *)pImage->m_bootObject; 170776af099aSliuyi CRKComm *pComm = NULL; 170876af099aSliuyi CRKDevice *pDevice = NULL; 170976af099aSliuyi 171076af099aSliuyi dev.emDeviceType = pBoot->SupportDevice; 171176af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 171276af099aSliuyi if (!bRet) { 171376af099aSliuyi if (pImage) 171476af099aSliuyi delete pImage; 171576af099aSliuyi ERROR_COLOR_ATTR; 171676af099aSliuyi printf("Creating Comm Object failed!"); 171776af099aSliuyi NORMAL_COLOR_ATTR; 171876af099aSliuyi printf("\r\n"); 171976af099aSliuyi return bSuccess; 172076af099aSliuyi } 172176af099aSliuyi 172276af099aSliuyi pDevice = new CRKDevice(dev); 172376af099aSliuyi if (!pDevice) { 172476af099aSliuyi if (pImage) 172576af099aSliuyi delete pImage; 172676af099aSliuyi if (pComm) 172776af099aSliuyi delete pComm; 172876af099aSliuyi ERROR_COLOR_ATTR; 172976af099aSliuyi printf("Creating device object failed!"); 173076af099aSliuyi NORMAL_COLOR_ATTR; 173176af099aSliuyi printf("\r\n"); 173276af099aSliuyi return bSuccess; 173376af099aSliuyi } 173476af099aSliuyi 173576af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 173632268622SAndreas Färber printf("Downloading bootloader...\r\n"); 173776af099aSliuyi iRet = pDevice->DownloadBoot(); 173876af099aSliuyi 173976af099aSliuyi CURSOR_MOVEUP_LINE(1); 174076af099aSliuyi CURSOR_DEL_LINE; 174176af099aSliuyi if (iRet == 0) { 174276af099aSliuyi bSuccess = true; 174332268622SAndreas Färber printf("Downloading bootloader succeeded.\r\n"); 174476af099aSliuyi } 174576af099aSliuyi else 174632268622SAndreas Färber printf("Downloading bootloader failed!\r\n"); 174776af099aSliuyi 174876af099aSliuyi if (pImage) 174976af099aSliuyi delete pImage; 175076af099aSliuyi if(pDevice) 175176af099aSliuyi delete pDevice; 175276af099aSliuyi } 175376af099aSliuyi return bSuccess; 175476af099aSliuyi } 1755c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1756c30d921cSKever Yang { 1757c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 1758c30d921cSKever Yang return false; 1759c30d921cSKever Yang CRKImage *pImage = NULL; 1760c30d921cSKever Yang CRKBoot *pBoot = NULL; 1761c30d921cSKever Yang CRKComm *pComm = NULL; 1762c30d921cSKever Yang bool bRet, bSuccess = false; 1763c30d921cSKever Yang int iRet; 1764c30d921cSKever Yang char index; 1765c30d921cSKever Yang USHORT usFlashDataSec, usFlashBootSec; 1766c30d921cSKever Yang DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1767c30d921cSKever Yang char loaderCodeName[] = "FlashBoot"; 1768c30d921cSKever Yang char loaderDataName[] = "FlashData"; 1769c30d921cSKever Yang PBYTE loaderCodeBuffer = NULL; 1770c30d921cSKever Yang PBYTE loaderDataBuffer = NULL; 1771c30d921cSKever Yang PBYTE pIDBData = NULL; 1772c30d921cSKever Yang pImage = new CRKImage(szLoader, bRet); 1773c30d921cSKever Yang if (!bRet){ 1774c30d921cSKever Yang ERROR_COLOR_ATTR; 177532268622SAndreas Färber printf("Opening loader failed, exiting upgrade loader!"); 1776c30d921cSKever Yang NORMAL_COLOR_ATTR; 1777c30d921cSKever Yang printf("\r\n"); 1778c30d921cSKever Yang goto Exit_UpgradeLoader; 1779c30d921cSKever Yang } else { 1780c30d921cSKever Yang pBoot = (CRKBoot *)pImage->m_bootObject; 1781c30d921cSKever Yang dev.emDeviceType = pBoot->SupportDevice; 1782c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1783c30d921cSKever Yang if (!bRet) { 1784c30d921cSKever Yang ERROR_COLOR_ATTR; 1785c30d921cSKever Yang printf("Creating Comm Object failed!"); 1786c30d921cSKever Yang NORMAL_COLOR_ATTR; 1787c30d921cSKever Yang printf("\r\n"); 1788c30d921cSKever Yang goto Exit_UpgradeLoader; 1789c30d921cSKever Yang } 1790c30d921cSKever Yang 179132268622SAndreas Färber printf("Upgrading loader...\r\n"); 1792c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1793c30d921cSKever Yang if (index == -1) { 1794c30d921cSKever Yang if (g_pLogObject) { 179532268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__); 1796c30d921cSKever Yang } 1797c30d921cSKever Yang goto Exit_UpgradeLoader; 1798c30d921cSKever Yang } 1799c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1800c30d921cSKever Yang if (!bRet) { 1801c30d921cSKever Yang if (g_pLogObject) { 180232268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__); 1803c30d921cSKever Yang } 1804c30d921cSKever Yang goto Exit_UpgradeLoader; 1805c30d921cSKever Yang } 1806c30d921cSKever Yang 1807c30d921cSKever Yang loaderCodeBuffer = new BYTE[dwLoaderSize]; 1808c30d921cSKever Yang memset(loaderCodeBuffer, 0, dwLoaderSize); 1809c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1810c30d921cSKever Yang if (g_pLogObject) { 181132268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__); 1812c30d921cSKever Yang } 1813c30d921cSKever Yang goto Exit_UpgradeLoader; 1814c30d921cSKever Yang } 1815c30d921cSKever Yang 1816c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1817c30d921cSKever Yang if (index == -1) { 1818c30d921cSKever Yang if (g_pLogObject) { 181932268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__); 1820c30d921cSKever Yang } 1821c30d921cSKever Yang delete []loaderCodeBuffer; 1822c30d921cSKever Yang return -4; 1823c30d921cSKever Yang } 1824c30d921cSKever Yang 1825c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1826c30d921cSKever Yang if (!bRet) { 1827c30d921cSKever Yang if (g_pLogObject) { 182832268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__); 1829c30d921cSKever Yang } 1830c30d921cSKever Yang goto Exit_UpgradeLoader; 1831c30d921cSKever Yang } 1832c30d921cSKever Yang 1833c30d921cSKever Yang loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1834c30d921cSKever Yang memset(loaderDataBuffer, 0, dwLoaderDataSize); 1835c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1836c30d921cSKever Yang if (g_pLogObject) { 183732268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__); 1838c30d921cSKever Yang } 1839c30d921cSKever Yang goto Exit_UpgradeLoader; 1840c30d921cSKever Yang } 1841c30d921cSKever Yang 1842c30d921cSKever Yang usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1843c30d921cSKever Yang usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1844c30d921cSKever Yang dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1845c30d921cSKever Yang pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1846c30d921cSKever Yang if (!pIDBData) { 1847c30d921cSKever Yang ERROR_COLOR_ATTR; 184832268622SAndreas Färber printf("Allocating memory failed!"); 1849c30d921cSKever Yang NORMAL_COLOR_ATTR; 1850c30d921cSKever Yang printf("\r\n"); 1851c30d921cSKever Yang goto Exit_UpgradeLoader; 1852c30d921cSKever Yang } 1853c30d921cSKever Yang memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1854b38fe5fcSliuyi iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag); 1855c30d921cSKever Yang if (iRet != 0) { 1856c30d921cSKever Yang ERROR_COLOR_ATTR; 185732268622SAndreas Färber printf("Making idblock failed!"); 1858c30d921cSKever Yang NORMAL_COLOR_ATTR; 1859c30d921cSKever Yang printf("\r\n"); 1860c30d921cSKever Yang goto Exit_UpgradeLoader; 1861c30d921cSKever Yang } 1862c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1863c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 1864c30d921cSKever Yang CURSOR_DEL_LINE; 1865c30d921cSKever Yang if (iRet == ERR_SUCCESS) { 1866b38fe5fcSliuyi //pComm->Reset_Usb_Device(); 1867c30d921cSKever Yang bSuccess = true; 186832268622SAndreas Färber printf("Upgrading loader succeeded.\r\n"); 1869c30d921cSKever Yang } else { 187032268622SAndreas Färber printf("Upgrading loader failed!\r\n"); 1871c30d921cSKever Yang goto Exit_UpgradeLoader; 1872c30d921cSKever Yang } 1873c30d921cSKever Yang } 1874c30d921cSKever Yang Exit_UpgradeLoader: 1875c30d921cSKever Yang if (pImage) 1876c30d921cSKever Yang delete pImage; 1877c30d921cSKever Yang if (pComm) 1878c30d921cSKever Yang delete pComm; 1879c30d921cSKever Yang if (loaderCodeBuffer) 1880c30d921cSKever Yang delete []loaderCodeBuffer; 1881c30d921cSKever Yang if (loaderDataBuffer) 1882c30d921cSKever Yang delete []loaderDataBuffer; 1883c30d921cSKever Yang if (pIDBData) 1884c30d921cSKever Yang delete []pIDBData; 1885c30d921cSKever Yang return bSuccess; 1886c30d921cSKever Yang } 1887c30d921cSKever Yang 188876af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 188976af099aSliuyi { 189076af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 189176af099aSliuyi return false; 189276af099aSliuyi CRKImage *pImage = NULL; 189376af099aSliuyi bool bRet, bSuccess = false; 189476af099aSliuyi int iRet; 189576af099aSliuyi CRKScan *pScan = NULL; 189676af099aSliuyi pScan = new CRKScan(); 189776af099aSliuyi pScan->SetVidPid(); 189876af099aSliuyi 189976af099aSliuyi CRKComm *pComm = NULL; 190076af099aSliuyi CRKDevice *pDevice = NULL; 190176af099aSliuyi 190276af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 190376af099aSliuyi if (!bRet) { 190476af099aSliuyi if (pScan) 190576af099aSliuyi delete pScan; 190676af099aSliuyi ERROR_COLOR_ATTR; 190776af099aSliuyi printf("Creating Comm Object failed!"); 190876af099aSliuyi NORMAL_COLOR_ATTR; 190976af099aSliuyi printf("\r\n"); 191076af099aSliuyi return bSuccess; 191176af099aSliuyi } 191276af099aSliuyi 191376af099aSliuyi pDevice = new CRKDevice(dev); 191476af099aSliuyi if (!pDevice) { 191576af099aSliuyi if (pComm) 191676af099aSliuyi delete pComm; 191776af099aSliuyi if (pScan) 191876af099aSliuyi delete pScan; 191976af099aSliuyi ERROR_COLOR_ATTR; 192076af099aSliuyi printf("Creating device object failed!"); 192176af099aSliuyi NORMAL_COLOR_ATTR; 192276af099aSliuyi printf("\r\n"); 192376af099aSliuyi return bSuccess; 192476af099aSliuyi } 192576af099aSliuyi 192676af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 192776af099aSliuyi pDevice->CallBackPointer = ProgressInfoProc; 192876af099aSliuyi 192932268622SAndreas Färber printf("Starting to erase flash...\r\n"); 193076af099aSliuyi iRet = pDevice->EraseAllBlocks(); 193176af099aSliuyi if (pDevice) 193276af099aSliuyi delete pDevice; 193376af099aSliuyi 193476af099aSliuyi if (iRet == 0) { 193576af099aSliuyi if (pScan) { 193676af099aSliuyi pScan->SetVidPid(); 193776af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 193876af099aSliuyi delete pScan; 193976af099aSliuyi } 194076af099aSliuyi CURSOR_MOVEUP_LINE(1); 194176af099aSliuyi CURSOR_DEL_LINE; 194276af099aSliuyi bSuccess = true; 194332268622SAndreas Färber printf("Erasing flash complete.\r\n"); 194476af099aSliuyi } 194576af099aSliuyi 194676af099aSliuyi return bSuccess; 194776af099aSliuyi } 194876af099aSliuyi 194976af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev) 195076af099aSliuyi { 195176af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 195276af099aSliuyi return false; 195376af099aSliuyi CRKUsbComm *pComm = NULL; 195476af099aSliuyi bool bRet, bSuccess = false; 195576af099aSliuyi int iRet; 195676af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 195776af099aSliuyi if (bRet) { 195876af099aSliuyi iRet = pComm->RKU_TestDeviceReady(); 195976af099aSliuyi if (iRet != ERR_SUCCESS) { 196076af099aSliuyi if (g_pLogObject) 196176af099aSliuyi g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 196232268622SAndreas Färber printf("Test Device failed!\r\n"); 196376af099aSliuyi } else { 196476af099aSliuyi bSuccess = true; 196576af099aSliuyi printf("Test Device OK.\r\n"); 196676af099aSliuyi } 196776af099aSliuyi } else { 196832268622SAndreas Färber printf("Test Device quit, creating comm object failed!\r\n"); 196976af099aSliuyi } 197076af099aSliuyi if (pComm) { 197176af099aSliuyi delete pComm; 197276af099aSliuyi pComm = NULL; 197376af099aSliuyi } 197476af099aSliuyi return bSuccess; 197576af099aSliuyi } 197676af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 197776af099aSliuyi { 197876af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 197976af099aSliuyi return false; 198076af099aSliuyi CRKUsbComm *pComm = NULL; 198176af099aSliuyi bool bRet, bSuccess = false; 198276af099aSliuyi int iRet; 198376af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 198476af099aSliuyi if (bRet) { 198576af099aSliuyi iRet = pComm->RKU_ResetDevice(subCode); 198676af099aSliuyi if (iRet != ERR_SUCCESS) { 198776af099aSliuyi if (g_pLogObject) 198876af099aSliuyi g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 198932268622SAndreas Färber printf("Reset Device failed!\r\n"); 199076af099aSliuyi } else { 199176af099aSliuyi bSuccess = true; 199276af099aSliuyi printf("Reset Device OK.\r\n"); 199376af099aSliuyi } 199476af099aSliuyi } else { 199532268622SAndreas Färber printf("Reset Device quit, creating comm object failed!\r\n"); 199676af099aSliuyi } 199776af099aSliuyi if (pComm) { 199876af099aSliuyi delete pComm; 199976af099aSliuyi pComm = NULL; 200076af099aSliuyi } 200176af099aSliuyi return bSuccess; 200276af099aSliuyi } 200376af099aSliuyi 200476af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 200576af099aSliuyi { 200676af099aSliuyi CRKUsbComm *pComm = NULL; 200776af099aSliuyi bool bRet, bSuccess = false; 200876af099aSliuyi int iRet; 200976af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 201076af099aSliuyi return bSuccess; 201176af099aSliuyi 201276af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 201376af099aSliuyi if (bRet) { 201476af099aSliuyi BYTE flashID[5]; 201576af099aSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 201676af099aSliuyi if (iRet != ERR_SUCCESS) { 201776af099aSliuyi if (g_pLogObject) 201876af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 201932268622SAndreas Färber printf("Reading flash ID failed!\r\n"); 202076af099aSliuyi } else { 202176af099aSliuyi printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 202276af099aSliuyi bSuccess = true; 202376af099aSliuyi } 202476af099aSliuyi } else { 202532268622SAndreas Färber printf("Read Flash ID quit, creating comm object failed!\r\n"); 202676af099aSliuyi } 202776af099aSliuyi if (pComm) { 202876af099aSliuyi delete pComm; 202976af099aSliuyi pComm = NULL; 203076af099aSliuyi } 203176af099aSliuyi return bSuccess; 203276af099aSliuyi } 203376af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 203476af099aSliuyi { 203576af099aSliuyi CRKUsbComm *pComm = NULL; 203676af099aSliuyi bool bRet, bSuccess = false; 203776af099aSliuyi int iRet; 203876af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 203976af099aSliuyi return bSuccess; 204076af099aSliuyi 204176af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 204276af099aSliuyi if (bRet) { 204376af099aSliuyi STRUCT_FLASHINFO_CMD info; 204476af099aSliuyi UINT uiRead; 204576af099aSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 204676af099aSliuyi if (iRet != ERR_SUCCESS) { 204776af099aSliuyi if (g_pLogObject) 204876af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 204932268622SAndreas Färber printf("Read Flash Info failed!\r\n"); 205076af099aSliuyi } else { 205176af099aSliuyi printf("Flash Info:\r\n"); 205276af099aSliuyi if (info.bManufCode <= 7) { 205376af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 205476af099aSliuyi } 205576af099aSliuyi else 205676af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 205776af099aSliuyi 205876af099aSliuyi printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 205976af099aSliuyi printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 206076af099aSliuyi printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 206176af099aSliuyi printf("\tECC Bits: %d\r\n", info.bECCBits); 206276af099aSliuyi printf("\tAccess Time: %d\r\n", info.bAccessTime); 206376af099aSliuyi printf("\tFlash CS: "); 206476af099aSliuyi for(int i = 0; i < 8; i++) { 206576af099aSliuyi if( info.bFlashCS & (1 << i) ) 206676af099aSliuyi printf("Flash<%d> ", i); 206776af099aSliuyi } 206876af099aSliuyi printf("\r\n"); 206976af099aSliuyi bSuccess = true; 207076af099aSliuyi } 207176af099aSliuyi }else { 207232268622SAndreas Färber printf("Read Flash Info quit, creating comm object failed!\r\n"); 207376af099aSliuyi } 207476af099aSliuyi if (pComm) { 207576af099aSliuyi delete pComm; 207676af099aSliuyi pComm = NULL; 207776af099aSliuyi } 207876af099aSliuyi return bSuccess; 207976af099aSliuyi } 208076af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 208176af099aSliuyi { 208276af099aSliuyi CRKUsbComm *pComm = NULL; 208376af099aSliuyi bool bRet, bSuccess = false; 208476af099aSliuyi int iRet; 208576af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 208676af099aSliuyi return bSuccess; 208776af099aSliuyi 208876af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 208976af099aSliuyi if (bRet) { 209076af099aSliuyi BYTE chipInfo[16]; 209176af099aSliuyi iRet = pComm->RKU_ReadChipInfo(chipInfo); 209276af099aSliuyi if (iRet != ERR_SUCCESS) { 209376af099aSliuyi if (g_pLogObject) 209476af099aSliuyi g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 209532268622SAndreas Färber printf("Read Chip Info failed!\r\n"); 209676af099aSliuyi } else { 209776af099aSliuyi string strChipInfo; 209876af099aSliuyi g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 209976af099aSliuyi printf("Chip Info: %s\r\n", strChipInfo.c_str()); 210076af099aSliuyi bSuccess = true; 210176af099aSliuyi } 210276af099aSliuyi } else { 210332268622SAndreas Färber printf("Read Chip Info quit, creating comm object failed!\r\n"); 210476af099aSliuyi } 210576af099aSliuyi if (pComm) { 210676af099aSliuyi delete pComm; 210776af099aSliuyi pComm = NULL; 210876af099aSliuyi } 210976af099aSliuyi return bSuccess; 211076af099aSliuyi } 2111*6ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt) 2112*6ae612beSliuyi { 2113*6ae612beSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2114*6ae612beSliuyi return false; 2115*6ae612beSliuyi gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE); 2116*6ae612beSliuyi CRKUsbComm *pComm = NULL; 2117*6ae612beSliuyi bool bRet, bSuccess = false; 2118*6ae612beSliuyi int iRet; 2119*6ae612beSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2120*6ae612beSliuyi if (bRet) { 2121*6ae612beSliuyi iRet = pComm->RKU_ReadLBA( 0, 34, pGpt); 2122*6ae612beSliuyi if(ERR_SUCCESS == iRet) { 2123*6ae612beSliuyi if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 2124*6ae612beSliuyi if (g_pLogObject) 2125*6ae612beSliuyi g_pLogObject->Record("Error: invalid gpt signature"); 2126*6ae612beSliuyi printf("Invalid GPT signature!\r\n"); 2127*6ae612beSliuyi goto Exit_ReadGPT; 2128*6ae612beSliuyi } 2129*6ae612beSliuyi 2130*6ae612beSliuyi } else { 2131*6ae612beSliuyi if (g_pLogObject) 2132*6ae612beSliuyi g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 2133*6ae612beSliuyi printf("Read GPT failed!\r\n"); 2134*6ae612beSliuyi goto Exit_ReadGPT; 2135*6ae612beSliuyi } 2136*6ae612beSliuyi bSuccess = true; 2137*6ae612beSliuyi } 2138*6ae612beSliuyi Exit_ReadGPT: 2139*6ae612beSliuyi if (pComm) { 2140*6ae612beSliuyi delete pComm; 2141*6ae612beSliuyi pComm = NULL; 2142*6ae612beSliuyi } 2143*6ae612beSliuyi return bSuccess; 2144*6ae612beSliuyi } 214576af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 214676af099aSliuyi { 214776af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 214876af099aSliuyi return false; 214976af099aSliuyi CRKUsbComm *pComm = NULL; 215076af099aSliuyi FILE *file = NULL; 215176af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 215276af099aSliuyi int iRet; 215376af099aSliuyi UINT iTotalRead = 0,iRead = 0; 215476af099aSliuyi int nSectorSize = 512; 215576af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 215676af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 215776af099aSliuyi if (bRet) { 215876af099aSliuyi if(szFile) { 215976af099aSliuyi file = fopen(szFile, "wb+"); 216076af099aSliuyi if( !file ) { 216176af099aSliuyi printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 216276af099aSliuyi goto Exit_ReadLBA; 216376af099aSliuyi } 216476af099aSliuyi } 216576af099aSliuyi 216676af099aSliuyi while(uiLen > 0) { 216776af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 216876af099aSliuyi iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 216976af099aSliuyi iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 217076af099aSliuyi if(ERR_SUCCESS == iRet) { 217176af099aSliuyi uiLen -= iRead; 217276af099aSliuyi iTotalRead += iRead; 217376af099aSliuyi 217476af099aSliuyi if(szFile) { 217576af099aSliuyi fwrite(pBuf, 1, iRead * nSectorSize, file); 217676af099aSliuyi if (bFirst){ 217776af099aSliuyi if (iTotalRead >= 1024) 217832268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 217976af099aSliuyi else 218032268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 218176af099aSliuyi bFirst = false; 218276af099aSliuyi } else { 218376af099aSliuyi CURSOR_MOVEUP_LINE(1); 218476af099aSliuyi CURSOR_DEL_LINE; 218576af099aSliuyi if (iTotalRead >= 1024) 218632268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 218776af099aSliuyi else 218832268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 218976af099aSliuyi } 219076af099aSliuyi } 219176af099aSliuyi else 219276af099aSliuyi PrintData(pBuf, nSectorSize * iRead); 219376af099aSliuyi } else { 219476af099aSliuyi if (g_pLogObject) 219576af099aSliuyi g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 219676af099aSliuyi 219776af099aSliuyi printf("Read LBA failed!\r\n"); 219876af099aSliuyi goto Exit_ReadLBA; 219976af099aSliuyi } 220076af099aSliuyi } 220176af099aSliuyi bSuccess = true; 220276af099aSliuyi } else { 220332268622SAndreas Färber printf("Read LBA quit, creating comm object failed!\r\n"); 220476af099aSliuyi } 220576af099aSliuyi Exit_ReadLBA: 220676af099aSliuyi if (pComm) { 220776af099aSliuyi delete pComm; 220876af099aSliuyi pComm = NULL; 220976af099aSliuyi } 221076af099aSliuyi if (file) 221176af099aSliuyi fclose(file); 221276af099aSliuyi return bSuccess; 221376af099aSliuyi } 2214*6ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize) 2215*6ae612beSliuyi { 2216*6ae612beSliuyi UINT uiErase=2048*64; 2217*6ae612beSliuyi bool bSuccess = true; 2218*6ae612beSliuyi int iRet; 2219*6ae612beSliuyi while (uiSize) 2220*6ae612beSliuyi { 2221*6ae612beSliuyi if (uiSize>=uiErase) 2222*6ae612beSliuyi { 2223*6ae612beSliuyi iRet = pComm->RKU_EraseLBA(uiOffset,uiErase); 2224*6ae612beSliuyi uiSize -= uiErase; 2225*6ae612beSliuyi uiOffset += uiErase; 2226*6ae612beSliuyi } 2227*6ae612beSliuyi else 2228*6ae612beSliuyi { 2229*6ae612beSliuyi iRet = pComm->RKU_EraseLBA(uiOffset,uiSize); 2230*6ae612beSliuyi uiSize = 0; 2231*6ae612beSliuyi uiOffset += uiSize; 2232*6ae612beSliuyi } 2233*6ae612beSliuyi if (iRet!=ERR_SUCCESS) 2234*6ae612beSliuyi { 2235*6ae612beSliuyi if (g_pLogObject) 2236*6ae612beSliuyi { 2237*6ae612beSliuyi g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet); 2238*6ae612beSliuyi } 2239*6ae612beSliuyi bSuccess = false; 2240*6ae612beSliuyi break; 2241*6ae612beSliuyi } 2242*6ae612beSliuyi } 2243*6ae612beSliuyi return bSuccess; 2244*6ae612beSliuyi 2245*6ae612beSliuyi } 2246*6ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk) 2247*6ae612beSliuyi { 2248*6ae612beSliuyi UINT uiRead; 2249*6ae612beSliuyi uiRead = fread(&chunk, 1, sizeof(chunk_header), file); 2250*6ae612beSliuyi if (uiRead != sizeof(chunk_header)) { 2251*6ae612beSliuyi if (g_pLogObject) 2252*6ae612beSliuyi { 2253*6ae612beSliuyi g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno); 2254*6ae612beSliuyi } 2255*6ae612beSliuyi return false; 2256*6ae612beSliuyi } 2257*6ae612beSliuyi return true; 2258*6ae612beSliuyi } 2259*6ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize) 2260*6ae612beSliuyi { 2261*6ae612beSliuyi UINT uiRead; 2262*6ae612beSliuyi uiRead = fread(pBuf, 1, dwSize, file); 2263*6ae612beSliuyi if (uiRead!=dwSize) 2264*6ae612beSliuyi { 2265*6ae612beSliuyi if (g_pLogObject) 2266*6ae612beSliuyi { 2267*6ae612beSliuyi g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno); 2268*6ae612beSliuyi } 2269*6ae612beSliuyi return false; 2270*6ae612beSliuyi } 2271*6ae612beSliuyi return true; 2272*6ae612beSliuyi } 2273*6ae612beSliuyi 2274*6ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile) 2275*6ae612beSliuyi { 2276*6ae612beSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2277*6ae612beSliuyi return false; 2278*6ae612beSliuyi CRKUsbComm *pComm = NULL; 2279*6ae612beSliuyi FILE *file = NULL; 2280*6ae612beSliuyi bool bRet, bSuccess = false, bFirst = true; 2281*6ae612beSliuyi int iRet; 2282*6ae612beSliuyi u64 iTotalWrite = 0, iFileSize = 0; 2283*6ae612beSliuyi UINT iRead = 0, uiTransferSec, curChunk, i; 2284*6ae612beSliuyi UINT dwChunkDataSize, dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc; 2285*6ae612beSliuyi BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA]; 2286*6ae612beSliuyi sparse_header header; 2287*6ae612beSliuyi chunk_header chunk; 2288*6ae612beSliuyi dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE; 2289*6ae612beSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2290*6ae612beSliuyi if (bRet) { 2291*6ae612beSliuyi bRet = erase_partition(pComm, uiBegin, uiSize); 2292*6ae612beSliuyi if (!bRet) { 2293*6ae612beSliuyi printf("%s failed, erase partition error\r\n", __func__); 2294*6ae612beSliuyi goto Exit_WriteSparseLBA; 2295*6ae612beSliuyi } 2296*6ae612beSliuyi file = fopen(szFile, "rb"); 2297*6ae612beSliuyi if( !file ) { 2298*6ae612beSliuyi printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile); 2299*6ae612beSliuyi goto Exit_WriteSparseLBA; 2300*6ae612beSliuyi } 2301*6ae612beSliuyi fseeko(file, 0, SEEK_SET); 2302*6ae612beSliuyi iRead = fread(&header, 1, sizeof(header), file); 2303*6ae612beSliuyi if (iRead != sizeof(sparse_header)) 2304*6ae612beSliuyi { 2305*6ae612beSliuyi if (g_pLogObject) 2306*6ae612beSliuyi { 2307*6ae612beSliuyi g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno); 2308*6ae612beSliuyi } 2309*6ae612beSliuyi goto Exit_WriteSparseLBA; 2310*6ae612beSliuyi } 2311*6ae612beSliuyi iFileSize = header.blk_sz * (u64)header.total_blks; 2312*6ae612beSliuyi iTotalWrite = 0; 2313*6ae612beSliuyi curChunk = 0; 2314*6ae612beSliuyi 2315*6ae612beSliuyi while(curChunk < header.total_chunks) 2316*6ae612beSliuyi { 2317*6ae612beSliuyi if (!EatSparseChunk(file, chunk)) { 2318*6ae612beSliuyi goto Exit_WriteSparseLBA; 2319*6ae612beSliuyi } 2320*6ae612beSliuyi curChunk++; 2321*6ae612beSliuyi switch (chunk.chunk_type) { 2322*6ae612beSliuyi case CHUNK_TYPE_RAW: 2323*6ae612beSliuyi dwChunkDataSize = chunk.total_sz - sizeof(chunk_header); 2324*6ae612beSliuyi while (dwChunkDataSize) { 2325*6ae612beSliuyi memset(pBuf, 0, dwMaxReadWriteBytes); 2326*6ae612beSliuyi if (dwChunkDataSize >= dwMaxReadWriteBytes) { 2327*6ae612beSliuyi dwTransferBytes = dwMaxReadWriteBytes; 2328*6ae612beSliuyi uiTransferSec = DEFAULT_RW_LBA; 2329*6ae612beSliuyi } else { 2330*6ae612beSliuyi dwTransferBytes = dwChunkDataSize; 2331*6ae612beSliuyi uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 2332*6ae612beSliuyi } 2333*6ae612beSliuyi if (!EatSparseData(file, pBuf, dwTransferBytes)) { 2334*6ae612beSliuyi goto Exit_WriteSparseLBA; 2335*6ae612beSliuyi } 2336*6ae612beSliuyi iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 2337*6ae612beSliuyi if( ERR_SUCCESS == iRet ) { 2338*6ae612beSliuyi dwChunkDataSize -= dwTransferBytes; 2339*6ae612beSliuyi iTotalWrite += dwTransferBytes; 2340*6ae612beSliuyi uiBegin += uiTransferSec; 2341*6ae612beSliuyi } else { 2342*6ae612beSliuyi if (g_pLogObject) { 2343*6ae612beSliuyi g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)", __func__, iTotalWrite, iRet); 2344*6ae612beSliuyi } 2345*6ae612beSliuyi goto Exit_WriteSparseLBA; 2346*6ae612beSliuyi } 2347*6ae612beSliuyi if (bFirst) { 2348*6ae612beSliuyi if (iTotalWrite >= 1024) 2349*6ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2350*6ae612beSliuyi else 2351*6ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2352*6ae612beSliuyi bFirst = false; 2353*6ae612beSliuyi } else { 2354*6ae612beSliuyi CURSOR_MOVEUP_LINE(1); 2355*6ae612beSliuyi CURSOR_DEL_LINE; 2356*6ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2357*6ae612beSliuyi } 2358*6ae612beSliuyi } 2359*6ae612beSliuyi break; 2360*6ae612beSliuyi case CHUNK_TYPE_FILL: 2361*6ae612beSliuyi dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 2362*6ae612beSliuyi if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) { 2363*6ae612beSliuyi goto Exit_WriteSparseLBA; 2364*6ae612beSliuyi } 2365*6ae612beSliuyi while (dwChunkDataSize) { 2366*6ae612beSliuyi memset(pBuf, 0, dwMaxReadWriteBytes); 2367*6ae612beSliuyi if (dwChunkDataSize >= dwMaxReadWriteBytes) { 2368*6ae612beSliuyi dwTransferBytes = dwMaxReadWriteBytes; 2369*6ae612beSliuyi uiTransferSec = DEFAULT_RW_LBA; 2370*6ae612beSliuyi } else { 2371*6ae612beSliuyi dwTransferBytes = dwChunkDataSize; 2372*6ae612beSliuyi uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 2373*6ae612beSliuyi } 2374*6ae612beSliuyi for (i = 0; i < dwTransferBytes / 4; i++) { 2375*6ae612beSliuyi *(DWORD *)(pBuf + i * 4) = dwFillByte; 2376*6ae612beSliuyi } 2377*6ae612beSliuyi iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 2378*6ae612beSliuyi if( ERR_SUCCESS == iRet ) { 2379*6ae612beSliuyi dwChunkDataSize -= dwTransferBytes; 2380*6ae612beSliuyi iTotalWrite += dwTransferBytes; 2381*6ae612beSliuyi uiBegin += uiTransferSec; 2382*6ae612beSliuyi } else { 2383*6ae612beSliuyi if (g_pLogObject) { 2384*6ae612beSliuyi g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet); 2385*6ae612beSliuyi } 2386*6ae612beSliuyi goto Exit_WriteSparseLBA; 2387*6ae612beSliuyi } 2388*6ae612beSliuyi if (bFirst) { 2389*6ae612beSliuyi if (iTotalWrite >= 1024) 2390*6ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2391*6ae612beSliuyi else 2392*6ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2393*6ae612beSliuyi bFirst = false; 2394*6ae612beSliuyi } else { 2395*6ae612beSliuyi CURSOR_MOVEUP_LINE(1); 2396*6ae612beSliuyi CURSOR_DEL_LINE; 2397*6ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2398*6ae612beSliuyi } 2399*6ae612beSliuyi } 2400*6ae612beSliuyi break; 2401*6ae612beSliuyi case CHUNK_TYPE_DONT_CARE: 2402*6ae612beSliuyi dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 2403*6ae612beSliuyi iTotalWrite += dwChunkDataSize; 2404*6ae612beSliuyi uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1)); 2405*6ae612beSliuyi uiBegin += uiTransferSec; 2406*6ae612beSliuyi if (bFirst) { 2407*6ae612beSliuyi if (iTotalWrite >= 1024) 2408*6ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2409*6ae612beSliuyi else 2410*6ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2411*6ae612beSliuyi bFirst = false; 2412*6ae612beSliuyi } else { 2413*6ae612beSliuyi CURSOR_MOVEUP_LINE(1); 2414*6ae612beSliuyi CURSOR_DEL_LINE; 2415*6ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2416*6ae612beSliuyi } 2417*6ae612beSliuyi break; 2418*6ae612beSliuyi case CHUNK_TYPE_CRC32: 2419*6ae612beSliuyi EatSparseData(file,(PBYTE)&dwCrc,4); 2420*6ae612beSliuyi break; 2421*6ae612beSliuyi } 2422*6ae612beSliuyi } 2423*6ae612beSliuyi bSuccess = true; 2424*6ae612beSliuyi } else { 2425*6ae612beSliuyi printf("Write LBA quit, creating comm object failed!\r\n"); 2426*6ae612beSliuyi } 2427*6ae612beSliuyi Exit_WriteSparseLBA: 2428*6ae612beSliuyi if (pComm) { 2429*6ae612beSliuyi delete pComm; 2430*6ae612beSliuyi pComm = NULL; 2431*6ae612beSliuyi } 2432*6ae612beSliuyi if (file) 2433*6ae612beSliuyi fclose(file); 2434*6ae612beSliuyi return bSuccess; 2435*6ae612beSliuyi 2436*6ae612beSliuyi } 2437*6ae612beSliuyi 243876af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 243976af099aSliuyi { 244076af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 244176af099aSliuyi return false; 244276af099aSliuyi CRKUsbComm *pComm = NULL; 244376af099aSliuyi FILE *file = NULL; 244476af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 244576af099aSliuyi int iRet; 244676af099aSliuyi long long iTotalWrite = 0, iFileSize = 0; 244776af099aSliuyi UINT iWrite = 0, iRead = 0; 244876af099aSliuyi UINT uiLen; 244976af099aSliuyi int nSectorSize = 512; 245076af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 245176af099aSliuyi 245276af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 245376af099aSliuyi if (bRet) { 245476af099aSliuyi file = fopen(szFile, "rb"); 245576af099aSliuyi if( !file ) { 245676af099aSliuyi printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 245776af099aSliuyi goto Exit_WriteLBA; 245876af099aSliuyi } 245976af099aSliuyi 246076af099aSliuyi iRet = fseeko(file, 0, SEEK_END); 246176af099aSliuyi iFileSize = ftello(file); 246276af099aSliuyi fseeko(file, 0, SEEK_SET); 246376af099aSliuyi while(iTotalWrite < iFileSize) { 246476af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 246576af099aSliuyi iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 246676af099aSliuyi uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 246776af099aSliuyi iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 246876af099aSliuyi if(ERR_SUCCESS == iRet) { 246976af099aSliuyi uiBegin += uiLen; 247076af099aSliuyi iTotalWrite += iWrite; 247176af099aSliuyi if (bFirst) { 247276af099aSliuyi if (iTotalWrite >= 1024) 247376af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 247476af099aSliuyi else 247532268622SAndreas Färber printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 247676af099aSliuyi bFirst = false; 247776af099aSliuyi } else { 247876af099aSliuyi CURSOR_MOVEUP_LINE(1); 247976af099aSliuyi CURSOR_DEL_LINE; 248076af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 248176af099aSliuyi } 248276af099aSliuyi } else { 248376af099aSliuyi if (g_pLogObject) 248476af099aSliuyi g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 248576af099aSliuyi 248676af099aSliuyi printf("Write LBA failed!\r\n"); 248776af099aSliuyi goto Exit_WriteLBA; 248876af099aSliuyi } 248976af099aSliuyi } 249076af099aSliuyi bSuccess = true; 249176af099aSliuyi } else { 249232268622SAndreas Färber printf("Write LBA quit, creating comm object failed!\r\n"); 249376af099aSliuyi } 249476af099aSliuyi Exit_WriteLBA: 249576af099aSliuyi if (pComm) { 249676af099aSliuyi delete pComm; 249776af099aSliuyi pComm = NULL; 249876af099aSliuyi } 249976af099aSliuyi if (file) 250076af099aSliuyi fclose(file); 250176af099aSliuyi return bSuccess; 250276af099aSliuyi } 250376af099aSliuyi 250476af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems) 250576af099aSliuyi { 250676af099aSliuyi string strItem; 250776af099aSliuyi char szItem[100]; 250876af099aSliuyi char *pos = NULL, *pStart; 250976af099aSliuyi pStart = pszItems; 251076af099aSliuyi pos = strchr(pStart, ','); 251176af099aSliuyi while(pos != NULL) { 251276af099aSliuyi memset(szItem, 0, 100); 251376af099aSliuyi strncpy(szItem, pStart, pos - pStart); 251476af099aSliuyi strItem = szItem; 251576af099aSliuyi vecItems.push_back(strItem); 251676af099aSliuyi pStart = pos + 1; 251776af099aSliuyi if (*pStart == 0) 251876af099aSliuyi break; 251976af099aSliuyi pos = strchr(pStart, ','); 252076af099aSliuyi } 252176af099aSliuyi if (strlen(pStart) > 0) { 252276af099aSliuyi memset(szItem, 0, 100); 252376af099aSliuyi strncpy(szItem, pStart, strlen(pStart)); 252476af099aSliuyi strItem = szItem; 252576af099aSliuyi vecItems.push_back(strItem); 252676af099aSliuyi } 252776af099aSliuyi } 2528c30d921cSKever Yang 2529d71e8c20SEddie Cai void tag_spl(char *tag, char *spl) 2530d71e8c20SEddie Cai { 2531d71e8c20SEddie Cai FILE *file = NULL; 2532d71e8c20SEddie Cai int len; 2533d71e8c20SEddie Cai 2534d71e8c20SEddie Cai if(!tag || !spl) 2535d71e8c20SEddie Cai return; 2536d71e8c20SEddie Cai len = strlen(tag); 2537d71e8c20SEddie Cai printf("tag len=%d\n",len); 2538d71e8c20SEddie Cai file = fopen(spl, "rb"); 2539d71e8c20SEddie Cai if( !file ){ 2540d71e8c20SEddie Cai return; 2541d71e8c20SEddie Cai } 2542d71e8c20SEddie Cai int iFileSize; 2543d71e8c20SEddie Cai fseek(file, 0, SEEK_END); 2544d71e8c20SEddie Cai iFileSize = ftell(file); 2545d71e8c20SEddie Cai fseek(file, 0, SEEK_SET); 2546d71e8c20SEddie Cai char *Buf = NULL; 2547d71e8c20SEddie Cai Buf = new char[iFileSize + len + 1]; 2548d71e8c20SEddie Cai if (!Buf){ 2549d71e8c20SEddie Cai fclose(file); 2550d71e8c20SEddie Cai return; 2551d71e8c20SEddie Cai } 2552d71e8c20SEddie Cai memset(Buf, 0, iFileSize + 1); 2553d71e8c20SEddie Cai memcpy(Buf, tag, len); 2554d71e8c20SEddie Cai int iRead; 2555d71e8c20SEddie Cai iRead = fread(Buf+len, 1, iFileSize, file); 2556d71e8c20SEddie Cai if (iRead != iFileSize){ 2557d71e8c20SEddie Cai fclose(file); 2558d71e8c20SEddie Cai delete []Buf; 2559d71e8c20SEddie Cai return; 2560d71e8c20SEddie Cai } 2561d71e8c20SEddie Cai fclose(file); 2562d71e8c20SEddie Cai 2563d71e8c20SEddie Cai len = strlen(spl); 256432268622SAndreas Färber char *taggedspl = new char[len + 5]; 256532268622SAndreas Färber strcpy(taggedspl, spl); 256632268622SAndreas Färber strcpy(taggedspl + len, ".tag"); 256732268622SAndreas Färber taggedspl[len+4] = 0; 256832268622SAndreas Färber printf("Writing tagged spl to %s\n", taggedspl); 2569d71e8c20SEddie Cai 257032268622SAndreas Färber file = fopen(taggedspl, "wb"); 2571d71e8c20SEddie Cai if( !file ){ 257232268622SAndreas Färber delete []taggedspl; 2573d71e8c20SEddie Cai delete []Buf; 2574d71e8c20SEddie Cai return; 2575d71e8c20SEddie Cai } 2576d71e8c20SEddie Cai fwrite(Buf, 1, iFileSize+len, file); 2577d71e8c20SEddie Cai fclose(file); 257832268622SAndreas Färber delete []taggedspl; 2579d71e8c20SEddie Cai delete []Buf; 2580d71e8c20SEddie Cai printf("done\n"); 2581d71e8c20SEddie Cai return; 2582d71e8c20SEddie Cai } 2583d71e8c20SEddie Cai 258476af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan) 258576af099aSliuyi { 258676af099aSliuyi string strCmd; 258776af099aSliuyi strCmd = argv[1]; 258876af099aSliuyi ssize_t cnt; 258976af099aSliuyi bool bRet,bSuccess = false; 25908df2d64aSEddie Cai char *s; 25918df2d64aSEddie Cai int i, ret; 259276af099aSliuyi STRUCT_RKDEVICE_DESC dev; 2593*6ae612beSliuyi u8 master_gpt[34 * SECTOR_SIZE]; 2594*6ae612beSliuyi u64 lba, lba_end; 259576af099aSliuyi 259676af099aSliuyi transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 25978df2d64aSEddie Cai s = (char*)strCmd.c_str(); 25988df2d64aSEddie Cai for(i = 0; i < (int)strlen(s); i++) 25998df2d64aSEddie Cai s[i] = toupper(s[i]); 260078884ef4SEddie Cai 26018df2d64aSEddie Cai if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 260276af099aSliuyi usage(); 260376af099aSliuyi return true; 26048df2d64aSEddie Cai } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2605c30d921cSKever Yang printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 260676af099aSliuyi return true; 260778884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 260878884ef4SEddie Cai mergeBoot(); 260978884ef4SEddie Cai 261078884ef4SEddie Cai return true; 261178884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 261278884ef4SEddie Cai string strLoader = argv[2]; 261378884ef4SEddie Cai 261478884ef4SEddie Cai unpackBoot((char*)strLoader.c_str()); 261578884ef4SEddie Cai return true; 2616d71e8c20SEddie Cai } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 2617d71e8c20SEddie Cai if (argc == 4) { 2618d71e8c20SEddie Cai string tag = argv[2]; 2619d71e8c20SEddie Cai string spl = argv[3]; 2620d71e8c20SEddie Cai printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 2621d71e8c20SEddie Cai tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 2622d71e8c20SEddie Cai return true; 2623d71e8c20SEddie Cai } 2624d71e8c20SEddie Cai printf("tagspl: parameter error\n"); 2625d71e8c20SEddie Cai usage(); 262676af099aSliuyi } 262776af099aSliuyi cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 262876af099aSliuyi if (cnt < 1) { 262976af099aSliuyi ERROR_COLOR_ATTR; 263032268622SAndreas Färber printf("Did not find any rockusb device, please plug device in!"); 263176af099aSliuyi NORMAL_COLOR_ATTR; 263276af099aSliuyi printf("\r\n"); 263376af099aSliuyi return bSuccess; 263476af099aSliuyi } else if (cnt > 1) { 263576af099aSliuyi ERROR_COLOR_ATTR; 263632268622SAndreas Färber printf("Found too many rockusb devices, please plug devices out!"); 263776af099aSliuyi NORMAL_COLOR_ATTR; 263876af099aSliuyi printf("\r\n"); 263976af099aSliuyi return bSuccess; 264076af099aSliuyi } 264176af099aSliuyi 264276af099aSliuyi bRet = pScan->GetDevice(dev, 0); 264376af099aSliuyi if (!bRet) { 264476af099aSliuyi ERROR_COLOR_ATTR; 264532268622SAndreas Färber printf("Getting information about rockusb device failed!"); 264676af099aSliuyi NORMAL_COLOR_ATTR; 264776af099aSliuyi printf("\r\n"); 264876af099aSliuyi return bSuccess; 264976af099aSliuyi } 265076af099aSliuyi 265176af099aSliuyi if(strcmp(strCmd.c_str(), "RD") == 0) { 265276af099aSliuyi if ((argc != 2) && (argc != 3)) 265376af099aSliuyi printf("Parameter of [RD] command is invalid, please check help!\r\n"); 265476af099aSliuyi else { 265576af099aSliuyi if (argc == 2) 265676af099aSliuyi bSuccess = reset_device(dev); 265776af099aSliuyi else { 265876af099aSliuyi UINT uiSubCode; 265976af099aSliuyi char *pszEnd; 266076af099aSliuyi uiSubCode = strtoul(argv[2], &pszEnd, 0); 266176af099aSliuyi if (*pszEnd) 266276af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 266376af099aSliuyi else { 266476af099aSliuyi if (uiSubCode <= 5) 266576af099aSliuyi bSuccess = reset_device(dev, uiSubCode); 266676af099aSliuyi else 266776af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 266876af099aSliuyi } 266976af099aSliuyi } 267076af099aSliuyi } 267176af099aSliuyi } else if(strcmp(strCmd.c_str(), "TD") == 0) { 267276af099aSliuyi bSuccess = test_device(dev); 267376af099aSliuyi } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 267476af099aSliuyi bSuccess = read_flash_id(dev); 267576af099aSliuyi } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 267676af099aSliuyi bSuccess = read_flash_info(dev); 267776af099aSliuyi } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 267876af099aSliuyi bSuccess = read_chip_info(dev); 267976af099aSliuyi } else if(strcmp(strCmd.c_str(), "DB") == 0) { 268076af099aSliuyi if (argc > 2) { 268176af099aSliuyi string strLoader; 268276af099aSliuyi strLoader = argv[2]; 268376af099aSliuyi bSuccess = download_boot(dev, (char *)strLoader.c_str()); 268476af099aSliuyi } else if (argc == 2) { 2685c29e5f0fSliuyi ret = find_config_item(g_ConfigItemVec, "loader"); 268676af099aSliuyi if (ret == -1) 268732268622SAndreas Färber printf("Did not find loader item in config!\r\n"); 268876af099aSliuyi else 268976af099aSliuyi bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 269076af099aSliuyi } else 269176af099aSliuyi printf("Parameter of [DB] command is invalid, please check help!\r\n"); 2692c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2693c30d921cSKever Yang if (argc > 2) { 2694c30d921cSKever Yang string strParameter; 2695c30d921cSKever Yang strParameter = argv[2]; 2696c30d921cSKever Yang bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2697c30d921cSKever Yang } else 2698c30d921cSKever Yang printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 2699c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2700c30d921cSKever Yang if (argc > 2) { 2701c30d921cSKever Yang string strLoader; 2702c30d921cSKever Yang strLoader = argv[2]; 2703c30d921cSKever Yang bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2704c30d921cSKever Yang } else 2705c30d921cSKever Yang printf("Parameter of [UL] command is invalid, please check help!\r\n"); 270676af099aSliuyi } else if(strcmp(strCmd.c_str(), "EF") == 0) { 270776af099aSliuyi if (argc == 2) { 270876af099aSliuyi bSuccess = erase_flash(dev); 270976af099aSliuyi } else 271076af099aSliuyi printf("Parameter of [EF] command is invalid, please check help!\r\n"); 271176af099aSliuyi } else if(strcmp(strCmd.c_str(), "WL") == 0) { 271276af099aSliuyi if (argc == 4) { 271376af099aSliuyi UINT uiBegin; 271476af099aSliuyi char *pszEnd; 271576af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 271676af099aSliuyi if (*pszEnd) 271776af099aSliuyi printf("Begin is invalid, please check!\r\n"); 271876af099aSliuyi else 271976af099aSliuyi bSuccess = write_lba(dev, uiBegin, argv[3]); 272076af099aSliuyi } else 272176af099aSliuyi printf("Parameter of [WL] command is invalid, please check help!\r\n"); 2722*6ae612beSliuyi } else if(strcmp(strCmd.c_str(), "WLX") == 0) { 2723*6ae612beSliuyi if (argc == 4) { 2724*6ae612beSliuyi bRet = read_gpt(dev, master_gpt); 2725*6ae612beSliuyi if (bRet) { 2726*6ae612beSliuyi bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end); 2727*6ae612beSliuyi if (bRet) { 2728*6ae612beSliuyi if (is_sparse_image(argv[3])) 2729*6ae612beSliuyi bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]); 2730*6ae612beSliuyi else 2731*6ae612beSliuyi bSuccess = write_lba(dev, (u32)lba, argv[3]); 2732*6ae612beSliuyi } else 2733*6ae612beSliuyi printf("No found %s partition\r\n", argv[2]); 2734*6ae612beSliuyi } 2735*6ae612beSliuyi } else 2736*6ae612beSliuyi printf("Parameter of [WLX] command is invalid, please check help!\r\n"); 273776af099aSliuyi } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 273876af099aSliuyi char *pszEnd; 273976af099aSliuyi UINT uiBegin, uiLen; 274076af099aSliuyi if (argc != 5) 274176af099aSliuyi printf("Parameter of [RL] command is invalid, please check help!\r\n"); 274276af099aSliuyi else { 274376af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 274476af099aSliuyi if (*pszEnd) 274576af099aSliuyi printf("Begin is invalid, please check!\r\n"); 274676af099aSliuyi else { 274776af099aSliuyi uiLen = strtoul(argv[3], &pszEnd, 0); 274876af099aSliuyi if (*pszEnd) 274976af099aSliuyi printf("Len is invalid, please check!\r\n"); 275076af099aSliuyi else { 275176af099aSliuyi bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 275276af099aSliuyi } 275376af099aSliuyi } 275476af099aSliuyi } 275576af099aSliuyi } else { 27569bc231bdSAndreas Färber printf("command is invalid!\r\n"); 27579bc231bdSAndreas Färber usage(); 275876af099aSliuyi } 275976af099aSliuyi return bSuccess; 276076af099aSliuyi } 276176af099aSliuyi 276276af099aSliuyi 276376af099aSliuyi int main(int argc, char* argv[]) 276476af099aSliuyi { 276576af099aSliuyi CRKScan *pScan = NULL; 276676af099aSliuyi int ret; 276776af099aSliuyi char szProgramProcPath[100]; 276876af099aSliuyi char szProgramDir[256]; 276976af099aSliuyi string strLogDir,strConfigFile; 277076af099aSliuyi struct stat statBuf; 277176af099aSliuyi 277276af099aSliuyi g_ConfigItemVec.clear(); 277376af099aSliuyi sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 277476af099aSliuyi if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 277576af099aSliuyi strcpy(szProgramDir, "."); 277676af099aSliuyi else { 277776af099aSliuyi char *pSlash; 277876af099aSliuyi pSlash = strrchr(szProgramDir, '/'); 277976af099aSliuyi if (pSlash) 278076af099aSliuyi *pSlash = '\0'; 278176af099aSliuyi } 278276af099aSliuyi strLogDir = szProgramDir; 278376af099aSliuyi strLogDir += "/log/"; 278476af099aSliuyi strConfigFile = szProgramDir; 278576af099aSliuyi strConfigFile += "/config.ini"; 278676af099aSliuyi if (opendir(strLogDir.c_str()) == NULL) 278776af099aSliuyi mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 2788e5ee8cc0Sliuyi g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 278976af099aSliuyi 279076af099aSliuyi if(stat(strConfigFile.c_str(), &statBuf) < 0) { 279176af099aSliuyi if (g_pLogObject) { 279276af099aSliuyi g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 279376af099aSliuyi } 279476af099aSliuyi } else if (S_ISREG(statBuf.st_mode)) { 279576af099aSliuyi parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 279676af099aSliuyi } 279776af099aSliuyi 279876af099aSliuyi ret = libusb_init(NULL); 279976af099aSliuyi if (ret < 0) { 280076af099aSliuyi if (g_pLogObject) { 280176af099aSliuyi g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 280276af099aSliuyi delete g_pLogObject; 280376af099aSliuyi } 280476af099aSliuyi return -1; 280576af099aSliuyi } 280676af099aSliuyi 280776af099aSliuyi pScan = new CRKScan(); 280876af099aSliuyi if (!pScan) { 280976af099aSliuyi if (g_pLogObject) { 281032268622SAndreas Färber g_pLogObject->Record("Error: failed to create object for searching device"); 281176af099aSliuyi delete g_pLogObject; 281276af099aSliuyi } 281376af099aSliuyi libusb_exit(NULL); 281476af099aSliuyi return -2; 281576af099aSliuyi } 281676af099aSliuyi pScan->SetVidPid(); 281776af099aSliuyi 281876af099aSliuyi if (argc == 1) 281976af099aSliuyi usage(); 282076af099aSliuyi else if (!handle_command(argc, argv, pScan)) 282176af099aSliuyi return -0xFF; 282276af099aSliuyi if (pScan) 282376af099aSliuyi delete pScan; 282476af099aSliuyi if (g_pLogObject) 282576af099aSliuyi delete g_pLogObject; 282676af099aSliuyi libusb_exit(NULL); 282776af099aSliuyi return 0; 282876af099aSliuyi } 2829