176af099aSliuyi /* 276af099aSliuyi * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 376af099aSliuyi * Seth Liu 2017.03.01 476af099aSliuyi * 576af099aSliuyi * SPDX-License-Identifier: GPL-2.0+ 676af099aSliuyi */ 776af099aSliuyi 876af099aSliuyi #include <unistd.h> 976af099aSliuyi #include <dirent.h> 10c30d921cSKever Yang #include "config.h" 1176af099aSliuyi #include "DefineHeader.h" 12c30d921cSKever Yang #include "gpt.h" 1376af099aSliuyi #include "RKLog.h" 1476af099aSliuyi #include "RKScan.h" 1576af099aSliuyi #include "RKComm.h" 1676af099aSliuyi #include "RKDevice.h" 1776af099aSliuyi #include "RKImage.h" 1876af099aSliuyi extern const char *szManufName[]; 1976af099aSliuyi CRKLog *g_pLogObject=NULL; 2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec; 2176af099aSliuyi #define DEFAULT_RW_LBA 128 2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n) 2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B) 2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B) 2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B) 2676af099aSliuyi #define ERROR_COLOR_ATTR printf("%c[30;41m", 0x1B); 273601cc08SAndreas Färber #define NORMAL_COLOR_ATTR printf("%c[0m", 0x1B); 28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize); 29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize); 30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len); 31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len); 32c30d921cSKever Yang /* 33c30d921cSKever Yang u8 test_gpt_head[] = { 34c30d921cSKever Yang 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00, 35c30d921cSKever Yang 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36c30d921cSKever Yang 0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37c30d921cSKever Yang 0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B, 38c30d921cSKever Yang 0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39c30d921cSKever Yang 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08}; 40c30d921cSKever Yang */ 41c30d921cSKever Yang 4276af099aSliuyi void usage() 4376af099aSliuyi { 4476af099aSliuyi printf("\r\n---------------------Tool Usage ---------------------\r\n"); 45154ee062SEddie Cai printf("Help:\t\t\t-h or --version\r\n"); 46154ee062SEddie Cai printf("Version:\t\t-v or --version\r\n"); 47154ee062SEddie Cai printf("DownloadBoot:\t\tdb <Loader>\r\n"); 48154ee062SEddie Cai printf("UpgradeLoader:\t\tul <Loader>\r\n"); 49154ee062SEddie Cai printf("ReadLBA:\t\trl <BeginSec> <SectorLen> <File>\r\n"); 50154ee062SEddie Cai printf("WriteLBA:\t\twl <BeginSec> <File>\r\n"); 51154ee062SEddie Cai printf("WriteGPT:\t\tgpt <gpt partition table>\r\n"); 52154ee062SEddie Cai printf("EraseFlash:\t\tef \r\n"); 53154ee062SEddie Cai printf("TestDevice:\t\ttd\r\n"); 54154ee062SEddie Cai printf("ResetDevice:\t\trd [subcode]\r\n"); 55154ee062SEddie Cai printf("ReadFlashID:\t\trid\r\n"); 56154ee062SEddie Cai printf("ReadFlashInfo:\t\trfi\r\n"); 57154ee062SEddie Cai printf("ReadChipInfo:\t\trci\r\n"); 5878884ef4SEddie Cai printf("PackBootLoader:\t\tpack\r\n"); 5978884ef4SEddie Cai printf("UnpackBootLoader:\tunpack <boot loader>\r\n"); 60d71e8c20SEddie Cai printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n"); 6176af099aSliuyi printf("-------------------------------------------------------\r\n\r\n"); 6276af099aSliuyi } 6376af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall) 6476af099aSliuyi { 6576af099aSliuyi string strInfoText=""; 6676af099aSliuyi char szText[256]; 6776af099aSliuyi switch (promptID) { 6876af099aSliuyi case TESTDEVICE_PROGRESS: 6932268622SAndreas Färber sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue); 7076af099aSliuyi strInfoText = szText; 7176af099aSliuyi break; 7276af099aSliuyi case LOWERFORMAT_PROGRESS: 7332268622SAndreas Färber sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue); 7476af099aSliuyi strInfoText = szText; 7576af099aSliuyi break; 7676af099aSliuyi case DOWNLOADIMAGE_PROGRESS: 7732268622SAndreas Färber sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 7876af099aSliuyi strInfoText = szText; 7976af099aSliuyi break; 8076af099aSliuyi case CHECKIMAGE_PROGRESS: 8132268622SAndreas Färber sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 8276af099aSliuyi strInfoText = szText; 8376af099aSliuyi break; 8476af099aSliuyi case TAGBADBLOCK_PROGRESS: 8532268622SAndreas Färber sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue); 8676af099aSliuyi strInfoText = szText; 8776af099aSliuyi break; 8876af099aSliuyi case TESTBLOCK_PROGRESS: 8932268622SAndreas Färber sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue); 9076af099aSliuyi strInfoText = szText; 9176af099aSliuyi break; 9276af099aSliuyi case ERASEFLASH_PROGRESS: 9332268622SAndreas Färber sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue); 9476af099aSliuyi strInfoText = szText; 9576af099aSliuyi break; 9676af099aSliuyi case ERASESYSTEM_PROGRESS: 9732268622SAndreas Färber sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue); 9876af099aSliuyi strInfoText = szText; 9976af099aSliuyi break; 10076af099aSliuyi case ERASEUSERDATA_PROGRESS: 10132268622SAndreas Färber sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue); 10276af099aSliuyi strInfoText = szText; 10376af099aSliuyi break; 10476af099aSliuyi } 10576af099aSliuyi if (strInfoText.size() > 0){ 10676af099aSliuyi CURSOR_MOVEUP_LINE(1); 10776af099aSliuyi CURSOR_DEL_LINE; 10876af099aSliuyi printf("%s\r\n", strInfoText.c_str()); 10976af099aSliuyi } 11076af099aSliuyi if (emCall == CALL_LAST) 11176af099aSliuyi deviceLayer = 0; 11276af099aSliuyi } 11376af099aSliuyi 11476af099aSliuyi char *strupr(char *szSrc) 11576af099aSliuyi { 11676af099aSliuyi char *p = szSrc; 11776af099aSliuyi while(*p){ 11876af099aSliuyi if ((*p >= 'a') && (*p <= 'z')) 11976af099aSliuyi *p = *p - 'a' + 'A'; 12076af099aSliuyi p++; 12176af099aSliuyi } 12276af099aSliuyi return szSrc; 12376af099aSliuyi } 12476af099aSliuyi void PrintData(PBYTE pData, int nSize) 12576af099aSliuyi { 12676af099aSliuyi char szPrint[17] = "\0"; 12776af099aSliuyi int i; 12876af099aSliuyi for( i = 0; i < nSize; i++){ 12976af099aSliuyi if(i % 16 == 0){ 13076af099aSliuyi if(i / 16 > 0) 13176af099aSliuyi printf(" %s\r\n", szPrint); 13276af099aSliuyi printf("%08d ", i / 16); 13376af099aSliuyi } 13476af099aSliuyi printf("%02X ", pData[i]); 13576af099aSliuyi szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.'; 13676af099aSliuyi } 13776af099aSliuyi if(i / 16 > 0) 13876af099aSliuyi printf(" %s\r\n", szPrint); 13976af099aSliuyi } 14076af099aSliuyi 14176af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest) 14276af099aSliuyi { 14376af099aSliuyi if (!pszSrc) 14476af099aSliuyi return false; 14576af099aSliuyi int nSrcLen = strlen(pszSrc); 14676af099aSliuyi int nDestLen = nSrcLen * 2; 14776af099aSliuyi 14876af099aSliuyi pszDest = NULL; 14976af099aSliuyi pszDest = new wchar_t[nDestLen]; 15076af099aSliuyi if (!pszDest) 15176af099aSliuyi return false; 15276af099aSliuyi nDestLen = nDestLen * sizeof(wchar_t); 15376af099aSliuyi memset(pszDest, 0, nDestLen); 15476af099aSliuyi int iRet; 15576af099aSliuyi iconv_t cd; 15676af099aSliuyi cd = iconv_open("UTF-32", "UTF-8"); 15776af099aSliuyi if((iconv_t)-1 == cd) { 15876af099aSliuyi delete []pszDest; 15976af099aSliuyi pszDest = NULL; 16076af099aSliuyi return false; 16176af099aSliuyi } 16276af099aSliuyi char *pIn, *pOut; 16376af099aSliuyi pIn = (char *)pszSrc; 16476af099aSliuyi pOut = (char *)pszDest; 16576af099aSliuyi 16676af099aSliuyi iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 16776af099aSliuyi 16876af099aSliuyi if(iRet == -1) { 16976af099aSliuyi delete []pszDest; 17076af099aSliuyi pszDest = NULL; 17176af099aSliuyi iconv_close(cd); 17276af099aSliuyi return false; 17376af099aSliuyi } 17476af099aSliuyi 17576af099aSliuyi iconv_close(cd); 17676af099aSliuyi 17776af099aSliuyi return true; 17876af099aSliuyi } 17976af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest) 18076af099aSliuyi { 18176af099aSliuyi if (!pszSrc) 18276af099aSliuyi return false; 18376af099aSliuyi int nSrcLen = wcslen(pszSrc); 18476af099aSliuyi int nDestLen = nSrcLen * 2; 18576af099aSliuyi nSrcLen = nSrcLen * sizeof(wchar_t); 18676af099aSliuyi pszDest = NULL; 18776af099aSliuyi pszDest = new char[nDestLen]; 18876af099aSliuyi if (!pszDest) 18976af099aSliuyi return false; 19076af099aSliuyi memset(pszDest, 0, nDestLen); 19176af099aSliuyi int iRet; 19276af099aSliuyi iconv_t cd; 19376af099aSliuyi cd = iconv_open("UTF-8", "UTF-32"); 19476af099aSliuyi 19576af099aSliuyi if((iconv_t)-1 == cd) { 19676af099aSliuyi delete []pszDest; 19776af099aSliuyi pszDest = NULL; 19876af099aSliuyi return false; 19976af099aSliuyi } 20076af099aSliuyi char *pIn, *pOut; 20176af099aSliuyi pIn = (char *)pszSrc; 20276af099aSliuyi pOut = (char *)pszDest; 20376af099aSliuyi iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 20476af099aSliuyi 20576af099aSliuyi if(iRet == -1) { 20676af099aSliuyi delete []pszDest; 20776af099aSliuyi pszDest = NULL; 20876af099aSliuyi iconv_close(cd); 20976af099aSliuyi return false; 21076af099aSliuyi } 21176af099aSliuyi 21276af099aSliuyi iconv_close(cd); 21376af099aSliuyi 21476af099aSliuyi return true; 21576af099aSliuyi } 21676af099aSliuyi int find_config_item(const char *pszName) 21776af099aSliuyi { 21876af099aSliuyi unsigned int i; 21976af099aSliuyi for(i = 0; i < g_ConfigItemVec.size(); i++){ 22076af099aSliuyi if (strcasecmp(pszName, g_ConfigItemVec[i].szItemName) == 0){ 22176af099aSliuyi return i; 22276af099aSliuyi } 22376af099aSliuyi } 22476af099aSliuyi return -1; 22576af099aSliuyi } 22676af099aSliuyi 22776af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 22876af099aSliuyi { 22976af099aSliuyi 23076af099aSliuyi stringstream configStream(pConfig); 23176af099aSliuyi string strLine, strItemName, strItemValue; 23276af099aSliuyi string::size_type line_size,pos; 23376af099aSliuyi STRUCT_CONFIG_ITEM item; 23476af099aSliuyi vecItem.clear(); 23576af099aSliuyi while (!configStream.eof()){ 23676af099aSliuyi getline(configStream, strLine); 23776af099aSliuyi line_size = strLine.size(); 23876af099aSliuyi if (line_size == 0) 23976af099aSliuyi continue; 24076af099aSliuyi if (strLine[line_size-1] == '\r'){ 24176af099aSliuyi strLine = strLine.substr(0, line_size-1); 24276af099aSliuyi } 243c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 244c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 245c30d921cSKever Yang if (strLine.size()==0 ) 246c30d921cSKever Yang continue; 247c30d921cSKever Yang if (strLine[0] == '#') 248c30d921cSKever Yang continue; 24976af099aSliuyi pos = strLine.find("="); 25076af099aSliuyi if (pos == string::npos){ 25176af099aSliuyi continue; 25276af099aSliuyi } 25376af099aSliuyi strItemName = strLine.substr(0, pos); 25476af099aSliuyi strItemValue = strLine.substr(pos + 1); 25576af099aSliuyi strItemName.erase(0, strItemName.find_first_not_of(" ")); 25676af099aSliuyi strItemName.erase(strItemName.find_last_not_of(" ") + 1); 25776af099aSliuyi strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 25876af099aSliuyi strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 25976af099aSliuyi if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 26076af099aSliuyi strcpy(item.szItemName, strItemName.c_str()); 26176af099aSliuyi strcpy(item.szItemValue, strItemValue.c_str()); 26276af099aSliuyi vecItem.push_back(item); 26376af099aSliuyi } 26476af099aSliuyi } 26576af099aSliuyi return true; 26676af099aSliuyi 26776af099aSliuyi } 26876af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 26976af099aSliuyi { 27076af099aSliuyi FILE *file = NULL; 27176af099aSliuyi file = fopen(pConfigFile, "rb"); 27276af099aSliuyi if( !file ){ 27376af099aSliuyi if (g_pLogObject) 27432268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile); 27576af099aSliuyi return false; 27676af099aSliuyi } 27776af099aSliuyi int iFileSize; 27876af099aSliuyi fseek(file, 0, SEEK_END); 27976af099aSliuyi iFileSize = ftell(file); 28076af099aSliuyi fseek(file, 0, SEEK_SET); 28176af099aSliuyi char *pConfigBuf = NULL; 28276af099aSliuyi pConfigBuf = new char[iFileSize + 1]; 28376af099aSliuyi if (!pConfigBuf){ 28476af099aSliuyi fclose(file); 28576af099aSliuyi return false; 28676af099aSliuyi } 28776af099aSliuyi memset(pConfigBuf, 0, iFileSize + 1); 28876af099aSliuyi int iRead; 28976af099aSliuyi iRead = fread(pConfigBuf, 1, iFileSize, file); 29076af099aSliuyi if (iRead != iFileSize){ 29176af099aSliuyi if (g_pLogObject) 29232268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize); 29376af099aSliuyi fclose(file); 29476af099aSliuyi delete []pConfigBuf; 29576af099aSliuyi return false; 29676af099aSliuyi } 29776af099aSliuyi fclose(file); 29876af099aSliuyi bool bRet; 29976af099aSliuyi bRet = parse_config(pConfigBuf, vecItem); 30076af099aSliuyi delete []pConfigBuf; 30176af099aSliuyi return bRet; 30276af099aSliuyi } 303c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 304c30d921cSKever Yang { 305c30d921cSKever Yang string::size_type pos,prevPos; 306c30d921cSKever Yang string strOffset,strLen; 307c30d921cSKever Yang int iCount; 308c30d921cSKever Yang prevPos = pos = 0; 309c30d921cSKever Yang if (strPartInfo.size() <= 0) { 310c30d921cSKever Yang return false; 311c30d921cSKever Yang } 312c30d921cSKever Yang pos = strPartInfo.find('@'); 313c30d921cSKever Yang if (pos == string::npos) { 314c30d921cSKever Yang return false; 315c30d921cSKever Yang } 316c30d921cSKever Yang strLen = strPartInfo.substr(prevPos, pos - prevPos); 317c30d921cSKever Yang strLen.erase(0, strLen.find_first_not_of(" ")); 318c30d921cSKever Yang strLen.erase(strLen.find_last_not_of(" ") + 1); 319c30d921cSKever Yang if (strchr(strLen.c_str(), '-')) { 320c30d921cSKever Yang uiLen = 0xFFFFFFFF; 321c30d921cSKever Yang } else { 322c30d921cSKever Yang iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 323c30d921cSKever Yang if (iCount != 1) { 324c30d921cSKever Yang return false; 325c30d921cSKever Yang } 326c30d921cSKever Yang } 327c30d921cSKever Yang 328c30d921cSKever Yang prevPos = pos + 1; 329c30d921cSKever Yang pos = strPartInfo.find('(',prevPos); 330c30d921cSKever Yang if (pos == string::npos) { 331c30d921cSKever Yang return false; 332c30d921cSKever Yang } 333c30d921cSKever Yang strOffset = strPartInfo.substr(prevPos, pos - prevPos); 334c30d921cSKever Yang strOffset.erase(0, strOffset.find_first_not_of(" ")); 335c30d921cSKever Yang strOffset.erase(strOffset.find_last_not_of(" ") + 1); 336c30d921cSKever Yang iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 337c30d921cSKever Yang if (iCount != 1) { 338c30d921cSKever Yang return false; 339c30d921cSKever Yang } 340c30d921cSKever Yang prevPos = pos + 1; 341c30d921cSKever Yang pos = strPartInfo.find(')', prevPos); 342c30d921cSKever Yang if (pos == string::npos) { 343c30d921cSKever Yang return false; 344c30d921cSKever Yang } 345c30d921cSKever Yang strName = strPartInfo.substr(prevPos, pos - prevPos); 346c30d921cSKever Yang strName.erase(0, strName.find_first_not_of(" ")); 347c30d921cSKever Yang strName.erase(strName.find_last_not_of(" ") + 1); 348c30d921cSKever Yang 349c30d921cSKever Yang return true; 350c30d921cSKever Yang } 351c30d921cSKever Yang 352c30d921cSKever Yang bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem) 353c30d921cSKever Yang { 354c30d921cSKever Yang stringstream paramStream(pParameter); 355c30d921cSKever Yang bool bRet,bFind = false; 356c30d921cSKever Yang string strLine, strPartition, strPartInfo, strPartName; 357c30d921cSKever Yang string::size_type line_size, pos, posColon, posComma; 358c30d921cSKever Yang UINT uiPartOffset, uiPartSize; 359c30d921cSKever Yang STRUCT_PARAM_ITEM item; 360c30d921cSKever Yang vecItem.clear(); 361c30d921cSKever Yang while (!paramStream.eof()) { 362c30d921cSKever Yang getline(paramStream,strLine); 363c30d921cSKever Yang line_size = strLine.size(); 364c30d921cSKever Yang if (line_size == 0) 365c30d921cSKever Yang continue; 366c30d921cSKever Yang if (strLine[line_size - 1] == '\r'){ 367c30d921cSKever Yang strLine = strLine.substr(0, line_size - 1); 368c30d921cSKever Yang } 369c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 370c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 371c30d921cSKever Yang if (strLine.size()==0 ) 372c30d921cSKever Yang continue; 373c30d921cSKever Yang if (strLine[0] == '#') 374c30d921cSKever Yang continue; 375c30d921cSKever Yang pos = strLine.find("mtdparts"); 376c30d921cSKever Yang if (pos == string::npos) { 377c30d921cSKever Yang continue; 378c30d921cSKever Yang } 379c30d921cSKever Yang bFind = true; 380c30d921cSKever Yang posColon = strLine.find(':', pos); 381c30d921cSKever Yang if (posColon == string::npos) { 382c30d921cSKever Yang continue; 383c30d921cSKever Yang } 384c30d921cSKever Yang strPartition = strLine.substr(posColon + 1); 385c30d921cSKever Yang pos = 0; 386c30d921cSKever Yang posComma = strPartition.find(',', pos); 387c30d921cSKever Yang while (posComma != string::npos) { 388c30d921cSKever Yang strPartInfo = strPartition.substr(pos, posComma - pos); 389c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 390c30d921cSKever Yang if (bRet) { 391c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 392c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 393c30d921cSKever Yang item.uiItemSize = uiPartSize; 394c30d921cSKever Yang vecItem.push_back(item); 395c30d921cSKever Yang } 396c30d921cSKever Yang pos = posComma + 1; 397c30d921cSKever Yang posComma = strPartition.find(',', pos); 398c30d921cSKever Yang } 399c30d921cSKever Yang strPartInfo = strPartition.substr(pos); 400c30d921cSKever Yang if (strPartInfo.size() > 0) { 401c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 402c30d921cSKever Yang if (bRet) { 403c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 404c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 405c30d921cSKever Yang item.uiItemSize = uiPartSize; 406c30d921cSKever Yang vecItem.push_back(item); 407c30d921cSKever Yang } 408c30d921cSKever Yang } 409c30d921cSKever Yang break; 410c30d921cSKever Yang } 411c30d921cSKever Yang return bFind; 412c30d921cSKever Yang 413c30d921cSKever Yang } 414c30d921cSKever Yang bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem) 415c30d921cSKever Yang { 416c30d921cSKever Yang FILE *file = NULL; 417c30d921cSKever Yang file = fopen(pParamFile, "rb"); 418c30d921cSKever Yang if( !file ) { 419c30d921cSKever Yang if (g_pLogObject) 42032268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 421c30d921cSKever Yang return false; 422c30d921cSKever Yang } 423c30d921cSKever Yang int iFileSize; 424c30d921cSKever Yang fseek(file, 0, SEEK_END); 425c30d921cSKever Yang iFileSize = ftell(file); 426c30d921cSKever Yang fseek(file, 0, SEEK_SET); 427c30d921cSKever Yang char *pParamBuf = NULL; 428c30d921cSKever Yang pParamBuf = new char[iFileSize]; 429c30d921cSKever Yang if (!pParamBuf) { 430c30d921cSKever Yang fclose(file); 431c30d921cSKever Yang return false; 432c30d921cSKever Yang } 433c30d921cSKever Yang int iRead; 434c30d921cSKever Yang iRead = fread(pParamBuf, 1, iFileSize, file); 435c30d921cSKever Yang if (iRead != iFileSize) { 436c30d921cSKever Yang if (g_pLogObject) 43732268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize); 438c30d921cSKever Yang fclose(file); 439c30d921cSKever Yang delete []pParamBuf; 440c30d921cSKever Yang return false; 441c30d921cSKever Yang } 442c30d921cSKever Yang fclose(file); 443c30d921cSKever Yang bool bRet; 444c30d921cSKever Yang bRet = parse_parameter(pParamBuf, vecItem); 445c30d921cSKever Yang delete []pParamBuf; 446c30d921cSKever Yang return bRet; 447c30d921cSKever Yang } 448c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin) 449c30d921cSKever Yang { 450c30d921cSKever Yang efi_guid_t id; 451c30d921cSKever Yang unsigned int *ptr = (unsigned int *)&id; 452c30d921cSKever Yang unsigned int i; 453c30d921cSKever Yang 454c30d921cSKever Yang /* Set all fields randomly */ 455c30d921cSKever Yang for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 456c30d921cSKever Yang *(ptr + i) = cpu_to_be32(rand()); 457c30d921cSKever Yang 458c30d921cSKever Yang id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 459c30d921cSKever Yang id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 460c30d921cSKever Yang 461c30d921cSKever Yang memcpy(uuid_bin, id.raw, sizeof(id)); 462c30d921cSKever Yang } 463c30d921cSKever Yang 464c30d921cSKever Yang void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, u64 diskSectors) 465c30d921cSKever Yang { 466c30d921cSKever Yang legacy_mbr *mbr = (legacy_mbr *)gpt; 467c30d921cSKever Yang gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 468c30d921cSKever Yang gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 469c30d921cSKever Yang u32 i,j; 470c30d921cSKever Yang string strPartName; 471c30d921cSKever Yang string::size_type colonPos; 472c30d921cSKever Yang /*1.protective mbr*/ 473c30d921cSKever Yang memset(gpt, 0, SECTOR_SIZE); 474c30d921cSKever Yang mbr->signature = MSDOS_MBR_SIGNATURE; 475c30d921cSKever Yang mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 476c30d921cSKever Yang mbr->partition_record[0].start_sect = 1; 477c30d921cSKever Yang mbr->partition_record[0].nr_sects = (u32)-1; 478c30d921cSKever Yang /*2.gpt header*/ 479c30d921cSKever Yang memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 480c30d921cSKever Yang gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 481c30d921cSKever Yang gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 482c30d921cSKever Yang gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 483c30d921cSKever Yang gptHead->my_lba = cpu_to_le64(1); 484c30d921cSKever Yang gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 485c30d921cSKever Yang gptHead->first_usable_lba = cpu_to_le64(34); 486c30d921cSKever Yang gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 487c30d921cSKever Yang gptHead->partition_entry_lba = cpu_to_le64(2); 488c30d921cSKever Yang gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 489c30d921cSKever Yang gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 490c30d921cSKever Yang gptHead->header_crc32 = 0; 491c30d921cSKever Yang gptHead->partition_entry_array_crc32 = 0; 492c30d921cSKever Yang gen_rand_uuid(gptHead->disk_guid.raw); 493c30d921cSKever Yang 494c30d921cSKever Yang /*3.gpt partition entry*/ 495c30d921cSKever Yang memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 496c30d921cSKever Yang for (i = 0; i < vecParts.size(); i++) { 497c30d921cSKever Yang gen_rand_uuid(gptEntry->partition_type_guid.raw); 498c30d921cSKever Yang gen_rand_uuid(gptEntry->unique_partition_guid.raw); 499c30d921cSKever Yang gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 500c30d921cSKever Yang gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 501c30d921cSKever Yang gptEntry->attributes.raw = 0; 502c30d921cSKever Yang strPartName = vecParts[i].szItemName; 503c30d921cSKever Yang colonPos = strPartName.find_first_of(':'); 504c30d921cSKever Yang if (colonPos != string::npos) { 505c30d921cSKever Yang if (strPartName.find("bootable") != string::npos) 506c30d921cSKever Yang gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 507c30d921cSKever Yang strPartName = strPartName.substr(0, colonPos); 508c30d921cSKever Yang vecParts[i].szItemName[strPartName.size()] = 0; 509c30d921cSKever Yang } 510c30d921cSKever Yang for (j = 0; j < strlen(vecParts[i].szItemName); j++) 511c30d921cSKever Yang gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 512c30d921cSKever Yang gptEntry++; 513c30d921cSKever Yang } 514c30d921cSKever Yang 515c30d921cSKever Yang gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 516c30d921cSKever Yang gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 517c30d921cSKever Yang 518c30d921cSKever Yang } 519*b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag) 520c30d921cSKever Yang { 521c30d921cSKever Yang PRK28_IDB_SEC0 pSec0; 522c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 523c30d921cSKever Yang pSec0 = (PRK28_IDB_SEC0)pSector; 524c30d921cSKever Yang 525c30d921cSKever Yang pSec0->dwTag = 0x0FF0AA55; 526*b38fe5fcSliuyi pSec0->uiRc4Flag = rc4Flag; 527c30d921cSKever Yang pSec0->usBootCode1Offset = 0x4; 528c30d921cSKever Yang pSec0->usBootCode2Offset = 0x4; 529c30d921cSKever Yang pSec0->usBootDataSize = usFlashDataSec; 530c30d921cSKever Yang pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 531c30d921cSKever Yang return true; 532c30d921cSKever Yang } 533c30d921cSKever Yang 534c30d921cSKever Yang 535c30d921cSKever Yang bool MakeSector1(PBYTE pSector) 536c30d921cSKever Yang { 537c30d921cSKever Yang PRK28_IDB_SEC1 pSec1; 538c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 539c30d921cSKever Yang pSec1 = (PRK28_IDB_SEC1)pSector; 540c30d921cSKever Yang 541c30d921cSKever Yang pSec1->usSysReservedBlock = 0xC; 542c30d921cSKever Yang pSec1->usDisk0Size = 0xFFFF; 543c30d921cSKever Yang pSec1->uiChipTag = 0x38324B52; 544c30d921cSKever Yang return true; 545c30d921cSKever Yang } 546c30d921cSKever Yang 547c30d921cSKever Yang bool MakeSector2(PBYTE pSector) 548c30d921cSKever Yang { 549c30d921cSKever Yang PRK28_IDB_SEC2 pSec2; 550c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 551c30d921cSKever Yang pSec2 = (PRK28_IDB_SEC2)pSector; 552c30d921cSKever Yang 553c30d921cSKever Yang strcpy(pSec2->szVcTag, "VC"); 554c30d921cSKever Yang strcpy(pSec2->szCrcTag, "CRC"); 555c30d921cSKever Yang return true; 556c30d921cSKever Yang } 557c30d921cSKever Yang 558c30d921cSKever Yang bool MakeSector3(PBYTE pSector) 559c30d921cSKever Yang { 560c30d921cSKever Yang memset(pSector,0,SECTOR_SIZE); 561c30d921cSKever Yang return true; 562c30d921cSKever Yang } 563c30d921cSKever Yang 564*b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag) 565c30d921cSKever Yang { 566c30d921cSKever Yang RK28_IDB_SEC0 sector0Info; 567c30d921cSKever Yang RK28_IDB_SEC1 sector1Info; 568c30d921cSKever Yang RK28_IDB_SEC2 sector2Info; 569c30d921cSKever Yang RK28_IDB_SEC3 sector3Info; 570c30d921cSKever Yang UINT i; 571*b38fe5fcSliuyi printf("rc4=%d\r\n\r\n\r\n",rc4Flag); 572*b38fe5fcSliuyi MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag); 573c30d921cSKever Yang MakeSector1((PBYTE)§or1Info); 574c30d921cSKever Yang if (!MakeSector2((PBYTE)§or2Info)) { 575c30d921cSKever Yang return -6; 576c30d921cSKever Yang } 577c30d921cSKever Yang if (!MakeSector3((PBYTE)§or3Info)) { 578c30d921cSKever Yang return -7; 579c30d921cSKever Yang } 580c30d921cSKever Yang sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 581c30d921cSKever Yang sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 582c30d921cSKever Yang sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 583c30d921cSKever Yang 584c30d921cSKever Yang memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 585c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 586c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 587*b38fe5fcSliuyi 588*b38fe5fcSliuyi if (rc4Flag) { 589*b38fe5fcSliuyi for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++) 590*b38fe5fcSliuyi P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE); 591*b38fe5fcSliuyi for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++) 592*b38fe5fcSliuyi P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE); 593*b38fe5fcSliuyi } 594*b38fe5fcSliuyi 595c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 596c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 597c30d921cSKever Yang 598c30d921cSKever Yang sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 599c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 600c30d921cSKever Yang for(i = 0; i < 4; i++) { 601c30d921cSKever Yang if(i == 1) { 602c30d921cSKever Yang continue; 603c30d921cSKever Yang } else { 604c30d921cSKever Yang P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 605c30d921cSKever Yang } 606c30d921cSKever Yang } 607c30d921cSKever Yang return 0; 608c30d921cSKever Yang } 609c30d921cSKever Yang 610c30d921cSKever Yang 61176af099aSliuyi 61276af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 61376af099aSliuyi { 61476af099aSliuyi if ((dev.emUsbType & uiSupportType) == dev.emUsbType) 61576af099aSliuyi return true; 61676af099aSliuyi else 61776af099aSliuyi { 61876af099aSliuyi ERROR_COLOR_ATTR; 61932268622SAndreas Färber printf("The device does not support this operation!"); 62076af099aSliuyi NORMAL_COLOR_ATTR; 62176af099aSliuyi printf("\r\n"); 62276af099aSliuyi return false; 62376af099aSliuyi } 62476af099aSliuyi } 625c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 626c30d921cSKever Yang { 627c30d921cSKever Yang u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 628c30d921cSKever Yang u32 total_size_sector; 629c30d921cSKever Yang CRKComm *pComm = NULL; 630c30d921cSKever Yang PARAM_ITEM_VECTOR vecItems; 631c30d921cSKever Yang int iRet; 632c30d921cSKever Yang bool bRet, bSuccess = false; 633c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 634c30d921cSKever Yang return false; 635c30d921cSKever Yang 636c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 637c30d921cSKever Yang if (!bRet) { 638c30d921cSKever Yang ERROR_COLOR_ATTR; 639c30d921cSKever Yang printf("Creating Comm Object failed!"); 640c30d921cSKever Yang NORMAL_COLOR_ATTR; 641c30d921cSKever Yang printf("\r\n"); 642c30d921cSKever Yang return bSuccess; 643c30d921cSKever Yang } 64432268622SAndreas Färber printf("Writing gpt...\r\n"); 645c30d921cSKever Yang //1.get flash info 646c30d921cSKever Yang iRet = pComm->RKU_ReadFlashInfo(flash_info); 647c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 648c30d921cSKever Yang ERROR_COLOR_ATTR; 649c30d921cSKever Yang printf("Reading Flash Info failed!"); 650c30d921cSKever Yang NORMAL_COLOR_ATTR; 651c30d921cSKever Yang printf("\r\n"); 652c30d921cSKever Yang return bSuccess; 653c30d921cSKever Yang } 654c30d921cSKever Yang total_size_sector = *(u32 *)flash_info; 655c30d921cSKever Yang //2.get partition from parameter 656c30d921cSKever Yang bRet = parse_parameter_file(szParameter, vecItems); 657c30d921cSKever Yang if (!bRet) { 658c30d921cSKever Yang ERROR_COLOR_ATTR; 659c30d921cSKever Yang printf("Parsing parameter failed!"); 660c30d921cSKever Yang NORMAL_COLOR_ATTR; 661c30d921cSKever Yang printf("\r\n"); 662c30d921cSKever Yang return bSuccess; 663c30d921cSKever Yang } 664c30d921cSKever Yang vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 34; 665c30d921cSKever Yang //3.generate gpt info 666c30d921cSKever Yang create_gpt_buffer(master_gpt, vecItems, total_size_sector); 667c30d921cSKever Yang memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 668c30d921cSKever Yang memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 669c30d921cSKever Yang //4. write gpt 670c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 671c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 672c30d921cSKever Yang ERROR_COLOR_ATTR; 673c30d921cSKever Yang printf("Writing master gpt failed!"); 674c30d921cSKever Yang NORMAL_COLOR_ATTR; 675c30d921cSKever Yang printf("\r\n"); 676c30d921cSKever Yang return bSuccess; 677c30d921cSKever Yang } 678c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(total_size_sector - 34, 33, backup_gpt); 679c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 680c30d921cSKever Yang ERROR_COLOR_ATTR; 681c30d921cSKever Yang printf("Writing backup gpt failed!"); 682c30d921cSKever Yang NORMAL_COLOR_ATTR; 683c30d921cSKever Yang printf("\r\n"); 684c30d921cSKever Yang return bSuccess; 685c30d921cSKever Yang } 686c30d921cSKever Yang bSuccess = true; 687c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 688c30d921cSKever Yang CURSOR_DEL_LINE; 68932268622SAndreas Färber printf("Writing gpt succeeded.\r\n"); 690c30d921cSKever Yang return bSuccess; 691c30d921cSKever Yang } 69276af099aSliuyi 69378884ef4SEddie Cai #include "boot_merger.h" 69478884ef4SEddie Cai #define ENTRY_ALIGN (2048) 69578884ef4SEddie Cai options gOpts; 69678884ef4SEddie Cai 69778884ef4SEddie Cai 69878884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 69978884ef4SEddie Cai char* gConfigPath; 70078884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE]; 70178884ef4SEddie Cai 70278884ef4SEddie Cai static inline void fixPath(char* path) { 70378884ef4SEddie Cai int i, len = strlen(path); 70478884ef4SEddie Cai for(i=0; i<len; i++) { 70578884ef4SEddie Cai if (path[i] == '\\') 70678884ef4SEddie Cai path[i] = '/'; 70778884ef4SEddie Cai else if (path[i] == '\r' || path[i] == '\n') 70878884ef4SEddie Cai path[i] = '\0'; 70978884ef4SEddie Cai } 71078884ef4SEddie Cai } 71178884ef4SEddie Cai 71278884ef4SEddie Cai static bool parseChip(FILE* file) { 71378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 71478884ef4SEddie Cai return false; 71578884ef4SEddie Cai } 71678884ef4SEddie Cai if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 71778884ef4SEddie Cai return false; 71878884ef4SEddie Cai } 71978884ef4SEddie Cai printf("chip: %s\n", gOpts.chip); 72078884ef4SEddie Cai return true; 72178884ef4SEddie Cai } 72278884ef4SEddie Cai 72378884ef4SEddie Cai static bool parseVersion(FILE* file) { 72478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 72578884ef4SEddie Cai return false; 72678884ef4SEddie Cai } 72778884ef4SEddie Cai if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 72878884ef4SEddie Cai return false; 72978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 73078884ef4SEddie Cai return false; 73178884ef4SEddie Cai } 73278884ef4SEddie Cai if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 73378884ef4SEddie Cai return false; 73478884ef4SEddie Cai printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor); 73578884ef4SEddie Cai return true; 73678884ef4SEddie Cai } 73778884ef4SEddie Cai 73878884ef4SEddie Cai static bool parse471(FILE* file) { 73978884ef4SEddie Cai int i, index, pos; 74078884ef4SEddie Cai char buf[MAX_LINE_LEN]; 74178884ef4SEddie Cai 74278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 74378884ef4SEddie Cai return false; 74478884ef4SEddie Cai } 74578884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 74678884ef4SEddie Cai return false; 74778884ef4SEddie Cai printf("num: %d\n", gOpts.code471Num); 74878884ef4SEddie Cai if (!gOpts.code471Num) 74978884ef4SEddie Cai return true; 75078884ef4SEddie Cai if (gOpts.code471Num < 0) 75178884ef4SEddie Cai return false; 75278884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 75378884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 75478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 75578884ef4SEddie Cai return false; 75678884ef4SEddie Cai } 75778884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 75878884ef4SEddie Cai != 2) 75978884ef4SEddie Cai return false; 76078884ef4SEddie Cai index--; 76178884ef4SEddie Cai fixPath(buf); 76278884ef4SEddie Cai strcpy((char*)gOpts.code471Path[index], buf); 76378884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code471Path[index]); 76478884ef4SEddie Cai } 76578884ef4SEddie Cai pos = ftell(file); 76678884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 76778884ef4SEddie Cai return false; 76878884ef4SEddie Cai } 76978884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 77078884ef4SEddie Cai fseek(file, pos, SEEK_SET); 77178884ef4SEddie Cai printf("sleep: %d\n", gOpts.code471Sleep); 77278884ef4SEddie Cai return true; 77378884ef4SEddie Cai } 77478884ef4SEddie Cai 77578884ef4SEddie Cai static bool parse472(FILE* file) { 77678884ef4SEddie Cai int i, index, pos; 77778884ef4SEddie Cai char buf[MAX_LINE_LEN]; 77878884ef4SEddie Cai 77978884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 78078884ef4SEddie Cai return false; 78178884ef4SEddie Cai } 78278884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 78378884ef4SEddie Cai return false; 78478884ef4SEddie Cai printf("num: %d\n", gOpts.code472Num); 78578884ef4SEddie Cai if (!gOpts.code472Num) 78678884ef4SEddie Cai return true; 78778884ef4SEddie Cai if (gOpts.code472Num < 0) 78878884ef4SEddie Cai return false; 78978884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 79078884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 79178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 79278884ef4SEddie Cai return false; 79378884ef4SEddie Cai } 79478884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 79578884ef4SEddie Cai != 2) 79678884ef4SEddie Cai return false; 79778884ef4SEddie Cai fixPath(buf); 79878884ef4SEddie Cai index--; 79978884ef4SEddie Cai strcpy((char*)gOpts.code472Path[index], buf); 80078884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code472Path[index]); 80178884ef4SEddie Cai } 80278884ef4SEddie Cai pos = ftell(file); 80378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 80478884ef4SEddie Cai return false; 80578884ef4SEddie Cai } 80678884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 80778884ef4SEddie Cai fseek(file, pos, SEEK_SET); 80878884ef4SEddie Cai printf("sleep: %d\n", gOpts.code472Sleep); 80978884ef4SEddie Cai return true; 81078884ef4SEddie Cai } 81178884ef4SEddie Cai 81278884ef4SEddie Cai static bool parseLoader(FILE* file) { 81378884ef4SEddie Cai int i, j, index, pos; 81478884ef4SEddie Cai char buf[MAX_LINE_LEN]; 81578884ef4SEddie Cai char buf2[MAX_LINE_LEN]; 81678884ef4SEddie Cai 81778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 81878884ef4SEddie Cai return false; 81978884ef4SEddie Cai } 82078884ef4SEddie Cai pos = ftell(file); 82178884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 82278884ef4SEddie Cai fseek(file, pos, SEEK_SET); 82378884ef4SEddie Cai if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 82478884ef4SEddie Cai return false; 82578884ef4SEddie Cai } 82678884ef4SEddie Cai } 82778884ef4SEddie Cai printf("num: %d\n", gOpts.loaderNum); 82878884ef4SEddie Cai if (!gOpts.loaderNum) 82978884ef4SEddie Cai return false; 83078884ef4SEddie Cai if (gOpts.loaderNum < 0) 83178884ef4SEddie Cai return false; 83278884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 83378884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 83478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 83578884ef4SEddie Cai return false; 83678884ef4SEddie Cai } 83778884ef4SEddie Cai if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 83878884ef4SEddie Cai != 2) 83978884ef4SEddie Cai return false; 84078884ef4SEddie Cai index--; 84178884ef4SEddie Cai strcpy(gOpts.loader[index].name, buf); 84278884ef4SEddie Cai printf("name%d: %s\n", index, gOpts.loader[index].name); 84378884ef4SEddie Cai } 84478884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 84578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 84678884ef4SEddie Cai return false; 84778884ef4SEddie Cai } 84878884ef4SEddie Cai if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 84978884ef4SEddie Cai != 2) 85078884ef4SEddie Cai return false; 85178884ef4SEddie Cai for (j=0; j<gOpts.loaderNum; j++) { 85278884ef4SEddie Cai if (!strcmp(gOpts.loader[j].name, buf)) { 85378884ef4SEddie Cai fixPath(buf2); 85478884ef4SEddie Cai strcpy(gOpts.loader[j].path, buf2); 85578884ef4SEddie Cai printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 85678884ef4SEddie Cai break; 85778884ef4SEddie Cai } 85878884ef4SEddie Cai } 85978884ef4SEddie Cai if (j >= gOpts.loaderNum) { 86078884ef4SEddie Cai return false; 86178884ef4SEddie Cai } 86278884ef4SEddie Cai } 86378884ef4SEddie Cai return true; 86478884ef4SEddie Cai } 86578884ef4SEddie Cai 86678884ef4SEddie Cai static bool parseOut(FILE* file) { 86778884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 86878884ef4SEddie Cai return false; 86978884ef4SEddie Cai } 87078884ef4SEddie Cai if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 87178884ef4SEddie Cai return false; 87278884ef4SEddie Cai fixPath(gOpts.outPath); 87378884ef4SEddie Cai printf("out: %s\n", gOpts.outPath); 87478884ef4SEddie Cai return true; 87578884ef4SEddie Cai } 87678884ef4SEddie Cai 87778884ef4SEddie Cai 87878884ef4SEddie Cai void printOpts(FILE* out) { 87978884ef4SEddie Cai int i; 88078884ef4SEddie Cai fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 88178884ef4SEddie Cai fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 88278884ef4SEddie Cai "=%d\n", gOpts.major, gOpts.minor); 88378884ef4SEddie Cai 88478884ef4SEddie Cai fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 88578884ef4SEddie Cai for (i=0 ;i<gOpts.code471Num ;i++) { 88678884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 88778884ef4SEddie Cai } 88878884ef4SEddie Cai if (gOpts.code471Sleep > 0) 88978884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 89078884ef4SEddie Cai 89178884ef4SEddie Cai fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 89278884ef4SEddie Cai for (i=0 ;i<gOpts.code472Num ;i++) { 89378884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 89478884ef4SEddie Cai } 89578884ef4SEddie Cai if (gOpts.code472Sleep > 0) 89678884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 89778884ef4SEddie Cai 89878884ef4SEddie Cai fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 89978884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 90078884ef4SEddie Cai fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 90178884ef4SEddie Cai } 90278884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 90378884ef4SEddie Cai fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 90478884ef4SEddie Cai } 90578884ef4SEddie Cai 90678884ef4SEddie Cai fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 90778884ef4SEddie Cai } 90878884ef4SEddie Cai 90978884ef4SEddie Cai static bool parseOpts(void) { 91078884ef4SEddie Cai bool ret = false; 91178884ef4SEddie Cai bool chipOk = false; 91278884ef4SEddie Cai bool versionOk = false; 91378884ef4SEddie Cai bool code471Ok = true; 91478884ef4SEddie Cai bool code472Ok = true; 91578884ef4SEddie Cai bool loaderOk = false; 91678884ef4SEddie Cai bool outOk = false; 91778884ef4SEddie Cai char buf[MAX_LINE_LEN]; 91878884ef4SEddie Cai 91978884ef4SEddie Cai char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 92078884ef4SEddie Cai FILE* file; 92178884ef4SEddie Cai file = fopen(configPath, "r"); 92278884ef4SEddie Cai if (!file) { 92378884ef4SEddie Cai fprintf(stderr, "config (%s) not found!\n", configPath); 92478884ef4SEddie Cai if (configPath == (char*)DEF_CONFIG_FILE) { 92578884ef4SEddie Cai file = fopen(DEF_CONFIG_FILE, "w"); 92678884ef4SEddie Cai if (file) { 92732268622SAndreas Färber fprintf(stderr, "creating defconfig\n"); 92878884ef4SEddie Cai printOpts(file); 92978884ef4SEddie Cai } 93078884ef4SEddie Cai } 93178884ef4SEddie Cai goto end; 93278884ef4SEddie Cai } 93378884ef4SEddie Cai 93432268622SAndreas Färber printf("Starting to parse...\n"); 93578884ef4SEddie Cai 93678884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 93778884ef4SEddie Cai goto end; 93878884ef4SEddie Cai } 93978884ef4SEddie Cai while(fscanf(file, "%s", buf) == 1) { 94078884ef4SEddie Cai if (!strcmp(buf, SEC_CHIP)) { 94178884ef4SEddie Cai chipOk = parseChip(file); 94278884ef4SEddie Cai if (!chipOk) { 94378884ef4SEddie Cai printf("parseChip failed!\n"); 94478884ef4SEddie Cai goto end; 94578884ef4SEddie Cai } 94678884ef4SEddie Cai } else if (!strcmp(buf, SEC_VERSION)) { 94778884ef4SEddie Cai versionOk = parseVersion(file); 94878884ef4SEddie Cai if (!versionOk) { 94978884ef4SEddie Cai printf("parseVersion failed!\n"); 95078884ef4SEddie Cai goto end; 95178884ef4SEddie Cai } 95278884ef4SEddie Cai } else if (!strcmp(buf, SEC_471)) { 95378884ef4SEddie Cai code471Ok = parse471(file); 95478884ef4SEddie Cai if (!code471Ok) { 95578884ef4SEddie Cai printf("parse471 failed!\n"); 95678884ef4SEddie Cai goto end; 95778884ef4SEddie Cai } 95878884ef4SEddie Cai } else if (!strcmp(buf, SEC_472)) { 95978884ef4SEddie Cai code472Ok = parse472(file); 96078884ef4SEddie Cai if (!code472Ok) { 96178884ef4SEddie Cai printf("parse472 failed!\n"); 96278884ef4SEddie Cai goto end; 96378884ef4SEddie Cai } 96478884ef4SEddie Cai } else if (!strcmp(buf, SEC_LOADER)) { 96578884ef4SEddie Cai loaderOk = parseLoader(file); 96678884ef4SEddie Cai if (!loaderOk) { 96778884ef4SEddie Cai printf("parseLoader failed!\n"); 96878884ef4SEddie Cai goto end; 96978884ef4SEddie Cai } 97078884ef4SEddie Cai } else if (!strcmp(buf, SEC_OUT)) { 97178884ef4SEddie Cai outOk = parseOut(file); 97278884ef4SEddie Cai if (!outOk) { 97378884ef4SEddie Cai printf("parseOut failed!\n"); 97478884ef4SEddie Cai goto end; 97578884ef4SEddie Cai } 97678884ef4SEddie Cai } else if (buf[0] == '#') { 97778884ef4SEddie Cai continue; 97878884ef4SEddie Cai } else { 97978884ef4SEddie Cai printf("unknown sec: %s!\n", buf); 98078884ef4SEddie Cai goto end; 98178884ef4SEddie Cai } 98278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 98378884ef4SEddie Cai goto end; 98478884ef4SEddie Cai } 98578884ef4SEddie Cai } 98678884ef4SEddie Cai 98778884ef4SEddie Cai if (chipOk && versionOk && code471Ok && code472Ok 98878884ef4SEddie Cai && loaderOk && outOk) 98978884ef4SEddie Cai ret = true; 99078884ef4SEddie Cai end: 99178884ef4SEddie Cai if (file) 99278884ef4SEddie Cai fclose(file); 99378884ef4SEddie Cai return ret; 99478884ef4SEddie Cai } 99578884ef4SEddie Cai 99678884ef4SEddie Cai bool initOpts(void) { 99778884ef4SEddie Cai //set default opts 99878884ef4SEddie Cai gOpts.major = DEF_MAJOR; 99978884ef4SEddie Cai gOpts.minor = DEF_MINOR; 100078884ef4SEddie Cai strcpy(gOpts.chip, DEF_CHIP); 100178884ef4SEddie Cai gOpts.code471Sleep = DEF_CODE471_SLEEP; 100278884ef4SEddie Cai gOpts.code472Sleep = DEF_CODE472_SLEEP; 100378884ef4SEddie Cai gOpts.code471Num = DEF_CODE471_NUM; 100478884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 100578884ef4SEddie Cai strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 100678884ef4SEddie Cai gOpts.code472Num = DEF_CODE472_NUM; 100778884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 100878884ef4SEddie Cai strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 100978884ef4SEddie Cai gOpts.loaderNum = DEF_LOADER_NUM; 101078884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 101178884ef4SEddie Cai strcpy(gOpts.loader[0].name, DEF_LOADER0); 101278884ef4SEddie Cai strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 101378884ef4SEddie Cai strcpy(gOpts.loader[1].name, DEF_LOADER1); 101478884ef4SEddie Cai strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 101578884ef4SEddie Cai strcpy(gOpts.outPath, DEF_OUT_PATH); 101678884ef4SEddie Cai 101778884ef4SEddie Cai return parseOpts(); 101878884ef4SEddie Cai } 101978884ef4SEddie Cai 102078884ef4SEddie Cai /************merge code****************/ 102178884ef4SEddie Cai 102278884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) { 102378884ef4SEddie Cai uint8_t tmp[2] = {0}; 102478884ef4SEddie Cai int i; 102578884ef4SEddie Cai uint32_t ret; 102678884ef4SEddie Cai //if (value > 0xFFFF) { 102778884ef4SEddie Cai // return 0; 102878884ef4SEddie Cai //} 102978884ef4SEddie Cai for(i=0; i < 2; i++) { 103078884ef4SEddie Cai tmp[i] = (((value/10)%10)<<4) | (value%10); 103178884ef4SEddie Cai value /= 100; 103278884ef4SEddie Cai } 103378884ef4SEddie Cai ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 103478884ef4SEddie Cai 103578884ef4SEddie Cai printf("ret: %x\n",ret); 103678884ef4SEddie Cai return ret&0xFF; 103778884ef4SEddie Cai } 103878884ef4SEddie Cai 103978884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len) 104078884ef4SEddie Cai { 104178884ef4SEddie Cai int i; 104278884ef4SEddie Cai for (i = 0; i < len; i++) { 104378884ef4SEddie Cai wide[i] = (uint16_t) str[i]; 104478884ef4SEddie Cai } 104578884ef4SEddie Cai wide[len] = 0; 104678884ef4SEddie Cai } 104778884ef4SEddie Cai 104878884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) { 104978884ef4SEddie Cai char* end; 105078884ef4SEddie Cai char* start; 105178884ef4SEddie Cai int len; 105278884ef4SEddie Cai if (!path || !dst) 105378884ef4SEddie Cai return; 105478884ef4SEddie Cai start = strrchr(path, '/'); 105578884ef4SEddie Cai if (!start) 105678884ef4SEddie Cai start = path; 105778884ef4SEddie Cai else 105878884ef4SEddie Cai start++; 105978884ef4SEddie Cai end = strrchr(path, '.'); 1060641cfa16SEddie Cai if (!end || (end < start)) 106178884ef4SEddie Cai end = path + strlen(path); 106278884ef4SEddie Cai len = end - start; 106378884ef4SEddie Cai if (len >= MAX_NAME_LEN) 106478884ef4SEddie Cai len = MAX_NAME_LEN -1; 106578884ef4SEddie Cai str2wide(start, dst, len); 106678884ef4SEddie Cai 106778884ef4SEddie Cai 106878884ef4SEddie Cai char name[MAX_NAME_LEN]; 106978884ef4SEddie Cai memset(name, 0, sizeof(name)); 107078884ef4SEddie Cai memcpy(name, start, len); 107178884ef4SEddie Cai printf("path: %s, name: %s\n", path, name); 107278884ef4SEddie Cai 107378884ef4SEddie Cai } 107478884ef4SEddie Cai 107578884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) { 107678884ef4SEddie Cai struct stat st; 107778884ef4SEddie Cai if(stat(path, &st) < 0) 107878884ef4SEddie Cai return false; 107978884ef4SEddie Cai *size = st.st_size; 108078884ef4SEddie Cai printf("path: %s, size: %d\n", path, *size); 108178884ef4SEddie Cai return true; 108278884ef4SEddie Cai } 108378884ef4SEddie Cai 108478884ef4SEddie Cai static inline rk_time getTime(void) { 108578884ef4SEddie Cai rk_time rkTime; 108678884ef4SEddie Cai 108778884ef4SEddie Cai struct tm *tm; 108878884ef4SEddie Cai time_t tt = time(NULL); 108978884ef4SEddie Cai tm = localtime(&tt); 109078884ef4SEddie Cai rkTime.year = tm->tm_year + 1900; 109178884ef4SEddie Cai rkTime.month = tm->tm_mon + 1; 109278884ef4SEddie Cai rkTime.day = tm->tm_mday; 109378884ef4SEddie Cai rkTime.hour = tm->tm_hour; 109478884ef4SEddie Cai rkTime.minute = tm->tm_min; 109578884ef4SEddie Cai rkTime.second = tm->tm_sec; 109678884ef4SEddie Cai printf("%d-%d-%d %02d:%02d:%02d\n", 109778884ef4SEddie Cai rkTime.year, rkTime.month, rkTime.day, 109878884ef4SEddie Cai rkTime.hour, rkTime.minute, rkTime.second); 109978884ef4SEddie Cai return rkTime; 110078884ef4SEddie Cai } 110178884ef4SEddie Cai 110278884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) { 110378884ef4SEddie Cai bool ret = false; 110478884ef4SEddie Cai uint32_t size = 0, fixSize = 0; 110578884ef4SEddie Cai uint8_t* buf; 110678884ef4SEddie Cai 110778884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 110878884ef4SEddie Cai if (!inFile) 110978884ef4SEddie Cai goto end; 111078884ef4SEddie Cai 111178884ef4SEddie Cai if (!getFileSize(path, &size)) 111278884ef4SEddie Cai goto end; 111378884ef4SEddie Cai if (fix) { 111478884ef4SEddie Cai fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 111578884ef4SEddie Cai uint32_t tmp = fixSize % ENTRY_ALIGN; 111678884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 111778884ef4SEddie Cai fixSize +=tmp; 111878884ef4SEddie Cai memset(gBuf, 0, fixSize); 111978884ef4SEddie Cai } else { 112078884ef4SEddie Cai memset(gBuf, 0, size+ENTRY_ALIGN); 112178884ef4SEddie Cai } 112278884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 112378884ef4SEddie Cai goto end; 112478884ef4SEddie Cai 112578884ef4SEddie Cai if (fix) { 112678884ef4SEddie Cai 112778884ef4SEddie Cai buf = gBuf; 112878884ef4SEddie Cai size = fixSize; 112978884ef4SEddie Cai while(1) { 113078884ef4SEddie Cai P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 113178884ef4SEddie Cai buf += SMALL_PACKET; 113278884ef4SEddie Cai if (fixSize <= SMALL_PACKET) 113378884ef4SEddie Cai break; 113478884ef4SEddie Cai fixSize -= SMALL_PACKET; 113578884ef4SEddie Cai } 113678884ef4SEddie Cai } else { 113778884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 113878884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 113978884ef4SEddie Cai size +=tmp; 114078884ef4SEddie Cai P_RC4(gBuf, size); 114178884ef4SEddie Cai } 114278884ef4SEddie Cai 114378884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 114478884ef4SEddie Cai goto end; 114578884ef4SEddie Cai ret = true; 114678884ef4SEddie Cai end: 114778884ef4SEddie Cai if (inFile) 114878884ef4SEddie Cai fclose(inFile); 114978884ef4SEddie Cai if (!ret) 115032268622SAndreas Färber printf("writing entry (%s) failed\n", path); 115178884ef4SEddie Cai return ret; 115278884ef4SEddie Cai } 115378884ef4SEddie Cai 115478884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 115578884ef4SEddie Cai uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 115678884ef4SEddie Cai uint32_t size; 115778884ef4SEddie Cai rk_boot_entry entry; 115878884ef4SEddie Cai 115932268622SAndreas Färber printf("writing: %s\n", path); 1160641cfa16SEddie Cai memset(&entry, 0, sizeof(rk_boot_entry)); 116178884ef4SEddie Cai getName(fixName ? fixName: path, entry.name); 116278884ef4SEddie Cai entry.size = sizeof(rk_boot_entry); 116378884ef4SEddie Cai entry.type = type; 116478884ef4SEddie Cai entry.dataOffset = *offset; 116578884ef4SEddie Cai if (!getFileSize(path, &size)) { 116632268622SAndreas Färber printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path); 116778884ef4SEddie Cai return false; 116878884ef4SEddie Cai } 116978884ef4SEddie Cai if (fix) 117078884ef4SEddie Cai size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 117178884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 117278884ef4SEddie Cai size += tmp ? (ENTRY_ALIGN - tmp): 0; 117332268622SAndreas Färber printf("alignment size: %d\n", size); 117478884ef4SEddie Cai entry.dataSize = size; 117578884ef4SEddie Cai entry.dataDelay = delay; 117678884ef4SEddie Cai *offset += size; 117778884ef4SEddie Cai fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 117878884ef4SEddie Cai return true; 117978884ef4SEddie Cai } 118078884ef4SEddie Cai 118178884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) { 118278884ef4SEddie Cai char buffer[5]; 118378884ef4SEddie Cai memset(buffer, 0, sizeof(buffer)); 118478884ef4SEddie Cai snprintf(buffer, sizeof(buffer), "%s", chip); 118578884ef4SEddie Cai return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 118678884ef4SEddie Cai } 118778884ef4SEddie Cai 118878884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) { 118978884ef4SEddie Cai printf("chip: %s\n", chip); 119078884ef4SEddie Cai int chipType = RKNONE_DEVICE; 119178884ef4SEddie Cai if(!chip) { 119278884ef4SEddie Cai goto end; 119378884ef4SEddie Cai } 119478884ef4SEddie Cai if (!strcmp(chip, CHIP_RK28)) { 119578884ef4SEddie Cai chipType = RK28_DEVICE; 119678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK28)) { 119778884ef4SEddie Cai chipType = RK28_DEVICE; 119878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK281X)) { 119978884ef4SEddie Cai chipType = RK281X_DEVICE; 120078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKPANDA)) { 120178884ef4SEddie Cai chipType = RKPANDA_DEVICE; 120278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK27)) { 120378884ef4SEddie Cai chipType = RK27_DEVICE; 120478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKNANO)) { 120578884ef4SEddie Cai chipType = RKNANO_DEVICE; 120678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKSMART)) { 120778884ef4SEddie Cai chipType = RKSMART_DEVICE; 120878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCROWN)) { 120978884ef4SEddie Cai chipType = RKCROWN_DEVICE; 121078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 121178884ef4SEddie Cai chipType = RKCAYMAN_DEVICE; 121278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK29)) { 121378884ef4SEddie Cai chipType = RK29_DEVICE; 121478884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK292X)) { 121578884ef4SEddie Cai chipType = RK292X_DEVICE; 121678884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30)) { 121778884ef4SEddie Cai chipType = RK30_DEVICE; 121878884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30B)) { 121978884ef4SEddie Cai chipType = RK30B_DEVICE; 122078884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK31)) { 122178884ef4SEddie Cai chipType = RK31_DEVICE; 122278884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK32)) { 122378884ef4SEddie Cai chipType = RK32_DEVICE; 122478884ef4SEddie Cai } else { 122578884ef4SEddie Cai chipType = convertChipType(chip + 2); 122678884ef4SEddie Cai } 122778884ef4SEddie Cai 122878884ef4SEddie Cai end: 122978884ef4SEddie Cai printf("type: 0x%x\n", chipType); 123078884ef4SEddie Cai if (chipType == RKNONE_DEVICE) { 123132268622SAndreas Färber printf("chip type not supported!\n"); 123278884ef4SEddie Cai } 123378884ef4SEddie Cai return chipType; 123478884ef4SEddie Cai } 123578884ef4SEddie Cai 123678884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) { 123778884ef4SEddie Cai memset(hdr, 0, sizeof(rk_boot_header)); 123878884ef4SEddie Cai hdr->tag = TAG; 123978884ef4SEddie Cai hdr->size = sizeof(rk_boot_header); 124078884ef4SEddie Cai hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 124178884ef4SEddie Cai hdr->mergerVersion = MERGER_VERSION; 124278884ef4SEddie Cai hdr->releaseTime = getTime(); 124378884ef4SEddie Cai hdr->chipType = getChipType(gOpts.chip); 124478884ef4SEddie Cai 124578884ef4SEddie Cai hdr->code471Num = gOpts.code471Num; 124678884ef4SEddie Cai hdr->code471Offset = sizeof(rk_boot_header); 124778884ef4SEddie Cai hdr->code471Size = sizeof(rk_boot_entry); 124878884ef4SEddie Cai 124978884ef4SEddie Cai hdr->code472Num = gOpts.code472Num; 125078884ef4SEddie Cai hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 125178884ef4SEddie Cai hdr->code472Size = sizeof(rk_boot_entry); 125278884ef4SEddie Cai 125378884ef4SEddie Cai hdr->loaderNum = gOpts.loaderNum; 125478884ef4SEddie Cai hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 125578884ef4SEddie Cai hdr->loaderSize = sizeof(rk_boot_entry); 125678884ef4SEddie Cai #ifndef USE_P_RC4 125778884ef4SEddie Cai hdr->rc4Flag = 1; 125878884ef4SEddie Cai #endif 125978884ef4SEddie Cai } 126078884ef4SEddie Cai 126178884ef4SEddie Cai static inline uint32_t getCrc(const char* path) { 126278884ef4SEddie Cai uint32_t size = 0; 126378884ef4SEddie Cai uint32_t crc = 0; 126478884ef4SEddie Cai 126578884ef4SEddie Cai FILE* file = fopen(path, "rb"); 126678884ef4SEddie Cai getFileSize(path, &size); 126778884ef4SEddie Cai if (!file) 126878884ef4SEddie Cai goto end; 126978884ef4SEddie Cai if (!fread(gBuf, size, 1, file)) 127078884ef4SEddie Cai goto end; 127178884ef4SEddie Cai crc = CRC_32(gBuf, size); 127278884ef4SEddie Cai printf("crc: 0x%08x\n", crc); 127378884ef4SEddie Cai end: 127478884ef4SEddie Cai if (file) 127578884ef4SEddie Cai fclose(file); 127678884ef4SEddie Cai return crc; 127778884ef4SEddie Cai } 127878884ef4SEddie Cai 127978884ef4SEddie Cai bool mergeBoot(void) { 128078884ef4SEddie Cai uint32_t dataOffset; 128178884ef4SEddie Cai bool ret = false; 128278884ef4SEddie Cai int i; 128378884ef4SEddie Cai FILE* outFile; 128478884ef4SEddie Cai uint32_t crc; 128578884ef4SEddie Cai rk_boot_header hdr; 128678884ef4SEddie Cai 128778884ef4SEddie Cai if (!initOpts()) 128878884ef4SEddie Cai return false; 128978884ef4SEddie Cai { 129078884ef4SEddie Cai char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 129178884ef4SEddie Cai char version[MAX_LINE_LEN]; 129278884ef4SEddie Cai snprintf(version, sizeof(version), "%s", gSubfix); 129378884ef4SEddie Cai if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 129478884ef4SEddie Cai subfix[0] = '\0'; 129578884ef4SEddie Cai } 129678884ef4SEddie Cai strcat(gOpts.outPath, version); 129778884ef4SEddie Cai printf("fix opt: %s\n", gOpts.outPath); 129878884ef4SEddie Cai } 129978884ef4SEddie Cai 130078884ef4SEddie Cai printf("---------------\nUSING CONFIG:\n"); 130178884ef4SEddie Cai printOpts(stdout); 130278884ef4SEddie Cai printf("---------------\n\n"); 130378884ef4SEddie Cai 130478884ef4SEddie Cai 130578884ef4SEddie Cai outFile = fopen(gOpts.outPath, "wb+"); 130678884ef4SEddie Cai if (!outFile) { 130732268622SAndreas Färber printf("Opening output file (%s) failed\n", gOpts.outPath); 130878884ef4SEddie Cai goto end; 130978884ef4SEddie Cai } 131078884ef4SEddie Cai 131178884ef4SEddie Cai getBoothdr(&hdr); 131232268622SAndreas Färber printf("Writing header...\n"); 131378884ef4SEddie Cai fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 131478884ef4SEddie Cai 131578884ef4SEddie Cai dataOffset = sizeof(rk_boot_header) + 131678884ef4SEddie Cai (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 131778884ef4SEddie Cai sizeof(rk_boot_entry); 131878884ef4SEddie Cai 131932268622SAndreas Färber printf("Writing code 471 entry...\n"); 132078884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 132178884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 132278884ef4SEddie Cai &dataOffset, NULL, false)) 132378884ef4SEddie Cai goto end; 132478884ef4SEddie Cai } 132532268622SAndreas Färber printf("Writing code 472 entry...\n"); 132678884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 132778884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 132878884ef4SEddie Cai &dataOffset, NULL, false)) 132978884ef4SEddie Cai goto end; 133078884ef4SEddie Cai } 133132268622SAndreas Färber printf("Writing loader entry...\n"); 133278884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 133378884ef4SEddie Cai if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 133478884ef4SEddie Cai &dataOffset, gOpts.loader[i].name, true)) 133578884ef4SEddie Cai goto end; 133678884ef4SEddie Cai } 133778884ef4SEddie Cai 133832268622SAndreas Färber printf("Writing code 471...\n"); 133978884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 134078884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 134178884ef4SEddie Cai goto end; 134278884ef4SEddie Cai } 134332268622SAndreas Färber printf("Writing code 472...\n"); 134478884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 134578884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 134678884ef4SEddie Cai goto end; 134778884ef4SEddie Cai } 134832268622SAndreas Färber printf("Writing loader...\n"); 134978884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 135078884ef4SEddie Cai if (!writeFile(outFile, gOpts.loader[i].path, true)) 135178884ef4SEddie Cai goto end; 135278884ef4SEddie Cai } 135378884ef4SEddie Cai fflush(outFile); 135478884ef4SEddie Cai 135532268622SAndreas Färber printf("Writing crc...\n"); 135678884ef4SEddie Cai crc = getCrc(gOpts.outPath); 135778884ef4SEddie Cai if (!fwrite(&crc, sizeof(crc), 1, outFile)) 135878884ef4SEddie Cai goto end; 135932268622SAndreas Färber printf("Done.\n"); 136078884ef4SEddie Cai ret = true; 136178884ef4SEddie Cai end: 136278884ef4SEddie Cai if (outFile) 136378884ef4SEddie Cai fclose(outFile); 136478884ef4SEddie Cai return ret; 136578884ef4SEddie Cai } 136678884ef4SEddie Cai 136778884ef4SEddie Cai /************merge code end************/ 136878884ef4SEddie Cai /************unpack code***************/ 136978884ef4SEddie Cai 137078884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len) 137178884ef4SEddie Cai { 137278884ef4SEddie Cai int i; 137378884ef4SEddie Cai for (i = 0; i < len; i++) { 137478884ef4SEddie Cai str[i] = (char) (wide[i] & 0xFF); 137578884ef4SEddie Cai } 137678884ef4SEddie Cai str[len] = 0; 137778884ef4SEddie Cai } 137878884ef4SEddie Cai 137978884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name, 138078884ef4SEddie Cai FILE* inFile) { 138178884ef4SEddie Cai bool ret = false; 138278884ef4SEddie Cai int size, i; 138378884ef4SEddie Cai FILE* outFile = fopen(name, "wb+"); 138478884ef4SEddie Cai if (!outFile) 138578884ef4SEddie Cai goto end; 138632268622SAndreas Färber printf("unpacking entry (%s)\n", name); 138778884ef4SEddie Cai fseek(inFile, entry->dataOffset, SEEK_SET); 138878884ef4SEddie Cai size = entry->dataSize; 138978884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 139078884ef4SEddie Cai goto end; 139178884ef4SEddie Cai if (entry->type == ENTRY_LOADER) { 139278884ef4SEddie Cai for(i=0; i<size/SMALL_PACKET; i++) 139378884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 139478884ef4SEddie Cai if (size % SMALL_PACKET) 139578884ef4SEddie Cai { 139678884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 139778884ef4SEddie Cai } 139878884ef4SEddie Cai } else { 139978884ef4SEddie Cai P_RC4(gBuf, size); 140078884ef4SEddie Cai } 140178884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 140278884ef4SEddie Cai goto end; 140378884ef4SEddie Cai ret = true; 140478884ef4SEddie Cai end: 140578884ef4SEddie Cai if (outFile) 140678884ef4SEddie Cai fclose(outFile); 140778884ef4SEddie Cai return ret; 140878884ef4SEddie Cai } 140978884ef4SEddie Cai 141078884ef4SEddie Cai bool unpackBoot(char* path) { 141178884ef4SEddie Cai bool ret = false; 141278884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 141378884ef4SEddie Cai int entryNum, i; 141478884ef4SEddie Cai char name[MAX_NAME_LEN]; 141578884ef4SEddie Cai rk_boot_entry* entrys; 141678884ef4SEddie Cai if (!inFile) { 141778884ef4SEddie Cai fprintf(stderr, "loader (%s) not found\n", path); 141878884ef4SEddie Cai goto end; 141978884ef4SEddie Cai } 142078884ef4SEddie Cai 142178884ef4SEddie Cai rk_boot_header hdr; 142278884ef4SEddie Cai if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 142332268622SAndreas Färber fprintf(stderr, "reading header failed\n"); 142478884ef4SEddie Cai goto end; 142578884ef4SEddie Cai } 142678884ef4SEddie Cai printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 142778884ef4SEddie Cai entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 142878884ef4SEddie Cai entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 142978884ef4SEddie Cai if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 143032268622SAndreas Färber fprintf(stderr, "reading data failed\n"); 143178884ef4SEddie Cai goto end; 143278884ef4SEddie Cai } 143378884ef4SEddie Cai 143478884ef4SEddie Cai printf("entry num: %d\n", entryNum); 143578884ef4SEddie Cai for (i=0; i<entryNum; i++) { 143678884ef4SEddie Cai wide2str(entrys[i].name, name, MAX_NAME_LEN); 143778884ef4SEddie Cai 143878884ef4SEddie Cai printf("entry: t=%d, name=%s, off=%d, size=%d\n", 143978884ef4SEddie Cai entrys[i].type, name, entrys[i].dataOffset, 144078884ef4SEddie Cai entrys[i].dataSize); 144178884ef4SEddie Cai if (!unpackEntry(entrys + i, name, inFile)) { 144232268622SAndreas Färber fprintf(stderr, "unpacking entry (%s) failed\n", name); 144378884ef4SEddie Cai goto end; 144478884ef4SEddie Cai } 144578884ef4SEddie Cai } 144678884ef4SEddie Cai printf("done\n"); 144778884ef4SEddie Cai ret = true; 144878884ef4SEddie Cai end: 144978884ef4SEddie Cai if (inFile) 145078884ef4SEddie Cai fclose(inFile); 145178884ef4SEddie Cai return ret; 145278884ef4SEddie Cai } 145378884ef4SEddie Cai 145476af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 145576af099aSliuyi { 145676af099aSliuyi if (!check_device_type(dev, RKUSB_MASKROM)) 145776af099aSliuyi return false; 145876af099aSliuyi CRKImage *pImage = NULL; 145976af099aSliuyi CRKBoot *pBoot = NULL; 146076af099aSliuyi bool bRet, bSuccess = false; 146176af099aSliuyi int iRet; 146276af099aSliuyi 146376af099aSliuyi pImage = new CRKImage(szLoader, bRet); 146476af099aSliuyi if (!bRet){ 146576af099aSliuyi ERROR_COLOR_ATTR; 146632268622SAndreas Färber printf("Opening loader failed, exiting download boot!"); 146776af099aSliuyi NORMAL_COLOR_ATTR; 146876af099aSliuyi printf("\r\n"); 146976af099aSliuyi return bSuccess; 147076af099aSliuyi } else { 147176af099aSliuyi pBoot = (CRKBoot *)pImage->m_bootObject; 147276af099aSliuyi CRKComm *pComm = NULL; 147376af099aSliuyi CRKDevice *pDevice = NULL; 147476af099aSliuyi 147576af099aSliuyi dev.emDeviceType = pBoot->SupportDevice; 147676af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 147776af099aSliuyi if (!bRet) { 147876af099aSliuyi if (pImage) 147976af099aSliuyi delete pImage; 148076af099aSliuyi ERROR_COLOR_ATTR; 148176af099aSliuyi printf("Creating Comm Object failed!"); 148276af099aSliuyi NORMAL_COLOR_ATTR; 148376af099aSliuyi printf("\r\n"); 148476af099aSliuyi return bSuccess; 148576af099aSliuyi } 148676af099aSliuyi 148776af099aSliuyi pDevice = new CRKDevice(dev); 148876af099aSliuyi if (!pDevice) { 148976af099aSliuyi if (pImage) 149076af099aSliuyi delete pImage; 149176af099aSliuyi if (pComm) 149276af099aSliuyi delete pComm; 149376af099aSliuyi ERROR_COLOR_ATTR; 149476af099aSliuyi printf("Creating device object failed!"); 149576af099aSliuyi NORMAL_COLOR_ATTR; 149676af099aSliuyi printf("\r\n"); 149776af099aSliuyi return bSuccess; 149876af099aSliuyi } 149976af099aSliuyi 150076af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 150132268622SAndreas Färber printf("Downloading bootloader...\r\n"); 150276af099aSliuyi iRet = pDevice->DownloadBoot(); 150376af099aSliuyi 150476af099aSliuyi CURSOR_MOVEUP_LINE(1); 150576af099aSliuyi CURSOR_DEL_LINE; 150676af099aSliuyi if (iRet == 0) { 150776af099aSliuyi bSuccess = true; 150832268622SAndreas Färber printf("Downloading bootloader succeeded.\r\n"); 150976af099aSliuyi } 151076af099aSliuyi else 151132268622SAndreas Färber printf("Downloading bootloader failed!\r\n"); 151276af099aSliuyi 151376af099aSliuyi if (pImage) 151476af099aSliuyi delete pImage; 151576af099aSliuyi if(pDevice) 151676af099aSliuyi delete pDevice; 151776af099aSliuyi } 151876af099aSliuyi return bSuccess; 151976af099aSliuyi } 1520c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1521c30d921cSKever Yang { 1522c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 1523c30d921cSKever Yang return false; 1524c30d921cSKever Yang CRKImage *pImage = NULL; 1525c30d921cSKever Yang CRKBoot *pBoot = NULL; 1526c30d921cSKever Yang CRKComm *pComm = NULL; 1527c30d921cSKever Yang bool bRet, bSuccess = false; 1528c30d921cSKever Yang int iRet; 1529c30d921cSKever Yang char index; 1530c30d921cSKever Yang USHORT usFlashDataSec, usFlashBootSec; 1531c30d921cSKever Yang DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1532c30d921cSKever Yang char loaderCodeName[] = "FlashBoot"; 1533c30d921cSKever Yang char loaderDataName[] = "FlashData"; 1534c30d921cSKever Yang PBYTE loaderCodeBuffer = NULL; 1535c30d921cSKever Yang PBYTE loaderDataBuffer = NULL; 1536c30d921cSKever Yang PBYTE pIDBData = NULL; 1537c30d921cSKever Yang pImage = new CRKImage(szLoader, bRet); 1538c30d921cSKever Yang if (!bRet){ 1539c30d921cSKever Yang ERROR_COLOR_ATTR; 154032268622SAndreas Färber printf("Opening loader failed, exiting upgrade loader!"); 1541c30d921cSKever Yang NORMAL_COLOR_ATTR; 1542c30d921cSKever Yang printf("\r\n"); 1543c30d921cSKever Yang goto Exit_UpgradeLoader; 1544c30d921cSKever Yang } else { 1545c30d921cSKever Yang pBoot = (CRKBoot *)pImage->m_bootObject; 1546c30d921cSKever Yang dev.emDeviceType = pBoot->SupportDevice; 1547c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1548c30d921cSKever Yang if (!bRet) { 1549c30d921cSKever Yang ERROR_COLOR_ATTR; 1550c30d921cSKever Yang printf("Creating Comm Object failed!"); 1551c30d921cSKever Yang NORMAL_COLOR_ATTR; 1552c30d921cSKever Yang printf("\r\n"); 1553c30d921cSKever Yang goto Exit_UpgradeLoader; 1554c30d921cSKever Yang } 1555c30d921cSKever Yang 155632268622SAndreas Färber printf("Upgrading loader...\r\n"); 1557c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1558c30d921cSKever Yang if (index == -1) { 1559c30d921cSKever Yang if (g_pLogObject) { 156032268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__); 1561c30d921cSKever Yang } 1562c30d921cSKever Yang goto Exit_UpgradeLoader; 1563c30d921cSKever Yang } 1564c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1565c30d921cSKever Yang if (!bRet) { 1566c30d921cSKever Yang if (g_pLogObject) { 156732268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__); 1568c30d921cSKever Yang } 1569c30d921cSKever Yang goto Exit_UpgradeLoader; 1570c30d921cSKever Yang } 1571c30d921cSKever Yang 1572c30d921cSKever Yang loaderCodeBuffer = new BYTE[dwLoaderSize]; 1573c30d921cSKever Yang memset(loaderCodeBuffer, 0, dwLoaderSize); 1574c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1575c30d921cSKever Yang if (g_pLogObject) { 157632268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__); 1577c30d921cSKever Yang } 1578c30d921cSKever Yang goto Exit_UpgradeLoader; 1579c30d921cSKever Yang } 1580c30d921cSKever Yang 1581c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1582c30d921cSKever Yang if (index == -1) { 1583c30d921cSKever Yang if (g_pLogObject) { 158432268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__); 1585c30d921cSKever Yang } 1586c30d921cSKever Yang delete []loaderCodeBuffer; 1587c30d921cSKever Yang return -4; 1588c30d921cSKever Yang } 1589c30d921cSKever Yang 1590c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1591c30d921cSKever Yang if (!bRet) { 1592c30d921cSKever Yang if (g_pLogObject) { 159332268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__); 1594c30d921cSKever Yang } 1595c30d921cSKever Yang goto Exit_UpgradeLoader; 1596c30d921cSKever Yang } 1597c30d921cSKever Yang 1598c30d921cSKever Yang loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1599c30d921cSKever Yang memset(loaderDataBuffer, 0, dwLoaderDataSize); 1600c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1601c30d921cSKever Yang if (g_pLogObject) { 160232268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__); 1603c30d921cSKever Yang } 1604c30d921cSKever Yang goto Exit_UpgradeLoader; 1605c30d921cSKever Yang } 1606c30d921cSKever Yang 1607c30d921cSKever Yang usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1608c30d921cSKever Yang usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1609c30d921cSKever Yang dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1610c30d921cSKever Yang pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1611c30d921cSKever Yang if (!pIDBData) { 1612c30d921cSKever Yang ERROR_COLOR_ATTR; 161332268622SAndreas Färber printf("Allocating memory failed!"); 1614c30d921cSKever Yang NORMAL_COLOR_ATTR; 1615c30d921cSKever Yang printf("\r\n"); 1616c30d921cSKever Yang goto Exit_UpgradeLoader; 1617c30d921cSKever Yang } 1618c30d921cSKever Yang memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1619*b38fe5fcSliuyi iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag); 1620c30d921cSKever Yang if (iRet != 0) { 1621c30d921cSKever Yang ERROR_COLOR_ATTR; 162232268622SAndreas Färber printf("Making idblock failed!"); 1623c30d921cSKever Yang NORMAL_COLOR_ATTR; 1624c30d921cSKever Yang printf("\r\n"); 1625c30d921cSKever Yang goto Exit_UpgradeLoader; 1626c30d921cSKever Yang } 1627*b38fe5fcSliuyi if (g_pLogObject) 1628*b38fe5fcSliuyi g_pLogObject->SaveBuffer("idblock.bin",pIDBData,dwSectorNum*SECTOR_SIZE); 1629c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1630c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 1631c30d921cSKever Yang CURSOR_DEL_LINE; 1632c30d921cSKever Yang if (iRet == ERR_SUCCESS) { 1633*b38fe5fcSliuyi //pComm->Reset_Usb_Device(); 1634c30d921cSKever Yang bSuccess = true; 163532268622SAndreas Färber printf("Upgrading loader succeeded.\r\n"); 1636c30d921cSKever Yang } else { 163732268622SAndreas Färber printf("Upgrading loader failed!\r\n"); 1638c30d921cSKever Yang goto Exit_UpgradeLoader; 1639c30d921cSKever Yang } 1640c30d921cSKever Yang } 1641c30d921cSKever Yang Exit_UpgradeLoader: 1642c30d921cSKever Yang if (pImage) 1643c30d921cSKever Yang delete pImage; 1644c30d921cSKever Yang if (pComm) 1645c30d921cSKever Yang delete pComm; 1646c30d921cSKever Yang if (loaderCodeBuffer) 1647c30d921cSKever Yang delete []loaderCodeBuffer; 1648c30d921cSKever Yang if (loaderDataBuffer) 1649c30d921cSKever Yang delete []loaderDataBuffer; 1650c30d921cSKever Yang if (pIDBData) 1651c30d921cSKever Yang delete []pIDBData; 1652c30d921cSKever Yang return bSuccess; 1653c30d921cSKever Yang } 1654c30d921cSKever Yang 165576af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 165676af099aSliuyi { 165776af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 165876af099aSliuyi return false; 165976af099aSliuyi CRKImage *pImage = NULL; 166076af099aSliuyi bool bRet, bSuccess = false; 166176af099aSliuyi int iRet; 166276af099aSliuyi CRKScan *pScan = NULL; 166376af099aSliuyi pScan = new CRKScan(); 166476af099aSliuyi pScan->SetVidPid(); 166576af099aSliuyi 166676af099aSliuyi CRKComm *pComm = NULL; 166776af099aSliuyi CRKDevice *pDevice = NULL; 166876af099aSliuyi 166976af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 167076af099aSliuyi if (!bRet) { 167176af099aSliuyi if (pScan) 167276af099aSliuyi delete pScan; 167376af099aSliuyi ERROR_COLOR_ATTR; 167476af099aSliuyi printf("Creating Comm Object failed!"); 167576af099aSliuyi NORMAL_COLOR_ATTR; 167676af099aSliuyi printf("\r\n"); 167776af099aSliuyi return bSuccess; 167876af099aSliuyi } 167976af099aSliuyi 168076af099aSliuyi pDevice = new CRKDevice(dev); 168176af099aSliuyi if (!pDevice) { 168276af099aSliuyi if (pComm) 168376af099aSliuyi delete pComm; 168476af099aSliuyi if (pScan) 168576af099aSliuyi delete pScan; 168676af099aSliuyi ERROR_COLOR_ATTR; 168776af099aSliuyi printf("Creating device object failed!"); 168876af099aSliuyi NORMAL_COLOR_ATTR; 168976af099aSliuyi printf("\r\n"); 169076af099aSliuyi return bSuccess; 169176af099aSliuyi } 169276af099aSliuyi 169376af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 169476af099aSliuyi pDevice->CallBackPointer = ProgressInfoProc; 169576af099aSliuyi 169632268622SAndreas Färber printf("Starting to erase flash...\r\n"); 169776af099aSliuyi iRet = pDevice->EraseAllBlocks(); 169876af099aSliuyi if (pDevice) 169976af099aSliuyi delete pDevice; 170076af099aSliuyi 170176af099aSliuyi if (iRet == 0) { 170276af099aSliuyi if (pScan) { 170376af099aSliuyi pScan->SetVidPid(); 170476af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 170576af099aSliuyi delete pScan; 170676af099aSliuyi } 170776af099aSliuyi CURSOR_MOVEUP_LINE(1); 170876af099aSliuyi CURSOR_DEL_LINE; 170976af099aSliuyi bSuccess = true; 171032268622SAndreas Färber printf("Erasing flash complete.\r\n"); 171176af099aSliuyi } 171276af099aSliuyi 171376af099aSliuyi return bSuccess; 171476af099aSliuyi } 171576af099aSliuyi 171676af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev) 171776af099aSliuyi { 171876af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 171976af099aSliuyi return false; 172076af099aSliuyi CRKUsbComm *pComm = NULL; 172176af099aSliuyi bool bRet, bSuccess = false; 172276af099aSliuyi int iRet; 172376af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 172476af099aSliuyi if (bRet) { 172576af099aSliuyi iRet = pComm->RKU_TestDeviceReady(); 172676af099aSliuyi if (iRet != ERR_SUCCESS) { 172776af099aSliuyi if (g_pLogObject) 172876af099aSliuyi g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 172932268622SAndreas Färber printf("Test Device failed!\r\n"); 173076af099aSliuyi } else { 173176af099aSliuyi bSuccess = true; 173276af099aSliuyi printf("Test Device OK.\r\n"); 173376af099aSliuyi } 173476af099aSliuyi } else { 173532268622SAndreas Färber printf("Test Device quit, creating comm object failed!\r\n"); 173676af099aSliuyi } 173776af099aSliuyi if (pComm) { 173876af099aSliuyi delete pComm; 173976af099aSliuyi pComm = NULL; 174076af099aSliuyi } 174176af099aSliuyi return bSuccess; 174276af099aSliuyi } 174376af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 174476af099aSliuyi { 174576af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 174676af099aSliuyi return false; 174776af099aSliuyi CRKUsbComm *pComm = NULL; 174876af099aSliuyi bool bRet, bSuccess = false; 174976af099aSliuyi int iRet; 175076af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 175176af099aSliuyi if (bRet) { 175276af099aSliuyi iRet = pComm->RKU_ResetDevice(subCode); 175376af099aSliuyi if (iRet != ERR_SUCCESS) { 175476af099aSliuyi if (g_pLogObject) 175576af099aSliuyi g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 175632268622SAndreas Färber printf("Reset Device failed!\r\n"); 175776af099aSliuyi } else { 175876af099aSliuyi bSuccess = true; 175976af099aSliuyi printf("Reset Device OK.\r\n"); 176076af099aSliuyi } 176176af099aSliuyi } else { 176232268622SAndreas Färber printf("Reset Device quit, creating comm object failed!\r\n"); 176376af099aSliuyi } 176476af099aSliuyi if (pComm) { 176576af099aSliuyi delete pComm; 176676af099aSliuyi pComm = NULL; 176776af099aSliuyi } 176876af099aSliuyi return bSuccess; 176976af099aSliuyi } 177076af099aSliuyi 177176af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 177276af099aSliuyi { 177376af099aSliuyi CRKUsbComm *pComm = NULL; 177476af099aSliuyi bool bRet, bSuccess = false; 177576af099aSliuyi int iRet; 177676af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 177776af099aSliuyi return bSuccess; 177876af099aSliuyi 177976af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 178076af099aSliuyi if (bRet) { 178176af099aSliuyi BYTE flashID[5]; 178276af099aSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 178376af099aSliuyi if (iRet != ERR_SUCCESS) { 178476af099aSliuyi if (g_pLogObject) 178576af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 178632268622SAndreas Färber printf("Reading flash ID failed!\r\n"); 178776af099aSliuyi } else { 178876af099aSliuyi printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 178976af099aSliuyi bSuccess = true; 179076af099aSliuyi } 179176af099aSliuyi } else { 179232268622SAndreas Färber printf("Read Flash ID quit, creating comm object failed!\r\n"); 179376af099aSliuyi } 179476af099aSliuyi if (pComm) { 179576af099aSliuyi delete pComm; 179676af099aSliuyi pComm = NULL; 179776af099aSliuyi } 179876af099aSliuyi return bSuccess; 179976af099aSliuyi } 180076af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 180176af099aSliuyi { 180276af099aSliuyi CRKUsbComm *pComm = NULL; 180376af099aSliuyi bool bRet, bSuccess = false; 180476af099aSliuyi int iRet; 180576af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 180676af099aSliuyi return bSuccess; 180776af099aSliuyi 180876af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 180976af099aSliuyi if (bRet) { 181076af099aSliuyi STRUCT_FLASHINFO_CMD info; 181176af099aSliuyi UINT uiRead; 181276af099aSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 181376af099aSliuyi if (iRet != ERR_SUCCESS) { 181476af099aSliuyi if (g_pLogObject) 181576af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 181632268622SAndreas Färber printf("Read Flash Info failed!\r\n"); 181776af099aSliuyi } else { 181876af099aSliuyi printf("Flash Info:\r\n"); 181976af099aSliuyi if (info.bManufCode <= 7) { 182076af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 182176af099aSliuyi } 182276af099aSliuyi else 182376af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 182476af099aSliuyi 182576af099aSliuyi printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 182676af099aSliuyi printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 182776af099aSliuyi printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 182876af099aSliuyi printf("\tECC Bits: %d\r\n", info.bECCBits); 182976af099aSliuyi printf("\tAccess Time: %d\r\n", info.bAccessTime); 183076af099aSliuyi printf("\tFlash CS: "); 183176af099aSliuyi for(int i = 0; i < 8; i++) { 183276af099aSliuyi if( info.bFlashCS & (1 << i) ) 183376af099aSliuyi printf("Flash<%d> ", i); 183476af099aSliuyi } 183576af099aSliuyi printf("\r\n"); 183676af099aSliuyi bSuccess = true; 183776af099aSliuyi } 183876af099aSliuyi }else { 183932268622SAndreas Färber printf("Read Flash Info quit, creating comm object failed!\r\n"); 184076af099aSliuyi } 184176af099aSliuyi if (pComm) { 184276af099aSliuyi delete pComm; 184376af099aSliuyi pComm = NULL; 184476af099aSliuyi } 184576af099aSliuyi return bSuccess; 184676af099aSliuyi } 184776af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 184876af099aSliuyi { 184976af099aSliuyi CRKUsbComm *pComm = NULL; 185076af099aSliuyi bool bRet, bSuccess = false; 185176af099aSliuyi int iRet; 185276af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 185376af099aSliuyi return bSuccess; 185476af099aSliuyi 185576af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 185676af099aSliuyi if (bRet) { 185776af099aSliuyi BYTE chipInfo[16]; 185876af099aSliuyi iRet = pComm->RKU_ReadChipInfo(chipInfo); 185976af099aSliuyi if (iRet != ERR_SUCCESS) { 186076af099aSliuyi if (g_pLogObject) 186176af099aSliuyi g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 186232268622SAndreas Färber printf("Read Chip Info failed!\r\n"); 186376af099aSliuyi } else { 186476af099aSliuyi string strChipInfo; 186576af099aSliuyi g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 186676af099aSliuyi printf("Chip Info: %s\r\n", strChipInfo.c_str()); 186776af099aSliuyi bSuccess = true; 186876af099aSliuyi } 186976af099aSliuyi } else { 187032268622SAndreas Färber printf("Read Chip Info quit, creating comm object failed!\r\n"); 187176af099aSliuyi } 187276af099aSliuyi if (pComm) { 187376af099aSliuyi delete pComm; 187476af099aSliuyi pComm = NULL; 187576af099aSliuyi } 187676af099aSliuyi return bSuccess; 187776af099aSliuyi } 187876af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 187976af099aSliuyi { 188076af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 188176af099aSliuyi return false; 188276af099aSliuyi CRKUsbComm *pComm = NULL; 188376af099aSliuyi FILE *file = NULL; 188476af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 188576af099aSliuyi int iRet; 188676af099aSliuyi UINT iTotalRead = 0,iRead = 0; 188776af099aSliuyi int nSectorSize = 512; 188876af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 188976af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 189076af099aSliuyi if (bRet) { 189176af099aSliuyi if(szFile) { 189276af099aSliuyi file = fopen(szFile, "wb+"); 189376af099aSliuyi if( !file ) { 189476af099aSliuyi printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 189576af099aSliuyi goto Exit_ReadLBA; 189676af099aSliuyi } 189776af099aSliuyi } 189876af099aSliuyi 189976af099aSliuyi while(uiLen > 0) { 190076af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 190176af099aSliuyi iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 190276af099aSliuyi iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 190376af099aSliuyi if(ERR_SUCCESS == iRet) { 190476af099aSliuyi uiLen -= iRead; 190576af099aSliuyi iTotalRead += iRead; 190676af099aSliuyi 190776af099aSliuyi if(szFile) { 190876af099aSliuyi fwrite(pBuf, 1, iRead * nSectorSize, file); 190976af099aSliuyi if (bFirst){ 191076af099aSliuyi if (iTotalRead >= 1024) 191132268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 191276af099aSliuyi else 191332268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 191476af099aSliuyi bFirst = false; 191576af099aSliuyi } else { 191676af099aSliuyi CURSOR_MOVEUP_LINE(1); 191776af099aSliuyi CURSOR_DEL_LINE; 191876af099aSliuyi if (iTotalRead >= 1024) 191932268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 192076af099aSliuyi else 192132268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 192276af099aSliuyi } 192376af099aSliuyi } 192476af099aSliuyi else 192576af099aSliuyi PrintData(pBuf, nSectorSize * iRead); 192676af099aSliuyi } else { 192776af099aSliuyi if (g_pLogObject) 192876af099aSliuyi g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 192976af099aSliuyi 193076af099aSliuyi printf("Read LBA failed!\r\n"); 193176af099aSliuyi goto Exit_ReadLBA; 193276af099aSliuyi } 193376af099aSliuyi } 193476af099aSliuyi bSuccess = true; 193576af099aSliuyi } else { 193632268622SAndreas Färber printf("Read LBA quit, creating comm object failed!\r\n"); 193776af099aSliuyi } 193876af099aSliuyi Exit_ReadLBA: 193976af099aSliuyi if (pComm) { 194076af099aSliuyi delete pComm; 194176af099aSliuyi pComm = NULL; 194276af099aSliuyi } 194376af099aSliuyi if (file) 194476af099aSliuyi fclose(file); 194576af099aSliuyi return bSuccess; 194676af099aSliuyi } 194776af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 194876af099aSliuyi { 194976af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 195076af099aSliuyi return false; 195176af099aSliuyi CRKUsbComm *pComm = NULL; 195276af099aSliuyi FILE *file = NULL; 195376af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 195476af099aSliuyi int iRet; 195576af099aSliuyi long long iTotalWrite = 0, iFileSize = 0; 195676af099aSliuyi UINT iWrite = 0, iRead = 0; 195776af099aSliuyi UINT uiLen; 195876af099aSliuyi int nSectorSize = 512; 195976af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 196076af099aSliuyi 196176af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 196276af099aSliuyi if (bRet) { 196376af099aSliuyi file = fopen(szFile, "rb"); 196476af099aSliuyi if( !file ) { 196576af099aSliuyi printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 196676af099aSliuyi goto Exit_WriteLBA; 196776af099aSliuyi } 196876af099aSliuyi 196976af099aSliuyi iRet = fseeko(file, 0, SEEK_END); 197076af099aSliuyi iFileSize = ftello(file); 197176af099aSliuyi fseeko(file, 0, SEEK_SET); 197276af099aSliuyi while(iTotalWrite < iFileSize) { 197376af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 197476af099aSliuyi iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 197576af099aSliuyi uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 197676af099aSliuyi iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 197776af099aSliuyi if(ERR_SUCCESS == iRet) { 197876af099aSliuyi uiBegin += uiLen; 197976af099aSliuyi iTotalWrite += iWrite; 198076af099aSliuyi if (bFirst) { 198176af099aSliuyi if (iTotalWrite >= 1024) 198276af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 198376af099aSliuyi else 198432268622SAndreas Färber printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 198576af099aSliuyi bFirst = false; 198676af099aSliuyi } else { 198776af099aSliuyi CURSOR_MOVEUP_LINE(1); 198876af099aSliuyi CURSOR_DEL_LINE; 198976af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 199076af099aSliuyi } 199176af099aSliuyi } else { 199276af099aSliuyi if (g_pLogObject) 199376af099aSliuyi g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 199476af099aSliuyi 199576af099aSliuyi printf("Write LBA failed!\r\n"); 199676af099aSliuyi goto Exit_WriteLBA; 199776af099aSliuyi } 199876af099aSliuyi } 199976af099aSliuyi bSuccess = true; 200076af099aSliuyi } else { 200132268622SAndreas Färber printf("Write LBA quit, creating comm object failed!\r\n"); 200276af099aSliuyi } 200376af099aSliuyi Exit_WriteLBA: 200476af099aSliuyi if (pComm) { 200576af099aSliuyi delete pComm; 200676af099aSliuyi pComm = NULL; 200776af099aSliuyi } 200876af099aSliuyi if (file) 200976af099aSliuyi fclose(file); 201076af099aSliuyi return bSuccess; 201176af099aSliuyi } 201276af099aSliuyi 201376af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems) 201476af099aSliuyi { 201576af099aSliuyi string strItem; 201676af099aSliuyi char szItem[100]; 201776af099aSliuyi char *pos = NULL, *pStart; 201876af099aSliuyi pStart = pszItems; 201976af099aSliuyi pos = strchr(pStart, ','); 202076af099aSliuyi while(pos != NULL) { 202176af099aSliuyi memset(szItem, 0, 100); 202276af099aSliuyi strncpy(szItem, pStart, pos - pStart); 202376af099aSliuyi strItem = szItem; 202476af099aSliuyi vecItems.push_back(strItem); 202576af099aSliuyi pStart = pos + 1; 202676af099aSliuyi if (*pStart == 0) 202776af099aSliuyi break; 202876af099aSliuyi pos = strchr(pStart, ','); 202976af099aSliuyi } 203076af099aSliuyi if (strlen(pStart) > 0) { 203176af099aSliuyi memset(szItem, 0, 100); 203276af099aSliuyi strncpy(szItem, pStart, strlen(pStart)); 203376af099aSliuyi strItem = szItem; 203476af099aSliuyi vecItems.push_back(strItem); 203576af099aSliuyi } 203676af099aSliuyi } 2037c30d921cSKever Yang 2038d71e8c20SEddie Cai void tag_spl(char *tag, char *spl) 2039d71e8c20SEddie Cai { 2040d71e8c20SEddie Cai FILE *file = NULL; 2041d71e8c20SEddie Cai int len; 2042d71e8c20SEddie Cai 2043d71e8c20SEddie Cai if(!tag || !spl) 2044d71e8c20SEddie Cai return; 2045d71e8c20SEddie Cai len = strlen(tag); 2046d71e8c20SEddie Cai printf("tag len=%d\n",len); 2047d71e8c20SEddie Cai file = fopen(spl, "rb"); 2048d71e8c20SEddie Cai if( !file ){ 2049d71e8c20SEddie Cai return; 2050d71e8c20SEddie Cai } 2051d71e8c20SEddie Cai int iFileSize; 2052d71e8c20SEddie Cai fseek(file, 0, SEEK_END); 2053d71e8c20SEddie Cai iFileSize = ftell(file); 2054d71e8c20SEddie Cai fseek(file, 0, SEEK_SET); 2055d71e8c20SEddie Cai char *Buf = NULL; 2056d71e8c20SEddie Cai Buf = new char[iFileSize + len + 1]; 2057d71e8c20SEddie Cai if (!Buf){ 2058d71e8c20SEddie Cai fclose(file); 2059d71e8c20SEddie Cai return; 2060d71e8c20SEddie Cai } 2061d71e8c20SEddie Cai memset(Buf, 0, iFileSize + 1); 2062d71e8c20SEddie Cai memcpy(Buf, tag, len); 2063d71e8c20SEddie Cai int iRead; 2064d71e8c20SEddie Cai iRead = fread(Buf+len, 1, iFileSize, file); 2065d71e8c20SEddie Cai if (iRead != iFileSize){ 2066d71e8c20SEddie Cai fclose(file); 2067d71e8c20SEddie Cai delete []Buf; 2068d71e8c20SEddie Cai return; 2069d71e8c20SEddie Cai } 2070d71e8c20SEddie Cai fclose(file); 2071d71e8c20SEddie Cai 2072d71e8c20SEddie Cai len = strlen(spl); 207332268622SAndreas Färber char *taggedspl = new char[len + 5]; 207432268622SAndreas Färber strcpy(taggedspl, spl); 207532268622SAndreas Färber strcpy(taggedspl + len, ".tag"); 207632268622SAndreas Färber taggedspl[len+4] = 0; 207732268622SAndreas Färber printf("Writing tagged spl to %s\n", taggedspl); 2078d71e8c20SEddie Cai 207932268622SAndreas Färber file = fopen(taggedspl, "wb"); 2080d71e8c20SEddie Cai if( !file ){ 208132268622SAndreas Färber delete []taggedspl; 2082d71e8c20SEddie Cai delete []Buf; 2083d71e8c20SEddie Cai return; 2084d71e8c20SEddie Cai } 2085d71e8c20SEddie Cai fwrite(Buf, 1, iFileSize+len, file); 2086d71e8c20SEddie Cai fclose(file); 208732268622SAndreas Färber delete []taggedspl; 2088d71e8c20SEddie Cai delete []Buf; 2089d71e8c20SEddie Cai printf("done\n"); 2090d71e8c20SEddie Cai return; 2091d71e8c20SEddie Cai } 2092d71e8c20SEddie Cai 209376af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan) 209476af099aSliuyi { 209576af099aSliuyi string strCmd; 209676af099aSliuyi strCmd = argv[1]; 209776af099aSliuyi ssize_t cnt; 209876af099aSliuyi bool bRet,bSuccess = false; 20998df2d64aSEddie Cai char *s; 21008df2d64aSEddie Cai int i, ret; 210176af099aSliuyi STRUCT_RKDEVICE_DESC dev; 210276af099aSliuyi 210376af099aSliuyi transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 21048df2d64aSEddie Cai s = (char*)strCmd.c_str(); 21058df2d64aSEddie Cai for(i = 0; i < (int)strlen(s); i++) 21068df2d64aSEddie Cai s[i] = toupper(s[i]); 210778884ef4SEddie Cai 21088df2d64aSEddie Cai if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 210976af099aSliuyi usage(); 211076af099aSliuyi return true; 21118df2d64aSEddie Cai } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2112c30d921cSKever Yang printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 211376af099aSliuyi return true; 211478884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 211578884ef4SEddie Cai mergeBoot(); 211678884ef4SEddie Cai 211778884ef4SEddie Cai return true; 211878884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 211978884ef4SEddie Cai string strLoader = argv[2]; 212078884ef4SEddie Cai 212178884ef4SEddie Cai unpackBoot((char*)strLoader.c_str()); 212278884ef4SEddie Cai return true; 2123d71e8c20SEddie Cai } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 2124d71e8c20SEddie Cai if (argc == 4) { 2125d71e8c20SEddie Cai string tag = argv[2]; 2126d71e8c20SEddie Cai string spl = argv[3]; 2127d71e8c20SEddie Cai printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 2128d71e8c20SEddie Cai tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 2129d71e8c20SEddie Cai return true; 2130d71e8c20SEddie Cai } 2131d71e8c20SEddie Cai printf("tagspl: parameter error\n"); 2132d71e8c20SEddie Cai usage(); 213376af099aSliuyi } 213476af099aSliuyi cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 213576af099aSliuyi if (cnt < 1) { 213676af099aSliuyi ERROR_COLOR_ATTR; 213732268622SAndreas Färber printf("Did not find any rockusb device, please plug device in!"); 213876af099aSliuyi NORMAL_COLOR_ATTR; 213976af099aSliuyi printf("\r\n"); 214076af099aSliuyi return bSuccess; 214176af099aSliuyi } else if (cnt > 1) { 214276af099aSliuyi ERROR_COLOR_ATTR; 214332268622SAndreas Färber printf("Found too many rockusb devices, please plug devices out!"); 214476af099aSliuyi NORMAL_COLOR_ATTR; 214576af099aSliuyi printf("\r\n"); 214676af099aSliuyi return bSuccess; 214776af099aSliuyi } 214876af099aSliuyi 214976af099aSliuyi bRet = pScan->GetDevice(dev, 0); 215076af099aSliuyi if (!bRet) { 215176af099aSliuyi ERROR_COLOR_ATTR; 215232268622SAndreas Färber printf("Getting information about rockusb device failed!"); 215376af099aSliuyi NORMAL_COLOR_ATTR; 215476af099aSliuyi printf("\r\n"); 215576af099aSliuyi return bSuccess; 215676af099aSliuyi } 215776af099aSliuyi 215876af099aSliuyi if(strcmp(strCmd.c_str(), "RD") == 0) { 215976af099aSliuyi if ((argc != 2) && (argc != 3)) 216076af099aSliuyi printf("Parameter of [RD] command is invalid, please check help!\r\n"); 216176af099aSliuyi else { 216276af099aSliuyi if (argc == 2) 216376af099aSliuyi bSuccess = reset_device(dev); 216476af099aSliuyi else { 216576af099aSliuyi UINT uiSubCode; 216676af099aSliuyi char *pszEnd; 216776af099aSliuyi uiSubCode = strtoul(argv[2], &pszEnd, 0); 216876af099aSliuyi if (*pszEnd) 216976af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 217076af099aSliuyi else { 217176af099aSliuyi if (uiSubCode <= 5) 217276af099aSliuyi bSuccess = reset_device(dev, uiSubCode); 217376af099aSliuyi else 217476af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 217576af099aSliuyi } 217676af099aSliuyi } 217776af099aSliuyi } 217876af099aSliuyi } else if(strcmp(strCmd.c_str(), "TD") == 0) { 217976af099aSliuyi bSuccess = test_device(dev); 218076af099aSliuyi } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 218176af099aSliuyi bSuccess = read_flash_id(dev); 218276af099aSliuyi } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 218376af099aSliuyi bSuccess = read_flash_info(dev); 218476af099aSliuyi } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 218576af099aSliuyi bSuccess = read_chip_info(dev); 218676af099aSliuyi } else if(strcmp(strCmd.c_str(), "DB") == 0) { 218776af099aSliuyi if (argc > 2) { 218876af099aSliuyi string strLoader; 218976af099aSliuyi strLoader = argv[2]; 219076af099aSliuyi bSuccess = download_boot(dev, (char *)strLoader.c_str()); 219176af099aSliuyi } else if (argc == 2) { 219276af099aSliuyi ret = find_config_item("loader"); 219376af099aSliuyi if (ret == -1) 219432268622SAndreas Färber printf("Did not find loader item in config!\r\n"); 219576af099aSliuyi else 219676af099aSliuyi bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 219776af099aSliuyi } else 219876af099aSliuyi printf("Parameter of [DB] command is invalid, please check help!\r\n"); 2199c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2200c30d921cSKever Yang if (argc > 2) { 2201c30d921cSKever Yang string strParameter; 2202c30d921cSKever Yang strParameter = argv[2]; 2203c30d921cSKever Yang bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2204c30d921cSKever Yang } else 2205c30d921cSKever Yang printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 2206c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2207c30d921cSKever Yang if (argc > 2) { 2208c30d921cSKever Yang string strLoader; 2209c30d921cSKever Yang strLoader = argv[2]; 2210c30d921cSKever Yang bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2211c30d921cSKever Yang } else 2212c30d921cSKever Yang printf("Parameter of [UL] command is invalid, please check help!\r\n"); 221376af099aSliuyi } else if(strcmp(strCmd.c_str(), "EF") == 0) { 221476af099aSliuyi if (argc == 2) { 221576af099aSliuyi bSuccess = erase_flash(dev); 221676af099aSliuyi } else 221776af099aSliuyi printf("Parameter of [EF] command is invalid, please check help!\r\n"); 221876af099aSliuyi } else if(strcmp(strCmd.c_str(), "WL") == 0) { 221976af099aSliuyi if (argc == 4) { 222076af099aSliuyi UINT uiBegin; 222176af099aSliuyi char *pszEnd; 222276af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 222376af099aSliuyi if (*pszEnd) 222476af099aSliuyi printf("Begin is invalid, please check!\r\n"); 222576af099aSliuyi else 222676af099aSliuyi bSuccess = write_lba(dev, uiBegin, argv[3]); 222776af099aSliuyi } else 222876af099aSliuyi printf("Parameter of [WL] command is invalid, please check help!\r\n"); 222976af099aSliuyi } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 223076af099aSliuyi char *pszEnd; 223176af099aSliuyi UINT uiBegin, uiLen; 223276af099aSliuyi if (argc != 5) 223376af099aSliuyi printf("Parameter of [RL] command is invalid, please check help!\r\n"); 223476af099aSliuyi else { 223576af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 223676af099aSliuyi if (*pszEnd) 223776af099aSliuyi printf("Begin is invalid, please check!\r\n"); 223876af099aSliuyi else { 223976af099aSliuyi uiLen = strtoul(argv[3], &pszEnd, 0); 224076af099aSliuyi if (*pszEnd) 224176af099aSliuyi printf("Len is invalid, please check!\r\n"); 224276af099aSliuyi else { 224376af099aSliuyi bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 224476af099aSliuyi } 224576af099aSliuyi } 224676af099aSliuyi } 224776af099aSliuyi } else { 22489bc231bdSAndreas Färber printf("command is invalid!\r\n"); 22499bc231bdSAndreas Färber usage(); 225076af099aSliuyi } 225176af099aSliuyi return bSuccess; 225276af099aSliuyi } 225376af099aSliuyi 225476af099aSliuyi 225576af099aSliuyi int main(int argc, char* argv[]) 225676af099aSliuyi { 225776af099aSliuyi CRKScan *pScan = NULL; 225876af099aSliuyi int ret; 225976af099aSliuyi char szProgramProcPath[100]; 226076af099aSliuyi char szProgramDir[256]; 226176af099aSliuyi string strLogDir,strConfigFile; 226276af099aSliuyi struct stat statBuf; 226376af099aSliuyi 226476af099aSliuyi g_ConfigItemVec.clear(); 226576af099aSliuyi sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 226676af099aSliuyi if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 226776af099aSliuyi strcpy(szProgramDir, "."); 226876af099aSliuyi else { 226976af099aSliuyi char *pSlash; 227076af099aSliuyi pSlash = strrchr(szProgramDir, '/'); 227176af099aSliuyi if (pSlash) 227276af099aSliuyi *pSlash = '\0'; 227376af099aSliuyi } 227476af099aSliuyi strLogDir = szProgramDir; 227576af099aSliuyi strLogDir += "/log/"; 227676af099aSliuyi strConfigFile = szProgramDir; 227776af099aSliuyi strConfigFile += "/config.ini"; 227876af099aSliuyi if (opendir(strLogDir.c_str()) == NULL) 227976af099aSliuyi mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 2280e5ee8cc0Sliuyi g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 228176af099aSliuyi 228276af099aSliuyi if(stat(strConfigFile.c_str(), &statBuf) < 0) { 228376af099aSliuyi if (g_pLogObject) { 228476af099aSliuyi g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 228576af099aSliuyi } 228676af099aSliuyi } else if (S_ISREG(statBuf.st_mode)) { 228776af099aSliuyi parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 228876af099aSliuyi } 228976af099aSliuyi 229076af099aSliuyi ret = libusb_init(NULL); 229176af099aSliuyi if (ret < 0) { 229276af099aSliuyi if (g_pLogObject) { 229376af099aSliuyi g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 229476af099aSliuyi delete g_pLogObject; 229576af099aSliuyi } 229676af099aSliuyi return -1; 229776af099aSliuyi } 229876af099aSliuyi 229976af099aSliuyi pScan = new CRKScan(); 230076af099aSliuyi if (!pScan) { 230176af099aSliuyi if (g_pLogObject) { 230232268622SAndreas Färber g_pLogObject->Record("Error: failed to create object for searching device"); 230376af099aSliuyi delete g_pLogObject; 230476af099aSliuyi } 230576af099aSliuyi libusb_exit(NULL); 230676af099aSliuyi return -2; 230776af099aSliuyi } 230876af099aSliuyi pScan->SetVidPid(); 230976af099aSliuyi 231076af099aSliuyi if (argc == 1) 231176af099aSliuyi usage(); 231276af099aSliuyi else if (!handle_command(argc, argv, pScan)) 231376af099aSliuyi return -0xFF; 231476af099aSliuyi if (pScan) 231576af099aSliuyi delete pScan; 231676af099aSliuyi if (g_pLogObject) 231776af099aSliuyi delete g_pLogObject; 231876af099aSliuyi libusb_exit(NULL); 231976af099aSliuyi return 0; 232076af099aSliuyi } 2321