176af099aSliuyi /* 276af099aSliuyi * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 376af099aSliuyi * Seth Liu 2017.03.01 476af099aSliuyi * 576af099aSliuyi * SPDX-License-Identifier: GPL-2.0+ 676af099aSliuyi */ 776af099aSliuyi 876af099aSliuyi #include <unistd.h> 976af099aSliuyi #include <dirent.h> 10c30d921cSKever Yang #include "config.h" 1176af099aSliuyi #include "DefineHeader.h" 12c30d921cSKever Yang #include "gpt.h" 1376af099aSliuyi #include "RKLog.h" 1476af099aSliuyi #include "RKScan.h" 1576af099aSliuyi #include "RKComm.h" 1676af099aSliuyi #include "RKDevice.h" 1776af099aSliuyi #include "RKImage.h" 1876af099aSliuyi extern const char *szManufName[]; 1976af099aSliuyi CRKLog *g_pLogObject=NULL; 2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec; 2176af099aSliuyi #define DEFAULT_RW_LBA 128 2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n) 2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B) 2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B) 2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B) 2676af099aSliuyi #define ERROR_COLOR_ATTR printf("%c[30;41m", 0x1B); 273601cc08SAndreas Färber #define NORMAL_COLOR_ATTR printf("%c[0m", 0x1B); 28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize); 29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize); 30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len); 31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len); 32c30d921cSKever Yang /* 33c30d921cSKever Yang u8 test_gpt_head[] = { 34c30d921cSKever Yang 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00, 35c30d921cSKever Yang 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36c30d921cSKever Yang 0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37c30d921cSKever Yang 0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B, 38c30d921cSKever Yang 0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39c30d921cSKever Yang 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08}; 40c30d921cSKever Yang */ 41c30d921cSKever Yang 4276af099aSliuyi void usage() 4376af099aSliuyi { 4476af099aSliuyi printf("\r\n---------------------Tool Usage ---------------------\r\n"); 45ae4252f0Sliuyi printf("Help:\t\t\t-h or --help\r\n"); 46154ee062SEddie Cai printf("Version:\t\t-v or --version\r\n"); 47081d237aSliuyi printf("ListDevice:\t\tld\r\n"); 48154ee062SEddie Cai printf("DownloadBoot:\t\tdb <Loader>\r\n"); 49154ee062SEddie Cai printf("UpgradeLoader:\t\tul <Loader>\r\n"); 50154ee062SEddie Cai printf("ReadLBA:\t\trl <BeginSec> <SectorLen> <File>\r\n"); 51154ee062SEddie Cai printf("WriteLBA:\t\twl <BeginSec> <File>\r\n"); 526ae612beSliuyi printf("WriteLBA:\t\twlx <PartitionName> <File>\r\n"); 53154ee062SEddie Cai printf("WriteGPT:\t\tgpt <gpt partition table>\r\n"); 54081d237aSliuyi printf("WriteParameter:\t\tprm <parameter>\r\n"); 55081d237aSliuyi printf("PrintPartition:\t\tppt \r\n"); 56154ee062SEddie Cai printf("EraseFlash:\t\tef \r\n"); 57154ee062SEddie Cai printf("TestDevice:\t\ttd\r\n"); 58154ee062SEddie Cai printf("ResetDevice:\t\trd [subcode]\r\n"); 59154ee062SEddie Cai printf("ReadFlashID:\t\trid\r\n"); 60154ee062SEddie Cai printf("ReadFlashInfo:\t\trfi\r\n"); 61154ee062SEddie Cai printf("ReadChipInfo:\t\trci\r\n"); 62081d237aSliuyi printf("ReadCapability:\t\trcb\r\n"); 6378884ef4SEddie Cai printf("PackBootLoader:\t\tpack\r\n"); 6478884ef4SEddie Cai printf("UnpackBootLoader:\tunpack <boot loader>\r\n"); 65d71e8c20SEddie Cai printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n"); 6676af099aSliuyi printf("-------------------------------------------------------\r\n\r\n"); 6776af099aSliuyi } 6876af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall) 6976af099aSliuyi { 7076af099aSliuyi string strInfoText=""; 7176af099aSliuyi char szText[256]; 7276af099aSliuyi switch (promptID) { 7376af099aSliuyi case TESTDEVICE_PROGRESS: 7432268622SAndreas Färber sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue); 7576af099aSliuyi strInfoText = szText; 7676af099aSliuyi break; 7776af099aSliuyi case LOWERFORMAT_PROGRESS: 7832268622SAndreas Färber sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue); 7976af099aSliuyi strInfoText = szText; 8076af099aSliuyi break; 8176af099aSliuyi case DOWNLOADIMAGE_PROGRESS: 8232268622SAndreas Färber sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 8376af099aSliuyi strInfoText = szText; 8476af099aSliuyi break; 8576af099aSliuyi case CHECKIMAGE_PROGRESS: 8632268622SAndreas Färber sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 8776af099aSliuyi strInfoText = szText; 8876af099aSliuyi break; 8976af099aSliuyi case TAGBADBLOCK_PROGRESS: 9032268622SAndreas Färber sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue); 9176af099aSliuyi strInfoText = szText; 9276af099aSliuyi break; 9376af099aSliuyi case TESTBLOCK_PROGRESS: 9432268622SAndreas Färber sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue); 9576af099aSliuyi strInfoText = szText; 9676af099aSliuyi break; 9776af099aSliuyi case ERASEFLASH_PROGRESS: 9832268622SAndreas Färber sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue); 9976af099aSliuyi strInfoText = szText; 10076af099aSliuyi break; 10176af099aSliuyi case ERASESYSTEM_PROGRESS: 10232268622SAndreas Färber sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue); 10376af099aSliuyi strInfoText = szText; 10476af099aSliuyi break; 10576af099aSliuyi case ERASEUSERDATA_PROGRESS: 10632268622SAndreas Färber sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue); 10776af099aSliuyi strInfoText = szText; 10876af099aSliuyi break; 10976af099aSliuyi } 11076af099aSliuyi if (strInfoText.size() > 0){ 11176af099aSliuyi CURSOR_MOVEUP_LINE(1); 11276af099aSliuyi CURSOR_DEL_LINE; 11376af099aSliuyi printf("%s\r\n", strInfoText.c_str()); 11476af099aSliuyi } 11576af099aSliuyi if (emCall == CALL_LAST) 11676af099aSliuyi deviceLayer = 0; 11776af099aSliuyi } 11876af099aSliuyi 11976af099aSliuyi char *strupr(char *szSrc) 12076af099aSliuyi { 12176af099aSliuyi char *p = szSrc; 12276af099aSliuyi while(*p){ 12376af099aSliuyi if ((*p >= 'a') && (*p <= 'z')) 12476af099aSliuyi *p = *p - 'a' + 'A'; 12576af099aSliuyi p++; 12676af099aSliuyi } 12776af099aSliuyi return szSrc; 12876af099aSliuyi } 12976af099aSliuyi void PrintData(PBYTE pData, int nSize) 13076af099aSliuyi { 13176af099aSliuyi char szPrint[17] = "\0"; 13276af099aSliuyi int i; 13376af099aSliuyi for( i = 0; i < nSize; i++){ 13476af099aSliuyi if(i % 16 == 0){ 13576af099aSliuyi if(i / 16 > 0) 13676af099aSliuyi printf(" %s\r\n", szPrint); 13776af099aSliuyi printf("%08d ", i / 16); 13876af099aSliuyi } 13976af099aSliuyi printf("%02X ", pData[i]); 14076af099aSliuyi szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.'; 14176af099aSliuyi } 14276af099aSliuyi if(i / 16 > 0) 14376af099aSliuyi printf(" %s\r\n", szPrint); 14476af099aSliuyi } 14576af099aSliuyi 146*0dcb0a4cSliuyi // bool StringToWideString(char *pszSrc, wchar_t *&pszDest) 147*0dcb0a4cSliuyi // { 148*0dcb0a4cSliuyi // if (!pszSrc) 149*0dcb0a4cSliuyi // return false; 150*0dcb0a4cSliuyi // int nSrcLen = strlen(pszSrc); 151*0dcb0a4cSliuyi // int nDestLen = nSrcLen * 2; 152*0dcb0a4cSliuyi // 153*0dcb0a4cSliuyi // pszDest = NULL; 154*0dcb0a4cSliuyi // pszDest = new wchar_t[nDestLen]; 155*0dcb0a4cSliuyi // if (!pszDest) 156*0dcb0a4cSliuyi // return false; 157*0dcb0a4cSliuyi // nDestLen = nDestLen * sizeof(wchar_t); 158*0dcb0a4cSliuyi // memset(pszDest, 0, nDestLen); 159*0dcb0a4cSliuyi // int iRet; 160*0dcb0a4cSliuyi // iconv_t cd; 161*0dcb0a4cSliuyi // cd = iconv_open("UTF-32", "UTF-8"); 162*0dcb0a4cSliuyi // if((iconv_t)-1 == cd) { 163*0dcb0a4cSliuyi // delete []pszDest; 164*0dcb0a4cSliuyi // pszDest = NULL; 165*0dcb0a4cSliuyi // return false; 166*0dcb0a4cSliuyi // } 167*0dcb0a4cSliuyi // char *pIn, *pOut; 168*0dcb0a4cSliuyi // pIn = (char *)pszSrc; 169*0dcb0a4cSliuyi // pOut = (char *)pszDest; 170*0dcb0a4cSliuyi // 171*0dcb0a4cSliuyi // iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 172*0dcb0a4cSliuyi // 173*0dcb0a4cSliuyi // if(iRet == -1) { 174*0dcb0a4cSliuyi // delete []pszDest; 175*0dcb0a4cSliuyi // pszDest = NULL; 176*0dcb0a4cSliuyi // iconv_close(cd); 177*0dcb0a4cSliuyi // return false; 178*0dcb0a4cSliuyi // } 179*0dcb0a4cSliuyi // 180*0dcb0a4cSliuyi // iconv_close(cd); 181*0dcb0a4cSliuyi // 182*0dcb0a4cSliuyi // return true; 183*0dcb0a4cSliuyi // } 184*0dcb0a4cSliuyi // bool WideStringToString(wchar_t *pszSrc, char *&pszDest) 185*0dcb0a4cSliuyi // { 186*0dcb0a4cSliuyi // if (!pszSrc) 187*0dcb0a4cSliuyi // return false; 188*0dcb0a4cSliuyi // int nSrcLen = wcslen(pszSrc); 189*0dcb0a4cSliuyi // int nDestLen = nSrcLen * 2; 190*0dcb0a4cSliuyi // nSrcLen = nSrcLen * sizeof(wchar_t); 191*0dcb0a4cSliuyi // pszDest = NULL; 192*0dcb0a4cSliuyi // pszDest = new char[nDestLen]; 193*0dcb0a4cSliuyi // if (!pszDest) 194*0dcb0a4cSliuyi // return false; 195*0dcb0a4cSliuyi // memset(pszDest, 0, nDestLen); 196*0dcb0a4cSliuyi // int iRet; 197*0dcb0a4cSliuyi // iconv_t cd; 198*0dcb0a4cSliuyi // cd = iconv_open("UTF-8", "UTF-32"); 199*0dcb0a4cSliuyi // 200*0dcb0a4cSliuyi // if((iconv_t)-1 == cd) { 201*0dcb0a4cSliuyi // delete []pszDest; 202*0dcb0a4cSliuyi // pszDest = NULL; 203*0dcb0a4cSliuyi // return false; 204*0dcb0a4cSliuyi // } 205*0dcb0a4cSliuyi // char *pIn, *pOut; 206*0dcb0a4cSliuyi // pIn = (char *)pszSrc; 207*0dcb0a4cSliuyi // pOut = (char *)pszDest; 208*0dcb0a4cSliuyi // iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 209*0dcb0a4cSliuyi // 210*0dcb0a4cSliuyi // if(iRet == -1) { 211*0dcb0a4cSliuyi // delete []pszDest; 212*0dcb0a4cSliuyi // pszDest = NULL; 213*0dcb0a4cSliuyi // iconv_close(cd); 214*0dcb0a4cSliuyi // return false; 215*0dcb0a4cSliuyi // } 216*0dcb0a4cSliuyi // 217*0dcb0a4cSliuyi // iconv_close(cd); 218*0dcb0a4cSliuyi // 219*0dcb0a4cSliuyi // return true; 220*0dcb0a4cSliuyi // } 221c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName) 22276af099aSliuyi { 22376af099aSliuyi unsigned int i; 224c29e5f0fSliuyi for(i = 0; i < vecItems.size(); i++){ 225c29e5f0fSliuyi if (strcasecmp(pszName, vecItems[i].szItemName) == 0){ 22676af099aSliuyi return i; 22776af099aSliuyi } 22876af099aSliuyi } 22976af099aSliuyi return -1; 23076af099aSliuyi } 231c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid) 232c29e5f0fSliuyi { 233c29e5f0fSliuyi unsigned int i; 234c29e5f0fSliuyi char value; 235c29e5f0fSliuyi memset(uuid, 0, 16); 236c29e5f0fSliuyi for (i =0; i < strUUid.size(); i++) { 237c29e5f0fSliuyi value = 0; 238c29e5f0fSliuyi if ((strUUid[i] >= '0')&&(strUUid[i] <= '9')) 239c29e5f0fSliuyi value = strUUid[i] - '0'; 240c29e5f0fSliuyi if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f')) 241c29e5f0fSliuyi value = strUUid[i] - 'a' + 10; 242c29e5f0fSliuyi if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F')) 243c29e5f0fSliuyi value = strUUid[i] - 'A' + 10; 244c29e5f0fSliuyi if ((i % 2) == 0) 245c29e5f0fSliuyi uuid[i / 2] += (value << 4); 246c29e5f0fSliuyi else 247c29e5f0fSliuyi uuid[i / 2] += value; 248c29e5f0fSliuyi } 249c29e5f0fSliuyi unsigned int *p32; 250c29e5f0fSliuyi unsigned short *p16; 251c29e5f0fSliuyi p32 = (unsigned int*)uuid; 252c29e5f0fSliuyi *p32 = cpu_to_be32(*p32); 253c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 4); 254c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 255c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 6); 256c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 257c29e5f0fSliuyi } 25876af099aSliuyi 25976af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 26076af099aSliuyi { 26176af099aSliuyi 26276af099aSliuyi stringstream configStream(pConfig); 26376af099aSliuyi string strLine, strItemName, strItemValue; 26476af099aSliuyi string::size_type line_size,pos; 26576af099aSliuyi STRUCT_CONFIG_ITEM item; 26676af099aSliuyi vecItem.clear(); 26776af099aSliuyi while (!configStream.eof()){ 26876af099aSliuyi getline(configStream, strLine); 26976af099aSliuyi line_size = strLine.size(); 27076af099aSliuyi if (line_size == 0) 27176af099aSliuyi continue; 27276af099aSliuyi if (strLine[line_size-1] == '\r'){ 27376af099aSliuyi strLine = strLine.substr(0, line_size-1); 27476af099aSliuyi } 275c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 276c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 277c30d921cSKever Yang if (strLine.size()==0 ) 278c30d921cSKever Yang continue; 279c30d921cSKever Yang if (strLine[0] == '#') 280c30d921cSKever Yang continue; 28176af099aSliuyi pos = strLine.find("="); 28276af099aSliuyi if (pos == string::npos){ 28376af099aSliuyi continue; 28476af099aSliuyi } 28576af099aSliuyi strItemName = strLine.substr(0, pos); 28676af099aSliuyi strItemValue = strLine.substr(pos + 1); 28776af099aSliuyi strItemName.erase(0, strItemName.find_first_not_of(" ")); 28876af099aSliuyi strItemName.erase(strItemName.find_last_not_of(" ") + 1); 28976af099aSliuyi strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 29076af099aSliuyi strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 29176af099aSliuyi if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 29276af099aSliuyi strcpy(item.szItemName, strItemName.c_str()); 29376af099aSliuyi strcpy(item.szItemValue, strItemValue.c_str()); 29476af099aSliuyi vecItem.push_back(item); 29576af099aSliuyi } 29676af099aSliuyi } 29776af099aSliuyi return true; 29876af099aSliuyi 29976af099aSliuyi } 30076af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 30176af099aSliuyi { 30276af099aSliuyi FILE *file = NULL; 30376af099aSliuyi file = fopen(pConfigFile, "rb"); 30476af099aSliuyi if( !file ){ 30576af099aSliuyi if (g_pLogObject) 30632268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile); 30776af099aSliuyi return false; 30876af099aSliuyi } 30976af099aSliuyi int iFileSize; 31076af099aSliuyi fseek(file, 0, SEEK_END); 31176af099aSliuyi iFileSize = ftell(file); 31276af099aSliuyi fseek(file, 0, SEEK_SET); 31376af099aSliuyi char *pConfigBuf = NULL; 31476af099aSliuyi pConfigBuf = new char[iFileSize + 1]; 31576af099aSliuyi if (!pConfigBuf){ 31676af099aSliuyi fclose(file); 31776af099aSliuyi return false; 31876af099aSliuyi } 31976af099aSliuyi memset(pConfigBuf, 0, iFileSize + 1); 32076af099aSliuyi int iRead; 32176af099aSliuyi iRead = fread(pConfigBuf, 1, iFileSize, file); 32276af099aSliuyi if (iRead != iFileSize){ 32376af099aSliuyi if (g_pLogObject) 32432268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize); 32576af099aSliuyi fclose(file); 32676af099aSliuyi delete []pConfigBuf; 32776af099aSliuyi return false; 32876af099aSliuyi } 32976af099aSliuyi fclose(file); 33076af099aSliuyi bool bRet; 33176af099aSliuyi bRet = parse_config(pConfigBuf, vecItem); 33276af099aSliuyi delete []pConfigBuf; 33376af099aSliuyi return bRet; 33476af099aSliuyi } 335c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 336c30d921cSKever Yang { 337c30d921cSKever Yang string::size_type pos,prevPos; 338c30d921cSKever Yang string strOffset,strLen; 339c30d921cSKever Yang int iCount; 340c30d921cSKever Yang prevPos = pos = 0; 341c30d921cSKever Yang if (strPartInfo.size() <= 0) { 342c30d921cSKever Yang return false; 343c30d921cSKever Yang } 344c30d921cSKever Yang pos = strPartInfo.find('@'); 345c30d921cSKever Yang if (pos == string::npos) { 346c30d921cSKever Yang return false; 347c30d921cSKever Yang } 348c30d921cSKever Yang strLen = strPartInfo.substr(prevPos, pos - prevPos); 349c30d921cSKever Yang strLen.erase(0, strLen.find_first_not_of(" ")); 350c30d921cSKever Yang strLen.erase(strLen.find_last_not_of(" ") + 1); 351c30d921cSKever Yang if (strchr(strLen.c_str(), '-')) { 352c30d921cSKever Yang uiLen = 0xFFFFFFFF; 353c30d921cSKever Yang } else { 354c30d921cSKever Yang iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 355c30d921cSKever Yang if (iCount != 1) { 356c30d921cSKever Yang return false; 357c30d921cSKever Yang } 358c30d921cSKever Yang } 359c30d921cSKever Yang 360c30d921cSKever Yang prevPos = pos + 1; 361c30d921cSKever Yang pos = strPartInfo.find('(',prevPos); 362c30d921cSKever Yang if (pos == string::npos) { 363c30d921cSKever Yang return false; 364c30d921cSKever Yang } 365c30d921cSKever Yang strOffset = strPartInfo.substr(prevPos, pos - prevPos); 366c30d921cSKever Yang strOffset.erase(0, strOffset.find_first_not_of(" ")); 367c30d921cSKever Yang strOffset.erase(strOffset.find_last_not_of(" ") + 1); 368c30d921cSKever Yang iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 369c30d921cSKever Yang if (iCount != 1) { 370c30d921cSKever Yang return false; 371c30d921cSKever Yang } 372c30d921cSKever Yang prevPos = pos + 1; 373c30d921cSKever Yang pos = strPartInfo.find(')', prevPos); 374c30d921cSKever Yang if (pos == string::npos) { 375c30d921cSKever Yang return false; 376c30d921cSKever Yang } 377c30d921cSKever Yang strName = strPartInfo.substr(prevPos, pos - prevPos); 378c30d921cSKever Yang strName.erase(0, strName.find_first_not_of(" ")); 379c30d921cSKever Yang strName.erase(strName.find_last_not_of(" ") + 1); 380c30d921cSKever Yang 381c30d921cSKever Yang return true; 382c30d921cSKever Yang } 383c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid) 384c29e5f0fSliuyi { 385c29e5f0fSliuyi string::size_type pos(0); 386c30d921cSKever Yang 387c29e5f0fSliuyi if (strUuidInfo.size() <= 0) { 388c29e5f0fSliuyi return false; 389c29e5f0fSliuyi } 390c29e5f0fSliuyi pos = strUuidInfo.find('='); 391c29e5f0fSliuyi if (pos == string::npos) { 392c29e5f0fSliuyi return false; 393c29e5f0fSliuyi } 394c29e5f0fSliuyi strName = strUuidInfo.substr(0, pos); 395c29e5f0fSliuyi strName.erase(0, strName.find_first_not_of(" ")); 396c29e5f0fSliuyi strName.erase(strName.find_last_not_of(" ") + 1); 397c29e5f0fSliuyi 398c29e5f0fSliuyi strUUid = strUuidInfo.substr(pos+1); 399c29e5f0fSliuyi strUUid.erase(0, strUUid.find_first_not_of(" ")); 400c29e5f0fSliuyi strUUid.erase(strUUid.find_last_not_of(" ") + 1); 401c29e5f0fSliuyi 402c29e5f0fSliuyi while(true) { 403c29e5f0fSliuyi pos = 0; 404c29e5f0fSliuyi if( (pos = strUUid.find("-")) != string::npos) 405c29e5f0fSliuyi strUUid.replace(pos,1,""); 406c29e5f0fSliuyi else 407c29e5f0fSliuyi break; 408c29e5f0fSliuyi } 409c29e5f0fSliuyi if (strUUid.size() != 32) 410c29e5f0fSliuyi return false; 411c29e5f0fSliuyi return true; 412c29e5f0fSliuyi } 413c29e5f0fSliuyi 414c29e5f0fSliuyi 415c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 416c30d921cSKever Yang { 417c30d921cSKever Yang stringstream paramStream(pParameter); 418c30d921cSKever Yang bool bRet,bFind = false; 419c29e5f0fSliuyi string strLine, strPartition, strPartInfo, strPartName, strUUid; 420c30d921cSKever Yang string::size_type line_size, pos, posColon, posComma; 421c30d921cSKever Yang UINT uiPartOffset, uiPartSize; 422c30d921cSKever Yang STRUCT_PARAM_ITEM item; 423c29e5f0fSliuyi STRUCT_CONFIG_ITEM uuid_item; 424c30d921cSKever Yang vecItem.clear(); 425c29e5f0fSliuyi vecUuidItem.clear(); 426c30d921cSKever Yang while (!paramStream.eof()) { 427c30d921cSKever Yang getline(paramStream,strLine); 428c30d921cSKever Yang line_size = strLine.size(); 429c30d921cSKever Yang if (line_size == 0) 430c30d921cSKever Yang continue; 431c30d921cSKever Yang if (strLine[line_size - 1] == '\r'){ 432c30d921cSKever Yang strLine = strLine.substr(0, line_size - 1); 433c30d921cSKever Yang } 434c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 435c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 436c30d921cSKever Yang if (strLine.size()==0 ) 437c30d921cSKever Yang continue; 438c30d921cSKever Yang if (strLine[0] == '#') 439c30d921cSKever Yang continue; 440c29e5f0fSliuyi pos = strLine.find("uuid:"); 441c29e5f0fSliuyi if (pos != string::npos) { 442c29e5f0fSliuyi strPartInfo = strLine.substr(pos+5); 443c29e5f0fSliuyi bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid); 444c29e5f0fSliuyi if (bRet) { 445c29e5f0fSliuyi strcpy(uuid_item.szItemName, strPartName.c_str()); 446c29e5f0fSliuyi string_to_uuid(strUUid,uuid_item.szItemValue); 447c29e5f0fSliuyi vecUuidItem.push_back(uuid_item); 448c29e5f0fSliuyi } 449c29e5f0fSliuyi continue; 450c29e5f0fSliuyi } 451c29e5f0fSliuyi 452c30d921cSKever Yang pos = strLine.find("mtdparts"); 453c30d921cSKever Yang if (pos == string::npos) { 454c30d921cSKever Yang continue; 455c30d921cSKever Yang } 456c30d921cSKever Yang bFind = true; 457c30d921cSKever Yang posColon = strLine.find(':', pos); 458c30d921cSKever Yang if (posColon == string::npos) { 459c30d921cSKever Yang continue; 460c30d921cSKever Yang } 461c30d921cSKever Yang strPartition = strLine.substr(posColon + 1); 462c30d921cSKever Yang pos = 0; 463c30d921cSKever Yang posComma = strPartition.find(',', pos); 464c30d921cSKever Yang while (posComma != string::npos) { 465c30d921cSKever Yang strPartInfo = strPartition.substr(pos, posComma - pos); 466c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 467c30d921cSKever Yang if (bRet) { 468c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 469c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 470c30d921cSKever Yang item.uiItemSize = uiPartSize; 471c30d921cSKever Yang vecItem.push_back(item); 472c30d921cSKever Yang } 473c30d921cSKever Yang pos = posComma + 1; 474c30d921cSKever Yang posComma = strPartition.find(',', pos); 475c30d921cSKever Yang } 476c30d921cSKever Yang strPartInfo = strPartition.substr(pos); 477c30d921cSKever Yang if (strPartInfo.size() > 0) { 478c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 479c30d921cSKever Yang if (bRet) { 480c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 481c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 482c30d921cSKever Yang item.uiItemSize = uiPartSize; 483c30d921cSKever Yang vecItem.push_back(item); 484c30d921cSKever Yang } 485c30d921cSKever Yang } 486c30d921cSKever Yang } 487c30d921cSKever Yang return bFind; 488c30d921cSKever Yang 489c30d921cSKever Yang } 490c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 491c30d921cSKever Yang { 492c30d921cSKever Yang FILE *file = NULL; 493c30d921cSKever Yang file = fopen(pParamFile, "rb"); 494c30d921cSKever Yang if( !file ) { 495c30d921cSKever Yang if (g_pLogObject) 49632268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 497c30d921cSKever Yang return false; 498c30d921cSKever Yang } 499c30d921cSKever Yang int iFileSize; 500c30d921cSKever Yang fseek(file, 0, SEEK_END); 501c30d921cSKever Yang iFileSize = ftell(file); 502c30d921cSKever Yang fseek(file, 0, SEEK_SET); 503c30d921cSKever Yang char *pParamBuf = NULL; 504c30d921cSKever Yang pParamBuf = new char[iFileSize]; 505c30d921cSKever Yang if (!pParamBuf) { 506c30d921cSKever Yang fclose(file); 507c30d921cSKever Yang return false; 508c30d921cSKever Yang } 509c30d921cSKever Yang int iRead; 510c30d921cSKever Yang iRead = fread(pParamBuf, 1, iFileSize, file); 511c30d921cSKever Yang if (iRead != iFileSize) { 512c30d921cSKever Yang if (g_pLogObject) 51332268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize); 514c30d921cSKever Yang fclose(file); 515c30d921cSKever Yang delete []pParamBuf; 516c30d921cSKever Yang return false; 517c30d921cSKever Yang } 518c30d921cSKever Yang fclose(file); 519c30d921cSKever Yang bool bRet; 520c29e5f0fSliuyi bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem); 521c30d921cSKever Yang delete []pParamBuf; 522c30d921cSKever Yang return bRet; 523c30d921cSKever Yang } 5246ae612beSliuyi bool is_sparse_image(char *szImage) 5256ae612beSliuyi { 5266ae612beSliuyi FILE *file = NULL; 5276ae612beSliuyi sparse_header head; 5286ae612beSliuyi u32 uiRead; 5296ae612beSliuyi file = fopen(szImage, "rb"); 5306ae612beSliuyi if( !file ) { 5316ae612beSliuyi if (g_pLogObject) 5326ae612beSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage); 5336ae612beSliuyi return false; 5346ae612beSliuyi } 5356ae612beSliuyi uiRead = fread(&head, 1, sizeof(head), file); 5366ae612beSliuyi if (uiRead != sizeof(head)) { 5376ae612beSliuyi if (g_pLogObject) 5386ae612beSliuyi g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head)); 5396ae612beSliuyi fclose(file); 5406ae612beSliuyi return false; 5416ae612beSliuyi } 5426ae612beSliuyi fclose(file); 5436ae612beSliuyi if (head.magic!=SPARSE_HEADER_MAGIC) 5446ae612beSliuyi { 5456ae612beSliuyi return false; 5466ae612beSliuyi } 5476ae612beSliuyi return true; 5486ae612beSliuyi 5496ae612beSliuyi } 550*0dcb0a4cSliuyi bool is_ubifs_image(char *szImage) 551*0dcb0a4cSliuyi { 552*0dcb0a4cSliuyi FILE *file = NULL; 553*0dcb0a4cSliuyi u32 magic; 554*0dcb0a4cSliuyi u32 uiRead; 555*0dcb0a4cSliuyi file = fopen(szImage, "rb"); 556*0dcb0a4cSliuyi if( !file ) { 557*0dcb0a4cSliuyi if (g_pLogObject) 558*0dcb0a4cSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage); 559*0dcb0a4cSliuyi return false; 560*0dcb0a4cSliuyi } 561*0dcb0a4cSliuyi uiRead = fread(&magic, 1, sizeof(magic), file); 562*0dcb0a4cSliuyi if (uiRead != sizeof(magic)) { 563*0dcb0a4cSliuyi if (g_pLogObject) 564*0dcb0a4cSliuyi g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(magic)); 565*0dcb0a4cSliuyi fclose(file); 566*0dcb0a4cSliuyi return false; 567*0dcb0a4cSliuyi } 568*0dcb0a4cSliuyi fclose(file); 569*0dcb0a4cSliuyi if (magic!=UBI_HEADER_MAGIC) 570*0dcb0a4cSliuyi { 571*0dcb0a4cSliuyi return false; 572*0dcb0a4cSliuyi } 573*0dcb0a4cSliuyi return true; 574*0dcb0a4cSliuyi } 575c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin) 576c30d921cSKever Yang { 577c30d921cSKever Yang efi_guid_t id; 578c30d921cSKever Yang unsigned int *ptr = (unsigned int *)&id; 579c30d921cSKever Yang unsigned int i; 580c30d921cSKever Yang 581c30d921cSKever Yang /* Set all fields randomly */ 582c30d921cSKever Yang for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 583c30d921cSKever Yang *(ptr + i) = cpu_to_be32(rand()); 584c30d921cSKever Yang 585c30d921cSKever Yang id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 586c30d921cSKever Yang id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 587c30d921cSKever Yang 588c30d921cSKever Yang memcpy(uuid_bin, id.raw, sizeof(id)); 589c30d921cSKever Yang } 590c30d921cSKever Yang 591c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup) 592c29e5f0fSliuyi { 593c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 594c29e5f0fSliuyi gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE); 595c29e5f0fSliuyi u32 calc_crc32; 596c29e5f0fSliuyi u64 val; 597c29e5f0fSliuyi 598c29e5f0fSliuyi /* recalculate the values for the Backup GPT Header */ 599c29e5f0fSliuyi val = le64_to_cpu(gptMasterHead->my_lba); 600c29e5f0fSliuyi gptBackupHead->my_lba = gptMasterHead->alternate_lba; 601c29e5f0fSliuyi gptBackupHead->alternate_lba = cpu_to_le64(val); 602c29e5f0fSliuyi gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1); 603c29e5f0fSliuyi gptBackupHead->header_crc32 = 0; 604c29e5f0fSliuyi 605c29e5f0fSliuyi calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size)); 606c29e5f0fSliuyi gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32); 607c29e5f0fSliuyi } 6086ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end) 6096ae612beSliuyi { 6106ae612beSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 6116ae612beSliuyi gpt_entry *gptEntry = NULL; 6126ae612beSliuyi u32 i,j; 6136ae612beSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 6146ae612beSliuyi bool bFound = false; 6156ae612beSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 6166ae612beSliuyi 6176ae612beSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 6186ae612beSliuyi gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 6196ae612beSliuyi if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0) 6206ae612beSliuyi break; 6216ae612beSliuyi for (j = 0; j < strlen(pszName); j++) 6226ae612beSliuyi if (gptEntry->partition_name[j] != pszName[j]) 6236ae612beSliuyi break; 6246ae612beSliuyi if (gptEntry->partition_name[j] != 0) 6256ae612beSliuyi continue; 6266ae612beSliuyi if (j == strlen(pszName)) { 6276ae612beSliuyi bFound = true; 6286ae612beSliuyi break; 6296ae612beSliuyi } 6306ae612beSliuyi } 6316ae612beSliuyi if (bFound) { 6326ae612beSliuyi *lba = le64_to_cpu(gptEntry->starting_lba); 6336ae612beSliuyi *lba_end = le64_to_cpu(gptEntry->ending_lba); 6346ae612beSliuyi return true; 6356ae612beSliuyi } 6366ae612beSliuyi return false; 6376ae612beSliuyi } 638081d237aSliuyi bool get_lba_from_param(u8 *param, char *pszName, u32 *part_offset, u32 *part_size) 639081d237aSliuyi { 640081d237aSliuyi u32 i; 641081d237aSliuyi bool bFound = false, bRet; 642081d237aSliuyi PARAM_ITEM_VECTOR vecItem; 643081d237aSliuyi CONFIG_ITEM_VECTOR vecUuid; 644081d237aSliuyi 645081d237aSliuyi bRet = parse_parameter((char *)param, vecItem, vecUuid); 646081d237aSliuyi if (!bRet) 647081d237aSliuyi return false; 648081d237aSliuyi 649081d237aSliuyi for (i = 0; i < vecItem.size(); i++) { 650081d237aSliuyi if (strcasecmp(pszName, vecItem[i].szItemName)==0) { 651081d237aSliuyi bFound = true; 652081d237aSliuyi break; 653081d237aSliuyi } 654081d237aSliuyi } 655081d237aSliuyi if (bFound) { 656081d237aSliuyi *part_offset = vecItem[i].uiItemOffset; 657081d237aSliuyi *part_size = vecItem[i].uiItemSize; 658081d237aSliuyi return true; 659081d237aSliuyi } 660081d237aSliuyi return false; 661081d237aSliuyi } 662081d237aSliuyi 663c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector) 664c29e5f0fSliuyi { 665c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 666c29e5f0fSliuyi gpt_entry *gptLastPartEntry = NULL; 667c29e5f0fSliuyi u32 i; 668c29e5f0fSliuyi u64 old_disksize; 669c29e5f0fSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 670c29e5f0fSliuyi 671c29e5f0fSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 672c29e5f0fSliuyi old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1; 673c29e5f0fSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 674c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 675c29e5f0fSliuyi if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0) 676c29e5f0fSliuyi break; 677c29e5f0fSliuyi } 678c29e5f0fSliuyi i--; 679c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry)); 680c29e5f0fSliuyi 681c29e5f0fSliuyi gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1); 682c29e5f0fSliuyi gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34); 683c29e5f0fSliuyi 684c29e5f0fSliuyi if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition 685c29e5f0fSliuyi gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34); 686c29e5f0fSliuyi gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 687c29e5f0fSliuyi } 688c29e5f0fSliuyi gptMasterHead->header_crc32 = 0; 689c29e5f0fSliuyi gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header))); 690c29e5f0fSliuyi memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS); 691c29e5f0fSliuyi memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE); 692c29e5f0fSliuyi prepare_gpt_backup(master, backup); 693c29e5f0fSliuyi 694c29e5f0fSliuyi } 695c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup) 696c29e5f0fSliuyi { 697c29e5f0fSliuyi FILE *file = NULL; 698c29e5f0fSliuyi file = fopen(pParamFile, "rb"); 699c29e5f0fSliuyi if( !file ) { 700c29e5f0fSliuyi if (g_pLogObject) 701c29e5f0fSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 702c29e5f0fSliuyi return false; 703c29e5f0fSliuyi } 704c29e5f0fSliuyi int iFileSize; 705c29e5f0fSliuyi fseek(file, 0, SEEK_END); 706c29e5f0fSliuyi iFileSize = ftell(file); 707c29e5f0fSliuyi fseek(file, 0, SEEK_SET); 708c29e5f0fSliuyi if (iFileSize != 67 * SECTOR_SIZE) { 709c29e5f0fSliuyi if (g_pLogObject) 710c29e5f0fSliuyi g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile); 711c29e5f0fSliuyi fclose(file); 712c29e5f0fSliuyi return false; 713c29e5f0fSliuyi } 714c29e5f0fSliuyi 715c29e5f0fSliuyi int iRead; 716c29e5f0fSliuyi iRead = fread(master, 1, 34 * SECTOR_SIZE, file); 717c29e5f0fSliuyi if (iRead != 34 * SECTOR_SIZE) { 718c29e5f0fSliuyi if (g_pLogObject) 719c29e5f0fSliuyi g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE); 720c29e5f0fSliuyi fclose(file); 721c29e5f0fSliuyi return false; 722c29e5f0fSliuyi } 723c29e5f0fSliuyi iRead = fread(backup, 1, 33 * SECTOR_SIZE, file); 724c29e5f0fSliuyi if (iRead != 33 * SECTOR_SIZE) { 725c29e5f0fSliuyi if (g_pLogObject) 726c29e5f0fSliuyi g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE); 727c29e5f0fSliuyi fclose(file); 728c29e5f0fSliuyi return false; 729c29e5f0fSliuyi } 730c29e5f0fSliuyi fclose(file); 731c29e5f0fSliuyi return true; 732c29e5f0fSliuyi } 733c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors) 734c30d921cSKever Yang { 735c30d921cSKever Yang legacy_mbr *mbr = (legacy_mbr *)gpt; 736c30d921cSKever Yang gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 737c30d921cSKever Yang gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 738c30d921cSKever Yang u32 i,j; 739c29e5f0fSliuyi int pos; 740c30d921cSKever Yang string strPartName; 741c30d921cSKever Yang string::size_type colonPos; 742c30d921cSKever Yang /*1.protective mbr*/ 743c30d921cSKever Yang memset(gpt, 0, SECTOR_SIZE); 744c30d921cSKever Yang mbr->signature = MSDOS_MBR_SIGNATURE; 745c30d921cSKever Yang mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 746c30d921cSKever Yang mbr->partition_record[0].start_sect = 1; 747c30d921cSKever Yang mbr->partition_record[0].nr_sects = (u32)-1; 748c30d921cSKever Yang /*2.gpt header*/ 749c30d921cSKever Yang memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 750c30d921cSKever Yang gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 751c30d921cSKever Yang gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 752c30d921cSKever Yang gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 753c30d921cSKever Yang gptHead->my_lba = cpu_to_le64(1); 754c30d921cSKever Yang gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 755c30d921cSKever Yang gptHead->first_usable_lba = cpu_to_le64(34); 756c30d921cSKever Yang gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 757c30d921cSKever Yang gptHead->partition_entry_lba = cpu_to_le64(2); 758c30d921cSKever Yang gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 759c30d921cSKever Yang gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 760c30d921cSKever Yang gptHead->header_crc32 = 0; 761c30d921cSKever Yang gptHead->partition_entry_array_crc32 = 0; 762c30d921cSKever Yang gen_rand_uuid(gptHead->disk_guid.raw); 763c30d921cSKever Yang 764c30d921cSKever Yang /*3.gpt partition entry*/ 765c30d921cSKever Yang memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 766c30d921cSKever Yang for (i = 0; i < vecParts.size(); i++) { 767c30d921cSKever Yang gen_rand_uuid(gptEntry->partition_type_guid.raw); 768c30d921cSKever Yang gen_rand_uuid(gptEntry->unique_partition_guid.raw); 769c30d921cSKever Yang gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 770c30d921cSKever Yang gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 771c30d921cSKever Yang gptEntry->attributes.raw = 0; 772c30d921cSKever Yang strPartName = vecParts[i].szItemName; 773c30d921cSKever Yang colonPos = strPartName.find_first_of(':'); 774c30d921cSKever Yang if (colonPos != string::npos) { 775c30d921cSKever Yang if (strPartName.find("bootable") != string::npos) 776c30d921cSKever Yang gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 777c29e5f0fSliuyi if (strPartName.find("grow") != string::npos) 778c29e5f0fSliuyi gptEntry->ending_lba = cpu_to_le64(diskSectors - 34); 779c30d921cSKever Yang strPartName = strPartName.substr(0, colonPos); 780c30d921cSKever Yang vecParts[i].szItemName[strPartName.size()] = 0; 781c30d921cSKever Yang } 782c30d921cSKever Yang for (j = 0; j < strlen(vecParts[i].szItemName); j++) 783c30d921cSKever Yang gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 784c29e5f0fSliuyi if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1) 785c29e5f0fSliuyi memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16); 786c30d921cSKever Yang gptEntry++; 787c30d921cSKever Yang } 788c30d921cSKever Yang 789c30d921cSKever Yang gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 790c30d921cSKever Yang gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 791c30d921cSKever Yang 792c30d921cSKever Yang } 793b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag) 794c30d921cSKever Yang { 795c30d921cSKever Yang PRK28_IDB_SEC0 pSec0; 796c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 797c30d921cSKever Yang pSec0 = (PRK28_IDB_SEC0)pSector; 798c30d921cSKever Yang 799c30d921cSKever Yang pSec0->dwTag = 0x0FF0AA55; 800b38fe5fcSliuyi pSec0->uiRc4Flag = rc4Flag; 801c30d921cSKever Yang pSec0->usBootCode1Offset = 0x4; 802c30d921cSKever Yang pSec0->usBootCode2Offset = 0x4; 803c30d921cSKever Yang pSec0->usBootDataSize = usFlashDataSec; 804c30d921cSKever Yang pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 805c30d921cSKever Yang return true; 806c30d921cSKever Yang } 807c30d921cSKever Yang 808c30d921cSKever Yang 809c30d921cSKever Yang bool MakeSector1(PBYTE pSector) 810c30d921cSKever Yang { 811c30d921cSKever Yang PRK28_IDB_SEC1 pSec1; 812c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 813c30d921cSKever Yang pSec1 = (PRK28_IDB_SEC1)pSector; 814c30d921cSKever Yang 815c30d921cSKever Yang pSec1->usSysReservedBlock = 0xC; 816c30d921cSKever Yang pSec1->usDisk0Size = 0xFFFF; 817c30d921cSKever Yang pSec1->uiChipTag = 0x38324B52; 818c30d921cSKever Yang return true; 819c30d921cSKever Yang } 820c30d921cSKever Yang 821c30d921cSKever Yang bool MakeSector2(PBYTE pSector) 822c30d921cSKever Yang { 823c30d921cSKever Yang PRK28_IDB_SEC2 pSec2; 824c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 825c30d921cSKever Yang pSec2 = (PRK28_IDB_SEC2)pSector; 826c30d921cSKever Yang 827c30d921cSKever Yang strcpy(pSec2->szVcTag, "VC"); 828c30d921cSKever Yang strcpy(pSec2->szCrcTag, "CRC"); 829c30d921cSKever Yang return true; 830c30d921cSKever Yang } 831c30d921cSKever Yang 832c30d921cSKever Yang bool MakeSector3(PBYTE pSector) 833c30d921cSKever Yang { 834c30d921cSKever Yang memset(pSector,0,SECTOR_SIZE); 835c30d921cSKever Yang return true; 836c30d921cSKever Yang } 837c30d921cSKever Yang 838b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag) 839c30d921cSKever Yang { 840c30d921cSKever Yang RK28_IDB_SEC0 sector0Info; 841c30d921cSKever Yang RK28_IDB_SEC1 sector1Info; 842c30d921cSKever Yang RK28_IDB_SEC2 sector2Info; 843c30d921cSKever Yang RK28_IDB_SEC3 sector3Info; 844c30d921cSKever Yang UINT i; 845b38fe5fcSliuyi MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag); 846c30d921cSKever Yang MakeSector1((PBYTE)§or1Info); 847c30d921cSKever Yang if (!MakeSector2((PBYTE)§or2Info)) { 848c30d921cSKever Yang return -6; 849c30d921cSKever Yang } 850c30d921cSKever Yang if (!MakeSector3((PBYTE)§or3Info)) { 851c30d921cSKever Yang return -7; 852c30d921cSKever Yang } 853c30d921cSKever Yang sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 854c30d921cSKever Yang sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 855c30d921cSKever Yang sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 856c30d921cSKever Yang 857c30d921cSKever Yang memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 858c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 859c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 860b38fe5fcSliuyi 861b38fe5fcSliuyi if (rc4Flag) { 862b38fe5fcSliuyi for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++) 863b38fe5fcSliuyi P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE); 864b38fe5fcSliuyi for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++) 865b38fe5fcSliuyi P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE); 866b38fe5fcSliuyi } 867b38fe5fcSliuyi 868c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 869c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 870c30d921cSKever Yang 871c30d921cSKever Yang sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 872c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 873c30d921cSKever Yang for(i = 0; i < 4; i++) { 874c30d921cSKever Yang if(i == 1) { 875c30d921cSKever Yang continue; 876c30d921cSKever Yang } else { 877c30d921cSKever Yang P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 878c30d921cSKever Yang } 879c30d921cSKever Yang } 880c30d921cSKever Yang return 0; 881c30d921cSKever Yang } 882c30d921cSKever Yang 883c30d921cSKever Yang 88476af099aSliuyi 88576af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 88676af099aSliuyi { 88706ea143eSKlaus Goger if (((UINT)dev.emUsbType & uiSupportType) == (UINT)dev.emUsbType) 88876af099aSliuyi return true; 88976af099aSliuyi else 89076af099aSliuyi { 89176af099aSliuyi ERROR_COLOR_ATTR; 89232268622SAndreas Färber printf("The device does not support this operation!"); 89376af099aSliuyi NORMAL_COLOR_ATTR; 89476af099aSliuyi printf("\r\n"); 89576af099aSliuyi return false; 89676af099aSliuyi } 89776af099aSliuyi } 898081d237aSliuyi bool MakeParamBuffer(char *pParamFile, char* &pParamData) 899081d237aSliuyi { 900081d237aSliuyi FILE *file=NULL; 901081d237aSliuyi file = fopen(pParamFile, "rb"); 902081d237aSliuyi if( !file ) 903081d237aSliuyi { 904081d237aSliuyi if (g_pLogObject) 905081d237aSliuyi g_pLogObject->Record("MakeParamBuffer failed,err=%d,can't open file: %s\r\n", errno, pParamFile); 906081d237aSliuyi return false; 907081d237aSliuyi } 908081d237aSliuyi int iFileSize; 909081d237aSliuyi fseek(file,0,SEEK_END); 910081d237aSliuyi iFileSize = ftell(file); 911081d237aSliuyi fseek(file,0,SEEK_SET); 912081d237aSliuyi char *pParamBuf=NULL; 913081d237aSliuyi pParamBuf = new char[iFileSize + 12]; 914081d237aSliuyi if (!pParamBuf) 915081d237aSliuyi { 916081d237aSliuyi fclose(file); 917081d237aSliuyi return false; 918081d237aSliuyi } 919081d237aSliuyi memset(pParamBuf,0,iFileSize+12); 920081d237aSliuyi *(UINT *)(pParamBuf) = 0x4D524150; 921081d237aSliuyi 922081d237aSliuyi int iRead; 923081d237aSliuyi iRead = fread(pParamBuf+8,1,iFileSize,file); 924081d237aSliuyi if (iRead!=iFileSize) 925081d237aSliuyi { 926081d237aSliuyi if (g_pLogObject) 927081d237aSliuyi g_pLogObject->Record("MakeParamBuffer failed,err=%d,read=%d,total=%d\r\n", errno, iRead, iFileSize); 928081d237aSliuyi fclose(file); 929081d237aSliuyi delete []pParamBuf; 930081d237aSliuyi return false; 931081d237aSliuyi } 932081d237aSliuyi fclose(file); 933081d237aSliuyi 934081d237aSliuyi *(UINT *)(pParamBuf+4) = iFileSize; 935081d237aSliuyi *(UINT *)(pParamBuf+8+iFileSize) = CRC_32( (PBYTE)pParamBuf+8, iFileSize); 936081d237aSliuyi pParamData = pParamBuf; 937081d237aSliuyi return true; 938081d237aSliuyi } 939081d237aSliuyi 940081d237aSliuyi bool write_parameter(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 941081d237aSliuyi { 942081d237aSliuyi CRKComm *pComm = NULL; 943081d237aSliuyi char *pParamBuf = NULL, writeBuf[512*1024]; 944081d237aSliuyi int iRet, nParamSec, nParamSize; 945081d237aSliuyi bool bRet, bSuccess = false; 946081d237aSliuyi if (!check_device_type(dev, RKUSB_MASKROM|RKUSB_LOADER)) 947081d237aSliuyi return false; 948081d237aSliuyi 949081d237aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 950081d237aSliuyi if (!bRet) { 951081d237aSliuyi ERROR_COLOR_ATTR; 952081d237aSliuyi printf("Creating Comm Object failed!"); 953081d237aSliuyi NORMAL_COLOR_ATTR; 954081d237aSliuyi printf("\r\n"); 955081d237aSliuyi return bSuccess; 956081d237aSliuyi } 957081d237aSliuyi if (!MakeParamBuffer(szParameter, pParamBuf)) { 958081d237aSliuyi ERROR_COLOR_ATTR; 959081d237aSliuyi printf("Generating parameter failed!"); 960081d237aSliuyi NORMAL_COLOR_ATTR; 961081d237aSliuyi printf("\r\n"); 962081d237aSliuyi return bSuccess; 963081d237aSliuyi } 964081d237aSliuyi printf("Writing parameter...\r\n"); 965081d237aSliuyi nParamSize = *(UINT *)(pParamBuf+4) + 12; 966081d237aSliuyi nParamSec = BYTE2SECTOR(nParamSize); 967081d237aSliuyi if (nParamSec > 1024) { 968081d237aSliuyi ERROR_COLOR_ATTR; 969081d237aSliuyi printf("parameter is too large!"); 970081d237aSliuyi NORMAL_COLOR_ATTR; 971081d237aSliuyi printf("\r\n"); 972081d237aSliuyi return bSuccess; 973081d237aSliuyi } 974081d237aSliuyi memset(writeBuf, 0, nParamSec*512); 975081d237aSliuyi memcpy(writeBuf, pParamBuf, nParamSize); 976081d237aSliuyi iRet = pComm->RKU_WriteLBA(0x2000, nParamSec, (BYTE *)writeBuf); 977081d237aSliuyi if (iRet != ERR_SUCCESS) { 978081d237aSliuyi ERROR_COLOR_ATTR; 979081d237aSliuyi printf("Writing parameter failed!"); 980081d237aSliuyi NORMAL_COLOR_ATTR; 981081d237aSliuyi printf("\r\n"); 982081d237aSliuyi return bSuccess; 983081d237aSliuyi } 984081d237aSliuyi 985081d237aSliuyi bSuccess = true; 986081d237aSliuyi CURSOR_MOVEUP_LINE(1); 987081d237aSliuyi CURSOR_DEL_LINE; 988081d237aSliuyi printf("Writing parameter succeeded.\r\n"); 989081d237aSliuyi return bSuccess; 990081d237aSliuyi } 991081d237aSliuyi 992c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 993c30d921cSKever Yang { 994c30d921cSKever Yang u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 995c30d921cSKever Yang u32 total_size_sector; 996c30d921cSKever Yang CRKComm *pComm = NULL; 997c30d921cSKever Yang PARAM_ITEM_VECTOR vecItems; 998c29e5f0fSliuyi CONFIG_ITEM_VECTOR vecUuid; 999c30d921cSKever Yang int iRet; 1000c30d921cSKever Yang bool bRet, bSuccess = false; 1001c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 1002c30d921cSKever Yang return false; 1003c30d921cSKever Yang 1004c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1005c30d921cSKever Yang if (!bRet) { 1006c30d921cSKever Yang ERROR_COLOR_ATTR; 1007c30d921cSKever Yang printf("Creating Comm Object failed!"); 1008c30d921cSKever Yang NORMAL_COLOR_ATTR; 1009c30d921cSKever Yang printf("\r\n"); 1010c30d921cSKever Yang return bSuccess; 1011c30d921cSKever Yang } 101232268622SAndreas Färber printf("Writing gpt...\r\n"); 1013c30d921cSKever Yang //1.get flash info 1014c30d921cSKever Yang iRet = pComm->RKU_ReadFlashInfo(flash_info); 1015c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 1016c30d921cSKever Yang ERROR_COLOR_ATTR; 1017c30d921cSKever Yang printf("Reading Flash Info failed!"); 1018c30d921cSKever Yang NORMAL_COLOR_ATTR; 1019c30d921cSKever Yang printf("\r\n"); 1020c30d921cSKever Yang return bSuccess; 1021c30d921cSKever Yang } 1022c30d921cSKever Yang total_size_sector = *(u32 *)flash_info; 1023c29e5f0fSliuyi if (strstr(szParameter, ".img")) { 1024c29e5f0fSliuyi if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) { 1025c29e5f0fSliuyi ERROR_COLOR_ATTR; 1026c29e5f0fSliuyi printf("Loading partition image failed!"); 1027c29e5f0fSliuyi NORMAL_COLOR_ATTR; 1028c29e5f0fSliuyi printf("\r\n"); 1029c29e5f0fSliuyi return bSuccess; 1030c29e5f0fSliuyi } 1031c29e5f0fSliuyi update_gpt_disksize(master_gpt, backup_gpt, total_size_sector); 1032c29e5f0fSliuyi } else { 1033c30d921cSKever Yang //2.get partition from parameter 1034c29e5f0fSliuyi bRet = parse_parameter_file(szParameter, vecItems, vecUuid); 1035c30d921cSKever Yang if (!bRet) { 1036c30d921cSKever Yang ERROR_COLOR_ATTR; 1037c30d921cSKever Yang printf("Parsing parameter failed!"); 1038c30d921cSKever Yang NORMAL_COLOR_ATTR; 1039c30d921cSKever Yang printf("\r\n"); 1040c30d921cSKever Yang return bSuccess; 1041c30d921cSKever Yang } 1042c29e5f0fSliuyi vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33; 1043c30d921cSKever Yang //3.generate gpt info 1044c29e5f0fSliuyi create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector); 1045c30d921cSKever Yang memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 1046c30d921cSKever Yang memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 1047c29e5f0fSliuyi prepare_gpt_backup(master_gpt, backup_gpt); 1048c29e5f0fSliuyi } 1049c29e5f0fSliuyi 1050c30d921cSKever Yang //4. write gpt 1051c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 1052c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 1053c30d921cSKever Yang ERROR_COLOR_ATTR; 1054c30d921cSKever Yang printf("Writing master gpt failed!"); 1055c30d921cSKever Yang NORMAL_COLOR_ATTR; 1056c30d921cSKever Yang printf("\r\n"); 1057c30d921cSKever Yang return bSuccess; 1058c30d921cSKever Yang } 1059c29e5f0fSliuyi iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt); 1060c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 1061c30d921cSKever Yang ERROR_COLOR_ATTR; 1062c30d921cSKever Yang printf("Writing backup gpt failed!"); 1063c30d921cSKever Yang NORMAL_COLOR_ATTR; 1064c30d921cSKever Yang printf("\r\n"); 1065c30d921cSKever Yang return bSuccess; 1066c30d921cSKever Yang } 1067c29e5f0fSliuyi 1068c30d921cSKever Yang bSuccess = true; 1069c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 1070c30d921cSKever Yang CURSOR_DEL_LINE; 107132268622SAndreas Färber printf("Writing gpt succeeded.\r\n"); 1072c30d921cSKever Yang return bSuccess; 1073c30d921cSKever Yang } 107476af099aSliuyi 107578884ef4SEddie Cai #include "boot_merger.h" 107678884ef4SEddie Cai #define ENTRY_ALIGN (2048) 107778884ef4SEddie Cai options gOpts; 107878884ef4SEddie Cai 107978884ef4SEddie Cai 108078884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 108178884ef4SEddie Cai char* gConfigPath; 108278884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE]; 108378884ef4SEddie Cai 108478884ef4SEddie Cai static inline void fixPath(char* path) { 108578884ef4SEddie Cai int i, len = strlen(path); 108678884ef4SEddie Cai for(i=0; i<len; i++) { 108778884ef4SEddie Cai if (path[i] == '\\') 108878884ef4SEddie Cai path[i] = '/'; 108978884ef4SEddie Cai else if (path[i] == '\r' || path[i] == '\n') 109078884ef4SEddie Cai path[i] = '\0'; 109178884ef4SEddie Cai } 109278884ef4SEddie Cai } 109378884ef4SEddie Cai 109478884ef4SEddie Cai static bool parseChip(FILE* file) { 109578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 109678884ef4SEddie Cai return false; 109778884ef4SEddie Cai } 109878884ef4SEddie Cai if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 109978884ef4SEddie Cai return false; 110078884ef4SEddie Cai } 110178884ef4SEddie Cai printf("chip: %s\n", gOpts.chip); 110278884ef4SEddie Cai return true; 110378884ef4SEddie Cai } 110478884ef4SEddie Cai 110578884ef4SEddie Cai static bool parseVersion(FILE* file) { 110678884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 110778884ef4SEddie Cai return false; 110878884ef4SEddie Cai } 110978884ef4SEddie Cai if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 111078884ef4SEddie Cai return false; 111178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 111278884ef4SEddie Cai return false; 111378884ef4SEddie Cai } 111478884ef4SEddie Cai if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 111578884ef4SEddie Cai return false; 111678884ef4SEddie Cai printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor); 111778884ef4SEddie Cai return true; 111878884ef4SEddie Cai } 111978884ef4SEddie Cai 112078884ef4SEddie Cai static bool parse471(FILE* file) { 112178884ef4SEddie Cai int i, index, pos; 112278884ef4SEddie Cai char buf[MAX_LINE_LEN]; 112378884ef4SEddie Cai 112478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 112578884ef4SEddie Cai return false; 112678884ef4SEddie Cai } 112778884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 112878884ef4SEddie Cai return false; 112978884ef4SEddie Cai printf("num: %d\n", gOpts.code471Num); 113078884ef4SEddie Cai if (!gOpts.code471Num) 113178884ef4SEddie Cai return true; 113278884ef4SEddie Cai if (gOpts.code471Num < 0) 113378884ef4SEddie Cai return false; 113478884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 113578884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 113678884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 113778884ef4SEddie Cai return false; 113878884ef4SEddie Cai } 113978884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 114078884ef4SEddie Cai != 2) 114178884ef4SEddie Cai return false; 114278884ef4SEddie Cai index--; 114378884ef4SEddie Cai fixPath(buf); 114478884ef4SEddie Cai strcpy((char*)gOpts.code471Path[index], buf); 114578884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code471Path[index]); 114678884ef4SEddie Cai } 114778884ef4SEddie Cai pos = ftell(file); 114878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 114978884ef4SEddie Cai return false; 115078884ef4SEddie Cai } 115178884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 115278884ef4SEddie Cai fseek(file, pos, SEEK_SET); 115378884ef4SEddie Cai printf("sleep: %d\n", gOpts.code471Sleep); 115478884ef4SEddie Cai return true; 115578884ef4SEddie Cai } 115678884ef4SEddie Cai 115778884ef4SEddie Cai static bool parse472(FILE* file) { 115878884ef4SEddie Cai int i, index, pos; 115978884ef4SEddie Cai char buf[MAX_LINE_LEN]; 116078884ef4SEddie Cai 116178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 116278884ef4SEddie Cai return false; 116378884ef4SEddie Cai } 116478884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 116578884ef4SEddie Cai return false; 116678884ef4SEddie Cai printf("num: %d\n", gOpts.code472Num); 116778884ef4SEddie Cai if (!gOpts.code472Num) 116878884ef4SEddie Cai return true; 116978884ef4SEddie Cai if (gOpts.code472Num < 0) 117078884ef4SEddie Cai return false; 117178884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 117278884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 117378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 117478884ef4SEddie Cai return false; 117578884ef4SEddie Cai } 117678884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 117778884ef4SEddie Cai != 2) 117878884ef4SEddie Cai return false; 117978884ef4SEddie Cai fixPath(buf); 118078884ef4SEddie Cai index--; 118178884ef4SEddie Cai strcpy((char*)gOpts.code472Path[index], buf); 118278884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code472Path[index]); 118378884ef4SEddie Cai } 118478884ef4SEddie Cai pos = ftell(file); 118578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 118678884ef4SEddie Cai return false; 118778884ef4SEddie Cai } 118878884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 118978884ef4SEddie Cai fseek(file, pos, SEEK_SET); 119078884ef4SEddie Cai printf("sleep: %d\n", gOpts.code472Sleep); 119178884ef4SEddie Cai return true; 119278884ef4SEddie Cai } 119378884ef4SEddie Cai 119478884ef4SEddie Cai static bool parseLoader(FILE* file) { 119578884ef4SEddie Cai int i, j, index, pos; 119678884ef4SEddie Cai char buf[MAX_LINE_LEN]; 119778884ef4SEddie Cai char buf2[MAX_LINE_LEN]; 119878884ef4SEddie Cai 119978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 120078884ef4SEddie Cai return false; 120178884ef4SEddie Cai } 120278884ef4SEddie Cai pos = ftell(file); 120378884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 120478884ef4SEddie Cai fseek(file, pos, SEEK_SET); 120578884ef4SEddie Cai if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 120678884ef4SEddie Cai return false; 120778884ef4SEddie Cai } 120878884ef4SEddie Cai } 120978884ef4SEddie Cai printf("num: %d\n", gOpts.loaderNum); 121078884ef4SEddie Cai if (!gOpts.loaderNum) 121178884ef4SEddie Cai return false; 121278884ef4SEddie Cai if (gOpts.loaderNum < 0) 121378884ef4SEddie Cai return false; 121478884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 121578884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 121678884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 121778884ef4SEddie Cai return false; 121878884ef4SEddie Cai } 121978884ef4SEddie Cai if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 122078884ef4SEddie Cai != 2) 122178884ef4SEddie Cai return false; 122278884ef4SEddie Cai strcpy(gOpts.loader[index].name, buf); 122378884ef4SEddie Cai printf("name%d: %s\n", index, gOpts.loader[index].name); 1224544ec1d4SKlaus Goger index++; 122578884ef4SEddie Cai } 122678884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 122778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 122878884ef4SEddie Cai return false; 122978884ef4SEddie Cai } 123078884ef4SEddie Cai if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 123178884ef4SEddie Cai != 2) 123278884ef4SEddie Cai return false; 123378884ef4SEddie Cai for (j=0; j<gOpts.loaderNum; j++) { 123478884ef4SEddie Cai if (!strcmp(gOpts.loader[j].name, buf)) { 123578884ef4SEddie Cai fixPath(buf2); 123678884ef4SEddie Cai strcpy(gOpts.loader[j].path, buf2); 123778884ef4SEddie Cai printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 123878884ef4SEddie Cai break; 123978884ef4SEddie Cai } 124078884ef4SEddie Cai } 124178884ef4SEddie Cai if (j >= gOpts.loaderNum) { 124278884ef4SEddie Cai return false; 124378884ef4SEddie Cai } 124478884ef4SEddie Cai } 124578884ef4SEddie Cai return true; 124678884ef4SEddie Cai } 124778884ef4SEddie Cai 124878884ef4SEddie Cai static bool parseOut(FILE* file) { 124978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 125078884ef4SEddie Cai return false; 125178884ef4SEddie Cai } 125278884ef4SEddie Cai if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 125378884ef4SEddie Cai return false; 125478884ef4SEddie Cai fixPath(gOpts.outPath); 125578884ef4SEddie Cai printf("out: %s\n", gOpts.outPath); 125678884ef4SEddie Cai return true; 125778884ef4SEddie Cai } 125878884ef4SEddie Cai 125978884ef4SEddie Cai 126078884ef4SEddie Cai void printOpts(FILE* out) { 126178884ef4SEddie Cai int i; 126278884ef4SEddie Cai fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 126378884ef4SEddie Cai fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 126478884ef4SEddie Cai "=%d\n", gOpts.major, gOpts.minor); 126578884ef4SEddie Cai 126678884ef4SEddie Cai fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 126778884ef4SEddie Cai for (i=0 ;i<gOpts.code471Num ;i++) { 126878884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 126978884ef4SEddie Cai } 127078884ef4SEddie Cai if (gOpts.code471Sleep > 0) 127178884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 127278884ef4SEddie Cai 127378884ef4SEddie Cai fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 127478884ef4SEddie Cai for (i=0 ;i<gOpts.code472Num ;i++) { 127578884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 127678884ef4SEddie Cai } 127778884ef4SEddie Cai if (gOpts.code472Sleep > 0) 127878884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 127978884ef4SEddie Cai 128078884ef4SEddie Cai fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 128178884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 128278884ef4SEddie Cai fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 128378884ef4SEddie Cai } 128478884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 128578884ef4SEddie Cai fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 128678884ef4SEddie Cai } 128778884ef4SEddie Cai 128878884ef4SEddie Cai fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 128978884ef4SEddie Cai } 129078884ef4SEddie Cai 129178884ef4SEddie Cai static bool parseOpts(void) { 129278884ef4SEddie Cai bool ret = false; 129378884ef4SEddie Cai bool chipOk = false; 129478884ef4SEddie Cai bool versionOk = false; 129578884ef4SEddie Cai bool code471Ok = true; 129678884ef4SEddie Cai bool code472Ok = true; 129778884ef4SEddie Cai bool loaderOk = false; 129878884ef4SEddie Cai bool outOk = false; 129978884ef4SEddie Cai char buf[MAX_LINE_LEN]; 130078884ef4SEddie Cai 130178884ef4SEddie Cai char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 130278884ef4SEddie Cai FILE* file; 130378884ef4SEddie Cai file = fopen(configPath, "r"); 130478884ef4SEddie Cai if (!file) { 130578884ef4SEddie Cai fprintf(stderr, "config (%s) not found!\n", configPath); 130608c0d218SKlaus Goger if (strcmp(configPath, (char*)DEF_CONFIG_FILE) == 0) { 130778884ef4SEddie Cai file = fopen(DEF_CONFIG_FILE, "w"); 130878884ef4SEddie Cai if (file) { 130932268622SAndreas Färber fprintf(stderr, "creating defconfig\n"); 131078884ef4SEddie Cai printOpts(file); 131178884ef4SEddie Cai } 131278884ef4SEddie Cai } 131378884ef4SEddie Cai goto end; 131478884ef4SEddie Cai } 131578884ef4SEddie Cai 131632268622SAndreas Färber printf("Starting to parse...\n"); 131778884ef4SEddie Cai 131878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 131978884ef4SEddie Cai goto end; 132078884ef4SEddie Cai } 132178884ef4SEddie Cai while(fscanf(file, "%s", buf) == 1) { 132278884ef4SEddie Cai if (!strcmp(buf, SEC_CHIP)) { 132378884ef4SEddie Cai chipOk = parseChip(file); 132478884ef4SEddie Cai if (!chipOk) { 132578884ef4SEddie Cai printf("parseChip failed!\n"); 132678884ef4SEddie Cai goto end; 132778884ef4SEddie Cai } 132878884ef4SEddie Cai } else if (!strcmp(buf, SEC_VERSION)) { 132978884ef4SEddie Cai versionOk = parseVersion(file); 133078884ef4SEddie Cai if (!versionOk) { 133178884ef4SEddie Cai printf("parseVersion failed!\n"); 133278884ef4SEddie Cai goto end; 133378884ef4SEddie Cai } 133478884ef4SEddie Cai } else if (!strcmp(buf, SEC_471)) { 133578884ef4SEddie Cai code471Ok = parse471(file); 133678884ef4SEddie Cai if (!code471Ok) { 133778884ef4SEddie Cai printf("parse471 failed!\n"); 133878884ef4SEddie Cai goto end; 133978884ef4SEddie Cai } 134078884ef4SEddie Cai } else if (!strcmp(buf, SEC_472)) { 134178884ef4SEddie Cai code472Ok = parse472(file); 134278884ef4SEddie Cai if (!code472Ok) { 134378884ef4SEddie Cai printf("parse472 failed!\n"); 134478884ef4SEddie Cai goto end; 134578884ef4SEddie Cai } 134678884ef4SEddie Cai } else if (!strcmp(buf, SEC_LOADER)) { 134778884ef4SEddie Cai loaderOk = parseLoader(file); 134878884ef4SEddie Cai if (!loaderOk) { 134978884ef4SEddie Cai printf("parseLoader failed!\n"); 135078884ef4SEddie Cai goto end; 135178884ef4SEddie Cai } 135278884ef4SEddie Cai } else if (!strcmp(buf, SEC_OUT)) { 135378884ef4SEddie Cai outOk = parseOut(file); 135478884ef4SEddie Cai if (!outOk) { 135578884ef4SEddie Cai printf("parseOut failed!\n"); 135678884ef4SEddie Cai goto end; 135778884ef4SEddie Cai } 135878884ef4SEddie Cai } else if (buf[0] == '#') { 135978884ef4SEddie Cai continue; 136078884ef4SEddie Cai } else { 136178884ef4SEddie Cai printf("unknown sec: %s!\n", buf); 136278884ef4SEddie Cai goto end; 136378884ef4SEddie Cai } 136478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 136578884ef4SEddie Cai goto end; 136678884ef4SEddie Cai } 136778884ef4SEddie Cai } 136878884ef4SEddie Cai 136978884ef4SEddie Cai if (chipOk && versionOk && code471Ok && code472Ok 137078884ef4SEddie Cai && loaderOk && outOk) 137178884ef4SEddie Cai ret = true; 137278884ef4SEddie Cai end: 137378884ef4SEddie Cai if (file) 137478884ef4SEddie Cai fclose(file); 137578884ef4SEddie Cai return ret; 137678884ef4SEddie Cai } 137778884ef4SEddie Cai 137878884ef4SEddie Cai bool initOpts(void) { 137978884ef4SEddie Cai //set default opts 138078884ef4SEddie Cai gOpts.major = DEF_MAJOR; 138178884ef4SEddie Cai gOpts.minor = DEF_MINOR; 138278884ef4SEddie Cai strcpy(gOpts.chip, DEF_CHIP); 138378884ef4SEddie Cai gOpts.code471Sleep = DEF_CODE471_SLEEP; 138478884ef4SEddie Cai gOpts.code472Sleep = DEF_CODE472_SLEEP; 138578884ef4SEddie Cai gOpts.code471Num = DEF_CODE471_NUM; 138678884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 138778884ef4SEddie Cai strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 138878884ef4SEddie Cai gOpts.code472Num = DEF_CODE472_NUM; 138978884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 139078884ef4SEddie Cai strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 139178884ef4SEddie Cai gOpts.loaderNum = DEF_LOADER_NUM; 139278884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 139378884ef4SEddie Cai strcpy(gOpts.loader[0].name, DEF_LOADER0); 139478884ef4SEddie Cai strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 139578884ef4SEddie Cai strcpy(gOpts.loader[1].name, DEF_LOADER1); 139678884ef4SEddie Cai strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 139778884ef4SEddie Cai strcpy(gOpts.outPath, DEF_OUT_PATH); 139878884ef4SEddie Cai 139978884ef4SEddie Cai return parseOpts(); 140078884ef4SEddie Cai } 140178884ef4SEddie Cai 140278884ef4SEddie Cai /************merge code****************/ 140378884ef4SEddie Cai 140478884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) { 140578884ef4SEddie Cai uint8_t tmp[2] = {0}; 140678884ef4SEddie Cai int i; 140778884ef4SEddie Cai uint32_t ret; 140878884ef4SEddie Cai //if (value > 0xFFFF) { 140978884ef4SEddie Cai // return 0; 141078884ef4SEddie Cai //} 141178884ef4SEddie Cai for(i=0; i < 2; i++) { 141278884ef4SEddie Cai tmp[i] = (((value/10)%10)<<4) | (value%10); 141378884ef4SEddie Cai value /= 100; 141478884ef4SEddie Cai } 141578884ef4SEddie Cai ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 141678884ef4SEddie Cai 141778884ef4SEddie Cai printf("ret: %x\n",ret); 141878884ef4SEddie Cai return ret&0xFF; 141978884ef4SEddie Cai } 142078884ef4SEddie Cai 142178884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len) 142278884ef4SEddie Cai { 142378884ef4SEddie Cai int i; 142478884ef4SEddie Cai for (i = 0; i < len; i++) { 142578884ef4SEddie Cai wide[i] = (uint16_t) str[i]; 142678884ef4SEddie Cai } 142778884ef4SEddie Cai wide[len] = 0; 142878884ef4SEddie Cai } 142978884ef4SEddie Cai 143078884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) { 143178884ef4SEddie Cai char* end; 143278884ef4SEddie Cai char* start; 143378884ef4SEddie Cai int len; 143478884ef4SEddie Cai if (!path || !dst) 143578884ef4SEddie Cai return; 143678884ef4SEddie Cai start = strrchr(path, '/'); 143778884ef4SEddie Cai if (!start) 143878884ef4SEddie Cai start = path; 143978884ef4SEddie Cai else 144078884ef4SEddie Cai start++; 144178884ef4SEddie Cai end = strrchr(path, '.'); 1442641cfa16SEddie Cai if (!end || (end < start)) 144378884ef4SEddie Cai end = path + strlen(path); 144478884ef4SEddie Cai len = end - start; 144578884ef4SEddie Cai if (len >= MAX_NAME_LEN) 144678884ef4SEddie Cai len = MAX_NAME_LEN -1; 144778884ef4SEddie Cai str2wide(start, dst, len); 144878884ef4SEddie Cai 144978884ef4SEddie Cai 145078884ef4SEddie Cai char name[MAX_NAME_LEN]; 145178884ef4SEddie Cai memset(name, 0, sizeof(name)); 145278884ef4SEddie Cai memcpy(name, start, len); 145378884ef4SEddie Cai printf("path: %s, name: %s\n", path, name); 145478884ef4SEddie Cai 145578884ef4SEddie Cai } 145678884ef4SEddie Cai 145778884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) { 145878884ef4SEddie Cai struct stat st; 145978884ef4SEddie Cai if(stat(path, &st) < 0) 146078884ef4SEddie Cai return false; 146178884ef4SEddie Cai *size = st.st_size; 146278884ef4SEddie Cai printf("path: %s, size: %d\n", path, *size); 146378884ef4SEddie Cai return true; 146478884ef4SEddie Cai } 146578884ef4SEddie Cai 146678884ef4SEddie Cai static inline rk_time getTime(void) { 146778884ef4SEddie Cai rk_time rkTime; 146878884ef4SEddie Cai 146978884ef4SEddie Cai struct tm *tm; 147078884ef4SEddie Cai time_t tt = time(NULL); 147178884ef4SEddie Cai tm = localtime(&tt); 147278884ef4SEddie Cai rkTime.year = tm->tm_year + 1900; 147378884ef4SEddie Cai rkTime.month = tm->tm_mon + 1; 147478884ef4SEddie Cai rkTime.day = tm->tm_mday; 147578884ef4SEddie Cai rkTime.hour = tm->tm_hour; 147678884ef4SEddie Cai rkTime.minute = tm->tm_min; 147778884ef4SEddie Cai rkTime.second = tm->tm_sec; 147878884ef4SEddie Cai printf("%d-%d-%d %02d:%02d:%02d\n", 147978884ef4SEddie Cai rkTime.year, rkTime.month, rkTime.day, 148078884ef4SEddie Cai rkTime.hour, rkTime.minute, rkTime.second); 148178884ef4SEddie Cai return rkTime; 148278884ef4SEddie Cai } 148378884ef4SEddie Cai 148478884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) { 148578884ef4SEddie Cai bool ret = false; 148678884ef4SEddie Cai uint32_t size = 0, fixSize = 0; 148778884ef4SEddie Cai uint8_t* buf; 148878884ef4SEddie Cai 148978884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 149078884ef4SEddie Cai if (!inFile) 149178884ef4SEddie Cai goto end; 149278884ef4SEddie Cai 149378884ef4SEddie Cai if (!getFileSize(path, &size)) 149478884ef4SEddie Cai goto end; 149578884ef4SEddie Cai if (fix) { 149678884ef4SEddie Cai fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 149778884ef4SEddie Cai uint32_t tmp = fixSize % ENTRY_ALIGN; 149878884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 149978884ef4SEddie Cai fixSize +=tmp; 150078884ef4SEddie Cai memset(gBuf, 0, fixSize); 150178884ef4SEddie Cai } else { 150278884ef4SEddie Cai memset(gBuf, 0, size+ENTRY_ALIGN); 150378884ef4SEddie Cai } 150478884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 150578884ef4SEddie Cai goto end; 150678884ef4SEddie Cai 150778884ef4SEddie Cai if (fix) { 150878884ef4SEddie Cai 150978884ef4SEddie Cai buf = gBuf; 151078884ef4SEddie Cai size = fixSize; 151178884ef4SEddie Cai while(1) { 151278884ef4SEddie Cai P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 151378884ef4SEddie Cai buf += SMALL_PACKET; 151478884ef4SEddie Cai if (fixSize <= SMALL_PACKET) 151578884ef4SEddie Cai break; 151678884ef4SEddie Cai fixSize -= SMALL_PACKET; 151778884ef4SEddie Cai } 151878884ef4SEddie Cai } else { 151978884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 152078884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 152178884ef4SEddie Cai size +=tmp; 152278884ef4SEddie Cai P_RC4(gBuf, size); 152378884ef4SEddie Cai } 152478884ef4SEddie Cai 152578884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 152678884ef4SEddie Cai goto end; 152778884ef4SEddie Cai ret = true; 152878884ef4SEddie Cai end: 152978884ef4SEddie Cai if (inFile) 153078884ef4SEddie Cai fclose(inFile); 153178884ef4SEddie Cai if (!ret) 153232268622SAndreas Färber printf("writing entry (%s) failed\n", path); 153378884ef4SEddie Cai return ret; 153478884ef4SEddie Cai } 153578884ef4SEddie Cai 153678884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 153778884ef4SEddie Cai uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 153878884ef4SEddie Cai uint32_t size; 153978884ef4SEddie Cai rk_boot_entry entry; 154078884ef4SEddie Cai 154132268622SAndreas Färber printf("writing: %s\n", path); 1542641cfa16SEddie Cai memset(&entry, 0, sizeof(rk_boot_entry)); 154378884ef4SEddie Cai getName(fixName ? fixName: path, entry.name); 154478884ef4SEddie Cai entry.size = sizeof(rk_boot_entry); 154578884ef4SEddie Cai entry.type = type; 154678884ef4SEddie Cai entry.dataOffset = *offset; 154778884ef4SEddie Cai if (!getFileSize(path, &size)) { 154832268622SAndreas Färber printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path); 154978884ef4SEddie Cai return false; 155078884ef4SEddie Cai } 155178884ef4SEddie Cai if (fix) 155278884ef4SEddie Cai size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 155378884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 155478884ef4SEddie Cai size += tmp ? (ENTRY_ALIGN - tmp): 0; 155532268622SAndreas Färber printf("alignment size: %d\n", size); 155678884ef4SEddie Cai entry.dataSize = size; 155778884ef4SEddie Cai entry.dataDelay = delay; 155878884ef4SEddie Cai *offset += size; 155978884ef4SEddie Cai fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 156078884ef4SEddie Cai return true; 156178884ef4SEddie Cai } 156278884ef4SEddie Cai 156378884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) { 156478884ef4SEddie Cai char buffer[5]; 156578884ef4SEddie Cai memset(buffer, 0, sizeof(buffer)); 156678884ef4SEddie Cai snprintf(buffer, sizeof(buffer), "%s", chip); 156778884ef4SEddie Cai return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 156878884ef4SEddie Cai } 156978884ef4SEddie Cai 157078884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) { 157178884ef4SEddie Cai printf("chip: %s\n", chip); 157278884ef4SEddie Cai int chipType = RKNONE_DEVICE; 157378884ef4SEddie Cai if(!chip) { 157478884ef4SEddie Cai goto end; 157578884ef4SEddie Cai } 157678884ef4SEddie Cai if (!strcmp(chip, CHIP_RK28)) { 157778884ef4SEddie Cai chipType = RK28_DEVICE; 157878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK28)) { 157978884ef4SEddie Cai chipType = RK28_DEVICE; 158078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK281X)) { 158178884ef4SEddie Cai chipType = RK281X_DEVICE; 158278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKPANDA)) { 158378884ef4SEddie Cai chipType = RKPANDA_DEVICE; 158478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK27)) { 158578884ef4SEddie Cai chipType = RK27_DEVICE; 158678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKNANO)) { 158778884ef4SEddie Cai chipType = RKNANO_DEVICE; 158878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKSMART)) { 158978884ef4SEddie Cai chipType = RKSMART_DEVICE; 159078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCROWN)) { 159178884ef4SEddie Cai chipType = RKCROWN_DEVICE; 159278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 159378884ef4SEddie Cai chipType = RKCAYMAN_DEVICE; 159478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK29)) { 159578884ef4SEddie Cai chipType = RK29_DEVICE; 159678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK292X)) { 159778884ef4SEddie Cai chipType = RK292X_DEVICE; 159878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30)) { 159978884ef4SEddie Cai chipType = RK30_DEVICE; 160078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30B)) { 160178884ef4SEddie Cai chipType = RK30B_DEVICE; 160278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK31)) { 160378884ef4SEddie Cai chipType = RK31_DEVICE; 160478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK32)) { 160578884ef4SEddie Cai chipType = RK32_DEVICE; 160678884ef4SEddie Cai } else { 160778884ef4SEddie Cai chipType = convertChipType(chip + 2); 160878884ef4SEddie Cai } 160978884ef4SEddie Cai 161078884ef4SEddie Cai end: 161178884ef4SEddie Cai printf("type: 0x%x\n", chipType); 161278884ef4SEddie Cai if (chipType == RKNONE_DEVICE) { 161332268622SAndreas Färber printf("chip type not supported!\n"); 161478884ef4SEddie Cai } 161578884ef4SEddie Cai return chipType; 161678884ef4SEddie Cai } 161778884ef4SEddie Cai 161878884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) { 161978884ef4SEddie Cai memset(hdr, 0, sizeof(rk_boot_header)); 162078884ef4SEddie Cai hdr->tag = TAG; 162178884ef4SEddie Cai hdr->size = sizeof(rk_boot_header); 162278884ef4SEddie Cai hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 162378884ef4SEddie Cai hdr->mergerVersion = MERGER_VERSION; 162478884ef4SEddie Cai hdr->releaseTime = getTime(); 162578884ef4SEddie Cai hdr->chipType = getChipType(gOpts.chip); 162678884ef4SEddie Cai 162778884ef4SEddie Cai hdr->code471Num = gOpts.code471Num; 162878884ef4SEddie Cai hdr->code471Offset = sizeof(rk_boot_header); 162978884ef4SEddie Cai hdr->code471Size = sizeof(rk_boot_entry); 163078884ef4SEddie Cai 163178884ef4SEddie Cai hdr->code472Num = gOpts.code472Num; 163278884ef4SEddie Cai hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 163378884ef4SEddie Cai hdr->code472Size = sizeof(rk_boot_entry); 163478884ef4SEddie Cai 163578884ef4SEddie Cai hdr->loaderNum = gOpts.loaderNum; 163678884ef4SEddie Cai hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 163778884ef4SEddie Cai hdr->loaderSize = sizeof(rk_boot_entry); 163878884ef4SEddie Cai #ifndef USE_P_RC4 163978884ef4SEddie Cai hdr->rc4Flag = 1; 164078884ef4SEddie Cai #endif 164178884ef4SEddie Cai } 164278884ef4SEddie Cai 164378884ef4SEddie Cai static inline uint32_t getCrc(const char* path) { 164478884ef4SEddie Cai uint32_t size = 0; 164578884ef4SEddie Cai uint32_t crc = 0; 164678884ef4SEddie Cai 164778884ef4SEddie Cai FILE* file = fopen(path, "rb"); 164878884ef4SEddie Cai getFileSize(path, &size); 164978884ef4SEddie Cai if (!file) 165078884ef4SEddie Cai goto end; 165178884ef4SEddie Cai if (!fread(gBuf, size, 1, file)) 165278884ef4SEddie Cai goto end; 165378884ef4SEddie Cai crc = CRC_32(gBuf, size); 165478884ef4SEddie Cai printf("crc: 0x%08x\n", crc); 165578884ef4SEddie Cai end: 165678884ef4SEddie Cai if (file) 165778884ef4SEddie Cai fclose(file); 165878884ef4SEddie Cai return crc; 165978884ef4SEddie Cai } 166078884ef4SEddie Cai 166178884ef4SEddie Cai bool mergeBoot(void) { 166278884ef4SEddie Cai uint32_t dataOffset; 166378884ef4SEddie Cai bool ret = false; 166478884ef4SEddie Cai int i; 166578884ef4SEddie Cai FILE* outFile; 166678884ef4SEddie Cai uint32_t crc; 166778884ef4SEddie Cai rk_boot_header hdr; 166878884ef4SEddie Cai 166978884ef4SEddie Cai if (!initOpts()) 167078884ef4SEddie Cai return false; 167178884ef4SEddie Cai { 167278884ef4SEddie Cai char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 167378884ef4SEddie Cai char version[MAX_LINE_LEN]; 167478884ef4SEddie Cai snprintf(version, sizeof(version), "%s", gSubfix); 167578884ef4SEddie Cai if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 167678884ef4SEddie Cai subfix[0] = '\0'; 167778884ef4SEddie Cai } 167878884ef4SEddie Cai strcat(gOpts.outPath, version); 167978884ef4SEddie Cai printf("fix opt: %s\n", gOpts.outPath); 168078884ef4SEddie Cai } 168178884ef4SEddie Cai 168278884ef4SEddie Cai printf("---------------\nUSING CONFIG:\n"); 168378884ef4SEddie Cai printOpts(stdout); 168478884ef4SEddie Cai printf("---------------\n\n"); 168578884ef4SEddie Cai 168678884ef4SEddie Cai 168778884ef4SEddie Cai outFile = fopen(gOpts.outPath, "wb+"); 168878884ef4SEddie Cai if (!outFile) { 168932268622SAndreas Färber printf("Opening output file (%s) failed\n", gOpts.outPath); 169078884ef4SEddie Cai goto end; 169178884ef4SEddie Cai } 169278884ef4SEddie Cai 169378884ef4SEddie Cai getBoothdr(&hdr); 169432268622SAndreas Färber printf("Writing header...\n"); 169578884ef4SEddie Cai fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 169678884ef4SEddie Cai 169778884ef4SEddie Cai dataOffset = sizeof(rk_boot_header) + 169878884ef4SEddie Cai (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 169978884ef4SEddie Cai sizeof(rk_boot_entry); 170078884ef4SEddie Cai 170132268622SAndreas Färber printf("Writing code 471 entry...\n"); 170278884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 170378884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 170478884ef4SEddie Cai &dataOffset, NULL, false)) 170578884ef4SEddie Cai goto end; 170678884ef4SEddie Cai } 170732268622SAndreas Färber printf("Writing code 472 entry...\n"); 170878884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 170978884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 171078884ef4SEddie Cai &dataOffset, NULL, false)) 171178884ef4SEddie Cai goto end; 171278884ef4SEddie Cai } 171332268622SAndreas Färber printf("Writing loader entry...\n"); 171478884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 171578884ef4SEddie Cai if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 171678884ef4SEddie Cai &dataOffset, gOpts.loader[i].name, true)) 171778884ef4SEddie Cai goto end; 171878884ef4SEddie Cai } 171978884ef4SEddie Cai 172032268622SAndreas Färber printf("Writing code 471...\n"); 172178884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 172278884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 172378884ef4SEddie Cai goto end; 172478884ef4SEddie Cai } 172532268622SAndreas Färber printf("Writing code 472...\n"); 172678884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 172778884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 172878884ef4SEddie Cai goto end; 172978884ef4SEddie Cai } 173032268622SAndreas Färber printf("Writing loader...\n"); 173178884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 173278884ef4SEddie Cai if (!writeFile(outFile, gOpts.loader[i].path, true)) 173378884ef4SEddie Cai goto end; 173478884ef4SEddie Cai } 173578884ef4SEddie Cai fflush(outFile); 173678884ef4SEddie Cai 173732268622SAndreas Färber printf("Writing crc...\n"); 173878884ef4SEddie Cai crc = getCrc(gOpts.outPath); 173978884ef4SEddie Cai if (!fwrite(&crc, sizeof(crc), 1, outFile)) 174078884ef4SEddie Cai goto end; 174132268622SAndreas Färber printf("Done.\n"); 174278884ef4SEddie Cai ret = true; 174378884ef4SEddie Cai end: 174478884ef4SEddie Cai if (outFile) 174578884ef4SEddie Cai fclose(outFile); 174678884ef4SEddie Cai return ret; 174778884ef4SEddie Cai } 174878884ef4SEddie Cai 174978884ef4SEddie Cai /************merge code end************/ 175078884ef4SEddie Cai /************unpack code***************/ 175178884ef4SEddie Cai 175278884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len) 175378884ef4SEddie Cai { 175478884ef4SEddie Cai int i; 175578884ef4SEddie Cai for (i = 0; i < len; i++) { 175678884ef4SEddie Cai str[i] = (char) (wide[i] & 0xFF); 175778884ef4SEddie Cai } 175878884ef4SEddie Cai } 175978884ef4SEddie Cai 176078884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name, 176178884ef4SEddie Cai FILE* inFile) { 176278884ef4SEddie Cai bool ret = false; 176378884ef4SEddie Cai int size, i; 176478884ef4SEddie Cai FILE* outFile = fopen(name, "wb+"); 176578884ef4SEddie Cai if (!outFile) 176678884ef4SEddie Cai goto end; 176732268622SAndreas Färber printf("unpacking entry (%s)\n", name); 176878884ef4SEddie Cai fseek(inFile, entry->dataOffset, SEEK_SET); 176978884ef4SEddie Cai size = entry->dataSize; 177078884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 177178884ef4SEddie Cai goto end; 177278884ef4SEddie Cai if (entry->type == ENTRY_LOADER) { 177378884ef4SEddie Cai for(i=0; i<size/SMALL_PACKET; i++) 177478884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 177578884ef4SEddie Cai if (size % SMALL_PACKET) 177678884ef4SEddie Cai { 177778884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 177878884ef4SEddie Cai } 177978884ef4SEddie Cai } else { 178078884ef4SEddie Cai P_RC4(gBuf, size); 178178884ef4SEddie Cai } 178278884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 178378884ef4SEddie Cai goto end; 178478884ef4SEddie Cai ret = true; 178578884ef4SEddie Cai end: 178678884ef4SEddie Cai if (outFile) 178778884ef4SEddie Cai fclose(outFile); 178878884ef4SEddie Cai return ret; 178978884ef4SEddie Cai } 179078884ef4SEddie Cai 179178884ef4SEddie Cai bool unpackBoot(char* path) { 179278884ef4SEddie Cai bool ret = false; 179378884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 179478884ef4SEddie Cai int entryNum, i; 179578884ef4SEddie Cai char name[MAX_NAME_LEN]; 179678884ef4SEddie Cai rk_boot_entry* entrys; 179778884ef4SEddie Cai if (!inFile) { 179878884ef4SEddie Cai fprintf(stderr, "loader (%s) not found\n", path); 179978884ef4SEddie Cai goto end; 180078884ef4SEddie Cai } 180178884ef4SEddie Cai 180278884ef4SEddie Cai rk_boot_header hdr; 180378884ef4SEddie Cai if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 180432268622SAndreas Färber fprintf(stderr, "reading header failed\n"); 180578884ef4SEddie Cai goto end; 180678884ef4SEddie Cai } 180778884ef4SEddie Cai printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 180878884ef4SEddie Cai entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 180978884ef4SEddie Cai entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 181078884ef4SEddie Cai if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 181132268622SAndreas Färber fprintf(stderr, "reading data failed\n"); 181278884ef4SEddie Cai goto end; 181378884ef4SEddie Cai } 181478884ef4SEddie Cai 181578884ef4SEddie Cai printf("entry num: %d\n", entryNum); 181678884ef4SEddie Cai for (i=0; i<entryNum; i++) { 181778884ef4SEddie Cai wide2str(entrys[i].name, name, MAX_NAME_LEN); 181878884ef4SEddie Cai 181978884ef4SEddie Cai printf("entry: t=%d, name=%s, off=%d, size=%d\n", 182078884ef4SEddie Cai entrys[i].type, name, entrys[i].dataOffset, 182178884ef4SEddie Cai entrys[i].dataSize); 182278884ef4SEddie Cai if (!unpackEntry(entrys + i, name, inFile)) { 182332268622SAndreas Färber fprintf(stderr, "unpacking entry (%s) failed\n", name); 182478884ef4SEddie Cai goto end; 182578884ef4SEddie Cai } 182678884ef4SEddie Cai } 182778884ef4SEddie Cai printf("done\n"); 182878884ef4SEddie Cai ret = true; 182978884ef4SEddie Cai end: 183078884ef4SEddie Cai if (inFile) 183178884ef4SEddie Cai fclose(inFile); 183278884ef4SEddie Cai return ret; 183378884ef4SEddie Cai } 183478884ef4SEddie Cai 183576af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 183676af099aSliuyi { 183776af099aSliuyi if (!check_device_type(dev, RKUSB_MASKROM)) 183876af099aSliuyi return false; 183976af099aSliuyi CRKImage *pImage = NULL; 184076af099aSliuyi CRKBoot *pBoot = NULL; 184176af099aSliuyi bool bRet, bSuccess = false; 184276af099aSliuyi int iRet; 184376af099aSliuyi 184476af099aSliuyi pImage = new CRKImage(szLoader, bRet); 184576af099aSliuyi if (!bRet){ 184676af099aSliuyi ERROR_COLOR_ATTR; 184732268622SAndreas Färber printf("Opening loader failed, exiting download boot!"); 184876af099aSliuyi NORMAL_COLOR_ATTR; 184976af099aSliuyi printf("\r\n"); 185076af099aSliuyi return bSuccess; 185176af099aSliuyi } else { 185276af099aSliuyi pBoot = (CRKBoot *)pImage->m_bootObject; 185376af099aSliuyi CRKComm *pComm = NULL; 185476af099aSliuyi CRKDevice *pDevice = NULL; 185576af099aSliuyi 185676af099aSliuyi dev.emDeviceType = pBoot->SupportDevice; 185776af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 185876af099aSliuyi if (!bRet) { 185976af099aSliuyi if (pImage) 186076af099aSliuyi delete pImage; 186176af099aSliuyi ERROR_COLOR_ATTR; 186276af099aSliuyi printf("Creating Comm Object failed!"); 186376af099aSliuyi NORMAL_COLOR_ATTR; 186476af099aSliuyi printf("\r\n"); 186576af099aSliuyi return bSuccess; 186676af099aSliuyi } 186776af099aSliuyi 186876af099aSliuyi pDevice = new CRKDevice(dev); 186976af099aSliuyi if (!pDevice) { 187076af099aSliuyi if (pImage) 187176af099aSliuyi delete pImage; 187276af099aSliuyi if (pComm) 187376af099aSliuyi delete pComm; 187476af099aSliuyi ERROR_COLOR_ATTR; 187576af099aSliuyi printf("Creating device object failed!"); 187676af099aSliuyi NORMAL_COLOR_ATTR; 187776af099aSliuyi printf("\r\n"); 187876af099aSliuyi return bSuccess; 187976af099aSliuyi } 188076af099aSliuyi 188176af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 188232268622SAndreas Färber printf("Downloading bootloader...\r\n"); 188376af099aSliuyi iRet = pDevice->DownloadBoot(); 188476af099aSliuyi 188576af099aSliuyi CURSOR_MOVEUP_LINE(1); 188676af099aSliuyi CURSOR_DEL_LINE; 188776af099aSliuyi if (iRet == 0) { 188876af099aSliuyi bSuccess = true; 188932268622SAndreas Färber printf("Downloading bootloader succeeded.\r\n"); 189076af099aSliuyi } 189176af099aSliuyi else 189232268622SAndreas Färber printf("Downloading bootloader failed!\r\n"); 189376af099aSliuyi 189476af099aSliuyi if (pImage) 189576af099aSliuyi delete pImage; 189676af099aSliuyi if(pDevice) 189776af099aSliuyi delete pDevice; 189876af099aSliuyi } 189976af099aSliuyi return bSuccess; 190076af099aSliuyi } 1901c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1902c30d921cSKever Yang { 1903c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 1904c30d921cSKever Yang return false; 1905c30d921cSKever Yang CRKImage *pImage = NULL; 1906c30d921cSKever Yang CRKBoot *pBoot = NULL; 1907c30d921cSKever Yang CRKComm *pComm = NULL; 1908c30d921cSKever Yang bool bRet, bSuccess = false; 1909c30d921cSKever Yang int iRet; 1910aca206f7SPeter Robinson signed char index; 1911c30d921cSKever Yang USHORT usFlashDataSec, usFlashBootSec; 1912c30d921cSKever Yang DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1913c30d921cSKever Yang char loaderCodeName[] = "FlashBoot"; 1914c30d921cSKever Yang char loaderDataName[] = "FlashData"; 1915c30d921cSKever Yang PBYTE loaderCodeBuffer = NULL; 1916c30d921cSKever Yang PBYTE loaderDataBuffer = NULL; 1917c30d921cSKever Yang PBYTE pIDBData = NULL; 1918c30d921cSKever Yang pImage = new CRKImage(szLoader, bRet); 1919c30d921cSKever Yang if (!bRet){ 1920c30d921cSKever Yang ERROR_COLOR_ATTR; 192132268622SAndreas Färber printf("Opening loader failed, exiting upgrade loader!"); 1922c30d921cSKever Yang NORMAL_COLOR_ATTR; 1923c30d921cSKever Yang printf("\r\n"); 1924c30d921cSKever Yang goto Exit_UpgradeLoader; 1925c30d921cSKever Yang } else { 1926c30d921cSKever Yang pBoot = (CRKBoot *)pImage->m_bootObject; 1927c30d921cSKever Yang dev.emDeviceType = pBoot->SupportDevice; 1928c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1929c30d921cSKever Yang if (!bRet) { 1930c30d921cSKever Yang ERROR_COLOR_ATTR; 1931c30d921cSKever Yang printf("Creating Comm Object failed!"); 1932c30d921cSKever Yang NORMAL_COLOR_ATTR; 1933c30d921cSKever Yang printf("\r\n"); 1934c30d921cSKever Yang goto Exit_UpgradeLoader; 1935c30d921cSKever Yang } 1936c30d921cSKever Yang 193732268622SAndreas Färber printf("Upgrading loader...\r\n"); 1938c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1939c30d921cSKever Yang if (index == -1) { 1940c30d921cSKever Yang if (g_pLogObject) { 194132268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__); 1942c30d921cSKever Yang } 1943c30d921cSKever Yang goto Exit_UpgradeLoader; 1944c30d921cSKever Yang } 1945c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1946c30d921cSKever Yang if (!bRet) { 1947c30d921cSKever Yang if (g_pLogObject) { 194832268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__); 1949c30d921cSKever Yang } 1950c30d921cSKever Yang goto Exit_UpgradeLoader; 1951c30d921cSKever Yang } 1952c30d921cSKever Yang 1953c30d921cSKever Yang loaderCodeBuffer = new BYTE[dwLoaderSize]; 1954c30d921cSKever Yang memset(loaderCodeBuffer, 0, dwLoaderSize); 1955c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1956c30d921cSKever Yang if (g_pLogObject) { 195732268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__); 1958c30d921cSKever Yang } 1959c30d921cSKever Yang goto Exit_UpgradeLoader; 1960c30d921cSKever Yang } 1961c30d921cSKever Yang 1962c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1963c30d921cSKever Yang if (index == -1) { 1964c30d921cSKever Yang if (g_pLogObject) { 196532268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__); 1966c30d921cSKever Yang } 1967c30d921cSKever Yang delete []loaderCodeBuffer; 1968c30d921cSKever Yang return -4; 1969c30d921cSKever Yang } 1970c30d921cSKever Yang 1971c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1972c30d921cSKever Yang if (!bRet) { 1973c30d921cSKever Yang if (g_pLogObject) { 197432268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__); 1975c30d921cSKever Yang } 1976c30d921cSKever Yang goto Exit_UpgradeLoader; 1977c30d921cSKever Yang } 1978c30d921cSKever Yang 1979c30d921cSKever Yang loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1980c30d921cSKever Yang memset(loaderDataBuffer, 0, dwLoaderDataSize); 1981c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1982c30d921cSKever Yang if (g_pLogObject) { 198332268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__); 1984c30d921cSKever Yang } 1985c30d921cSKever Yang goto Exit_UpgradeLoader; 1986c30d921cSKever Yang } 1987c30d921cSKever Yang 1988c30d921cSKever Yang usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1989c30d921cSKever Yang usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1990c30d921cSKever Yang dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1991c30d921cSKever Yang pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1992c30d921cSKever Yang if (!pIDBData) { 1993c30d921cSKever Yang ERROR_COLOR_ATTR; 199432268622SAndreas Färber printf("Allocating memory failed!"); 1995c30d921cSKever Yang NORMAL_COLOR_ATTR; 1996c30d921cSKever Yang printf("\r\n"); 1997c30d921cSKever Yang goto Exit_UpgradeLoader; 1998c30d921cSKever Yang } 1999c30d921cSKever Yang memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 2000b38fe5fcSliuyi iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag); 2001c30d921cSKever Yang if (iRet != 0) { 2002c30d921cSKever Yang ERROR_COLOR_ATTR; 200332268622SAndreas Färber printf("Making idblock failed!"); 2004c30d921cSKever Yang NORMAL_COLOR_ATTR; 2005c30d921cSKever Yang printf("\r\n"); 2006c30d921cSKever Yang goto Exit_UpgradeLoader; 2007c30d921cSKever Yang } 2008c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 2009c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 2010c30d921cSKever Yang CURSOR_DEL_LINE; 2011c30d921cSKever Yang if (iRet == ERR_SUCCESS) { 2012b38fe5fcSliuyi //pComm->Reset_Usb_Device(); 2013c30d921cSKever Yang bSuccess = true; 201432268622SAndreas Färber printf("Upgrading loader succeeded.\r\n"); 2015c30d921cSKever Yang } else { 201632268622SAndreas Färber printf("Upgrading loader failed!\r\n"); 2017c30d921cSKever Yang goto Exit_UpgradeLoader; 2018c30d921cSKever Yang } 2019c30d921cSKever Yang } 2020c30d921cSKever Yang Exit_UpgradeLoader: 2021c30d921cSKever Yang if (pImage) 2022c30d921cSKever Yang delete pImage; 2023c30d921cSKever Yang if (pComm) 2024c30d921cSKever Yang delete pComm; 2025c30d921cSKever Yang if (loaderCodeBuffer) 2026c30d921cSKever Yang delete []loaderCodeBuffer; 2027c30d921cSKever Yang if (loaderDataBuffer) 2028c30d921cSKever Yang delete []loaderDataBuffer; 2029c30d921cSKever Yang if (pIDBData) 2030c30d921cSKever Yang delete []pIDBData; 2031c30d921cSKever Yang return bSuccess; 2032c30d921cSKever Yang } 20333dc7e3ceSliuyi bool print_gpt(STRUCT_RKDEVICE_DESC &dev) 20343dc7e3ceSliuyi { 20353dc7e3ceSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 20363dc7e3ceSliuyi return false; 20373dc7e3ceSliuyi u8 master_gpt[34 * SECTOR_SIZE]; 20383dc7e3ceSliuyi gpt_header *gptHead = (gpt_header *)(master_gpt + SECTOR_SIZE); 20393dc7e3ceSliuyi bool bRet, bSuccess = false; 20403dc7e3ceSliuyi int iRet; 20413dc7e3ceSliuyi gpt_entry *gptEntry = NULL; 20423dc7e3ceSliuyi u32 i,j; 20433dc7e3ceSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 20443dc7e3ceSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 20453dc7e3ceSliuyi CRKComm *pComm = NULL; 20463dc7e3ceSliuyi char partName[36]; 20473dc7e3ceSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 20483dc7e3ceSliuyi if (!bRet) { 20493dc7e3ceSliuyi ERROR_COLOR_ATTR; 20503dc7e3ceSliuyi printf("Creating Comm Object failed!"); 20513dc7e3ceSliuyi NORMAL_COLOR_ATTR; 20523dc7e3ceSliuyi printf("\r\n"); 20533dc7e3ceSliuyi return bSuccess; 20543dc7e3ceSliuyi } 20553dc7e3ceSliuyi iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt); 20563dc7e3ceSliuyi if(ERR_SUCCESS == iRet) { 20573dc7e3ceSliuyi if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 20583dc7e3ceSliuyi goto Exit_PrintGpt; 20593dc7e3ceSliuyi } 20603dc7e3ceSliuyi 20613dc7e3ceSliuyi } else { 20623dc7e3ceSliuyi if (g_pLogObject) 20633dc7e3ceSliuyi g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 20643dc7e3ceSliuyi printf("Read GPT failed!\r\n"); 20653dc7e3ceSliuyi goto Exit_PrintGpt; 20663dc7e3ceSliuyi } 20673dc7e3ceSliuyi 2068081d237aSliuyi printf("**********Partition Info(GPT)**********\r\n"); 20693dc7e3ceSliuyi printf("NO LBA Name \r\n"); 20703dc7e3ceSliuyi for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) { 20713dc7e3ceSliuyi gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 20723dc7e3ceSliuyi if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0) 20733dc7e3ceSliuyi break; 20743dc7e3ceSliuyi memset(partName, 0 , 36); 20753dc7e3ceSliuyi j = 0; 20763dc7e3ceSliuyi while (gptEntry->partition_name[j]) { 20773dc7e3ceSliuyi partName[j] = (char)gptEntry->partition_name[j]; 20783dc7e3ceSliuyi j++; 20793dc7e3ceSliuyi } 20803dc7e3ceSliuyi printf("%02d %08X %s\r\n", i, (u32)le64_to_cpu(gptEntry->starting_lba), partName); 20813dc7e3ceSliuyi } 20823dc7e3ceSliuyi bSuccess = true; 20833dc7e3ceSliuyi Exit_PrintGpt: 20843dc7e3ceSliuyi if (pComm) 20853dc7e3ceSliuyi delete pComm; 20863dc7e3ceSliuyi return bSuccess; 20873dc7e3ceSliuyi } 2088081d237aSliuyi bool print_parameter(STRUCT_RKDEVICE_DESC &dev) 2089081d237aSliuyi { 2090081d237aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2091081d237aSliuyi return false; 2092081d237aSliuyi u8 param_buf[512 * SECTOR_SIZE]; 2093081d237aSliuyi bool bRet, bSuccess = false; 2094081d237aSliuyi int iRet; 2095081d237aSliuyi u32 i, nParamSize; 2096081d237aSliuyi CRKComm *pComm = NULL; 2097081d237aSliuyi PARAM_ITEM_VECTOR vecParamItem; 2098081d237aSliuyi CONFIG_ITEM_VECTOR vecUuidItem; 2099081d237aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2100081d237aSliuyi if (!bRet) { 2101081d237aSliuyi ERROR_COLOR_ATTR; 2102081d237aSliuyi printf("Creating Comm Object failed!"); 2103081d237aSliuyi NORMAL_COLOR_ATTR; 2104081d237aSliuyi printf("\r\n"); 2105081d237aSliuyi return bSuccess; 2106081d237aSliuyi } 2107081d237aSliuyi iRet = pComm->RKU_ReadLBA( 0x2000, 512, param_buf); 2108081d237aSliuyi if(ERR_SUCCESS == iRet) { 2109081d237aSliuyi if (*(u32 *)param_buf != 0x4D524150) { 2110081d237aSliuyi goto Exit_PrintParam; 2111081d237aSliuyi } 2112081d237aSliuyi 2113081d237aSliuyi } else { 2114081d237aSliuyi if (g_pLogObject) 2115081d237aSliuyi g_pLogObject->Record("Error: read parameter failed, err=%d", iRet); 2116081d237aSliuyi printf("Read parameter failed!\r\n"); 2117081d237aSliuyi goto Exit_PrintParam; 2118081d237aSliuyi } 2119081d237aSliuyi nParamSize = *(u32 *)(param_buf + 4); 2120081d237aSliuyi memset(param_buf+8+nParamSize, 0, 512*SECTOR_SIZE - nParamSize - 8); 2121081d237aSliuyi 2122081d237aSliuyi bRet = parse_parameter((char *)(param_buf+8), vecParamItem, vecUuidItem); 2123081d237aSliuyi if (!bRet) { 2124081d237aSliuyi if (g_pLogObject) 2125081d237aSliuyi g_pLogObject->Record("Error: parse parameter failed"); 2126081d237aSliuyi printf("Parse parameter failed!\r\n"); 2127081d237aSliuyi goto Exit_PrintParam; 2128081d237aSliuyi } 2129081d237aSliuyi printf("**********Partition Info(parameter)**********\r\n"); 2130081d237aSliuyi printf("NO LBA Name \r\n"); 2131081d237aSliuyi for (i = 0; i < vecParamItem.size(); i++) { 2132081d237aSliuyi printf("%02d %08X %s\r\n", i, vecParamItem[i].uiItemOffset, vecParamItem[i].szItemName); 2133081d237aSliuyi } 2134081d237aSliuyi bSuccess = true; 2135081d237aSliuyi Exit_PrintParam: 2136081d237aSliuyi if (pComm) 2137081d237aSliuyi delete pComm; 2138081d237aSliuyi return bSuccess; 2139081d237aSliuyi } 2140c30d921cSKever Yang 214176af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 214276af099aSliuyi { 214376af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 214476af099aSliuyi return false; 214576af099aSliuyi CRKImage *pImage = NULL; 214676af099aSliuyi bool bRet, bSuccess = false; 214776af099aSliuyi int iRet; 214876af099aSliuyi CRKScan *pScan = NULL; 214976af099aSliuyi pScan = new CRKScan(); 215076af099aSliuyi pScan->SetVidPid(); 215176af099aSliuyi 215276af099aSliuyi CRKComm *pComm = NULL; 215376af099aSliuyi CRKDevice *pDevice = NULL; 215476af099aSliuyi 215576af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 215676af099aSliuyi if (!bRet) { 215776af099aSliuyi if (pScan) 215876af099aSliuyi delete pScan; 215976af099aSliuyi ERROR_COLOR_ATTR; 216076af099aSliuyi printf("Creating Comm Object failed!"); 216176af099aSliuyi NORMAL_COLOR_ATTR; 216276af099aSliuyi printf("\r\n"); 216376af099aSliuyi return bSuccess; 216476af099aSliuyi } 216576af099aSliuyi 216676af099aSliuyi pDevice = new CRKDevice(dev); 216776af099aSliuyi if (!pDevice) { 216876af099aSliuyi if (pComm) 216976af099aSliuyi delete pComm; 217076af099aSliuyi if (pScan) 217176af099aSliuyi delete pScan; 217276af099aSliuyi ERROR_COLOR_ATTR; 217376af099aSliuyi printf("Creating device object failed!"); 217476af099aSliuyi NORMAL_COLOR_ATTR; 217576af099aSliuyi printf("\r\n"); 217676af099aSliuyi return bSuccess; 217776af099aSliuyi } 217876af099aSliuyi 217976af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 218076af099aSliuyi pDevice->CallBackPointer = ProgressInfoProc; 218176af099aSliuyi 218232268622SAndreas Färber printf("Starting to erase flash...\r\n"); 21836502326dSliuyi bRet = pDevice->GetFlashInfo(); 21846502326dSliuyi if (!bRet) { 21856502326dSliuyi if (pDevice) 21866502326dSliuyi delete pDevice; 21876502326dSliuyi if (pScan) 21886502326dSliuyi delete pScan; 21896502326dSliuyi ERROR_COLOR_ATTR; 21906502326dSliuyi printf("Getting flash info from device failed!"); 21916502326dSliuyi NORMAL_COLOR_ATTR; 21926502326dSliuyi printf("\r\n"); 21936502326dSliuyi return bSuccess; 21946502326dSliuyi } 219576af099aSliuyi iRet = pDevice->EraseAllBlocks(); 219676af099aSliuyi if (pDevice) 219776af099aSliuyi delete pDevice; 219876af099aSliuyi 219976af099aSliuyi if (iRet == 0) { 220076af099aSliuyi if (pScan) { 220176af099aSliuyi pScan->SetVidPid(); 220276af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 220376af099aSliuyi delete pScan; 220476af099aSliuyi } 220576af099aSliuyi CURSOR_MOVEUP_LINE(1); 220676af099aSliuyi CURSOR_DEL_LINE; 220776af099aSliuyi bSuccess = true; 220832268622SAndreas Färber printf("Erasing flash complete.\r\n"); 220976af099aSliuyi } 221076af099aSliuyi 221176af099aSliuyi return bSuccess; 221276af099aSliuyi } 221376af099aSliuyi 221476af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev) 221576af099aSliuyi { 221676af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 221776af099aSliuyi return false; 221876af099aSliuyi CRKUsbComm *pComm = NULL; 221976af099aSliuyi bool bRet, bSuccess = false; 222076af099aSliuyi int iRet; 222176af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 222276af099aSliuyi if (bRet) { 222376af099aSliuyi iRet = pComm->RKU_TestDeviceReady(); 222476af099aSliuyi if (iRet != ERR_SUCCESS) { 222576af099aSliuyi if (g_pLogObject) 222676af099aSliuyi g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 222732268622SAndreas Färber printf("Test Device failed!\r\n"); 222876af099aSliuyi } else { 222976af099aSliuyi bSuccess = true; 223076af099aSliuyi printf("Test Device OK.\r\n"); 223176af099aSliuyi } 223276af099aSliuyi } else { 223332268622SAndreas Färber printf("Test Device quit, creating comm object failed!\r\n"); 223476af099aSliuyi } 223576af099aSliuyi if (pComm) { 223676af099aSliuyi delete pComm; 223776af099aSliuyi pComm = NULL; 223876af099aSliuyi } 223976af099aSliuyi return bSuccess; 224076af099aSliuyi } 224176af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 224276af099aSliuyi { 224376af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 224476af099aSliuyi return false; 224576af099aSliuyi CRKUsbComm *pComm = NULL; 224676af099aSliuyi bool bRet, bSuccess = false; 224776af099aSliuyi int iRet; 224876af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 224976af099aSliuyi if (bRet) { 225076af099aSliuyi iRet = pComm->RKU_ResetDevice(subCode); 225176af099aSliuyi if (iRet != ERR_SUCCESS) { 225276af099aSliuyi if (g_pLogObject) 225376af099aSliuyi g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 225432268622SAndreas Färber printf("Reset Device failed!\r\n"); 225576af099aSliuyi } else { 225676af099aSliuyi bSuccess = true; 225776af099aSliuyi printf("Reset Device OK.\r\n"); 225876af099aSliuyi } 225976af099aSliuyi } else { 226032268622SAndreas Färber printf("Reset Device quit, creating comm object failed!\r\n"); 226176af099aSliuyi } 226276af099aSliuyi if (pComm) { 226376af099aSliuyi delete pComm; 226476af099aSliuyi pComm = NULL; 226576af099aSliuyi } 226676af099aSliuyi return bSuccess; 226776af099aSliuyi } 226876af099aSliuyi 226976af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 227076af099aSliuyi { 227176af099aSliuyi CRKUsbComm *pComm = NULL; 227276af099aSliuyi bool bRet, bSuccess = false; 227376af099aSliuyi int iRet; 227476af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 227576af099aSliuyi return bSuccess; 227676af099aSliuyi 227776af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 227876af099aSliuyi if (bRet) { 227976af099aSliuyi BYTE flashID[5]; 228076af099aSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 228176af099aSliuyi if (iRet != ERR_SUCCESS) { 228276af099aSliuyi if (g_pLogObject) 228376af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 228432268622SAndreas Färber printf("Reading flash ID failed!\r\n"); 228576af099aSliuyi } else { 228676af099aSliuyi printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 228776af099aSliuyi bSuccess = true; 228876af099aSliuyi } 228976af099aSliuyi } else { 229032268622SAndreas Färber printf("Read Flash ID quit, creating comm object failed!\r\n"); 229176af099aSliuyi } 229276af099aSliuyi if (pComm) { 229376af099aSliuyi delete pComm; 229476af099aSliuyi pComm = NULL; 229576af099aSliuyi } 229676af099aSliuyi return bSuccess; 229776af099aSliuyi } 229876af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 229976af099aSliuyi { 230076af099aSliuyi CRKUsbComm *pComm = NULL; 230176af099aSliuyi bool bRet, bSuccess = false; 230276af099aSliuyi int iRet; 230376af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 230476af099aSliuyi return bSuccess; 230576af099aSliuyi 230676af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 230776af099aSliuyi if (bRet) { 230876af099aSliuyi STRUCT_FLASHINFO_CMD info; 230976af099aSliuyi UINT uiRead; 231076af099aSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 231176af099aSliuyi if (iRet != ERR_SUCCESS) { 231276af099aSliuyi if (g_pLogObject) 231376af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 231432268622SAndreas Färber printf("Read Flash Info failed!\r\n"); 231576af099aSliuyi } else { 231676af099aSliuyi printf("Flash Info:\r\n"); 231776af099aSliuyi if (info.bManufCode <= 7) { 231876af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 231976af099aSliuyi } 232076af099aSliuyi else 232176af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 232276af099aSliuyi 232376af099aSliuyi printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 2324*0dcb0a4cSliuyi printf("\tFlash Size: %d Sectors\r\n", info.uiFlashSize); 232576af099aSliuyi printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 232676af099aSliuyi printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 232776af099aSliuyi printf("\tECC Bits: %d\r\n", info.bECCBits); 232876af099aSliuyi printf("\tAccess Time: %d\r\n", info.bAccessTime); 232976af099aSliuyi printf("\tFlash CS: "); 233076af099aSliuyi for(int i = 0; i < 8; i++) { 233176af099aSliuyi if( info.bFlashCS & (1 << i) ) 233276af099aSliuyi printf("Flash<%d> ", i); 233376af099aSliuyi } 233476af099aSliuyi printf("\r\n"); 233576af099aSliuyi bSuccess = true; 233676af099aSliuyi } 233776af099aSliuyi }else { 233832268622SAndreas Färber printf("Read Flash Info quit, creating comm object failed!\r\n"); 233976af099aSliuyi } 234076af099aSliuyi if (pComm) { 234176af099aSliuyi delete pComm; 234276af099aSliuyi pComm = NULL; 234376af099aSliuyi } 234476af099aSliuyi return bSuccess; 234576af099aSliuyi } 234676af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 234776af099aSliuyi { 234876af099aSliuyi CRKUsbComm *pComm = NULL; 234976af099aSliuyi bool bRet, bSuccess = false; 235076af099aSliuyi int iRet; 235176af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 235276af099aSliuyi return bSuccess; 235376af099aSliuyi 235476af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 235576af099aSliuyi if (bRet) { 235676af099aSliuyi BYTE chipInfo[16]; 235776af099aSliuyi iRet = pComm->RKU_ReadChipInfo(chipInfo); 235876af099aSliuyi if (iRet != ERR_SUCCESS) { 235976af099aSliuyi if (g_pLogObject) 236076af099aSliuyi g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 236132268622SAndreas Färber printf("Read Chip Info failed!\r\n"); 236276af099aSliuyi } else { 236376af099aSliuyi string strChipInfo; 236476af099aSliuyi g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 236576af099aSliuyi printf("Chip Info: %s\r\n", strChipInfo.c_str()); 236676af099aSliuyi bSuccess = true; 236776af099aSliuyi } 236876af099aSliuyi } else { 236932268622SAndreas Färber printf("Read Chip Info quit, creating comm object failed!\r\n"); 237076af099aSliuyi } 237176af099aSliuyi if (pComm) { 237276af099aSliuyi delete pComm; 237376af099aSliuyi pComm = NULL; 237476af099aSliuyi } 237576af099aSliuyi return bSuccess; 237676af099aSliuyi } 2377081d237aSliuyi bool read_capability(STRUCT_RKDEVICE_DESC &dev) 2378081d237aSliuyi { 2379081d237aSliuyi CRKUsbComm *pComm = NULL; 2380081d237aSliuyi bool bRet, bSuccess = false; 2381081d237aSliuyi int iRet; 2382081d237aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2383081d237aSliuyi return bSuccess; 2384081d237aSliuyi 2385081d237aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2386081d237aSliuyi if (bRet) { 2387081d237aSliuyi 2388081d237aSliuyi BYTE capability[8]; 2389081d237aSliuyi iRet = pComm->RKU_ReadCapability(capability); 2390081d237aSliuyi if (iRet != ERR_SUCCESS) 2391081d237aSliuyi { 2392081d237aSliuyi if (g_pLogObject) 2393081d237aSliuyi g_pLogObject->Record("Error:read_capability failed,err=%d", iRet); 2394081d237aSliuyi printf("Read capability Fail!\r\n"); 2395081d237aSliuyi } else { 2396081d237aSliuyi printf("Capability:%02X %02X %02X %02X %02X %02X %02X %02X \r\n", 2397081d237aSliuyi capability[0], capability[1], capability[2], capability[3], 2398081d237aSliuyi capability[4], capability[5], capability[6], capability[7]); 2399081d237aSliuyi if (capability[0] & 1) 2400081d237aSliuyi { 2401081d237aSliuyi printf("Direct LBA:\tenabled\r\n"); 2402081d237aSliuyi } 2403081d237aSliuyi 2404081d237aSliuyi if (capability[0] & 2) 2405081d237aSliuyi { 2406081d237aSliuyi printf("Vendor Storage:\tenabled\r\n"); 2407081d237aSliuyi } 2408081d237aSliuyi 2409081d237aSliuyi if (capability[0] & 4) 2410081d237aSliuyi { 2411081d237aSliuyi printf("First 4m Access:\tenabled\r\n"); 2412081d237aSliuyi } 2413081d237aSliuyi bSuccess = true; 2414081d237aSliuyi } 2415081d237aSliuyi } else { 2416081d237aSliuyi printf("Read capability quit, creating comm object failed!\r\n"); 2417081d237aSliuyi } 2418081d237aSliuyi if (pComm) { 2419081d237aSliuyi delete pComm; 2420081d237aSliuyi pComm = NULL; 2421081d237aSliuyi } 2422081d237aSliuyi return bSuccess; 2423081d237aSliuyi } 2424081d237aSliuyi bool read_param(STRUCT_RKDEVICE_DESC &dev, u8 *pParam) 2425081d237aSliuyi { 2426081d237aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2427081d237aSliuyi return false; 2428081d237aSliuyi CRKUsbComm *pComm = NULL; 2429081d237aSliuyi bool bRet, bSuccess = false; 2430081d237aSliuyi int iRet; 2431081d237aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2432081d237aSliuyi if (bRet) { 2433081d237aSliuyi iRet = pComm->RKU_ReadLBA( 0x2000, 512, pParam); 2434081d237aSliuyi if(ERR_SUCCESS == iRet) { 2435081d237aSliuyi if (*(u32 *)pParam != 0x4D524150) { 2436081d237aSliuyi goto Exit_ReadParam; 2437081d237aSliuyi } 2438081d237aSliuyi } else { 2439081d237aSliuyi if (g_pLogObject) 2440081d237aSliuyi g_pLogObject->Record("Error: read parameter failed, err=%d", iRet); 2441081d237aSliuyi printf("Read parameter failed!\r\n"); 2442081d237aSliuyi goto Exit_ReadParam; 2443081d237aSliuyi } 2444081d237aSliuyi bSuccess = true; 2445081d237aSliuyi } 2446081d237aSliuyi Exit_ReadParam: 2447081d237aSliuyi if (pComm) { 2448081d237aSliuyi delete pComm; 2449081d237aSliuyi pComm = NULL; 2450081d237aSliuyi } 2451081d237aSliuyi return bSuccess; 2452081d237aSliuyi } 2453081d237aSliuyi 2454081d237aSliuyi 24556ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt) 24566ae612beSliuyi { 24576ae612beSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 24586ae612beSliuyi return false; 24596ae612beSliuyi gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE); 24606ae612beSliuyi CRKUsbComm *pComm = NULL; 24616ae612beSliuyi bool bRet, bSuccess = false; 24626ae612beSliuyi int iRet; 24636ae612beSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 24646ae612beSliuyi if (bRet) { 24656ae612beSliuyi iRet = pComm->RKU_ReadLBA( 0, 34, pGpt); 24666ae612beSliuyi if(ERR_SUCCESS == iRet) { 24676ae612beSliuyi if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 24686ae612beSliuyi goto Exit_ReadGPT; 24696ae612beSliuyi } 24706ae612beSliuyi } else { 24716ae612beSliuyi if (g_pLogObject) 24726ae612beSliuyi g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 24736ae612beSliuyi printf("Read GPT failed!\r\n"); 24746ae612beSliuyi goto Exit_ReadGPT; 24756ae612beSliuyi } 24766ae612beSliuyi bSuccess = true; 24776ae612beSliuyi } 24786ae612beSliuyi Exit_ReadGPT: 24796ae612beSliuyi if (pComm) { 24806ae612beSliuyi delete pComm; 24816ae612beSliuyi pComm = NULL; 24826ae612beSliuyi } 24836ae612beSliuyi return bSuccess; 24846ae612beSliuyi } 248576af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 248676af099aSliuyi { 248776af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 248876af099aSliuyi return false; 248976af099aSliuyi CRKUsbComm *pComm = NULL; 249076af099aSliuyi FILE *file = NULL; 249176af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 249276af099aSliuyi int iRet; 249376af099aSliuyi UINT iTotalRead = 0,iRead = 0; 249476af099aSliuyi int nSectorSize = 512; 249576af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 249676af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 249776af099aSliuyi if (bRet) { 249876af099aSliuyi if(szFile) { 249976af099aSliuyi file = fopen(szFile, "wb+"); 250076af099aSliuyi if( !file ) { 250176af099aSliuyi printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 250276af099aSliuyi goto Exit_ReadLBA; 250376af099aSliuyi } 250476af099aSliuyi } 250576af099aSliuyi 250676af099aSliuyi while(uiLen > 0) { 250776af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 250876af099aSliuyi iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 250976af099aSliuyi iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 251076af099aSliuyi if(ERR_SUCCESS == iRet) { 251176af099aSliuyi uiLen -= iRead; 251276af099aSliuyi iTotalRead += iRead; 251376af099aSliuyi 251476af099aSliuyi if(szFile) { 251576af099aSliuyi fwrite(pBuf, 1, iRead * nSectorSize, file); 251676af099aSliuyi if (bFirst){ 251776af099aSliuyi if (iTotalRead >= 1024) 251832268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 251976af099aSliuyi else 252032268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 252176af099aSliuyi bFirst = false; 252276af099aSliuyi } else { 252376af099aSliuyi CURSOR_MOVEUP_LINE(1); 252476af099aSliuyi CURSOR_DEL_LINE; 252576af099aSliuyi if (iTotalRead >= 1024) 252632268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 252776af099aSliuyi else 252832268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 252976af099aSliuyi } 253076af099aSliuyi } 253176af099aSliuyi else 253276af099aSliuyi PrintData(pBuf, nSectorSize * iRead); 253376af099aSliuyi } else { 253476af099aSliuyi if (g_pLogObject) 253576af099aSliuyi g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 253676af099aSliuyi 253776af099aSliuyi printf("Read LBA failed!\r\n"); 253876af099aSliuyi goto Exit_ReadLBA; 253976af099aSliuyi } 254076af099aSliuyi } 254176af099aSliuyi bSuccess = true; 254276af099aSliuyi } else { 254332268622SAndreas Färber printf("Read LBA quit, creating comm object failed!\r\n"); 254476af099aSliuyi } 254576af099aSliuyi Exit_ReadLBA: 254676af099aSliuyi if (pComm) { 254776af099aSliuyi delete pComm; 254876af099aSliuyi pComm = NULL; 254976af099aSliuyi } 255076af099aSliuyi if (file) 255176af099aSliuyi fclose(file); 255276af099aSliuyi return bSuccess; 255376af099aSliuyi } 2554*0dcb0a4cSliuyi bool erase_ubi_block(STRUCT_RKDEVICE_DESC &dev, u32 uiOffset, u32 uiPartSize) 2555*0dcb0a4cSliuyi { 2556*0dcb0a4cSliuyi STRUCT_FLASHINFO_CMD info; 2557*0dcb0a4cSliuyi CRKComm *pComm = NULL; 2558*0dcb0a4cSliuyi BYTE flashID[5]; 2559*0dcb0a4cSliuyi bool bRet,bSuccess=false; 2560*0dcb0a4cSliuyi UINT uiReadCount,uiStartBlock,uiEraseBlock,uiBlockCount,uiErasePos; 2561*0dcb0a4cSliuyi int iRet; 2562*0dcb0a4cSliuyi DWORD *pID=NULL; 2563*0dcb0a4cSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2564*0dcb0a4cSliuyi return false; 2565*0dcb0a4cSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2566*0dcb0a4cSliuyi if (!bRet) 2567*0dcb0a4cSliuyi { 2568*0dcb0a4cSliuyi printf("Erase ubi quit, creating comm object failed!\r\n"); 2569*0dcb0a4cSliuyi goto EXIT_UBI_ERASE; 2570*0dcb0a4cSliuyi } 2571*0dcb0a4cSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 2572*0dcb0a4cSliuyi if(iRet!=ERR_SUCCESS) 2573*0dcb0a4cSliuyi { 2574*0dcb0a4cSliuyi if (g_pLogObject) 2575*0dcb0a4cSliuyi { 2576*0dcb0a4cSliuyi g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashID failed,RetCode(%d)",iRet); 2577*0dcb0a4cSliuyi } 2578*0dcb0a4cSliuyi goto EXIT_UBI_ERASE; 2579*0dcb0a4cSliuyi } 2580*0dcb0a4cSliuyi pID = (DWORD *)flashID; 2581*0dcb0a4cSliuyi if (*pID==0x434d4d45)//emmc 2582*0dcb0a4cSliuyi { 2583*0dcb0a4cSliuyi bSuccess = true; 2584*0dcb0a4cSliuyi goto EXIT_UBI_ERASE; 2585*0dcb0a4cSliuyi } 2586*0dcb0a4cSliuyi 2587*0dcb0a4cSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info,&uiReadCount); 2588*0dcb0a4cSliuyi if (iRet!=ERR_SUCCESS) 2589*0dcb0a4cSliuyi { 2590*0dcb0a4cSliuyi if (g_pLogObject) 2591*0dcb0a4cSliuyi g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashInfo err=%d", iRet); 2592*0dcb0a4cSliuyi goto EXIT_UBI_ERASE; 2593*0dcb0a4cSliuyi } 2594*0dcb0a4cSliuyi if (uiPartSize==0xFFFFFFFF) 2595*0dcb0a4cSliuyi uiPartSize = info.uiFlashSize - uiOffset - (info.usBlockSize * 4); 2596*0dcb0a4cSliuyi 2597*0dcb0a4cSliuyi uiStartBlock = uiOffset / info.usBlockSize; 2598*0dcb0a4cSliuyi if ((uiPartSize % info.usBlockSize) == 0) 2599*0dcb0a4cSliuyi uiEraseBlock = uiPartSize / info.usBlockSize; 2600*0dcb0a4cSliuyi else 2601*0dcb0a4cSliuyi uiEraseBlock = uiPartSize / info.usBlockSize + 1; 2602*0dcb0a4cSliuyi 2603*0dcb0a4cSliuyi 2604*0dcb0a4cSliuyi uiErasePos=uiStartBlock; 2605*0dcb0a4cSliuyi while (uiEraseBlock>0) 2606*0dcb0a4cSliuyi { 2607*0dcb0a4cSliuyi uiBlockCount = (uiEraseBlock<MAX_ERASE_BLOCKS)?uiEraseBlock:MAX_ERASE_BLOCKS; 2608*0dcb0a4cSliuyi 2609*0dcb0a4cSliuyi iRet = pComm->RKU_EraseBlock(0,uiErasePos,uiBlockCount,ERASE_FORCE); 2610*0dcb0a4cSliuyi if ((iRet!=ERR_SUCCESS)&&(iRet!=ERR_FOUND_BAD_BLOCK)) 2611*0dcb0a4cSliuyi { 2612*0dcb0a4cSliuyi if (g_pLogObject) 2613*0dcb0a4cSliuyi { 2614*0dcb0a4cSliuyi g_pLogObject->Record("Error:EraseUBIBlock-->RKU_EraseBlock failed,RetCode(%d)",iRet); 2615*0dcb0a4cSliuyi } 2616*0dcb0a4cSliuyi goto EXIT_UBI_ERASE; 2617*0dcb0a4cSliuyi } 2618*0dcb0a4cSliuyi 2619*0dcb0a4cSliuyi uiErasePos += uiBlockCount; 2620*0dcb0a4cSliuyi uiEraseBlock -= uiBlockCount; 2621*0dcb0a4cSliuyi } 2622*0dcb0a4cSliuyi bSuccess = true; 2623*0dcb0a4cSliuyi EXIT_UBI_ERASE: 2624*0dcb0a4cSliuyi if (pComm) 2625*0dcb0a4cSliuyi delete pComm; 2626*0dcb0a4cSliuyi return bSuccess; 2627*0dcb0a4cSliuyi } 26286ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize) 26296ae612beSliuyi { 2630ae4252f0Sliuyi UINT uiErase=1024*32; 26316ae612beSliuyi bool bSuccess = true; 26326ae612beSliuyi int iRet; 26336ae612beSliuyi while (uiSize) 26346ae612beSliuyi { 26356ae612beSliuyi if (uiSize>=uiErase) 26366ae612beSliuyi { 26376ae612beSliuyi iRet = pComm->RKU_EraseLBA(uiOffset,uiErase); 26386ae612beSliuyi uiSize -= uiErase; 26396ae612beSliuyi uiOffset += uiErase; 26406ae612beSliuyi } 26416ae612beSliuyi else 26426ae612beSliuyi { 26436ae612beSliuyi iRet = pComm->RKU_EraseLBA(uiOffset,uiSize); 26446ae612beSliuyi uiSize = 0; 26456ae612beSliuyi uiOffset += uiSize; 26466ae612beSliuyi } 26476ae612beSliuyi if (iRet!=ERR_SUCCESS) 26486ae612beSliuyi { 26496ae612beSliuyi if (g_pLogObject) 26506ae612beSliuyi { 26516ae612beSliuyi g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet); 26526ae612beSliuyi } 26536ae612beSliuyi bSuccess = false; 26546ae612beSliuyi break; 26556ae612beSliuyi } 26566ae612beSliuyi } 26576ae612beSliuyi return bSuccess; 26586ae612beSliuyi 26596ae612beSliuyi } 26606ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk) 26616ae612beSliuyi { 26626ae612beSliuyi UINT uiRead; 26636ae612beSliuyi uiRead = fread(&chunk, 1, sizeof(chunk_header), file); 26646ae612beSliuyi if (uiRead != sizeof(chunk_header)) { 26656ae612beSliuyi if (g_pLogObject) 26666ae612beSliuyi { 26676ae612beSliuyi g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno); 26686ae612beSliuyi } 26696ae612beSliuyi return false; 26706ae612beSliuyi } 26716ae612beSliuyi return true; 26726ae612beSliuyi } 26736ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize) 26746ae612beSliuyi { 26756ae612beSliuyi UINT uiRead; 26766ae612beSliuyi uiRead = fread(pBuf, 1, dwSize, file); 26776ae612beSliuyi if (uiRead!=dwSize) 26786ae612beSliuyi { 26796ae612beSliuyi if (g_pLogObject) 26806ae612beSliuyi { 26816ae612beSliuyi g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno); 26826ae612beSliuyi } 26836ae612beSliuyi return false; 26846ae612beSliuyi } 26856ae612beSliuyi return true; 26866ae612beSliuyi } 26876ae612beSliuyi 26886ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile) 26896ae612beSliuyi { 26906ae612beSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 26916ae612beSliuyi return false; 26926ae612beSliuyi CRKUsbComm *pComm = NULL; 26936ae612beSliuyi FILE *file = NULL; 26946ae612beSliuyi bool bRet, bSuccess = false, bFirst = true; 26956ae612beSliuyi int iRet; 26966ae612beSliuyi u64 iTotalWrite = 0, iFileSize = 0; 26976ae612beSliuyi UINT iRead = 0, uiTransferSec, curChunk, i; 26986ae612beSliuyi UINT dwChunkDataSize, dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc; 26996ae612beSliuyi BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA]; 27006ae612beSliuyi sparse_header header; 27016ae612beSliuyi chunk_header chunk; 27026ae612beSliuyi dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE; 27036ae612beSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 27046ae612beSliuyi if (bRet) { 2705ae4252f0Sliuyi 27066ae612beSliuyi file = fopen(szFile, "rb"); 27076ae612beSliuyi if( !file ) { 27086ae612beSliuyi printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile); 27096ae612beSliuyi goto Exit_WriteSparseLBA; 27106ae612beSliuyi } 27116ae612beSliuyi fseeko(file, 0, SEEK_SET); 27126ae612beSliuyi iRead = fread(&header, 1, sizeof(header), file); 27136ae612beSliuyi if (iRead != sizeof(sparse_header)) 27146ae612beSliuyi { 27156ae612beSliuyi if (g_pLogObject) 27166ae612beSliuyi { 27176ae612beSliuyi g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno); 27186ae612beSliuyi } 27196ae612beSliuyi goto Exit_WriteSparseLBA; 27206ae612beSliuyi } 27216ae612beSliuyi iFileSize = header.blk_sz * (u64)header.total_blks; 27226ae612beSliuyi iTotalWrite = 0; 27236ae612beSliuyi curChunk = 0; 2724ae4252f0Sliuyi if (uiSize==(u32)-1) 2725ae4252f0Sliuyi uiSize = ALIGN(iFileSize, SECTOR_SIZE); 2726ae4252f0Sliuyi bRet = erase_partition(pComm, uiBegin, uiSize); 2727ae4252f0Sliuyi if (!bRet) { 2728ae4252f0Sliuyi printf("%s failed, erase partition error\r\n", __func__); 2729ae4252f0Sliuyi goto Exit_WriteSparseLBA; 2730ae4252f0Sliuyi } 27316ae612beSliuyi while(curChunk < header.total_chunks) 27326ae612beSliuyi { 27336ae612beSliuyi if (!EatSparseChunk(file, chunk)) { 27346ae612beSliuyi goto Exit_WriteSparseLBA; 27356ae612beSliuyi } 27366ae612beSliuyi curChunk++; 27376ae612beSliuyi switch (chunk.chunk_type) { 27386ae612beSliuyi case CHUNK_TYPE_RAW: 27396ae612beSliuyi dwChunkDataSize = chunk.total_sz - sizeof(chunk_header); 27406ae612beSliuyi while (dwChunkDataSize) { 27416ae612beSliuyi memset(pBuf, 0, dwMaxReadWriteBytes); 27426ae612beSliuyi if (dwChunkDataSize >= dwMaxReadWriteBytes) { 27436ae612beSliuyi dwTransferBytes = dwMaxReadWriteBytes; 27446ae612beSliuyi uiTransferSec = DEFAULT_RW_LBA; 27456ae612beSliuyi } else { 27466ae612beSliuyi dwTransferBytes = dwChunkDataSize; 27476ae612beSliuyi uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 27486ae612beSliuyi } 27496ae612beSliuyi if (!EatSparseData(file, pBuf, dwTransferBytes)) { 27506ae612beSliuyi goto Exit_WriteSparseLBA; 27516ae612beSliuyi } 27526ae612beSliuyi iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 27536ae612beSliuyi if( ERR_SUCCESS == iRet ) { 27546ae612beSliuyi dwChunkDataSize -= dwTransferBytes; 27556ae612beSliuyi iTotalWrite += dwTransferBytes; 27566ae612beSliuyi uiBegin += uiTransferSec; 27576ae612beSliuyi } else { 27586ae612beSliuyi if (g_pLogObject) { 27596ae612beSliuyi g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)", __func__, iTotalWrite, iRet); 27606ae612beSliuyi } 27616ae612beSliuyi goto Exit_WriteSparseLBA; 27626ae612beSliuyi } 27636ae612beSliuyi if (bFirst) { 27646ae612beSliuyi if (iTotalWrite >= 1024) 27656ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 27666ae612beSliuyi else 27676ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 27686ae612beSliuyi bFirst = false; 27696ae612beSliuyi } else { 27706ae612beSliuyi CURSOR_MOVEUP_LINE(1); 27716ae612beSliuyi CURSOR_DEL_LINE; 27726ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 27736ae612beSliuyi } 27746ae612beSliuyi } 27756ae612beSliuyi break; 27766ae612beSliuyi case CHUNK_TYPE_FILL: 27776ae612beSliuyi dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 27786ae612beSliuyi if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) { 27796ae612beSliuyi goto Exit_WriteSparseLBA; 27806ae612beSliuyi } 27816ae612beSliuyi while (dwChunkDataSize) { 27826ae612beSliuyi memset(pBuf, 0, dwMaxReadWriteBytes); 27836ae612beSliuyi if (dwChunkDataSize >= dwMaxReadWriteBytes) { 27846ae612beSliuyi dwTransferBytes = dwMaxReadWriteBytes; 27856ae612beSliuyi uiTransferSec = DEFAULT_RW_LBA; 27866ae612beSliuyi } else { 27876ae612beSliuyi dwTransferBytes = dwChunkDataSize; 27886ae612beSliuyi uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 27896ae612beSliuyi } 27906ae612beSliuyi for (i = 0; i < dwTransferBytes / 4; i++) { 27916ae612beSliuyi *(DWORD *)(pBuf + i * 4) = dwFillByte; 27926ae612beSliuyi } 27936ae612beSliuyi iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 27946ae612beSliuyi if( ERR_SUCCESS == iRet ) { 27956ae612beSliuyi dwChunkDataSize -= dwTransferBytes; 27966ae612beSliuyi iTotalWrite += dwTransferBytes; 27976ae612beSliuyi uiBegin += uiTransferSec; 27986ae612beSliuyi } else { 27996ae612beSliuyi if (g_pLogObject) { 28006ae612beSliuyi g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet); 28016ae612beSliuyi } 28026ae612beSliuyi goto Exit_WriteSparseLBA; 28036ae612beSliuyi } 28046ae612beSliuyi if (bFirst) { 28056ae612beSliuyi if (iTotalWrite >= 1024) 28066ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 28076ae612beSliuyi else 28086ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 28096ae612beSliuyi bFirst = false; 28106ae612beSliuyi } else { 28116ae612beSliuyi CURSOR_MOVEUP_LINE(1); 28126ae612beSliuyi CURSOR_DEL_LINE; 28136ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 28146ae612beSliuyi } 28156ae612beSliuyi } 28166ae612beSliuyi break; 28176ae612beSliuyi case CHUNK_TYPE_DONT_CARE: 28186ae612beSliuyi dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 28196ae612beSliuyi iTotalWrite += dwChunkDataSize; 28206ae612beSliuyi uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1)); 28216ae612beSliuyi uiBegin += uiTransferSec; 28226ae612beSliuyi if (bFirst) { 28236ae612beSliuyi if (iTotalWrite >= 1024) 28246ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 28256ae612beSliuyi else 28266ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 28276ae612beSliuyi bFirst = false; 28286ae612beSliuyi } else { 28296ae612beSliuyi CURSOR_MOVEUP_LINE(1); 28306ae612beSliuyi CURSOR_DEL_LINE; 28316ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 28326ae612beSliuyi } 28336ae612beSliuyi break; 28346ae612beSliuyi case CHUNK_TYPE_CRC32: 28356ae612beSliuyi EatSparseData(file,(PBYTE)&dwCrc,4); 28366ae612beSliuyi break; 28376ae612beSliuyi } 28386ae612beSliuyi } 28396ae612beSliuyi bSuccess = true; 28406ae612beSliuyi } else { 28416ae612beSliuyi printf("Write LBA quit, creating comm object failed!\r\n"); 28426ae612beSliuyi } 28436ae612beSliuyi Exit_WriteSparseLBA: 28446ae612beSliuyi if (pComm) { 28456ae612beSliuyi delete pComm; 28466ae612beSliuyi pComm = NULL; 28476ae612beSliuyi } 28486ae612beSliuyi if (file) 28496ae612beSliuyi fclose(file); 28506ae612beSliuyi return bSuccess; 28516ae612beSliuyi 28526ae612beSliuyi } 28536ae612beSliuyi 285476af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 285576af099aSliuyi { 285676af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 285776af099aSliuyi return false; 285876af099aSliuyi CRKUsbComm *pComm = NULL; 285976af099aSliuyi FILE *file = NULL; 286076af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 286176af099aSliuyi int iRet; 286276af099aSliuyi long long iTotalWrite = 0, iFileSize = 0; 286376af099aSliuyi UINT iWrite = 0, iRead = 0; 286476af099aSliuyi UINT uiLen; 286576af099aSliuyi int nSectorSize = 512; 286676af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 286776af099aSliuyi 2868*0dcb0a4cSliuyi 286976af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 287076af099aSliuyi if (bRet) { 287176af099aSliuyi file = fopen(szFile, "rb"); 287276af099aSliuyi if( !file ) { 287376af099aSliuyi printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 287476af099aSliuyi goto Exit_WriteLBA; 287576af099aSliuyi } 287676af099aSliuyi 287776af099aSliuyi iRet = fseeko(file, 0, SEEK_END); 287876af099aSliuyi iFileSize = ftello(file); 287976af099aSliuyi fseeko(file, 0, SEEK_SET); 288076af099aSliuyi while(iTotalWrite < iFileSize) { 288176af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 288276af099aSliuyi iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 288376af099aSliuyi uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 288476af099aSliuyi iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 288576af099aSliuyi if(ERR_SUCCESS == iRet) { 288676af099aSliuyi uiBegin += uiLen; 288776af099aSliuyi iTotalWrite += iWrite; 288876af099aSliuyi if (bFirst) { 288976af099aSliuyi if (iTotalWrite >= 1024) 289076af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 289176af099aSliuyi else 289232268622SAndreas Färber printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 289376af099aSliuyi bFirst = false; 289476af099aSliuyi } else { 289576af099aSliuyi CURSOR_MOVEUP_LINE(1); 289676af099aSliuyi CURSOR_DEL_LINE; 289776af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 289876af099aSliuyi } 289976af099aSliuyi } else { 290076af099aSliuyi if (g_pLogObject) 290176af099aSliuyi g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 290276af099aSliuyi 290376af099aSliuyi printf("Write LBA failed!\r\n"); 290476af099aSliuyi goto Exit_WriteLBA; 290576af099aSliuyi } 290676af099aSliuyi } 290776af099aSliuyi bSuccess = true; 290876af099aSliuyi } else { 290932268622SAndreas Färber printf("Write LBA quit, creating comm object failed!\r\n"); 291076af099aSliuyi } 291176af099aSliuyi Exit_WriteLBA: 291276af099aSliuyi if (pComm) { 291376af099aSliuyi delete pComm; 291476af099aSliuyi pComm = NULL; 291576af099aSliuyi } 291676af099aSliuyi if (file) 291776af099aSliuyi fclose(file); 291876af099aSliuyi return bSuccess; 291976af099aSliuyi } 292076af099aSliuyi 292176af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems) 292276af099aSliuyi { 292376af099aSliuyi string strItem; 292476af099aSliuyi char szItem[100]; 292576af099aSliuyi char *pos = NULL, *pStart; 292676af099aSliuyi pStart = pszItems; 292776af099aSliuyi pos = strchr(pStart, ','); 292876af099aSliuyi while(pos != NULL) { 292902bc7763SChristoph Muellner memset(szItem, 0, sizeof(szItem)); 293076af099aSliuyi strncpy(szItem, pStart, pos - pStart); 293176af099aSliuyi strItem = szItem; 293276af099aSliuyi vecItems.push_back(strItem); 293376af099aSliuyi pStart = pos + 1; 293476af099aSliuyi if (*pStart == 0) 293576af099aSliuyi break; 293676af099aSliuyi pos = strchr(pStart, ','); 293776af099aSliuyi } 293876af099aSliuyi if (strlen(pStart) > 0) { 293902bc7763SChristoph Muellner memset(szItem, 0, sizeof(szItem)); 294002bc7763SChristoph Muellner strncpy(szItem, pStart, sizeof(szItem)-1); 294176af099aSliuyi strItem = szItem; 294276af099aSliuyi vecItems.push_back(strItem); 294376af099aSliuyi } 294476af099aSliuyi } 2945c30d921cSKever Yang 2946d71e8c20SEddie Cai void tag_spl(char *tag, char *spl) 2947d71e8c20SEddie Cai { 2948d71e8c20SEddie Cai FILE *file = NULL; 2949d71e8c20SEddie Cai int len; 2950d71e8c20SEddie Cai 2951d71e8c20SEddie Cai if(!tag || !spl) 2952d71e8c20SEddie Cai return; 2953d71e8c20SEddie Cai len = strlen(tag); 2954d71e8c20SEddie Cai printf("tag len=%d\n",len); 2955d71e8c20SEddie Cai file = fopen(spl, "rb"); 2956d71e8c20SEddie Cai if( !file ){ 2957d71e8c20SEddie Cai return; 2958d71e8c20SEddie Cai } 2959d71e8c20SEddie Cai int iFileSize; 2960d71e8c20SEddie Cai fseek(file, 0, SEEK_END); 2961d71e8c20SEddie Cai iFileSize = ftell(file); 2962d71e8c20SEddie Cai fseek(file, 0, SEEK_SET); 2963d71e8c20SEddie Cai char *Buf = NULL; 2964d71e8c20SEddie Cai Buf = new char[iFileSize + len + 1]; 2965d71e8c20SEddie Cai if (!Buf){ 2966d71e8c20SEddie Cai fclose(file); 2967d71e8c20SEddie Cai return; 2968d71e8c20SEddie Cai } 2969d71e8c20SEddie Cai memset(Buf, 0, iFileSize + 1); 2970d71e8c20SEddie Cai memcpy(Buf, tag, len); 2971d71e8c20SEddie Cai int iRead; 2972d71e8c20SEddie Cai iRead = fread(Buf+len, 1, iFileSize, file); 2973d71e8c20SEddie Cai if (iRead != iFileSize){ 2974d71e8c20SEddie Cai fclose(file); 2975d71e8c20SEddie Cai delete []Buf; 2976d71e8c20SEddie Cai return; 2977d71e8c20SEddie Cai } 2978d71e8c20SEddie Cai fclose(file); 2979d71e8c20SEddie Cai 2980d71e8c20SEddie Cai len = strlen(spl); 298132268622SAndreas Färber char *taggedspl = new char[len + 5]; 298232268622SAndreas Färber strcpy(taggedspl, spl); 298332268622SAndreas Färber strcpy(taggedspl + len, ".tag"); 298432268622SAndreas Färber taggedspl[len+4] = 0; 298532268622SAndreas Färber printf("Writing tagged spl to %s\n", taggedspl); 2986d71e8c20SEddie Cai 298732268622SAndreas Färber file = fopen(taggedspl, "wb"); 2988d71e8c20SEddie Cai if( !file ){ 298932268622SAndreas Färber delete []taggedspl; 2990d71e8c20SEddie Cai delete []Buf; 2991d71e8c20SEddie Cai return; 2992d71e8c20SEddie Cai } 2993d71e8c20SEddie Cai fwrite(Buf, 1, iFileSize+len, file); 2994d71e8c20SEddie Cai fclose(file); 299532268622SAndreas Färber delete []taggedspl; 2996d71e8c20SEddie Cai delete []Buf; 2997d71e8c20SEddie Cai printf("done\n"); 2998d71e8c20SEddie Cai return; 2999d71e8c20SEddie Cai } 3000081d237aSliuyi void list_device(CRKScan *pScan) 3001081d237aSliuyi { 3002081d237aSliuyi STRUCT_RKDEVICE_DESC desc; 3003081d237aSliuyi string strDevType; 3004081d237aSliuyi int i,cnt; 3005081d237aSliuyi cnt = pScan->DEVICE_COUNTS; 3006081d237aSliuyi if (cnt == 0) { 3007081d237aSliuyi printf("not found any devices!\r\n"); 3008081d237aSliuyi return; 3009081d237aSliuyi } 3010081d237aSliuyi for (i=0;i<cnt;i++) 3011081d237aSliuyi { 3012081d237aSliuyi pScan->GetDevice(desc, i); 3013081d237aSliuyi if (desc.emUsbType==RKUSB_MASKROM) 3014081d237aSliuyi strDevType = "Maskrom"; 3015081d237aSliuyi else if (desc.emUsbType==RKUSB_LOADER) 3016081d237aSliuyi strDevType = "Loader"; 3017081d237aSliuyi else 3018081d237aSliuyi strDevType = "Unknown"; 3019081d237aSliuyi printf("DevNo=%d\tVid=0x%x,Pid=0x%x,LocationID=%x\t%s\r\n",i+1,desc.usVid, 3020081d237aSliuyi desc.usPid,desc.uiLocationID,strDevType.c_str()); 3021081d237aSliuyi } 3022081d237aSliuyi 3023081d237aSliuyi } 3024081d237aSliuyi 3025d71e8c20SEddie Cai 302676af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan) 302776af099aSliuyi { 302876af099aSliuyi string strCmd; 302976af099aSliuyi strCmd = argv[1]; 303076af099aSliuyi ssize_t cnt; 303176af099aSliuyi bool bRet,bSuccess = false; 30328df2d64aSEddie Cai char *s; 30338df2d64aSEddie Cai int i, ret; 303476af099aSliuyi STRUCT_RKDEVICE_DESC dev; 3035081d237aSliuyi u8 master_gpt[34 * SECTOR_SIZE], param_buffer[512 * SECTOR_SIZE]; 30366ae612beSliuyi u64 lba, lba_end; 3037081d237aSliuyi u32 part_size, part_offset; 303876af099aSliuyi 303976af099aSliuyi transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 30408df2d64aSEddie Cai s = (char*)strCmd.c_str(); 30418df2d64aSEddie Cai for(i = 0; i < (int)strlen(s); i++) 30428df2d64aSEddie Cai s[i] = toupper(s[i]); 304378884ef4SEddie Cai 30448df2d64aSEddie Cai if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 304576af099aSliuyi usage(); 304676af099aSliuyi return true; 30478df2d64aSEddie Cai } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 3048c30d921cSKever Yang printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 304976af099aSliuyi return true; 305078884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 305178884ef4SEddie Cai mergeBoot(); 305278884ef4SEddie Cai return true; 305378884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 305478884ef4SEddie Cai string strLoader = argv[2]; 305578884ef4SEddie Cai unpackBoot((char*)strLoader.c_str()); 305678884ef4SEddie Cai return true; 3057d71e8c20SEddie Cai } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 3058d71e8c20SEddie Cai if (argc == 4) { 3059d71e8c20SEddie Cai string tag = argv[2]; 3060d71e8c20SEddie Cai string spl = argv[3]; 3061d71e8c20SEddie Cai printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 3062d71e8c20SEddie Cai tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 3063d71e8c20SEddie Cai return true; 3064d71e8c20SEddie Cai } 3065d71e8c20SEddie Cai printf("tagspl: parameter error\n"); 3066d71e8c20SEddie Cai usage(); 306776af099aSliuyi } 306876af099aSliuyi cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 3069081d237aSliuyi if(strcmp(strCmd.c_str(), "LD") == 0) { 3070081d237aSliuyi list_device(pScan); 3071*0dcb0a4cSliuyi return (cnt>0)?true:false; 3072081d237aSliuyi } 3073081d237aSliuyi 307476af099aSliuyi if (cnt < 1) { 307576af099aSliuyi ERROR_COLOR_ATTR; 307632268622SAndreas Färber printf("Did not find any rockusb device, please plug device in!"); 307776af099aSliuyi NORMAL_COLOR_ATTR; 307876af099aSliuyi printf("\r\n"); 307976af099aSliuyi return bSuccess; 308076af099aSliuyi } else if (cnt > 1) { 308176af099aSliuyi ERROR_COLOR_ATTR; 308232268622SAndreas Färber printf("Found too many rockusb devices, please plug devices out!"); 308376af099aSliuyi NORMAL_COLOR_ATTR; 308476af099aSliuyi printf("\r\n"); 308576af099aSliuyi return bSuccess; 308676af099aSliuyi } 308776af099aSliuyi 308876af099aSliuyi bRet = pScan->GetDevice(dev, 0); 308976af099aSliuyi if (!bRet) { 309076af099aSliuyi ERROR_COLOR_ATTR; 309132268622SAndreas Färber printf("Getting information about rockusb device failed!"); 309276af099aSliuyi NORMAL_COLOR_ATTR; 309376af099aSliuyi printf("\r\n"); 309476af099aSliuyi return bSuccess; 309576af099aSliuyi } 309676af099aSliuyi 309776af099aSliuyi if(strcmp(strCmd.c_str(), "RD") == 0) { 309876af099aSliuyi if ((argc != 2) && (argc != 3)) 309976af099aSliuyi printf("Parameter of [RD] command is invalid, please check help!\r\n"); 310076af099aSliuyi else { 310176af099aSliuyi if (argc == 2) 310276af099aSliuyi bSuccess = reset_device(dev); 310376af099aSliuyi else { 310476af099aSliuyi UINT uiSubCode; 310576af099aSliuyi char *pszEnd; 310676af099aSliuyi uiSubCode = strtoul(argv[2], &pszEnd, 0); 310776af099aSliuyi if (*pszEnd) 310876af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 310976af099aSliuyi else { 311076af099aSliuyi if (uiSubCode <= 5) 311176af099aSliuyi bSuccess = reset_device(dev, uiSubCode); 311276af099aSliuyi else 311376af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 311476af099aSliuyi } 311576af099aSliuyi } 311676af099aSliuyi } 311776af099aSliuyi } else if(strcmp(strCmd.c_str(), "TD") == 0) { 311876af099aSliuyi bSuccess = test_device(dev); 311976af099aSliuyi } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 312076af099aSliuyi bSuccess = read_flash_id(dev); 312176af099aSliuyi } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 312276af099aSliuyi bSuccess = read_flash_info(dev); 312376af099aSliuyi } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 312476af099aSliuyi bSuccess = read_chip_info(dev); 3125081d237aSliuyi } else if (strcmp(strCmd.c_str(), "RCB") == 0) {//Read Capability 3126081d237aSliuyi bSuccess = read_capability(dev); 312776af099aSliuyi } else if(strcmp(strCmd.c_str(), "DB") == 0) { 312876af099aSliuyi if (argc > 2) { 312976af099aSliuyi string strLoader; 313076af099aSliuyi strLoader = argv[2]; 313176af099aSliuyi bSuccess = download_boot(dev, (char *)strLoader.c_str()); 313276af099aSliuyi } else if (argc == 2) { 3133c29e5f0fSliuyi ret = find_config_item(g_ConfigItemVec, "loader"); 313476af099aSliuyi if (ret == -1) 313532268622SAndreas Färber printf("Did not find loader item in config!\r\n"); 313676af099aSliuyi else 313776af099aSliuyi bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 313876af099aSliuyi } else 313976af099aSliuyi printf("Parameter of [DB] command is invalid, please check help!\r\n"); 3140c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 3141c30d921cSKever Yang if (argc > 2) { 3142c30d921cSKever Yang string strParameter; 3143c30d921cSKever Yang strParameter = argv[2]; 3144c30d921cSKever Yang bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 3145c30d921cSKever Yang } else 3146c30d921cSKever Yang printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 3147081d237aSliuyi } else if(strcmp(strCmd.c_str(), "PRM") == 0) { 3148081d237aSliuyi if (argc > 2) { 3149081d237aSliuyi string strParameter; 3150081d237aSliuyi strParameter = argv[2]; 3151081d237aSliuyi bSuccess = write_parameter(dev, (char *)strParameter.c_str()); 3152081d237aSliuyi } else 3153081d237aSliuyi printf("Parameter of [PRM] command is invalid, please check help!\r\n"); 3154c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "UL") == 0) { 3155c30d921cSKever Yang if (argc > 2) { 3156c30d921cSKever Yang string strLoader; 3157c30d921cSKever Yang strLoader = argv[2]; 3158c30d921cSKever Yang bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 3159c30d921cSKever Yang } else 3160c30d921cSKever Yang printf("Parameter of [UL] command is invalid, please check help!\r\n"); 316176af099aSliuyi } else if(strcmp(strCmd.c_str(), "EF") == 0) { 316276af099aSliuyi if (argc == 2) { 316376af099aSliuyi bSuccess = erase_flash(dev); 316476af099aSliuyi } else 316576af099aSliuyi printf("Parameter of [EF] command is invalid, please check help!\r\n"); 316676af099aSliuyi } else if(strcmp(strCmd.c_str(), "WL") == 0) { 316776af099aSliuyi if (argc == 4) { 316876af099aSliuyi UINT uiBegin; 316976af099aSliuyi char *pszEnd; 317076af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 317176af099aSliuyi if (*pszEnd) 317276af099aSliuyi printf("Begin is invalid, please check!\r\n"); 3173ae4252f0Sliuyi else { 3174ae4252f0Sliuyi if (is_sparse_image(argv[3])) 3175ae4252f0Sliuyi bSuccess = write_sparse_lba(dev, (u32)uiBegin, (u32)-1, argv[3]); 3176*0dcb0a4cSliuyi else { 3177*0dcb0a4cSliuyi bSuccess = true; 3178*0dcb0a4cSliuyi if (is_ubifs_image(argv[3])) 3179*0dcb0a4cSliuyi bSuccess = erase_ubi_block(dev, (u32)uiBegin, (u32)-1); 3180*0dcb0a4cSliuyi if (bSuccess) 3181ae4252f0Sliuyi bSuccess = write_lba(dev, (u32)uiBegin, argv[3]); 3182*0dcb0a4cSliuyi else 3183*0dcb0a4cSliuyi printf("Failure of Erase for writing ubi image!\r\n"); 3184*0dcb0a4cSliuyi } 3185ae4252f0Sliuyi } 318676af099aSliuyi } else 318776af099aSliuyi printf("Parameter of [WL] command is invalid, please check help!\r\n"); 31886ae612beSliuyi } else if(strcmp(strCmd.c_str(), "WLX") == 0) { 31896ae612beSliuyi if (argc == 4) { 31906ae612beSliuyi bRet = read_gpt(dev, master_gpt); 31916ae612beSliuyi if (bRet) { 31926ae612beSliuyi bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end); 31936ae612beSliuyi if (bRet) { 31946ae612beSliuyi if (is_sparse_image(argv[3])) 31956ae612beSliuyi bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]); 3196*0dcb0a4cSliuyi else { 3197*0dcb0a4cSliuyi bSuccess = true; 3198*0dcb0a4cSliuyi if (is_ubifs_image(argv[3])) 3199*0dcb0a4cSliuyi bSuccess = erase_ubi_block(dev, (u32)lba, (u32)(lba_end - lba + 1)); 3200*0dcb0a4cSliuyi if (bSuccess) 32016ae612beSliuyi bSuccess = write_lba(dev, (u32)lba, argv[3]); 3202*0dcb0a4cSliuyi else 3203*0dcb0a4cSliuyi printf("Failure of Erase for writing ubi image!\r\n"); 3204*0dcb0a4cSliuyi } 32056ae612beSliuyi } else 32066ae612beSliuyi printf("No found %s partition\r\n", argv[2]); 3207081d237aSliuyi } else { 3208081d237aSliuyi bRet = read_param(dev, param_buffer); 3209081d237aSliuyi if (bRet) { 3210081d237aSliuyi bRet = get_lba_from_param(param_buffer+8, argv[2], &part_offset, &part_size); 3211081d237aSliuyi if (bRet) { 3212081d237aSliuyi if (is_sparse_image(argv[3])) 3213081d237aSliuyi bSuccess = write_sparse_lba(dev, part_offset, part_size, argv[3]); 3214*0dcb0a4cSliuyi else { 3215*0dcb0a4cSliuyi bSuccess = true; 3216*0dcb0a4cSliuyi if (is_ubifs_image(argv[3])) 3217*0dcb0a4cSliuyi bSuccess = erase_ubi_block(dev, part_offset, part_size); 3218*0dcb0a4cSliuyi if (bSuccess) 3219081d237aSliuyi bSuccess = write_lba(dev, part_offset, argv[3]); 3220*0dcb0a4cSliuyi else 3221*0dcb0a4cSliuyi printf("Failure of Erase for writing ubi image!\r\n"); 3222*0dcb0a4cSliuyi } 3223081d237aSliuyi } else 3224081d237aSliuyi printf("No found %s partition\r\n", argv[2]); 32256ae612beSliuyi } 3226081d237aSliuyi else 3227081d237aSliuyi printf("Not found any partition table!\r\n"); 3228081d237aSliuyi } 3229081d237aSliuyi 32306ae612beSliuyi } else 32316ae612beSliuyi printf("Parameter of [WLX] command is invalid, please check help!\r\n"); 323276af099aSliuyi } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 323376af099aSliuyi char *pszEnd; 323476af099aSliuyi UINT uiBegin, uiLen; 323576af099aSliuyi if (argc != 5) 323676af099aSliuyi printf("Parameter of [RL] command is invalid, please check help!\r\n"); 323776af099aSliuyi else { 323876af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 323976af099aSliuyi if (*pszEnd) 324076af099aSliuyi printf("Begin is invalid, please check!\r\n"); 324176af099aSliuyi else { 324276af099aSliuyi uiLen = strtoul(argv[3], &pszEnd, 0); 324376af099aSliuyi if (*pszEnd) 324476af099aSliuyi printf("Len is invalid, please check!\r\n"); 324576af099aSliuyi else { 324676af099aSliuyi bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 324776af099aSliuyi } 324876af099aSliuyi } 324976af099aSliuyi } 3250081d237aSliuyi } else if(strcmp(strCmd.c_str(), "PPT") == 0) { 32513dc7e3ceSliuyi if (argc == 2) { 32523dc7e3ceSliuyi bSuccess = print_gpt(dev); 3253081d237aSliuyi if (!bSuccess) { 3254081d237aSliuyi bSuccess = print_parameter(dev); 3255081d237aSliuyi if (!bSuccess) 3256081d237aSliuyi printf("Not found any partition table!\r\n"); 3257081d237aSliuyi } 32583dc7e3ceSliuyi } else 3259081d237aSliuyi printf("Parameter of [PPT] command is invalid, please check help!\r\n"); 326076af099aSliuyi } else { 32619bc231bdSAndreas Färber printf("command is invalid!\r\n"); 32629bc231bdSAndreas Färber usage(); 326376af099aSliuyi } 326476af099aSliuyi return bSuccess; 326576af099aSliuyi } 326676af099aSliuyi 326776af099aSliuyi 326876af099aSliuyi int main(int argc, char* argv[]) 326976af099aSliuyi { 327076af099aSliuyi CRKScan *pScan = NULL; 327176af099aSliuyi int ret; 327276af099aSliuyi char szProgramProcPath[100]; 327376af099aSliuyi char szProgramDir[256]; 327476af099aSliuyi string strLogDir,strConfigFile; 327576af099aSliuyi struct stat statBuf; 327676af099aSliuyi 327776af099aSliuyi g_ConfigItemVec.clear(); 327876af099aSliuyi sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 327976af099aSliuyi if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 328076af099aSliuyi strcpy(szProgramDir, "."); 328176af099aSliuyi else { 328276af099aSliuyi char *pSlash; 328376af099aSliuyi pSlash = strrchr(szProgramDir, '/'); 328476af099aSliuyi if (pSlash) 328576af099aSliuyi *pSlash = '\0'; 328676af099aSliuyi } 328776af099aSliuyi strLogDir = szProgramDir; 328876af099aSliuyi strLogDir += "/log/"; 328976af099aSliuyi strConfigFile = szProgramDir; 329076af099aSliuyi strConfigFile += "/config.ini"; 329176af099aSliuyi if (opendir(strLogDir.c_str()) == NULL) 329276af099aSliuyi mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 3293e5ee8cc0Sliuyi g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 329476af099aSliuyi 329576af099aSliuyi if(stat(strConfigFile.c_str(), &statBuf) < 0) { 329676af099aSliuyi if (g_pLogObject) { 329776af099aSliuyi g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 329876af099aSliuyi } 329976af099aSliuyi } else if (S_ISREG(statBuf.st_mode)) { 330076af099aSliuyi parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 330176af099aSliuyi } 330276af099aSliuyi 330376af099aSliuyi ret = libusb_init(NULL); 330476af099aSliuyi if (ret < 0) { 330576af099aSliuyi if (g_pLogObject) { 330676af099aSliuyi g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 330776af099aSliuyi delete g_pLogObject; 330876af099aSliuyi } 330976af099aSliuyi return -1; 331076af099aSliuyi } 331176af099aSliuyi 331276af099aSliuyi pScan = new CRKScan(); 331376af099aSliuyi if (!pScan) { 331476af099aSliuyi if (g_pLogObject) { 331532268622SAndreas Färber g_pLogObject->Record("Error: failed to create object for searching device"); 331676af099aSliuyi delete g_pLogObject; 331776af099aSliuyi } 331876af099aSliuyi libusb_exit(NULL); 331976af099aSliuyi return -2; 332076af099aSliuyi } 332176af099aSliuyi pScan->SetVidPid(); 332276af099aSliuyi 332376af099aSliuyi if (argc == 1) 332476af099aSliuyi usage(); 332576af099aSliuyi else if (!handle_command(argc, argv, pScan)) 332676af099aSliuyi return -0xFF; 332776af099aSliuyi if (pScan) 332876af099aSliuyi delete pScan; 332976af099aSliuyi if (g_pLogObject) 333076af099aSliuyi delete g_pLogObject; 333176af099aSliuyi libusb_exit(NULL); 333276af099aSliuyi return 0; 333376af099aSliuyi } 3334