176af099aSliuyi /* 276af099aSliuyi * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 376af099aSliuyi * Seth Liu 2017.03.01 476af099aSliuyi * 576af099aSliuyi * SPDX-License-Identifier: GPL-2.0+ 676af099aSliuyi */ 776af099aSliuyi 876af099aSliuyi #include <unistd.h> 976af099aSliuyi #include <dirent.h> 10c30d921cSKever Yang #include "config.h" 1176af099aSliuyi #include "DefineHeader.h" 12c30d921cSKever Yang #include "gpt.h" 1376af099aSliuyi #include "RKLog.h" 1476af099aSliuyi #include "RKScan.h" 1576af099aSliuyi #include "RKComm.h" 1676af099aSliuyi #include "RKDevice.h" 1776af099aSliuyi #include "RKImage.h" 1876af099aSliuyi extern const char *szManufName[]; 1976af099aSliuyi CRKLog *g_pLogObject=NULL; 2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec; 2176af099aSliuyi #define DEFAULT_RW_LBA 128 2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n) 2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B) 2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B) 2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B) 2676af099aSliuyi #define ERROR_COLOR_ATTR printf("%c[30;41m", 0x1B); 273601cc08SAndreas Färber #define NORMAL_COLOR_ATTR printf("%c[0m", 0x1B); 28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize); 29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize); 30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len); 31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len); 32c30d921cSKever Yang /* 33c30d921cSKever Yang u8 test_gpt_head[] = { 34c30d921cSKever Yang 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00, 35c30d921cSKever Yang 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36c30d921cSKever Yang 0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37c30d921cSKever Yang 0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B, 38c30d921cSKever Yang 0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39c30d921cSKever Yang 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08}; 40c30d921cSKever Yang */ 41c30d921cSKever Yang 4276af099aSliuyi void usage() 4376af099aSliuyi { 4476af099aSliuyi printf("\r\n---------------------Tool Usage ---------------------\r\n"); 45ae4252f0Sliuyi printf("Help:\t\t\t-h or --help\r\n"); 46154ee062SEddie Cai printf("Version:\t\t-v or --version\r\n"); 47081d237aSliuyi printf("ListDevice:\t\tld\r\n"); 48154ee062SEddie Cai printf("DownloadBoot:\t\tdb <Loader>\r\n"); 49154ee062SEddie Cai printf("UpgradeLoader:\t\tul <Loader>\r\n"); 50154ee062SEddie Cai printf("ReadLBA:\t\trl <BeginSec> <SectorLen> <File>\r\n"); 51154ee062SEddie Cai printf("WriteLBA:\t\twl <BeginSec> <File>\r\n"); 526ae612beSliuyi printf("WriteLBA:\t\twlx <PartitionName> <File>\r\n"); 53154ee062SEddie Cai printf("WriteGPT:\t\tgpt <gpt partition table>\r\n"); 54081d237aSliuyi printf("WriteParameter:\t\tprm <parameter>\r\n"); 55081d237aSliuyi printf("PrintPartition:\t\tppt \r\n"); 56154ee062SEddie Cai printf("EraseFlash:\t\tef \r\n"); 57154ee062SEddie Cai printf("TestDevice:\t\ttd\r\n"); 58154ee062SEddie Cai printf("ResetDevice:\t\trd [subcode]\r\n"); 59154ee062SEddie Cai printf("ReadFlashID:\t\trid\r\n"); 60154ee062SEddie Cai printf("ReadFlashInfo:\t\trfi\r\n"); 61154ee062SEddie Cai printf("ReadChipInfo:\t\trci\r\n"); 62081d237aSliuyi printf("ReadCapability:\t\trcb\r\n"); 6378884ef4SEddie Cai printf("PackBootLoader:\t\tpack\r\n"); 6478884ef4SEddie Cai printf("UnpackBootLoader:\tunpack <boot loader>\r\n"); 65d71e8c20SEddie Cai printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n"); 6676af099aSliuyi printf("-------------------------------------------------------\r\n\r\n"); 6776af099aSliuyi } 6876af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall) 6976af099aSliuyi { 7076af099aSliuyi string strInfoText=""; 7176af099aSliuyi char szText[256]; 7276af099aSliuyi switch (promptID) { 7376af099aSliuyi case TESTDEVICE_PROGRESS: 7432268622SAndreas Färber sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue); 7576af099aSliuyi strInfoText = szText; 7676af099aSliuyi break; 7776af099aSliuyi case LOWERFORMAT_PROGRESS: 7832268622SAndreas Färber sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue); 7976af099aSliuyi strInfoText = szText; 8076af099aSliuyi break; 8176af099aSliuyi case DOWNLOADIMAGE_PROGRESS: 8232268622SAndreas Färber sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 8376af099aSliuyi strInfoText = szText; 8476af099aSliuyi break; 8576af099aSliuyi case CHECKIMAGE_PROGRESS: 8632268622SAndreas Färber sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 8776af099aSliuyi strInfoText = szText; 8876af099aSliuyi break; 8976af099aSliuyi case TAGBADBLOCK_PROGRESS: 9032268622SAndreas Färber sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue); 9176af099aSliuyi strInfoText = szText; 9276af099aSliuyi break; 9376af099aSliuyi case TESTBLOCK_PROGRESS: 9432268622SAndreas Färber sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue); 9576af099aSliuyi strInfoText = szText; 9676af099aSliuyi break; 9776af099aSliuyi case ERASEFLASH_PROGRESS: 9832268622SAndreas Färber sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue); 9976af099aSliuyi strInfoText = szText; 10076af099aSliuyi break; 10176af099aSliuyi case ERASESYSTEM_PROGRESS: 10232268622SAndreas Färber sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue); 10376af099aSliuyi strInfoText = szText; 10476af099aSliuyi break; 10576af099aSliuyi case ERASEUSERDATA_PROGRESS: 10632268622SAndreas Färber sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue); 10776af099aSliuyi strInfoText = szText; 10876af099aSliuyi break; 10976af099aSliuyi } 11076af099aSliuyi if (strInfoText.size() > 0){ 11176af099aSliuyi CURSOR_MOVEUP_LINE(1); 11276af099aSliuyi CURSOR_DEL_LINE; 11376af099aSliuyi printf("%s\r\n", strInfoText.c_str()); 11476af099aSliuyi } 11576af099aSliuyi if (emCall == CALL_LAST) 11676af099aSliuyi deviceLayer = 0; 11776af099aSliuyi } 11876af099aSliuyi 11976af099aSliuyi char *strupr(char *szSrc) 12076af099aSliuyi { 12176af099aSliuyi char *p = szSrc; 12276af099aSliuyi while(*p){ 12376af099aSliuyi if ((*p >= 'a') && (*p <= 'z')) 12476af099aSliuyi *p = *p - 'a' + 'A'; 12576af099aSliuyi p++; 12676af099aSliuyi } 12776af099aSliuyi return szSrc; 12876af099aSliuyi } 12976af099aSliuyi void PrintData(PBYTE pData, int nSize) 13076af099aSliuyi { 13176af099aSliuyi char szPrint[17] = "\0"; 13276af099aSliuyi int i; 13376af099aSliuyi for( i = 0; i < nSize; i++){ 13476af099aSliuyi if(i % 16 == 0){ 13576af099aSliuyi if(i / 16 > 0) 13676af099aSliuyi printf(" %s\r\n", szPrint); 13776af099aSliuyi printf("%08d ", i / 16); 13876af099aSliuyi } 13976af099aSliuyi printf("%02X ", pData[i]); 14076af099aSliuyi szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.'; 14176af099aSliuyi } 14276af099aSliuyi if(i / 16 > 0) 14376af099aSliuyi printf(" %s\r\n", szPrint); 14476af099aSliuyi } 14576af099aSliuyi 146c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName) 14776af099aSliuyi { 14876af099aSliuyi unsigned int i; 149c29e5f0fSliuyi for(i = 0; i < vecItems.size(); i++){ 150c29e5f0fSliuyi if (strcasecmp(pszName, vecItems[i].szItemName) == 0){ 15176af099aSliuyi return i; 15276af099aSliuyi } 15376af099aSliuyi } 15476af099aSliuyi return -1; 15576af099aSliuyi } 156c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid) 157c29e5f0fSliuyi { 158c29e5f0fSliuyi unsigned int i; 159c29e5f0fSliuyi char value; 160c29e5f0fSliuyi memset(uuid, 0, 16); 161c29e5f0fSliuyi for (i =0; i < strUUid.size(); i++) { 162c29e5f0fSliuyi value = 0; 163c29e5f0fSliuyi if ((strUUid[i] >= '0')&&(strUUid[i] <= '9')) 164c29e5f0fSliuyi value = strUUid[i] - '0'; 165c29e5f0fSliuyi if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f')) 166c29e5f0fSliuyi value = strUUid[i] - 'a' + 10; 167c29e5f0fSliuyi if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F')) 168c29e5f0fSliuyi value = strUUid[i] - 'A' + 10; 169c29e5f0fSliuyi if ((i % 2) == 0) 170c29e5f0fSliuyi uuid[i / 2] += (value << 4); 171c29e5f0fSliuyi else 172c29e5f0fSliuyi uuid[i / 2] += value; 173c29e5f0fSliuyi } 174c29e5f0fSliuyi unsigned int *p32; 175c29e5f0fSliuyi unsigned short *p16; 176c29e5f0fSliuyi p32 = (unsigned int*)uuid; 177c29e5f0fSliuyi *p32 = cpu_to_be32(*p32); 178c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 4); 179c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 180c29e5f0fSliuyi p16 = (unsigned short *)(uuid + 6); 181c29e5f0fSliuyi *p16 = cpu_to_be16(*p16); 182c29e5f0fSliuyi } 18376af099aSliuyi 18476af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 18576af099aSliuyi { 18676af099aSliuyi 18776af099aSliuyi stringstream configStream(pConfig); 18876af099aSliuyi string strLine, strItemName, strItemValue; 18976af099aSliuyi string::size_type line_size,pos; 19076af099aSliuyi STRUCT_CONFIG_ITEM item; 19176af099aSliuyi vecItem.clear(); 19276af099aSliuyi while (!configStream.eof()){ 19376af099aSliuyi getline(configStream, strLine); 19476af099aSliuyi line_size = strLine.size(); 19576af099aSliuyi if (line_size == 0) 19676af099aSliuyi continue; 19776af099aSliuyi if (strLine[line_size-1] == '\r'){ 19876af099aSliuyi strLine = strLine.substr(0, line_size-1); 19976af099aSliuyi } 200c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 201c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 202c30d921cSKever Yang if (strLine.size()==0 ) 203c30d921cSKever Yang continue; 204c30d921cSKever Yang if (strLine[0] == '#') 205c30d921cSKever Yang continue; 20676af099aSliuyi pos = strLine.find("="); 20776af099aSliuyi if (pos == string::npos){ 20876af099aSliuyi continue; 20976af099aSliuyi } 21076af099aSliuyi strItemName = strLine.substr(0, pos); 21176af099aSliuyi strItemValue = strLine.substr(pos + 1); 21276af099aSliuyi strItemName.erase(0, strItemName.find_first_not_of(" ")); 21376af099aSliuyi strItemName.erase(strItemName.find_last_not_of(" ") + 1); 21476af099aSliuyi strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 21576af099aSliuyi strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 21676af099aSliuyi if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 21776af099aSliuyi strcpy(item.szItemName, strItemName.c_str()); 21876af099aSliuyi strcpy(item.szItemValue, strItemValue.c_str()); 21976af099aSliuyi vecItem.push_back(item); 22076af099aSliuyi } 22176af099aSliuyi } 22276af099aSliuyi return true; 22376af099aSliuyi 22476af099aSliuyi } 22576af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 22676af099aSliuyi { 22776af099aSliuyi FILE *file = NULL; 22876af099aSliuyi file = fopen(pConfigFile, "rb"); 22976af099aSliuyi if( !file ){ 23076af099aSliuyi if (g_pLogObject) 23132268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile); 23276af099aSliuyi return false; 23376af099aSliuyi } 23476af099aSliuyi int iFileSize; 23576af099aSliuyi fseek(file, 0, SEEK_END); 23676af099aSliuyi iFileSize = ftell(file); 23776af099aSliuyi fseek(file, 0, SEEK_SET); 23876af099aSliuyi char *pConfigBuf = NULL; 23976af099aSliuyi pConfigBuf = new char[iFileSize + 1]; 24076af099aSliuyi if (!pConfigBuf){ 24176af099aSliuyi fclose(file); 24276af099aSliuyi return false; 24376af099aSliuyi } 24476af099aSliuyi memset(pConfigBuf, 0, iFileSize + 1); 24576af099aSliuyi int iRead; 24676af099aSliuyi iRead = fread(pConfigBuf, 1, iFileSize, file); 24776af099aSliuyi if (iRead != iFileSize){ 24876af099aSliuyi if (g_pLogObject) 24932268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize); 25076af099aSliuyi fclose(file); 25176af099aSliuyi delete []pConfigBuf; 25276af099aSliuyi return false; 25376af099aSliuyi } 25476af099aSliuyi fclose(file); 25576af099aSliuyi bool bRet; 25676af099aSliuyi bRet = parse_config(pConfigBuf, vecItem); 25776af099aSliuyi delete []pConfigBuf; 25876af099aSliuyi return bRet; 25976af099aSliuyi } 260c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 261c30d921cSKever Yang { 262c30d921cSKever Yang string::size_type pos,prevPos; 263c30d921cSKever Yang string strOffset,strLen; 264c30d921cSKever Yang int iCount; 265c30d921cSKever Yang prevPos = pos = 0; 266c30d921cSKever Yang if (strPartInfo.size() <= 0) { 267c30d921cSKever Yang return false; 268c30d921cSKever Yang } 269c30d921cSKever Yang pos = strPartInfo.find('@'); 270c30d921cSKever Yang if (pos == string::npos) { 271c30d921cSKever Yang return false; 272c30d921cSKever Yang } 273c30d921cSKever Yang strLen = strPartInfo.substr(prevPos, pos - prevPos); 274c30d921cSKever Yang strLen.erase(0, strLen.find_first_not_of(" ")); 275c30d921cSKever Yang strLen.erase(strLen.find_last_not_of(" ") + 1); 276c30d921cSKever Yang if (strchr(strLen.c_str(), '-')) { 277c30d921cSKever Yang uiLen = 0xFFFFFFFF; 278c30d921cSKever Yang } else { 279c30d921cSKever Yang iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 280c30d921cSKever Yang if (iCount != 1) { 281c30d921cSKever Yang return false; 282c30d921cSKever Yang } 283c30d921cSKever Yang } 284c30d921cSKever Yang 285c30d921cSKever Yang prevPos = pos + 1; 286c30d921cSKever Yang pos = strPartInfo.find('(',prevPos); 287c30d921cSKever Yang if (pos == string::npos) { 288c30d921cSKever Yang return false; 289c30d921cSKever Yang } 290c30d921cSKever Yang strOffset = strPartInfo.substr(prevPos, pos - prevPos); 291c30d921cSKever Yang strOffset.erase(0, strOffset.find_first_not_of(" ")); 292c30d921cSKever Yang strOffset.erase(strOffset.find_last_not_of(" ") + 1); 293c30d921cSKever Yang iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 294c30d921cSKever Yang if (iCount != 1) { 295c30d921cSKever Yang return false; 296c30d921cSKever Yang } 297c30d921cSKever Yang prevPos = pos + 1; 298c30d921cSKever Yang pos = strPartInfo.find(')', prevPos); 299c30d921cSKever Yang if (pos == string::npos) { 300c30d921cSKever Yang return false; 301c30d921cSKever Yang } 302c30d921cSKever Yang strName = strPartInfo.substr(prevPos, pos - prevPos); 303c30d921cSKever Yang strName.erase(0, strName.find_first_not_of(" ")); 304c30d921cSKever Yang strName.erase(strName.find_last_not_of(" ") + 1); 305c30d921cSKever Yang 306c30d921cSKever Yang return true; 307c30d921cSKever Yang } 308c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid) 309c29e5f0fSliuyi { 310c29e5f0fSliuyi string::size_type pos(0); 311c30d921cSKever Yang 312c29e5f0fSliuyi if (strUuidInfo.size() <= 0) { 313c29e5f0fSliuyi return false; 314c29e5f0fSliuyi } 315c29e5f0fSliuyi pos = strUuidInfo.find('='); 316c29e5f0fSliuyi if (pos == string::npos) { 317c29e5f0fSliuyi return false; 318c29e5f0fSliuyi } 319c29e5f0fSliuyi strName = strUuidInfo.substr(0, pos); 320c29e5f0fSliuyi strName.erase(0, strName.find_first_not_of(" ")); 321c29e5f0fSliuyi strName.erase(strName.find_last_not_of(" ") + 1); 322c29e5f0fSliuyi 323c29e5f0fSliuyi strUUid = strUuidInfo.substr(pos+1); 324c29e5f0fSliuyi strUUid.erase(0, strUUid.find_first_not_of(" ")); 325c29e5f0fSliuyi strUUid.erase(strUUid.find_last_not_of(" ") + 1); 326c29e5f0fSliuyi 327c29e5f0fSliuyi while(true) { 328c29e5f0fSliuyi pos = 0; 329c29e5f0fSliuyi if( (pos = strUUid.find("-")) != string::npos) 330c29e5f0fSliuyi strUUid.replace(pos,1,""); 331c29e5f0fSliuyi else 332c29e5f0fSliuyi break; 333c29e5f0fSliuyi } 334c29e5f0fSliuyi if (strUUid.size() != 32) 335c29e5f0fSliuyi return false; 336c29e5f0fSliuyi return true; 337c29e5f0fSliuyi } 338c29e5f0fSliuyi 339c29e5f0fSliuyi 340c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 341c30d921cSKever Yang { 342c30d921cSKever Yang stringstream paramStream(pParameter); 343c30d921cSKever Yang bool bRet,bFind = false; 344c29e5f0fSliuyi string strLine, strPartition, strPartInfo, strPartName, strUUid; 345c30d921cSKever Yang string::size_type line_size, pos, posColon, posComma; 346c30d921cSKever Yang UINT uiPartOffset, uiPartSize; 347c30d921cSKever Yang STRUCT_PARAM_ITEM item; 348c29e5f0fSliuyi STRUCT_CONFIG_ITEM uuid_item; 349c30d921cSKever Yang vecItem.clear(); 350c29e5f0fSliuyi vecUuidItem.clear(); 351c30d921cSKever Yang while (!paramStream.eof()) { 352c30d921cSKever Yang getline(paramStream,strLine); 353c30d921cSKever Yang line_size = strLine.size(); 354c30d921cSKever Yang if (line_size == 0) 355c30d921cSKever Yang continue; 356c30d921cSKever Yang if (strLine[line_size - 1] == '\r'){ 357c30d921cSKever Yang strLine = strLine.substr(0, line_size - 1); 358c30d921cSKever Yang } 359c30d921cSKever Yang strLine.erase(0, strLine.find_first_not_of(" ")); 360c30d921cSKever Yang strLine.erase(strLine.find_last_not_of(" ") + 1); 361c30d921cSKever Yang if (strLine.size()==0 ) 362c30d921cSKever Yang continue; 363c30d921cSKever Yang if (strLine[0] == '#') 364c30d921cSKever Yang continue; 365c29e5f0fSliuyi pos = strLine.find("uuid:"); 366c29e5f0fSliuyi if (pos != string::npos) { 367c29e5f0fSliuyi strPartInfo = strLine.substr(pos+5); 368c29e5f0fSliuyi bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid); 369c29e5f0fSliuyi if (bRet) { 370c29e5f0fSliuyi strcpy(uuid_item.szItemName, strPartName.c_str()); 371c29e5f0fSliuyi string_to_uuid(strUUid,uuid_item.szItemValue); 372c29e5f0fSliuyi vecUuidItem.push_back(uuid_item); 373c29e5f0fSliuyi } 374c29e5f0fSliuyi continue; 375c29e5f0fSliuyi } 376c29e5f0fSliuyi 377c30d921cSKever Yang pos = strLine.find("mtdparts"); 378c30d921cSKever Yang if (pos == string::npos) { 379c30d921cSKever Yang continue; 380c30d921cSKever Yang } 381c30d921cSKever Yang bFind = true; 382c30d921cSKever Yang posColon = strLine.find(':', pos); 383c30d921cSKever Yang if (posColon == string::npos) { 384c30d921cSKever Yang continue; 385c30d921cSKever Yang } 386c30d921cSKever Yang strPartition = strLine.substr(posColon + 1); 387c30d921cSKever Yang pos = 0; 388c30d921cSKever Yang posComma = strPartition.find(',', pos); 389c30d921cSKever Yang while (posComma != string::npos) { 390c30d921cSKever Yang strPartInfo = strPartition.substr(pos, posComma - pos); 391c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 392c30d921cSKever Yang if (bRet) { 393c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 394c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 395c30d921cSKever Yang item.uiItemSize = uiPartSize; 396c30d921cSKever Yang vecItem.push_back(item); 397c30d921cSKever Yang } 398c30d921cSKever Yang pos = posComma + 1; 399c30d921cSKever Yang posComma = strPartition.find(',', pos); 400c30d921cSKever Yang } 401c30d921cSKever Yang strPartInfo = strPartition.substr(pos); 402c30d921cSKever Yang if (strPartInfo.size() > 0) { 403c30d921cSKever Yang bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 404c30d921cSKever Yang if (bRet) { 405c30d921cSKever Yang strcpy(item.szItemName, strPartName.c_str()); 406c30d921cSKever Yang item.uiItemOffset = uiPartOffset; 407c30d921cSKever Yang item.uiItemSize = uiPartSize; 408c30d921cSKever Yang vecItem.push_back(item); 409c30d921cSKever Yang } 410c30d921cSKever Yang } 411c30d921cSKever Yang } 412c30d921cSKever Yang return bFind; 413c30d921cSKever Yang 414c30d921cSKever Yang } 415c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 416c30d921cSKever Yang { 417c30d921cSKever Yang FILE *file = NULL; 418c30d921cSKever Yang file = fopen(pParamFile, "rb"); 419c30d921cSKever Yang if( !file ) { 420c30d921cSKever Yang if (g_pLogObject) 42132268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 422c30d921cSKever Yang return false; 423c30d921cSKever Yang } 424c30d921cSKever Yang int iFileSize; 425c30d921cSKever Yang fseek(file, 0, SEEK_END); 426c30d921cSKever Yang iFileSize = ftell(file); 427c30d921cSKever Yang fseek(file, 0, SEEK_SET); 428c30d921cSKever Yang char *pParamBuf = NULL; 429c30d921cSKever Yang pParamBuf = new char[iFileSize]; 430c30d921cSKever Yang if (!pParamBuf) { 431c30d921cSKever Yang fclose(file); 432c30d921cSKever Yang return false; 433c30d921cSKever Yang } 434c30d921cSKever Yang int iRead; 435c30d921cSKever Yang iRead = fread(pParamBuf, 1, iFileSize, file); 436c30d921cSKever Yang if (iRead != iFileSize) { 437c30d921cSKever Yang if (g_pLogObject) 43832268622SAndreas Färber g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize); 439c30d921cSKever Yang fclose(file); 440c30d921cSKever Yang delete []pParamBuf; 441c30d921cSKever Yang return false; 442c30d921cSKever Yang } 443c30d921cSKever Yang fclose(file); 444c30d921cSKever Yang bool bRet; 445c29e5f0fSliuyi bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem); 446c30d921cSKever Yang delete []pParamBuf; 447c30d921cSKever Yang return bRet; 448c30d921cSKever Yang } 4496ae612beSliuyi bool is_sparse_image(char *szImage) 4506ae612beSliuyi { 4516ae612beSliuyi FILE *file = NULL; 4526ae612beSliuyi sparse_header head; 4536ae612beSliuyi u32 uiRead; 4546ae612beSliuyi file = fopen(szImage, "rb"); 4556ae612beSliuyi if( !file ) { 4566ae612beSliuyi if (g_pLogObject) 4576ae612beSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage); 4586ae612beSliuyi return false; 4596ae612beSliuyi } 4606ae612beSliuyi uiRead = fread(&head, 1, sizeof(head), file); 4616ae612beSliuyi if (uiRead != sizeof(head)) { 4626ae612beSliuyi if (g_pLogObject) 4636ae612beSliuyi g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head)); 4646ae612beSliuyi fclose(file); 4656ae612beSliuyi return false; 4666ae612beSliuyi } 4676ae612beSliuyi fclose(file); 4686ae612beSliuyi if (head.magic!=SPARSE_HEADER_MAGIC) 4696ae612beSliuyi { 4706ae612beSliuyi return false; 4716ae612beSliuyi } 4726ae612beSliuyi return true; 4736ae612beSliuyi 4746ae612beSliuyi } 4750dcb0a4cSliuyi bool is_ubifs_image(char *szImage) 4760dcb0a4cSliuyi { 4770dcb0a4cSliuyi FILE *file = NULL; 4780dcb0a4cSliuyi u32 magic; 4790dcb0a4cSliuyi u32 uiRead; 4800dcb0a4cSliuyi file = fopen(szImage, "rb"); 4810dcb0a4cSliuyi if( !file ) { 4820dcb0a4cSliuyi if (g_pLogObject) 4830dcb0a4cSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage); 4840dcb0a4cSliuyi return false; 4850dcb0a4cSliuyi } 4860dcb0a4cSliuyi uiRead = fread(&magic, 1, sizeof(magic), file); 4870dcb0a4cSliuyi if (uiRead != sizeof(magic)) { 4880dcb0a4cSliuyi if (g_pLogObject) 4890dcb0a4cSliuyi g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(magic)); 4900dcb0a4cSliuyi fclose(file); 4910dcb0a4cSliuyi return false; 4920dcb0a4cSliuyi } 4930dcb0a4cSliuyi fclose(file); 4940dcb0a4cSliuyi if (magic!=UBI_HEADER_MAGIC) 4950dcb0a4cSliuyi { 4960dcb0a4cSliuyi return false; 4970dcb0a4cSliuyi } 4980dcb0a4cSliuyi return true; 4990dcb0a4cSliuyi } 500c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin) 501c30d921cSKever Yang { 502c30d921cSKever Yang efi_guid_t id; 503c30d921cSKever Yang unsigned int *ptr = (unsigned int *)&id; 504c30d921cSKever Yang unsigned int i; 505c30d921cSKever Yang 506c30d921cSKever Yang /* Set all fields randomly */ 507c30d921cSKever Yang for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 508c30d921cSKever Yang *(ptr + i) = cpu_to_be32(rand()); 509c30d921cSKever Yang 510c30d921cSKever Yang id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 511c30d921cSKever Yang id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 512c30d921cSKever Yang 513c30d921cSKever Yang memcpy(uuid_bin, id.raw, sizeof(id)); 514c30d921cSKever Yang } 515c30d921cSKever Yang 516c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup) 517c29e5f0fSliuyi { 518c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 519c29e5f0fSliuyi gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE); 520c29e5f0fSliuyi u32 calc_crc32; 521c29e5f0fSliuyi u64 val; 522c29e5f0fSliuyi 523c29e5f0fSliuyi /* recalculate the values for the Backup GPT Header */ 524c29e5f0fSliuyi val = le64_to_cpu(gptMasterHead->my_lba); 525c29e5f0fSliuyi gptBackupHead->my_lba = gptMasterHead->alternate_lba; 526c29e5f0fSliuyi gptBackupHead->alternate_lba = cpu_to_le64(val); 527c29e5f0fSliuyi gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1); 528c29e5f0fSliuyi gptBackupHead->header_crc32 = 0; 529c29e5f0fSliuyi 530c29e5f0fSliuyi calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size)); 531c29e5f0fSliuyi gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32); 532c29e5f0fSliuyi } 5336ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end) 5346ae612beSliuyi { 5356ae612beSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 5366ae612beSliuyi gpt_entry *gptEntry = NULL; 5376ae612beSliuyi u32 i,j; 5386ae612beSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 5396ae612beSliuyi bool bFound = false; 5406ae612beSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 5416ae612beSliuyi 5426ae612beSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 5436ae612beSliuyi gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 5446ae612beSliuyi if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0) 5456ae612beSliuyi break; 5466ae612beSliuyi for (j = 0; j < strlen(pszName); j++) 5476ae612beSliuyi if (gptEntry->partition_name[j] != pszName[j]) 5486ae612beSliuyi break; 5496ae612beSliuyi if (gptEntry->partition_name[j] != 0) 5506ae612beSliuyi continue; 5516ae612beSliuyi if (j == strlen(pszName)) { 5526ae612beSliuyi bFound = true; 5536ae612beSliuyi break; 5546ae612beSliuyi } 5556ae612beSliuyi } 5566ae612beSliuyi if (bFound) { 5576ae612beSliuyi *lba = le64_to_cpu(gptEntry->starting_lba); 558e541b7bbSliuyi if (gptMasterHead->last_usable_lba == gptEntry->ending_lba) 559e541b7bbSliuyi *lba_end = 0xFFFFFFFF; 560e541b7bbSliuyi else 5616ae612beSliuyi *lba_end = le64_to_cpu(gptEntry->ending_lba); 5626ae612beSliuyi return true; 5636ae612beSliuyi } 5646ae612beSliuyi return false; 5656ae612beSliuyi } 566081d237aSliuyi bool get_lba_from_param(u8 *param, char *pszName, u32 *part_offset, u32 *part_size) 567081d237aSliuyi { 568081d237aSliuyi u32 i; 569081d237aSliuyi bool bFound = false, bRet; 570081d237aSliuyi PARAM_ITEM_VECTOR vecItem; 571081d237aSliuyi CONFIG_ITEM_VECTOR vecUuid; 572081d237aSliuyi 573081d237aSliuyi bRet = parse_parameter((char *)param, vecItem, vecUuid); 574081d237aSliuyi if (!bRet) 575081d237aSliuyi return false; 576081d237aSliuyi 577081d237aSliuyi for (i = 0; i < vecItem.size(); i++) { 578081d237aSliuyi if (strcasecmp(pszName, vecItem[i].szItemName)==0) { 579081d237aSliuyi bFound = true; 580081d237aSliuyi break; 581081d237aSliuyi } 582081d237aSliuyi } 583081d237aSliuyi if (bFound) { 584081d237aSliuyi *part_offset = vecItem[i].uiItemOffset; 585081d237aSliuyi *part_size = vecItem[i].uiItemSize; 586081d237aSliuyi return true; 587081d237aSliuyi } 588081d237aSliuyi return false; 589081d237aSliuyi } 590081d237aSliuyi 591c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector) 592c29e5f0fSliuyi { 593c29e5f0fSliuyi gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 594c29e5f0fSliuyi gpt_entry *gptLastPartEntry = NULL; 595c29e5f0fSliuyi u32 i; 596c29e5f0fSliuyi u64 old_disksize; 597c29e5f0fSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 598c29e5f0fSliuyi 599c29e5f0fSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 600c29e5f0fSliuyi old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1; 601c29e5f0fSliuyi for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 602c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 603c29e5f0fSliuyi if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0) 604c29e5f0fSliuyi break; 605c29e5f0fSliuyi } 606c29e5f0fSliuyi i--; 607c29e5f0fSliuyi gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry)); 608c29e5f0fSliuyi 609c29e5f0fSliuyi gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1); 610c29e5f0fSliuyi gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34); 611c29e5f0fSliuyi 612c29e5f0fSliuyi if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition 613c29e5f0fSliuyi gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34); 614c29e5f0fSliuyi gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 615c29e5f0fSliuyi } 616c29e5f0fSliuyi gptMasterHead->header_crc32 = 0; 617c29e5f0fSliuyi gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header))); 618c29e5f0fSliuyi memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS); 619c29e5f0fSliuyi memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE); 620c29e5f0fSliuyi prepare_gpt_backup(master, backup); 621c29e5f0fSliuyi 622c29e5f0fSliuyi } 623c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup) 624c29e5f0fSliuyi { 625c29e5f0fSliuyi FILE *file = NULL; 626c29e5f0fSliuyi file = fopen(pParamFile, "rb"); 627c29e5f0fSliuyi if( !file ) { 628c29e5f0fSliuyi if (g_pLogObject) 629c29e5f0fSliuyi g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 630c29e5f0fSliuyi return false; 631c29e5f0fSliuyi } 632c29e5f0fSliuyi int iFileSize; 633c29e5f0fSliuyi fseek(file, 0, SEEK_END); 634c29e5f0fSliuyi iFileSize = ftell(file); 635c29e5f0fSliuyi fseek(file, 0, SEEK_SET); 636c29e5f0fSliuyi if (iFileSize != 67 * SECTOR_SIZE) { 637c29e5f0fSliuyi if (g_pLogObject) 638c29e5f0fSliuyi g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile); 639c29e5f0fSliuyi fclose(file); 640c29e5f0fSliuyi return false; 641c29e5f0fSliuyi } 642c29e5f0fSliuyi 643c29e5f0fSliuyi int iRead; 644c29e5f0fSliuyi iRead = fread(master, 1, 34 * SECTOR_SIZE, file); 645c29e5f0fSliuyi if (iRead != 34 * SECTOR_SIZE) { 646c29e5f0fSliuyi if (g_pLogObject) 647c29e5f0fSliuyi g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE); 648c29e5f0fSliuyi fclose(file); 649c29e5f0fSliuyi return false; 650c29e5f0fSliuyi } 651c29e5f0fSliuyi iRead = fread(backup, 1, 33 * SECTOR_SIZE, file); 652c29e5f0fSliuyi if (iRead != 33 * SECTOR_SIZE) { 653c29e5f0fSliuyi if (g_pLogObject) 654c29e5f0fSliuyi g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE); 655c29e5f0fSliuyi fclose(file); 656c29e5f0fSliuyi return false; 657c29e5f0fSliuyi } 658c29e5f0fSliuyi fclose(file); 659c29e5f0fSliuyi return true; 660c29e5f0fSliuyi } 661c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors) 662c30d921cSKever Yang { 663c30d921cSKever Yang legacy_mbr *mbr = (legacy_mbr *)gpt; 664c30d921cSKever Yang gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 665c30d921cSKever Yang gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 666c30d921cSKever Yang u32 i,j; 667c29e5f0fSliuyi int pos; 668c30d921cSKever Yang string strPartName; 669c30d921cSKever Yang string::size_type colonPos; 670c30d921cSKever Yang /*1.protective mbr*/ 671c30d921cSKever Yang memset(gpt, 0, SECTOR_SIZE); 672c30d921cSKever Yang mbr->signature = MSDOS_MBR_SIGNATURE; 673c30d921cSKever Yang mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 674c30d921cSKever Yang mbr->partition_record[0].start_sect = 1; 675c30d921cSKever Yang mbr->partition_record[0].nr_sects = (u32)-1; 676c30d921cSKever Yang /*2.gpt header*/ 677c30d921cSKever Yang memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 678c30d921cSKever Yang gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 679c30d921cSKever Yang gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 680c30d921cSKever Yang gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 681c30d921cSKever Yang gptHead->my_lba = cpu_to_le64(1); 682c30d921cSKever Yang gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 683c30d921cSKever Yang gptHead->first_usable_lba = cpu_to_le64(34); 684c30d921cSKever Yang gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 685c30d921cSKever Yang gptHead->partition_entry_lba = cpu_to_le64(2); 686c30d921cSKever Yang gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 687c30d921cSKever Yang gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 688c30d921cSKever Yang gptHead->header_crc32 = 0; 689c30d921cSKever Yang gptHead->partition_entry_array_crc32 = 0; 690c30d921cSKever Yang gen_rand_uuid(gptHead->disk_guid.raw); 691c30d921cSKever Yang 692c30d921cSKever Yang /*3.gpt partition entry*/ 693c30d921cSKever Yang memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 694c30d921cSKever Yang for (i = 0; i < vecParts.size(); i++) { 695c30d921cSKever Yang gen_rand_uuid(gptEntry->partition_type_guid.raw); 696c30d921cSKever Yang gen_rand_uuid(gptEntry->unique_partition_guid.raw); 697c30d921cSKever Yang gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 698c30d921cSKever Yang gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 699c30d921cSKever Yang gptEntry->attributes.raw = 0; 700c30d921cSKever Yang strPartName = vecParts[i].szItemName; 701c30d921cSKever Yang colonPos = strPartName.find_first_of(':'); 702c30d921cSKever Yang if (colonPos != string::npos) { 703c30d921cSKever Yang if (strPartName.find("bootable") != string::npos) 704c30d921cSKever Yang gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 705c29e5f0fSliuyi if (strPartName.find("grow") != string::npos) 706c29e5f0fSliuyi gptEntry->ending_lba = cpu_to_le64(diskSectors - 34); 707c30d921cSKever Yang strPartName = strPartName.substr(0, colonPos); 708c30d921cSKever Yang vecParts[i].szItemName[strPartName.size()] = 0; 709c30d921cSKever Yang } 710c30d921cSKever Yang for (j = 0; j < strlen(vecParts[i].szItemName); j++) 711c30d921cSKever Yang gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 712c29e5f0fSliuyi if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1) 713c29e5f0fSliuyi memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16); 714c30d921cSKever Yang gptEntry++; 715c30d921cSKever Yang } 716c30d921cSKever Yang 717c30d921cSKever Yang gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 718c30d921cSKever Yang gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 719c30d921cSKever Yang 720c30d921cSKever Yang } 721b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag) 722c30d921cSKever Yang { 723c30d921cSKever Yang PRK28_IDB_SEC0 pSec0; 724c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 725c30d921cSKever Yang pSec0 = (PRK28_IDB_SEC0)pSector; 726c30d921cSKever Yang 727c30d921cSKever Yang pSec0->dwTag = 0x0FF0AA55; 728b38fe5fcSliuyi pSec0->uiRc4Flag = rc4Flag; 729c30d921cSKever Yang pSec0->usBootCode1Offset = 0x4; 730c30d921cSKever Yang pSec0->usBootCode2Offset = 0x4; 731c30d921cSKever Yang pSec0->usBootDataSize = usFlashDataSec; 732c30d921cSKever Yang pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 733c30d921cSKever Yang return true; 734c30d921cSKever Yang } 735c30d921cSKever Yang 736c30d921cSKever Yang 737c30d921cSKever Yang bool MakeSector1(PBYTE pSector) 738c30d921cSKever Yang { 739c30d921cSKever Yang PRK28_IDB_SEC1 pSec1; 740c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 741c30d921cSKever Yang pSec1 = (PRK28_IDB_SEC1)pSector; 742c30d921cSKever Yang 743c30d921cSKever Yang pSec1->usSysReservedBlock = 0xC; 744c30d921cSKever Yang pSec1->usDisk0Size = 0xFFFF; 745c30d921cSKever Yang pSec1->uiChipTag = 0x38324B52; 746c30d921cSKever Yang return true; 747c30d921cSKever Yang } 748c30d921cSKever Yang 749c30d921cSKever Yang bool MakeSector2(PBYTE pSector) 750c30d921cSKever Yang { 751c30d921cSKever Yang PRK28_IDB_SEC2 pSec2; 752c30d921cSKever Yang memset(pSector, 0, SECTOR_SIZE); 753c30d921cSKever Yang pSec2 = (PRK28_IDB_SEC2)pSector; 754c30d921cSKever Yang 755c30d921cSKever Yang strcpy(pSec2->szVcTag, "VC"); 756c30d921cSKever Yang strcpy(pSec2->szCrcTag, "CRC"); 757c30d921cSKever Yang return true; 758c30d921cSKever Yang } 759c30d921cSKever Yang 760c30d921cSKever Yang bool MakeSector3(PBYTE pSector) 761c30d921cSKever Yang { 762c30d921cSKever Yang memset(pSector,0,SECTOR_SIZE); 763c30d921cSKever Yang return true; 764c30d921cSKever Yang } 765c30d921cSKever Yang 766b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag) 767c30d921cSKever Yang { 768c30d921cSKever Yang RK28_IDB_SEC0 sector0Info; 769c30d921cSKever Yang RK28_IDB_SEC1 sector1Info; 770c30d921cSKever Yang RK28_IDB_SEC2 sector2Info; 771c30d921cSKever Yang RK28_IDB_SEC3 sector3Info; 772c30d921cSKever Yang UINT i; 773b38fe5fcSliuyi MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag); 774c30d921cSKever Yang MakeSector1((PBYTE)§or1Info); 775c30d921cSKever Yang if (!MakeSector2((PBYTE)§or2Info)) { 776c30d921cSKever Yang return -6; 777c30d921cSKever Yang } 778c30d921cSKever Yang if (!MakeSector3((PBYTE)§or3Info)) { 779c30d921cSKever Yang return -7; 780c30d921cSKever Yang } 781c30d921cSKever Yang sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 782c30d921cSKever Yang sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 783c30d921cSKever Yang sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 784c30d921cSKever Yang 785c30d921cSKever Yang memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 786c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 787c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 788b38fe5fcSliuyi 789b38fe5fcSliuyi if (rc4Flag) { 790b38fe5fcSliuyi for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++) 791b38fe5fcSliuyi P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE); 792b38fe5fcSliuyi for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++) 793b38fe5fcSliuyi P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE); 794b38fe5fcSliuyi } 795b38fe5fcSliuyi 796c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 797c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 798c30d921cSKever Yang 799c30d921cSKever Yang sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 800c30d921cSKever Yang memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 801c30d921cSKever Yang for(i = 0; i < 4; i++) { 802c30d921cSKever Yang if(i == 1) { 803c30d921cSKever Yang continue; 804c30d921cSKever Yang } else { 805c30d921cSKever Yang P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 806c30d921cSKever Yang } 807c30d921cSKever Yang } 808c30d921cSKever Yang return 0; 809c30d921cSKever Yang } 810c30d921cSKever Yang 811c30d921cSKever Yang 81276af099aSliuyi 81376af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 81476af099aSliuyi { 81506ea143eSKlaus Goger if (((UINT)dev.emUsbType & uiSupportType) == (UINT)dev.emUsbType) 81676af099aSliuyi return true; 81776af099aSliuyi else 81876af099aSliuyi { 81976af099aSliuyi ERROR_COLOR_ATTR; 82032268622SAndreas Färber printf("The device does not support this operation!"); 82176af099aSliuyi NORMAL_COLOR_ATTR; 82276af099aSliuyi printf("\r\n"); 82376af099aSliuyi return false; 82476af099aSliuyi } 82576af099aSliuyi } 826081d237aSliuyi bool MakeParamBuffer(char *pParamFile, char* &pParamData) 827081d237aSliuyi { 828081d237aSliuyi FILE *file=NULL; 829081d237aSliuyi file = fopen(pParamFile, "rb"); 830081d237aSliuyi if( !file ) 831081d237aSliuyi { 832081d237aSliuyi if (g_pLogObject) 833081d237aSliuyi g_pLogObject->Record("MakeParamBuffer failed,err=%d,can't open file: %s\r\n", errno, pParamFile); 834081d237aSliuyi return false; 835081d237aSliuyi } 836081d237aSliuyi int iFileSize; 837081d237aSliuyi fseek(file,0,SEEK_END); 838081d237aSliuyi iFileSize = ftell(file); 839081d237aSliuyi fseek(file,0,SEEK_SET); 840081d237aSliuyi char *pParamBuf=NULL; 841081d237aSliuyi pParamBuf = new char[iFileSize + 12]; 842081d237aSliuyi if (!pParamBuf) 843081d237aSliuyi { 844081d237aSliuyi fclose(file); 845081d237aSliuyi return false; 846081d237aSliuyi } 847081d237aSliuyi memset(pParamBuf,0,iFileSize+12); 848081d237aSliuyi *(UINT *)(pParamBuf) = 0x4D524150; 849081d237aSliuyi 850081d237aSliuyi int iRead; 851081d237aSliuyi iRead = fread(pParamBuf+8,1,iFileSize,file); 852081d237aSliuyi if (iRead!=iFileSize) 853081d237aSliuyi { 854081d237aSliuyi if (g_pLogObject) 855081d237aSliuyi g_pLogObject->Record("MakeParamBuffer failed,err=%d,read=%d,total=%d\r\n", errno, iRead, iFileSize); 856081d237aSliuyi fclose(file); 857081d237aSliuyi delete []pParamBuf; 858081d237aSliuyi return false; 859081d237aSliuyi } 860081d237aSliuyi fclose(file); 861081d237aSliuyi 862081d237aSliuyi *(UINT *)(pParamBuf+4) = iFileSize; 863081d237aSliuyi *(UINT *)(pParamBuf+8+iFileSize) = CRC_32( (PBYTE)pParamBuf+8, iFileSize); 864081d237aSliuyi pParamData = pParamBuf; 865081d237aSliuyi return true; 866081d237aSliuyi } 867081d237aSliuyi 868081d237aSliuyi bool write_parameter(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 869081d237aSliuyi { 870081d237aSliuyi CRKComm *pComm = NULL; 871081d237aSliuyi char *pParamBuf = NULL, writeBuf[512*1024]; 872081d237aSliuyi int iRet, nParamSec, nParamSize; 873081d237aSliuyi bool bRet, bSuccess = false; 874081d237aSliuyi if (!check_device_type(dev, RKUSB_MASKROM|RKUSB_LOADER)) 875081d237aSliuyi return false; 876081d237aSliuyi 877081d237aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 878081d237aSliuyi if (!bRet) { 879081d237aSliuyi ERROR_COLOR_ATTR; 880081d237aSliuyi printf("Creating Comm Object failed!"); 881081d237aSliuyi NORMAL_COLOR_ATTR; 882081d237aSliuyi printf("\r\n"); 883081d237aSliuyi return bSuccess; 884081d237aSliuyi } 885081d237aSliuyi if (!MakeParamBuffer(szParameter, pParamBuf)) { 886081d237aSliuyi ERROR_COLOR_ATTR; 887081d237aSliuyi printf("Generating parameter failed!"); 888081d237aSliuyi NORMAL_COLOR_ATTR; 889081d237aSliuyi printf("\r\n"); 890081d237aSliuyi return bSuccess; 891081d237aSliuyi } 892081d237aSliuyi printf("Writing parameter...\r\n"); 893081d237aSliuyi nParamSize = *(UINT *)(pParamBuf+4) + 12; 894081d237aSliuyi nParamSec = BYTE2SECTOR(nParamSize); 895081d237aSliuyi if (nParamSec > 1024) { 896081d237aSliuyi ERROR_COLOR_ATTR; 897081d237aSliuyi printf("parameter is too large!"); 898081d237aSliuyi NORMAL_COLOR_ATTR; 899081d237aSliuyi printf("\r\n"); 900081d237aSliuyi return bSuccess; 901081d237aSliuyi } 902081d237aSliuyi memset(writeBuf, 0, nParamSec*512); 903081d237aSliuyi memcpy(writeBuf, pParamBuf, nParamSize); 904081d237aSliuyi iRet = pComm->RKU_WriteLBA(0x2000, nParamSec, (BYTE *)writeBuf); 905081d237aSliuyi if (iRet != ERR_SUCCESS) { 906081d237aSliuyi ERROR_COLOR_ATTR; 907081d237aSliuyi printf("Writing parameter failed!"); 908081d237aSliuyi NORMAL_COLOR_ATTR; 909081d237aSliuyi printf("\r\n"); 910081d237aSliuyi return bSuccess; 911081d237aSliuyi } 912081d237aSliuyi 913081d237aSliuyi bSuccess = true; 914081d237aSliuyi CURSOR_MOVEUP_LINE(1); 915081d237aSliuyi CURSOR_DEL_LINE; 916081d237aSliuyi printf("Writing parameter succeeded.\r\n"); 917081d237aSliuyi return bSuccess; 918081d237aSliuyi } 919081d237aSliuyi 920c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 921c30d921cSKever Yang { 922c30d921cSKever Yang u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 923c30d921cSKever Yang u32 total_size_sector; 924c30d921cSKever Yang CRKComm *pComm = NULL; 925c30d921cSKever Yang PARAM_ITEM_VECTOR vecItems; 926c29e5f0fSliuyi CONFIG_ITEM_VECTOR vecUuid; 927c30d921cSKever Yang int iRet; 928c30d921cSKever Yang bool bRet, bSuccess = false; 929c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 930c30d921cSKever Yang return false; 931c30d921cSKever Yang 932c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 933c30d921cSKever Yang if (!bRet) { 934c30d921cSKever Yang ERROR_COLOR_ATTR; 935c30d921cSKever Yang printf("Creating Comm Object failed!"); 936c30d921cSKever Yang NORMAL_COLOR_ATTR; 937c30d921cSKever Yang printf("\r\n"); 938c30d921cSKever Yang return bSuccess; 939c30d921cSKever Yang } 94032268622SAndreas Färber printf("Writing gpt...\r\n"); 941c30d921cSKever Yang //1.get flash info 942c30d921cSKever Yang iRet = pComm->RKU_ReadFlashInfo(flash_info); 943c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 944c30d921cSKever Yang ERROR_COLOR_ATTR; 945c30d921cSKever Yang printf("Reading Flash Info failed!"); 946c30d921cSKever Yang NORMAL_COLOR_ATTR; 947c30d921cSKever Yang printf("\r\n"); 948c30d921cSKever Yang return bSuccess; 949c30d921cSKever Yang } 950c30d921cSKever Yang total_size_sector = *(u32 *)flash_info; 951c29e5f0fSliuyi if (strstr(szParameter, ".img")) { 952c29e5f0fSliuyi if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) { 953c29e5f0fSliuyi ERROR_COLOR_ATTR; 954c29e5f0fSliuyi printf("Loading partition image failed!"); 955c29e5f0fSliuyi NORMAL_COLOR_ATTR; 956c29e5f0fSliuyi printf("\r\n"); 957c29e5f0fSliuyi return bSuccess; 958c29e5f0fSliuyi } 959c29e5f0fSliuyi update_gpt_disksize(master_gpt, backup_gpt, total_size_sector); 960c29e5f0fSliuyi } else { 961c30d921cSKever Yang //2.get partition from parameter 962c29e5f0fSliuyi bRet = parse_parameter_file(szParameter, vecItems, vecUuid); 963c30d921cSKever Yang if (!bRet) { 964c30d921cSKever Yang ERROR_COLOR_ATTR; 965c30d921cSKever Yang printf("Parsing parameter failed!"); 966c30d921cSKever Yang NORMAL_COLOR_ATTR; 967c30d921cSKever Yang printf("\r\n"); 968c30d921cSKever Yang return bSuccess; 969c30d921cSKever Yang } 970c30d921cSKever Yang //3.generate gpt info 971c29e5f0fSliuyi create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector); 972c30d921cSKever Yang memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 973c30d921cSKever Yang memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 974c29e5f0fSliuyi prepare_gpt_backup(master_gpt, backup_gpt); 975c29e5f0fSliuyi } 976c29e5f0fSliuyi 977c30d921cSKever Yang //4. write gpt 978c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 979c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 980c30d921cSKever Yang ERROR_COLOR_ATTR; 981c30d921cSKever Yang printf("Writing master gpt failed!"); 982c30d921cSKever Yang NORMAL_COLOR_ATTR; 983c30d921cSKever Yang printf("\r\n"); 984c30d921cSKever Yang return bSuccess; 985c30d921cSKever Yang } 986c29e5f0fSliuyi iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt); 987c30d921cSKever Yang if (iRet != ERR_SUCCESS) { 988c30d921cSKever Yang ERROR_COLOR_ATTR; 989c30d921cSKever Yang printf("Writing backup gpt failed!"); 990c30d921cSKever Yang NORMAL_COLOR_ATTR; 991c30d921cSKever Yang printf("\r\n"); 992c30d921cSKever Yang return bSuccess; 993c30d921cSKever Yang } 994c29e5f0fSliuyi 995c30d921cSKever Yang bSuccess = true; 996c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 997c30d921cSKever Yang CURSOR_DEL_LINE; 99832268622SAndreas Färber printf("Writing gpt succeeded.\r\n"); 999c30d921cSKever Yang return bSuccess; 1000c30d921cSKever Yang } 100176af099aSliuyi 100278884ef4SEddie Cai #include "boot_merger.h" 100378884ef4SEddie Cai #define ENTRY_ALIGN (2048) 100478884ef4SEddie Cai options gOpts; 100578884ef4SEddie Cai 100678884ef4SEddie Cai 100778884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 100878884ef4SEddie Cai char* gConfigPath; 100978884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE]; 101078884ef4SEddie Cai 101178884ef4SEddie Cai static inline void fixPath(char* path) { 101278884ef4SEddie Cai int i, len = strlen(path); 101378884ef4SEddie Cai for(i=0; i<len; i++) { 101478884ef4SEddie Cai if (path[i] == '\\') 101578884ef4SEddie Cai path[i] = '/'; 101678884ef4SEddie Cai else if (path[i] == '\r' || path[i] == '\n') 101778884ef4SEddie Cai path[i] = '\0'; 101878884ef4SEddie Cai } 101978884ef4SEddie Cai } 102078884ef4SEddie Cai 102178884ef4SEddie Cai static bool parseChip(FILE* file) { 102278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 102378884ef4SEddie Cai return false; 102478884ef4SEddie Cai } 102578884ef4SEddie Cai if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 102678884ef4SEddie Cai return false; 102778884ef4SEddie Cai } 102878884ef4SEddie Cai printf("chip: %s\n", gOpts.chip); 102978884ef4SEddie Cai return true; 103078884ef4SEddie Cai } 103178884ef4SEddie Cai 103278884ef4SEddie Cai static bool parseVersion(FILE* file) { 103378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 103478884ef4SEddie Cai return false; 103578884ef4SEddie Cai } 103678884ef4SEddie Cai if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 103778884ef4SEddie Cai return false; 103878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 103978884ef4SEddie Cai return false; 104078884ef4SEddie Cai } 104178884ef4SEddie Cai if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 104278884ef4SEddie Cai return false; 104378884ef4SEddie Cai printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor); 104478884ef4SEddie Cai return true; 104578884ef4SEddie Cai } 104678884ef4SEddie Cai 104778884ef4SEddie Cai static bool parse471(FILE* file) { 104878884ef4SEddie Cai int i, index, pos; 104978884ef4SEddie Cai char buf[MAX_LINE_LEN]; 105078884ef4SEddie Cai 105178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 105278884ef4SEddie Cai return false; 105378884ef4SEddie Cai } 105478884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 105578884ef4SEddie Cai return false; 105678884ef4SEddie Cai printf("num: %d\n", gOpts.code471Num); 105778884ef4SEddie Cai if (!gOpts.code471Num) 105878884ef4SEddie Cai return true; 105978884ef4SEddie Cai if (gOpts.code471Num < 0) 106078884ef4SEddie Cai return false; 106178884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 106278884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 106378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 106478884ef4SEddie Cai return false; 106578884ef4SEddie Cai } 106678884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 106778884ef4SEddie Cai != 2) 106878884ef4SEddie Cai return false; 106978884ef4SEddie Cai index--; 107078884ef4SEddie Cai fixPath(buf); 107178884ef4SEddie Cai strcpy((char*)gOpts.code471Path[index], buf); 107278884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code471Path[index]); 107378884ef4SEddie Cai } 107478884ef4SEddie Cai pos = ftell(file); 107578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 107678884ef4SEddie Cai return false; 107778884ef4SEddie Cai } 107878884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 107978884ef4SEddie Cai fseek(file, pos, SEEK_SET); 108078884ef4SEddie Cai printf("sleep: %d\n", gOpts.code471Sleep); 108178884ef4SEddie Cai return true; 108278884ef4SEddie Cai } 108378884ef4SEddie Cai 108478884ef4SEddie Cai static bool parse472(FILE* file) { 108578884ef4SEddie Cai int i, index, pos; 108678884ef4SEddie Cai char buf[MAX_LINE_LEN]; 108778884ef4SEddie Cai 108878884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 108978884ef4SEddie Cai return false; 109078884ef4SEddie Cai } 109178884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 109278884ef4SEddie Cai return false; 109378884ef4SEddie Cai printf("num: %d\n", gOpts.code472Num); 109478884ef4SEddie Cai if (!gOpts.code472Num) 109578884ef4SEddie Cai return true; 109678884ef4SEddie Cai if (gOpts.code472Num < 0) 109778884ef4SEddie Cai return false; 109878884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 109978884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 110078884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 110178884ef4SEddie Cai return false; 110278884ef4SEddie Cai } 110378884ef4SEddie Cai if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 110478884ef4SEddie Cai != 2) 110578884ef4SEddie Cai return false; 110678884ef4SEddie Cai fixPath(buf); 110778884ef4SEddie Cai index--; 110878884ef4SEddie Cai strcpy((char*)gOpts.code472Path[index], buf); 110978884ef4SEddie Cai printf("path%i: %s\n", index, gOpts.code472Path[index]); 111078884ef4SEddie Cai } 111178884ef4SEddie Cai pos = ftell(file); 111278884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 111378884ef4SEddie Cai return false; 111478884ef4SEddie Cai } 111578884ef4SEddie Cai if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 111678884ef4SEddie Cai fseek(file, pos, SEEK_SET); 111778884ef4SEddie Cai printf("sleep: %d\n", gOpts.code472Sleep); 111878884ef4SEddie Cai return true; 111978884ef4SEddie Cai } 112078884ef4SEddie Cai 112178884ef4SEddie Cai static bool parseLoader(FILE* file) { 112278884ef4SEddie Cai int i, j, index, pos; 112378884ef4SEddie Cai char buf[MAX_LINE_LEN]; 112478884ef4SEddie Cai char buf2[MAX_LINE_LEN]; 112578884ef4SEddie Cai 112678884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 112778884ef4SEddie Cai return false; 112878884ef4SEddie Cai } 112978884ef4SEddie Cai pos = ftell(file); 113078884ef4SEddie Cai if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 113178884ef4SEddie Cai fseek(file, pos, SEEK_SET); 113278884ef4SEddie Cai if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 113378884ef4SEddie Cai return false; 113478884ef4SEddie Cai } 113578884ef4SEddie Cai } 113678884ef4SEddie Cai printf("num: %d\n", gOpts.loaderNum); 113778884ef4SEddie Cai if (!gOpts.loaderNum) 113878884ef4SEddie Cai return false; 113978884ef4SEddie Cai if (gOpts.loaderNum < 0) 114078884ef4SEddie Cai return false; 114178884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 114278884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 114378884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 114478884ef4SEddie Cai return false; 114578884ef4SEddie Cai } 114678884ef4SEddie Cai if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 114778884ef4SEddie Cai != 2) 114878884ef4SEddie Cai return false; 114978884ef4SEddie Cai strcpy(gOpts.loader[index].name, buf); 115078884ef4SEddie Cai printf("name%d: %s\n", index, gOpts.loader[index].name); 1151544ec1d4SKlaus Goger index++; 115278884ef4SEddie Cai } 115378884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 115478884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 115578884ef4SEddie Cai return false; 115678884ef4SEddie Cai } 115778884ef4SEddie Cai if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 115878884ef4SEddie Cai != 2) 115978884ef4SEddie Cai return false; 116078884ef4SEddie Cai for (j=0; j<gOpts.loaderNum; j++) { 116178884ef4SEddie Cai if (!strcmp(gOpts.loader[j].name, buf)) { 116278884ef4SEddie Cai fixPath(buf2); 116378884ef4SEddie Cai strcpy(gOpts.loader[j].path, buf2); 116478884ef4SEddie Cai printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 116578884ef4SEddie Cai break; 116678884ef4SEddie Cai } 116778884ef4SEddie Cai } 116878884ef4SEddie Cai if (j >= gOpts.loaderNum) { 116978884ef4SEddie Cai return false; 117078884ef4SEddie Cai } 117178884ef4SEddie Cai } 117278884ef4SEddie Cai return true; 117378884ef4SEddie Cai } 117478884ef4SEddie Cai 117578884ef4SEddie Cai static bool parseOut(FILE* file) { 117678884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 117778884ef4SEddie Cai return false; 117878884ef4SEddie Cai } 117978884ef4SEddie Cai if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 118078884ef4SEddie Cai return false; 118178884ef4SEddie Cai fixPath(gOpts.outPath); 118278884ef4SEddie Cai printf("out: %s\n", gOpts.outPath); 118378884ef4SEddie Cai return true; 118478884ef4SEddie Cai } 118578884ef4SEddie Cai 118678884ef4SEddie Cai 118778884ef4SEddie Cai void printOpts(FILE* out) { 118878884ef4SEddie Cai int i; 118978884ef4SEddie Cai fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 119078884ef4SEddie Cai fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 119178884ef4SEddie Cai "=%d\n", gOpts.major, gOpts.minor); 119278884ef4SEddie Cai 119378884ef4SEddie Cai fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 119478884ef4SEddie Cai for (i=0 ;i<gOpts.code471Num ;i++) { 119578884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 119678884ef4SEddie Cai } 119778884ef4SEddie Cai if (gOpts.code471Sleep > 0) 119878884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 119978884ef4SEddie Cai 120078884ef4SEddie Cai fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 120178884ef4SEddie Cai for (i=0 ;i<gOpts.code472Num ;i++) { 120278884ef4SEddie Cai fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 120378884ef4SEddie Cai } 120478884ef4SEddie Cai if (gOpts.code472Sleep > 0) 120578884ef4SEddie Cai fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 120678884ef4SEddie Cai 120778884ef4SEddie Cai fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 120878884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 120978884ef4SEddie Cai fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 121078884ef4SEddie Cai } 121178884ef4SEddie Cai for (i=0 ;i<gOpts.loaderNum ;i++) { 121278884ef4SEddie Cai fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 121378884ef4SEddie Cai } 121478884ef4SEddie Cai 121578884ef4SEddie Cai fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 121678884ef4SEddie Cai } 121778884ef4SEddie Cai 121878884ef4SEddie Cai static bool parseOpts(void) { 121978884ef4SEddie Cai bool ret = false; 122078884ef4SEddie Cai bool chipOk = false; 122178884ef4SEddie Cai bool versionOk = false; 122278884ef4SEddie Cai bool code471Ok = true; 122378884ef4SEddie Cai bool code472Ok = true; 122478884ef4SEddie Cai bool loaderOk = false; 122578884ef4SEddie Cai bool outOk = false; 122678884ef4SEddie Cai char buf[MAX_LINE_LEN]; 122778884ef4SEddie Cai 122878884ef4SEddie Cai char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 122978884ef4SEddie Cai FILE* file; 123078884ef4SEddie Cai file = fopen(configPath, "r"); 123178884ef4SEddie Cai if (!file) { 123278884ef4SEddie Cai fprintf(stderr, "config (%s) not found!\n", configPath); 123308c0d218SKlaus Goger if (strcmp(configPath, (char*)DEF_CONFIG_FILE) == 0) { 123478884ef4SEddie Cai file = fopen(DEF_CONFIG_FILE, "w"); 123578884ef4SEddie Cai if (file) { 123632268622SAndreas Färber fprintf(stderr, "creating defconfig\n"); 123778884ef4SEddie Cai printOpts(file); 123878884ef4SEddie Cai } 123978884ef4SEddie Cai } 124078884ef4SEddie Cai goto end; 124178884ef4SEddie Cai } 124278884ef4SEddie Cai 124332268622SAndreas Färber printf("Starting to parse...\n"); 124478884ef4SEddie Cai 124578884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 124678884ef4SEddie Cai goto end; 124778884ef4SEddie Cai } 124878884ef4SEddie Cai while(fscanf(file, "%s", buf) == 1) { 124978884ef4SEddie Cai if (!strcmp(buf, SEC_CHIP)) { 125078884ef4SEddie Cai chipOk = parseChip(file); 125178884ef4SEddie Cai if (!chipOk) { 125278884ef4SEddie Cai printf("parseChip failed!\n"); 125378884ef4SEddie Cai goto end; 125478884ef4SEddie Cai } 125578884ef4SEddie Cai } else if (!strcmp(buf, SEC_VERSION)) { 125678884ef4SEddie Cai versionOk = parseVersion(file); 125778884ef4SEddie Cai if (!versionOk) { 125878884ef4SEddie Cai printf("parseVersion failed!\n"); 125978884ef4SEddie Cai goto end; 126078884ef4SEddie Cai } 126178884ef4SEddie Cai } else if (!strcmp(buf, SEC_471)) { 126278884ef4SEddie Cai code471Ok = parse471(file); 126378884ef4SEddie Cai if (!code471Ok) { 126478884ef4SEddie Cai printf("parse471 failed!\n"); 126578884ef4SEddie Cai goto end; 126678884ef4SEddie Cai } 126778884ef4SEddie Cai } else if (!strcmp(buf, SEC_472)) { 126878884ef4SEddie Cai code472Ok = parse472(file); 126978884ef4SEddie Cai if (!code472Ok) { 127078884ef4SEddie Cai printf("parse472 failed!\n"); 127178884ef4SEddie Cai goto end; 127278884ef4SEddie Cai } 127378884ef4SEddie Cai } else if (!strcmp(buf, SEC_LOADER)) { 127478884ef4SEddie Cai loaderOk = parseLoader(file); 127578884ef4SEddie Cai if (!loaderOk) { 127678884ef4SEddie Cai printf("parseLoader failed!\n"); 127778884ef4SEddie Cai goto end; 127878884ef4SEddie Cai } 127978884ef4SEddie Cai } else if (!strcmp(buf, SEC_OUT)) { 128078884ef4SEddie Cai outOk = parseOut(file); 128178884ef4SEddie Cai if (!outOk) { 128278884ef4SEddie Cai printf("parseOut failed!\n"); 128378884ef4SEddie Cai goto end; 128478884ef4SEddie Cai } 128578884ef4SEddie Cai } else if (buf[0] == '#') { 128678884ef4SEddie Cai continue; 128778884ef4SEddie Cai } else { 128878884ef4SEddie Cai printf("unknown sec: %s!\n", buf); 128978884ef4SEddie Cai goto end; 129078884ef4SEddie Cai } 129178884ef4SEddie Cai if (SCANF_EAT(file) != 0) { 129278884ef4SEddie Cai goto end; 129378884ef4SEddie Cai } 129478884ef4SEddie Cai } 129578884ef4SEddie Cai 129678884ef4SEddie Cai if (chipOk && versionOk && code471Ok && code472Ok 129778884ef4SEddie Cai && loaderOk && outOk) 129878884ef4SEddie Cai ret = true; 129978884ef4SEddie Cai end: 130078884ef4SEddie Cai if (file) 130178884ef4SEddie Cai fclose(file); 130278884ef4SEddie Cai return ret; 130378884ef4SEddie Cai } 130478884ef4SEddie Cai 130578884ef4SEddie Cai bool initOpts(void) { 130678884ef4SEddie Cai //set default opts 130778884ef4SEddie Cai gOpts.major = DEF_MAJOR; 130878884ef4SEddie Cai gOpts.minor = DEF_MINOR; 130978884ef4SEddie Cai strcpy(gOpts.chip, DEF_CHIP); 131078884ef4SEddie Cai gOpts.code471Sleep = DEF_CODE471_SLEEP; 131178884ef4SEddie Cai gOpts.code472Sleep = DEF_CODE472_SLEEP; 131278884ef4SEddie Cai gOpts.code471Num = DEF_CODE471_NUM; 131378884ef4SEddie Cai gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 131478884ef4SEddie Cai strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 131578884ef4SEddie Cai gOpts.code472Num = DEF_CODE472_NUM; 131678884ef4SEddie Cai gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 131778884ef4SEddie Cai strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 131878884ef4SEddie Cai gOpts.loaderNum = DEF_LOADER_NUM; 131978884ef4SEddie Cai gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 132078884ef4SEddie Cai strcpy(gOpts.loader[0].name, DEF_LOADER0); 132178884ef4SEddie Cai strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 132278884ef4SEddie Cai strcpy(gOpts.loader[1].name, DEF_LOADER1); 132378884ef4SEddie Cai strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 132478884ef4SEddie Cai strcpy(gOpts.outPath, DEF_OUT_PATH); 132578884ef4SEddie Cai 132678884ef4SEddie Cai return parseOpts(); 132778884ef4SEddie Cai } 132878884ef4SEddie Cai 132978884ef4SEddie Cai /************merge code****************/ 133078884ef4SEddie Cai 133178884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) { 133278884ef4SEddie Cai uint8_t tmp[2] = {0}; 133378884ef4SEddie Cai int i; 133478884ef4SEddie Cai uint32_t ret; 133578884ef4SEddie Cai //if (value > 0xFFFF) { 133678884ef4SEddie Cai // return 0; 133778884ef4SEddie Cai //} 133878884ef4SEddie Cai for(i=0; i < 2; i++) { 133978884ef4SEddie Cai tmp[i] = (((value/10)%10)<<4) | (value%10); 134078884ef4SEddie Cai value /= 100; 134178884ef4SEddie Cai } 134278884ef4SEddie Cai ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 134378884ef4SEddie Cai 134478884ef4SEddie Cai printf("ret: %x\n",ret); 134578884ef4SEddie Cai return ret&0xFF; 134678884ef4SEddie Cai } 134778884ef4SEddie Cai 134878884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len) 134978884ef4SEddie Cai { 135078884ef4SEddie Cai int i; 135178884ef4SEddie Cai for (i = 0; i < len; i++) { 135278884ef4SEddie Cai wide[i] = (uint16_t) str[i]; 135378884ef4SEddie Cai } 135478884ef4SEddie Cai wide[len] = 0; 135578884ef4SEddie Cai } 135678884ef4SEddie Cai 135778884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) { 135878884ef4SEddie Cai char* end; 135978884ef4SEddie Cai char* start; 136078884ef4SEddie Cai int len; 136178884ef4SEddie Cai if (!path || !dst) 136278884ef4SEddie Cai return; 136378884ef4SEddie Cai start = strrchr(path, '/'); 136478884ef4SEddie Cai if (!start) 136578884ef4SEddie Cai start = path; 136678884ef4SEddie Cai else 136778884ef4SEddie Cai start++; 136878884ef4SEddie Cai end = strrchr(path, '.'); 1369641cfa16SEddie Cai if (!end || (end < start)) 137078884ef4SEddie Cai end = path + strlen(path); 137178884ef4SEddie Cai len = end - start; 137278884ef4SEddie Cai if (len >= MAX_NAME_LEN) 137378884ef4SEddie Cai len = MAX_NAME_LEN -1; 137478884ef4SEddie Cai str2wide(start, dst, len); 137578884ef4SEddie Cai 137678884ef4SEddie Cai 137778884ef4SEddie Cai char name[MAX_NAME_LEN]; 137878884ef4SEddie Cai memset(name, 0, sizeof(name)); 137978884ef4SEddie Cai memcpy(name, start, len); 138078884ef4SEddie Cai printf("path: %s, name: %s\n", path, name); 138178884ef4SEddie Cai 138278884ef4SEddie Cai } 138378884ef4SEddie Cai 138478884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) { 138578884ef4SEddie Cai struct stat st; 138678884ef4SEddie Cai if(stat(path, &st) < 0) 138778884ef4SEddie Cai return false; 138878884ef4SEddie Cai *size = st.st_size; 138978884ef4SEddie Cai printf("path: %s, size: %d\n", path, *size); 139078884ef4SEddie Cai return true; 139178884ef4SEddie Cai } 139278884ef4SEddie Cai 139378884ef4SEddie Cai static inline rk_time getTime(void) { 139478884ef4SEddie Cai rk_time rkTime; 139578884ef4SEddie Cai 139678884ef4SEddie Cai struct tm *tm; 139778884ef4SEddie Cai time_t tt = time(NULL); 139878884ef4SEddie Cai tm = localtime(&tt); 139978884ef4SEddie Cai rkTime.year = tm->tm_year + 1900; 140078884ef4SEddie Cai rkTime.month = tm->tm_mon + 1; 140178884ef4SEddie Cai rkTime.day = tm->tm_mday; 140278884ef4SEddie Cai rkTime.hour = tm->tm_hour; 140378884ef4SEddie Cai rkTime.minute = tm->tm_min; 140478884ef4SEddie Cai rkTime.second = tm->tm_sec; 140578884ef4SEddie Cai printf("%d-%d-%d %02d:%02d:%02d\n", 140678884ef4SEddie Cai rkTime.year, rkTime.month, rkTime.day, 140778884ef4SEddie Cai rkTime.hour, rkTime.minute, rkTime.second); 140878884ef4SEddie Cai return rkTime; 140978884ef4SEddie Cai } 141078884ef4SEddie Cai 141178884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) { 141278884ef4SEddie Cai bool ret = false; 141378884ef4SEddie Cai uint32_t size = 0, fixSize = 0; 141478884ef4SEddie Cai uint8_t* buf; 141578884ef4SEddie Cai 141678884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 141778884ef4SEddie Cai if (!inFile) 141878884ef4SEddie Cai goto end; 141978884ef4SEddie Cai 142078884ef4SEddie Cai if (!getFileSize(path, &size)) 142178884ef4SEddie Cai goto end; 142278884ef4SEddie Cai if (fix) { 142378884ef4SEddie Cai fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 142478884ef4SEddie Cai uint32_t tmp = fixSize % ENTRY_ALIGN; 142578884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 142678884ef4SEddie Cai fixSize +=tmp; 142778884ef4SEddie Cai memset(gBuf, 0, fixSize); 142878884ef4SEddie Cai } else { 142978884ef4SEddie Cai memset(gBuf, 0, size+ENTRY_ALIGN); 143078884ef4SEddie Cai } 143178884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 143278884ef4SEddie Cai goto end; 143378884ef4SEddie Cai 143478884ef4SEddie Cai if (fix) { 143578884ef4SEddie Cai 143678884ef4SEddie Cai buf = gBuf; 143778884ef4SEddie Cai size = fixSize; 143878884ef4SEddie Cai while(1) { 143978884ef4SEddie Cai P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 144078884ef4SEddie Cai buf += SMALL_PACKET; 144178884ef4SEddie Cai if (fixSize <= SMALL_PACKET) 144278884ef4SEddie Cai break; 144378884ef4SEddie Cai fixSize -= SMALL_PACKET; 144478884ef4SEddie Cai } 144578884ef4SEddie Cai } else { 144678884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 144778884ef4SEddie Cai tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 144878884ef4SEddie Cai size +=tmp; 144978884ef4SEddie Cai P_RC4(gBuf, size); 145078884ef4SEddie Cai } 145178884ef4SEddie Cai 145278884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 145378884ef4SEddie Cai goto end; 145478884ef4SEddie Cai ret = true; 145578884ef4SEddie Cai end: 145678884ef4SEddie Cai if (inFile) 145778884ef4SEddie Cai fclose(inFile); 145878884ef4SEddie Cai if (!ret) 145932268622SAndreas Färber printf("writing entry (%s) failed\n", path); 146078884ef4SEddie Cai return ret; 146178884ef4SEddie Cai } 146278884ef4SEddie Cai 146378884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 146478884ef4SEddie Cai uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 146578884ef4SEddie Cai uint32_t size; 146678884ef4SEddie Cai rk_boot_entry entry; 146778884ef4SEddie Cai 146832268622SAndreas Färber printf("writing: %s\n", path); 1469641cfa16SEddie Cai memset(&entry, 0, sizeof(rk_boot_entry)); 147078884ef4SEddie Cai getName(fixName ? fixName: path, entry.name); 147178884ef4SEddie Cai entry.size = sizeof(rk_boot_entry); 147278884ef4SEddie Cai entry.type = type; 147378884ef4SEddie Cai entry.dataOffset = *offset; 147478884ef4SEddie Cai if (!getFileSize(path, &size)) { 147532268622SAndreas Färber printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path); 147678884ef4SEddie Cai return false; 147778884ef4SEddie Cai } 147878884ef4SEddie Cai if (fix) 147978884ef4SEddie Cai size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 148078884ef4SEddie Cai uint32_t tmp = size % ENTRY_ALIGN; 148178884ef4SEddie Cai size += tmp ? (ENTRY_ALIGN - tmp): 0; 148232268622SAndreas Färber printf("alignment size: %d\n", size); 148378884ef4SEddie Cai entry.dataSize = size; 148478884ef4SEddie Cai entry.dataDelay = delay; 148578884ef4SEddie Cai *offset += size; 148678884ef4SEddie Cai fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 148778884ef4SEddie Cai return true; 148878884ef4SEddie Cai } 148978884ef4SEddie Cai 149078884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) { 149178884ef4SEddie Cai char buffer[5]; 149278884ef4SEddie Cai memset(buffer, 0, sizeof(buffer)); 1493*8ca2bcc6SDan Horák memccpy(buffer, chip, '\0', sizeof(buffer)); 149478884ef4SEddie Cai return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 149578884ef4SEddie Cai } 149678884ef4SEddie Cai 149778884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) { 149878884ef4SEddie Cai printf("chip: %s\n", chip); 149978884ef4SEddie Cai int chipType = RKNONE_DEVICE; 150078884ef4SEddie Cai if(!chip) { 150178884ef4SEddie Cai goto end; 150278884ef4SEddie Cai } 150378884ef4SEddie Cai if (!strcmp(chip, CHIP_RK28)) { 150478884ef4SEddie Cai chipType = RK28_DEVICE; 150578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK28)) { 150678884ef4SEddie Cai chipType = RK28_DEVICE; 150778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK281X)) { 150878884ef4SEddie Cai chipType = RK281X_DEVICE; 150978884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKPANDA)) { 151078884ef4SEddie Cai chipType = RKPANDA_DEVICE; 151178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK27)) { 151278884ef4SEddie Cai chipType = RK27_DEVICE; 151378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKNANO)) { 151478884ef4SEddie Cai chipType = RKNANO_DEVICE; 151578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKSMART)) { 151678884ef4SEddie Cai chipType = RKSMART_DEVICE; 151778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCROWN)) { 151878884ef4SEddie Cai chipType = RKCROWN_DEVICE; 151978884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 152078884ef4SEddie Cai chipType = RKCAYMAN_DEVICE; 152178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK29)) { 152278884ef4SEddie Cai chipType = RK29_DEVICE; 152378884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK292X)) { 152478884ef4SEddie Cai chipType = RK292X_DEVICE; 152578884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30)) { 152678884ef4SEddie Cai chipType = RK30_DEVICE; 152778884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK30B)) { 152878884ef4SEddie Cai chipType = RK30B_DEVICE; 152978884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK31)) { 153078884ef4SEddie Cai chipType = RK31_DEVICE; 153178884ef4SEddie Cai } else if (!strcmp(chip, CHIP_RK32)) { 153278884ef4SEddie Cai chipType = RK32_DEVICE; 153378884ef4SEddie Cai } else { 153478884ef4SEddie Cai chipType = convertChipType(chip + 2); 153578884ef4SEddie Cai } 153678884ef4SEddie Cai 153778884ef4SEddie Cai end: 153878884ef4SEddie Cai printf("type: 0x%x\n", chipType); 153978884ef4SEddie Cai if (chipType == RKNONE_DEVICE) { 154032268622SAndreas Färber printf("chip type not supported!\n"); 154178884ef4SEddie Cai } 154278884ef4SEddie Cai return chipType; 154378884ef4SEddie Cai } 154478884ef4SEddie Cai 154578884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) { 154678884ef4SEddie Cai memset(hdr, 0, sizeof(rk_boot_header)); 154778884ef4SEddie Cai hdr->tag = TAG; 154878884ef4SEddie Cai hdr->size = sizeof(rk_boot_header); 154978884ef4SEddie Cai hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 155078884ef4SEddie Cai hdr->mergerVersion = MERGER_VERSION; 155178884ef4SEddie Cai hdr->releaseTime = getTime(); 155278884ef4SEddie Cai hdr->chipType = getChipType(gOpts.chip); 155378884ef4SEddie Cai 155478884ef4SEddie Cai hdr->code471Num = gOpts.code471Num; 155578884ef4SEddie Cai hdr->code471Offset = sizeof(rk_boot_header); 155678884ef4SEddie Cai hdr->code471Size = sizeof(rk_boot_entry); 155778884ef4SEddie Cai 155878884ef4SEddie Cai hdr->code472Num = gOpts.code472Num; 155978884ef4SEddie Cai hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 156078884ef4SEddie Cai hdr->code472Size = sizeof(rk_boot_entry); 156178884ef4SEddie Cai 156278884ef4SEddie Cai hdr->loaderNum = gOpts.loaderNum; 156378884ef4SEddie Cai hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 156478884ef4SEddie Cai hdr->loaderSize = sizeof(rk_boot_entry); 156578884ef4SEddie Cai #ifndef USE_P_RC4 156678884ef4SEddie Cai hdr->rc4Flag = 1; 156778884ef4SEddie Cai #endif 156878884ef4SEddie Cai } 156978884ef4SEddie Cai 157078884ef4SEddie Cai static inline uint32_t getCrc(const char* path) { 157178884ef4SEddie Cai uint32_t size = 0; 157278884ef4SEddie Cai uint32_t crc = 0; 157378884ef4SEddie Cai 157478884ef4SEddie Cai FILE* file = fopen(path, "rb"); 157578884ef4SEddie Cai getFileSize(path, &size); 157678884ef4SEddie Cai if (!file) 157778884ef4SEddie Cai goto end; 157878884ef4SEddie Cai if (!fread(gBuf, size, 1, file)) 157978884ef4SEddie Cai goto end; 158078884ef4SEddie Cai crc = CRC_32(gBuf, size); 158178884ef4SEddie Cai printf("crc: 0x%08x\n", crc); 158278884ef4SEddie Cai end: 158378884ef4SEddie Cai if (file) 158478884ef4SEddie Cai fclose(file); 158578884ef4SEddie Cai return crc; 158678884ef4SEddie Cai } 158778884ef4SEddie Cai 158878884ef4SEddie Cai bool mergeBoot(void) { 158978884ef4SEddie Cai uint32_t dataOffset; 159078884ef4SEddie Cai bool ret = false; 159178884ef4SEddie Cai int i; 159278884ef4SEddie Cai FILE* outFile; 159378884ef4SEddie Cai uint32_t crc; 159478884ef4SEddie Cai rk_boot_header hdr; 159578884ef4SEddie Cai 159678884ef4SEddie Cai if (!initOpts()) 159778884ef4SEddie Cai return false; 159878884ef4SEddie Cai { 159978884ef4SEddie Cai char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 160078884ef4SEddie Cai char version[MAX_LINE_LEN]; 160178884ef4SEddie Cai snprintf(version, sizeof(version), "%s", gSubfix); 160278884ef4SEddie Cai if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 160378884ef4SEddie Cai subfix[0] = '\0'; 160478884ef4SEddie Cai } 160578884ef4SEddie Cai strcat(gOpts.outPath, version); 160678884ef4SEddie Cai printf("fix opt: %s\n", gOpts.outPath); 160778884ef4SEddie Cai } 160878884ef4SEddie Cai 160978884ef4SEddie Cai printf("---------------\nUSING CONFIG:\n"); 161078884ef4SEddie Cai printOpts(stdout); 161178884ef4SEddie Cai printf("---------------\n\n"); 161278884ef4SEddie Cai 161378884ef4SEddie Cai 161478884ef4SEddie Cai outFile = fopen(gOpts.outPath, "wb+"); 161578884ef4SEddie Cai if (!outFile) { 161632268622SAndreas Färber printf("Opening output file (%s) failed\n", gOpts.outPath); 161778884ef4SEddie Cai goto end; 161878884ef4SEddie Cai } 161978884ef4SEddie Cai 162078884ef4SEddie Cai getBoothdr(&hdr); 162132268622SAndreas Färber printf("Writing header...\n"); 162278884ef4SEddie Cai fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 162378884ef4SEddie Cai 162478884ef4SEddie Cai dataOffset = sizeof(rk_boot_header) + 162578884ef4SEddie Cai (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 162678884ef4SEddie Cai sizeof(rk_boot_entry); 162778884ef4SEddie Cai 162832268622SAndreas Färber printf("Writing code 471 entry...\n"); 162978884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 163078884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 163178884ef4SEddie Cai &dataOffset, NULL, false)) 163278884ef4SEddie Cai goto end; 163378884ef4SEddie Cai } 163432268622SAndreas Färber printf("Writing code 472 entry...\n"); 163578884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 163678884ef4SEddie Cai if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 163778884ef4SEddie Cai &dataOffset, NULL, false)) 163878884ef4SEddie Cai goto end; 163978884ef4SEddie Cai } 164032268622SAndreas Färber printf("Writing loader entry...\n"); 164178884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 164278884ef4SEddie Cai if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 164378884ef4SEddie Cai &dataOffset, gOpts.loader[i].name, true)) 164478884ef4SEddie Cai goto end; 164578884ef4SEddie Cai } 164678884ef4SEddie Cai 164732268622SAndreas Färber printf("Writing code 471...\n"); 164878884ef4SEddie Cai for (i=0; i<gOpts.code471Num; i++) { 164978884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 165078884ef4SEddie Cai goto end; 165178884ef4SEddie Cai } 165232268622SAndreas Färber printf("Writing code 472...\n"); 165378884ef4SEddie Cai for (i=0; i<gOpts.code472Num; i++) { 165478884ef4SEddie Cai if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 165578884ef4SEddie Cai goto end; 165678884ef4SEddie Cai } 165732268622SAndreas Färber printf("Writing loader...\n"); 165878884ef4SEddie Cai for (i=0; i<gOpts.loaderNum; i++) { 165978884ef4SEddie Cai if (!writeFile(outFile, gOpts.loader[i].path, true)) 166078884ef4SEddie Cai goto end; 166178884ef4SEddie Cai } 166278884ef4SEddie Cai fflush(outFile); 166378884ef4SEddie Cai 166432268622SAndreas Färber printf("Writing crc...\n"); 166578884ef4SEddie Cai crc = getCrc(gOpts.outPath); 166678884ef4SEddie Cai if (!fwrite(&crc, sizeof(crc), 1, outFile)) 166778884ef4SEddie Cai goto end; 166832268622SAndreas Färber printf("Done.\n"); 166978884ef4SEddie Cai ret = true; 167078884ef4SEddie Cai end: 167178884ef4SEddie Cai if (outFile) 167278884ef4SEddie Cai fclose(outFile); 167378884ef4SEddie Cai return ret; 167478884ef4SEddie Cai } 167578884ef4SEddie Cai 167678884ef4SEddie Cai /************merge code end************/ 167778884ef4SEddie Cai /************unpack code***************/ 167878884ef4SEddie Cai 167978884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len) 168078884ef4SEddie Cai { 168178884ef4SEddie Cai int i; 168278884ef4SEddie Cai for (i = 0; i < len; i++) { 168378884ef4SEddie Cai str[i] = (char) (wide[i] & 0xFF); 168478884ef4SEddie Cai } 168578884ef4SEddie Cai } 168678884ef4SEddie Cai 168778884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name, 168878884ef4SEddie Cai FILE* inFile) { 168978884ef4SEddie Cai bool ret = false; 169078884ef4SEddie Cai int size, i; 169178884ef4SEddie Cai FILE* outFile = fopen(name, "wb+"); 169278884ef4SEddie Cai if (!outFile) 169378884ef4SEddie Cai goto end; 169432268622SAndreas Färber printf("unpacking entry (%s)\n", name); 169578884ef4SEddie Cai fseek(inFile, entry->dataOffset, SEEK_SET); 169678884ef4SEddie Cai size = entry->dataSize; 169778884ef4SEddie Cai if (!fread(gBuf, size, 1, inFile)) 169878884ef4SEddie Cai goto end; 169978884ef4SEddie Cai if (entry->type == ENTRY_LOADER) { 170078884ef4SEddie Cai for(i=0; i<size/SMALL_PACKET; i++) 170178884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 170278884ef4SEddie Cai if (size % SMALL_PACKET) 170378884ef4SEddie Cai { 170478884ef4SEddie Cai P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 170578884ef4SEddie Cai } 170678884ef4SEddie Cai } else { 170778884ef4SEddie Cai P_RC4(gBuf, size); 170878884ef4SEddie Cai } 170978884ef4SEddie Cai if (!fwrite(gBuf, size, 1, outFile)) 171078884ef4SEddie Cai goto end; 171178884ef4SEddie Cai ret = true; 171278884ef4SEddie Cai end: 171378884ef4SEddie Cai if (outFile) 171478884ef4SEddie Cai fclose(outFile); 171578884ef4SEddie Cai return ret; 171678884ef4SEddie Cai } 171778884ef4SEddie Cai 171878884ef4SEddie Cai bool unpackBoot(char* path) { 171978884ef4SEddie Cai bool ret = false; 172078884ef4SEddie Cai FILE* inFile = fopen(path, "rb"); 172178884ef4SEddie Cai int entryNum, i; 172278884ef4SEddie Cai char name[MAX_NAME_LEN]; 172378884ef4SEddie Cai rk_boot_entry* entrys; 172478884ef4SEddie Cai if (!inFile) { 172578884ef4SEddie Cai fprintf(stderr, "loader (%s) not found\n", path); 172678884ef4SEddie Cai goto end; 172778884ef4SEddie Cai } 172878884ef4SEddie Cai 172978884ef4SEddie Cai rk_boot_header hdr; 173078884ef4SEddie Cai if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 173132268622SAndreas Färber fprintf(stderr, "reading header failed\n"); 173278884ef4SEddie Cai goto end; 173378884ef4SEddie Cai } 173478884ef4SEddie Cai printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 173578884ef4SEddie Cai entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 173678884ef4SEddie Cai entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 173778884ef4SEddie Cai if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 173832268622SAndreas Färber fprintf(stderr, "reading data failed\n"); 173978884ef4SEddie Cai goto end; 174078884ef4SEddie Cai } 174178884ef4SEddie Cai 174278884ef4SEddie Cai printf("entry num: %d\n", entryNum); 174378884ef4SEddie Cai for (i=0; i<entryNum; i++) { 174478884ef4SEddie Cai wide2str(entrys[i].name, name, MAX_NAME_LEN); 174578884ef4SEddie Cai 174678884ef4SEddie Cai printf("entry: t=%d, name=%s, off=%d, size=%d\n", 174778884ef4SEddie Cai entrys[i].type, name, entrys[i].dataOffset, 174878884ef4SEddie Cai entrys[i].dataSize); 174978884ef4SEddie Cai if (!unpackEntry(entrys + i, name, inFile)) { 175032268622SAndreas Färber fprintf(stderr, "unpacking entry (%s) failed\n", name); 175178884ef4SEddie Cai goto end; 175278884ef4SEddie Cai } 175378884ef4SEddie Cai } 175478884ef4SEddie Cai printf("done\n"); 175578884ef4SEddie Cai ret = true; 175678884ef4SEddie Cai end: 175778884ef4SEddie Cai if (inFile) 175878884ef4SEddie Cai fclose(inFile); 175978884ef4SEddie Cai return ret; 176078884ef4SEddie Cai } 176178884ef4SEddie Cai 176276af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 176376af099aSliuyi { 176476af099aSliuyi if (!check_device_type(dev, RKUSB_MASKROM)) 176576af099aSliuyi return false; 176676af099aSliuyi CRKImage *pImage = NULL; 176776af099aSliuyi CRKBoot *pBoot = NULL; 176876af099aSliuyi bool bRet, bSuccess = false; 176976af099aSliuyi int iRet; 177076af099aSliuyi 177176af099aSliuyi pImage = new CRKImage(szLoader, bRet); 177276af099aSliuyi if (!bRet){ 177376af099aSliuyi ERROR_COLOR_ATTR; 177432268622SAndreas Färber printf("Opening loader failed, exiting download boot!"); 177576af099aSliuyi NORMAL_COLOR_ATTR; 177676af099aSliuyi printf("\r\n"); 177776af099aSliuyi return bSuccess; 177876af099aSliuyi } else { 177976af099aSliuyi pBoot = (CRKBoot *)pImage->m_bootObject; 178076af099aSliuyi CRKComm *pComm = NULL; 178176af099aSliuyi CRKDevice *pDevice = NULL; 178276af099aSliuyi 178376af099aSliuyi dev.emDeviceType = pBoot->SupportDevice; 178476af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 178576af099aSliuyi if (!bRet) { 178676af099aSliuyi if (pImage) 178776af099aSliuyi delete pImage; 178876af099aSliuyi ERROR_COLOR_ATTR; 178976af099aSliuyi printf("Creating Comm Object failed!"); 179076af099aSliuyi NORMAL_COLOR_ATTR; 179176af099aSliuyi printf("\r\n"); 179276af099aSliuyi return bSuccess; 179376af099aSliuyi } 179476af099aSliuyi 179576af099aSliuyi pDevice = new CRKDevice(dev); 179676af099aSliuyi if (!pDevice) { 179776af099aSliuyi if (pImage) 179876af099aSliuyi delete pImage; 179976af099aSliuyi if (pComm) 180076af099aSliuyi delete pComm; 180176af099aSliuyi ERROR_COLOR_ATTR; 180276af099aSliuyi printf("Creating device object failed!"); 180376af099aSliuyi NORMAL_COLOR_ATTR; 180476af099aSliuyi printf("\r\n"); 180576af099aSliuyi return bSuccess; 180676af099aSliuyi } 180776af099aSliuyi 180876af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 180932268622SAndreas Färber printf("Downloading bootloader...\r\n"); 181076af099aSliuyi iRet = pDevice->DownloadBoot(); 181176af099aSliuyi 181276af099aSliuyi CURSOR_MOVEUP_LINE(1); 181376af099aSliuyi CURSOR_DEL_LINE; 181476af099aSliuyi if (iRet == 0) { 181576af099aSliuyi bSuccess = true; 181632268622SAndreas Färber printf("Downloading bootloader succeeded.\r\n"); 181776af099aSliuyi } 181876af099aSliuyi else 181932268622SAndreas Färber printf("Downloading bootloader failed!\r\n"); 182076af099aSliuyi 182176af099aSliuyi if (pImage) 182276af099aSliuyi delete pImage; 182376af099aSliuyi if(pDevice) 182476af099aSliuyi delete pDevice; 182576af099aSliuyi } 182676af099aSliuyi return bSuccess; 182776af099aSliuyi } 1828c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1829c30d921cSKever Yang { 1830c30d921cSKever Yang if (!check_device_type(dev, RKUSB_MASKROM)) 1831c30d921cSKever Yang return false; 1832c30d921cSKever Yang CRKImage *pImage = NULL; 1833c30d921cSKever Yang CRKBoot *pBoot = NULL; 1834c30d921cSKever Yang CRKComm *pComm = NULL; 183546bb4c07Sliuyi bool bRet,bNewIDBlock=false, bSuccess = false; 1836c30d921cSKever Yang int iRet; 183746bb4c07Sliuyi unsigned int i; 1838aca206f7SPeter Robinson signed char index; 183946bb4c07Sliuyi USHORT usFlashDataSec, usFlashBootSec, usFlashHeadSec; 184046bb4c07Sliuyi DWORD dwLoaderSize, dwLoaderDataSize, dwLoaderHeadSize, dwDelay, dwSectorNum; 1841c30d921cSKever Yang char loaderCodeName[] = "FlashBoot"; 1842c30d921cSKever Yang char loaderDataName[] = "FlashData"; 184346bb4c07Sliuyi char loaderHeadName[] = "FlashHead"; 1844c30d921cSKever Yang PBYTE loaderCodeBuffer = NULL; 1845c30d921cSKever Yang PBYTE loaderDataBuffer = NULL; 184646bb4c07Sliuyi PBYTE loaderHeadBuffer = NULL; 1847c30d921cSKever Yang PBYTE pIDBData = NULL; 184846bb4c07Sliuyi BYTE capability[8]; 1849c30d921cSKever Yang pImage = new CRKImage(szLoader, bRet); 1850c30d921cSKever Yang if (!bRet){ 1851c30d921cSKever Yang ERROR_COLOR_ATTR; 185232268622SAndreas Färber printf("Opening loader failed, exiting upgrade loader!"); 1853c30d921cSKever Yang NORMAL_COLOR_ATTR; 1854c30d921cSKever Yang printf("\r\n"); 1855c30d921cSKever Yang goto Exit_UpgradeLoader; 1856c30d921cSKever Yang } else { 1857c30d921cSKever Yang pBoot = (CRKBoot *)pImage->m_bootObject; 1858c30d921cSKever Yang dev.emDeviceType = pBoot->SupportDevice; 1859c30d921cSKever Yang pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1860c30d921cSKever Yang if (!bRet) { 1861c30d921cSKever Yang ERROR_COLOR_ATTR; 1862c30d921cSKever Yang printf("Creating Comm Object failed!"); 1863c30d921cSKever Yang NORMAL_COLOR_ATTR; 1864c30d921cSKever Yang printf("\r\n"); 1865c30d921cSKever Yang goto Exit_UpgradeLoader; 1866c30d921cSKever Yang } 1867c30d921cSKever Yang 186832268622SAndreas Färber printf("Upgrading loader...\r\n"); 1869c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1870c30d921cSKever Yang if (index == -1) { 1871c30d921cSKever Yang if (g_pLogObject) { 187232268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__); 1873c30d921cSKever Yang } 1874c30d921cSKever Yang goto Exit_UpgradeLoader; 1875c30d921cSKever Yang } 1876c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1877c30d921cSKever Yang if (!bRet) { 1878c30d921cSKever Yang if (g_pLogObject) { 187932268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__); 1880c30d921cSKever Yang } 1881c30d921cSKever Yang goto Exit_UpgradeLoader; 1882c30d921cSKever Yang } 1883c30d921cSKever Yang 1884c30d921cSKever Yang loaderCodeBuffer = new BYTE[dwLoaderSize]; 1885c30d921cSKever Yang memset(loaderCodeBuffer, 0, dwLoaderSize); 1886c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1887c30d921cSKever Yang if (g_pLogObject) { 188832268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__); 1889c30d921cSKever Yang } 1890c30d921cSKever Yang goto Exit_UpgradeLoader; 1891c30d921cSKever Yang } 1892c30d921cSKever Yang 1893c30d921cSKever Yang index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1894c30d921cSKever Yang if (index == -1) { 1895c30d921cSKever Yang if (g_pLogObject) { 189632268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__); 1897c30d921cSKever Yang } 1898c30d921cSKever Yang delete []loaderCodeBuffer; 1899c30d921cSKever Yang return -4; 1900c30d921cSKever Yang } 1901c30d921cSKever Yang 1902c30d921cSKever Yang bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1903c30d921cSKever Yang if (!bRet) { 1904c30d921cSKever Yang if (g_pLogObject) { 190532268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__); 1906c30d921cSKever Yang } 1907c30d921cSKever Yang goto Exit_UpgradeLoader; 1908c30d921cSKever Yang } 1909c30d921cSKever Yang 1910c30d921cSKever Yang loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1911c30d921cSKever Yang memset(loaderDataBuffer, 0, dwLoaderDataSize); 1912c30d921cSKever Yang if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1913c30d921cSKever Yang if (g_pLogObject) { 191432268622SAndreas Färber g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__); 1915c30d921cSKever Yang } 1916c30d921cSKever Yang goto Exit_UpgradeLoader; 1917c30d921cSKever Yang } 1918c30d921cSKever Yang 191946bb4c07Sliuyi index = pBoot->GetIndexByName(ENTRYLOADER, loaderHeadName); 192046bb4c07Sliuyi if (index != -1) { 192146bb4c07Sliuyi bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderHeadSize, dwDelay); 192246bb4c07Sliuyi if (!bRet) { 192346bb4c07Sliuyi if (g_pLogObject) { 192446bb4c07Sliuyi g_pLogObject->Record("ERROR: %s --> Get LoaderHead Entry Size failed", __func__); 192546bb4c07Sliuyi } 192646bb4c07Sliuyi goto Exit_UpgradeLoader; 192746bb4c07Sliuyi } 192846bb4c07Sliuyi 192946bb4c07Sliuyi loaderHeadBuffer= new BYTE[dwLoaderHeadSize]; 193046bb4c07Sliuyi memset(loaderHeadBuffer, 0, dwLoaderHeadSize); 193146bb4c07Sliuyi if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderHeadBuffer)) { 193246bb4c07Sliuyi if (g_pLogObject) { 193346bb4c07Sliuyi g_pLogObject->Record("ERROR: %s --> Get LoaderHead Data failed", __func__); 193446bb4c07Sliuyi } 193546bb4c07Sliuyi goto Exit_UpgradeLoader; 193646bb4c07Sliuyi } 193746bb4c07Sliuyi 193846bb4c07Sliuyi iRet = pComm->RKU_ReadCapability(capability); 193946bb4c07Sliuyi if (iRet != ERR_SUCCESS) 194046bb4c07Sliuyi { 194146bb4c07Sliuyi if (g_pLogObject) 194246bb4c07Sliuyi g_pLogObject->Record("ERROR: %s --> read capability failed", __func__); 194346bb4c07Sliuyi goto Exit_UpgradeLoader; 194446bb4c07Sliuyi } 194546bb4c07Sliuyi if ((capability[1] & 1) == 0) { 194646bb4c07Sliuyi if (g_pLogObject) 194746bb4c07Sliuyi g_pLogObject->Record("ERROR: %s --> device did not support to upgrade the loader", __func__); 194846bb4c07Sliuyi ERROR_COLOR_ATTR; 194946bb4c07Sliuyi printf("Device not support to upgrade the loader!"); 195046bb4c07Sliuyi NORMAL_COLOR_ATTR; 195146bb4c07Sliuyi printf("\r\n"); 195246bb4c07Sliuyi goto Exit_UpgradeLoader; 195346bb4c07Sliuyi } 195446bb4c07Sliuyi bNewIDBlock = true; 195546bb4c07Sliuyi } 195646bb4c07Sliuyi 1957c30d921cSKever Yang usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1958c30d921cSKever Yang usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 195946bb4c07Sliuyi if (bNewIDBlock) { 196046bb4c07Sliuyi usFlashHeadSec = (ALIGN(dwLoaderHeadSize, 2048)) / SECTOR_SIZE; 196146bb4c07Sliuyi dwSectorNum = usFlashHeadSec + usFlashDataSec + usFlashBootSec; 196246bb4c07Sliuyi } else 1963c30d921cSKever Yang dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1964c30d921cSKever Yang pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1965c30d921cSKever Yang if (!pIDBData) { 1966c30d921cSKever Yang ERROR_COLOR_ATTR; 196732268622SAndreas Färber printf("Allocating memory failed!"); 1968c30d921cSKever Yang NORMAL_COLOR_ATTR; 1969c30d921cSKever Yang printf("\r\n"); 1970c30d921cSKever Yang goto Exit_UpgradeLoader; 1971c30d921cSKever Yang } 1972c30d921cSKever Yang memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 197346bb4c07Sliuyi if (bNewIDBlock) { 197446bb4c07Sliuyi if (pBoot->Rc4DisableFlag) 197546bb4c07Sliuyi {//close rc4 encryption 197646bb4c07Sliuyi for (i=0;i<dwLoaderHeadSize/SECTOR_SIZE;i++) 197746bb4c07Sliuyi { 197846bb4c07Sliuyi P_RC4(loaderHeadBuffer+SECTOR_SIZE*i,SECTOR_SIZE); 197946bb4c07Sliuyi } 198046bb4c07Sliuyi for (i=0;i<dwLoaderDataSize/SECTOR_SIZE;i++) 198146bb4c07Sliuyi { 198246bb4c07Sliuyi P_RC4(loaderDataBuffer+SECTOR_SIZE*i,SECTOR_SIZE); 198346bb4c07Sliuyi } 198446bb4c07Sliuyi for (i=0;i<dwLoaderSize/SECTOR_SIZE;i++) 198546bb4c07Sliuyi { 198646bb4c07Sliuyi P_RC4(loaderCodeBuffer+SECTOR_SIZE*i,SECTOR_SIZE); 198746bb4c07Sliuyi } 198846bb4c07Sliuyi } 198946bb4c07Sliuyi memcpy(pIDBData, loaderHeadBuffer, dwLoaderHeadSize); 199046bb4c07Sliuyi memcpy(pIDBData+SECTOR_SIZE*usFlashHeadSec, loaderDataBuffer, dwLoaderDataSize); 199146bb4c07Sliuyi memcpy(pIDBData+SECTOR_SIZE*(usFlashHeadSec+usFlashDataSec), loaderCodeBuffer, dwLoaderSize); 199246bb4c07Sliuyi } else { 1993b38fe5fcSliuyi iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag); 1994c30d921cSKever Yang if (iRet != 0) { 1995c30d921cSKever Yang ERROR_COLOR_ATTR; 199632268622SAndreas Färber printf("Making idblock failed!"); 1997c30d921cSKever Yang NORMAL_COLOR_ATTR; 1998c30d921cSKever Yang printf("\r\n"); 1999c30d921cSKever Yang goto Exit_UpgradeLoader; 2000c30d921cSKever Yang } 200146bb4c07Sliuyi } 200246bb4c07Sliuyi 2003c30d921cSKever Yang iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 2004c30d921cSKever Yang CURSOR_MOVEUP_LINE(1); 2005c30d921cSKever Yang CURSOR_DEL_LINE; 2006c30d921cSKever Yang if (iRet == ERR_SUCCESS) { 2007b38fe5fcSliuyi //pComm->Reset_Usb_Device(); 2008c30d921cSKever Yang bSuccess = true; 200932268622SAndreas Färber printf("Upgrading loader succeeded.\r\n"); 2010c30d921cSKever Yang } else { 201132268622SAndreas Färber printf("Upgrading loader failed!\r\n"); 2012c30d921cSKever Yang goto Exit_UpgradeLoader; 2013c30d921cSKever Yang } 2014c30d921cSKever Yang } 2015c30d921cSKever Yang Exit_UpgradeLoader: 2016c30d921cSKever Yang if (pImage) 2017c30d921cSKever Yang delete pImage; 2018c30d921cSKever Yang if (pComm) 2019c30d921cSKever Yang delete pComm; 2020c30d921cSKever Yang if (loaderCodeBuffer) 2021c30d921cSKever Yang delete []loaderCodeBuffer; 2022c30d921cSKever Yang if (loaderDataBuffer) 2023c30d921cSKever Yang delete []loaderDataBuffer; 202446bb4c07Sliuyi if (loaderHeadBuffer) 202546bb4c07Sliuyi delete []loaderHeadBuffer; 2026c30d921cSKever Yang if (pIDBData) 2027c30d921cSKever Yang delete []pIDBData; 2028c30d921cSKever Yang return bSuccess; 2029c30d921cSKever Yang } 20303dc7e3ceSliuyi bool print_gpt(STRUCT_RKDEVICE_DESC &dev) 20313dc7e3ceSliuyi { 20323dc7e3ceSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 20333dc7e3ceSliuyi return false; 20343dc7e3ceSliuyi u8 master_gpt[34 * SECTOR_SIZE]; 20353dc7e3ceSliuyi gpt_header *gptHead = (gpt_header *)(master_gpt + SECTOR_SIZE); 20363dc7e3ceSliuyi bool bRet, bSuccess = false; 20373dc7e3ceSliuyi int iRet; 20383dc7e3ceSliuyi gpt_entry *gptEntry = NULL; 20393dc7e3ceSliuyi u32 i,j; 20403dc7e3ceSliuyi u8 zerobuf[GPT_ENTRY_SIZE]; 20413dc7e3ceSliuyi memset(zerobuf,0,GPT_ENTRY_SIZE); 20423dc7e3ceSliuyi CRKComm *pComm = NULL; 20433dc7e3ceSliuyi char partName[36]; 20443dc7e3ceSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 20453dc7e3ceSliuyi if (!bRet) { 20463dc7e3ceSliuyi ERROR_COLOR_ATTR; 20473dc7e3ceSliuyi printf("Creating Comm Object failed!"); 20483dc7e3ceSliuyi NORMAL_COLOR_ATTR; 20493dc7e3ceSliuyi printf("\r\n"); 20503dc7e3ceSliuyi return bSuccess; 20513dc7e3ceSliuyi } 20523dc7e3ceSliuyi iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt); 20533dc7e3ceSliuyi if(ERR_SUCCESS == iRet) { 20543dc7e3ceSliuyi if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 20553dc7e3ceSliuyi goto Exit_PrintGpt; 20563dc7e3ceSliuyi } 20573dc7e3ceSliuyi 20583dc7e3ceSliuyi } else { 20593dc7e3ceSliuyi if (g_pLogObject) 20603dc7e3ceSliuyi g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 20613dc7e3ceSliuyi printf("Read GPT failed!\r\n"); 20623dc7e3ceSliuyi goto Exit_PrintGpt; 20633dc7e3ceSliuyi } 20643dc7e3ceSliuyi 2065081d237aSliuyi printf("**********Partition Info(GPT)**********\r\n"); 20663dc7e3ceSliuyi printf("NO LBA Name \r\n"); 20673dc7e3ceSliuyi for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) { 20683dc7e3ceSliuyi gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 20693dc7e3ceSliuyi if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0) 20703dc7e3ceSliuyi break; 20713dc7e3ceSliuyi memset(partName, 0 , 36); 20723dc7e3ceSliuyi j = 0; 20733dc7e3ceSliuyi while (gptEntry->partition_name[j]) { 20743dc7e3ceSliuyi partName[j] = (char)gptEntry->partition_name[j]; 20753dc7e3ceSliuyi j++; 20763dc7e3ceSliuyi } 20773dc7e3ceSliuyi printf("%02d %08X %s\r\n", i, (u32)le64_to_cpu(gptEntry->starting_lba), partName); 20783dc7e3ceSliuyi } 20793dc7e3ceSliuyi bSuccess = true; 20803dc7e3ceSliuyi Exit_PrintGpt: 20813dc7e3ceSliuyi if (pComm) 20823dc7e3ceSliuyi delete pComm; 20833dc7e3ceSliuyi return bSuccess; 20843dc7e3ceSliuyi } 2085081d237aSliuyi bool print_parameter(STRUCT_RKDEVICE_DESC &dev) 2086081d237aSliuyi { 2087081d237aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2088081d237aSliuyi return false; 2089081d237aSliuyi u8 param_buf[512 * SECTOR_SIZE]; 2090081d237aSliuyi bool bRet, bSuccess = false; 2091081d237aSliuyi int iRet; 2092081d237aSliuyi u32 i, nParamSize; 2093081d237aSliuyi CRKComm *pComm = NULL; 2094081d237aSliuyi PARAM_ITEM_VECTOR vecParamItem; 2095081d237aSliuyi CONFIG_ITEM_VECTOR vecUuidItem; 2096081d237aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2097081d237aSliuyi if (!bRet) { 2098081d237aSliuyi ERROR_COLOR_ATTR; 2099081d237aSliuyi printf("Creating Comm Object failed!"); 2100081d237aSliuyi NORMAL_COLOR_ATTR; 2101081d237aSliuyi printf("\r\n"); 2102081d237aSliuyi return bSuccess; 2103081d237aSliuyi } 2104081d237aSliuyi iRet = pComm->RKU_ReadLBA( 0x2000, 512, param_buf); 2105081d237aSliuyi if(ERR_SUCCESS == iRet) { 2106081d237aSliuyi if (*(u32 *)param_buf != 0x4D524150) { 2107081d237aSliuyi goto Exit_PrintParam; 2108081d237aSliuyi } 2109081d237aSliuyi 2110081d237aSliuyi } else { 2111081d237aSliuyi if (g_pLogObject) 2112081d237aSliuyi g_pLogObject->Record("Error: read parameter failed, err=%d", iRet); 2113081d237aSliuyi printf("Read parameter failed!\r\n"); 2114081d237aSliuyi goto Exit_PrintParam; 2115081d237aSliuyi } 2116081d237aSliuyi nParamSize = *(u32 *)(param_buf + 4); 2117081d237aSliuyi memset(param_buf+8+nParamSize, 0, 512*SECTOR_SIZE - nParamSize - 8); 2118081d237aSliuyi 2119081d237aSliuyi bRet = parse_parameter((char *)(param_buf+8), vecParamItem, vecUuidItem); 2120081d237aSliuyi if (!bRet) { 2121081d237aSliuyi if (g_pLogObject) 2122081d237aSliuyi g_pLogObject->Record("Error: parse parameter failed"); 2123081d237aSliuyi printf("Parse parameter failed!\r\n"); 2124081d237aSliuyi goto Exit_PrintParam; 2125081d237aSliuyi } 2126081d237aSliuyi printf("**********Partition Info(parameter)**********\r\n"); 2127081d237aSliuyi printf("NO LBA Name \r\n"); 2128081d237aSliuyi for (i = 0; i < vecParamItem.size(); i++) { 2129081d237aSliuyi printf("%02d %08X %s\r\n", i, vecParamItem[i].uiItemOffset, vecParamItem[i].szItemName); 2130081d237aSliuyi } 2131081d237aSliuyi bSuccess = true; 2132081d237aSliuyi Exit_PrintParam: 2133081d237aSliuyi if (pComm) 2134081d237aSliuyi delete pComm; 2135081d237aSliuyi return bSuccess; 2136081d237aSliuyi } 2137c30d921cSKever Yang 213876af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 213976af099aSliuyi { 214076af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 214176af099aSliuyi return false; 214276af099aSliuyi CRKImage *pImage = NULL; 214376af099aSliuyi bool bRet, bSuccess = false; 214476af099aSliuyi int iRet; 214576af099aSliuyi CRKScan *pScan = NULL; 214676af099aSliuyi pScan = new CRKScan(); 214776af099aSliuyi pScan->SetVidPid(); 214876af099aSliuyi 214976af099aSliuyi CRKComm *pComm = NULL; 215076af099aSliuyi CRKDevice *pDevice = NULL; 215176af099aSliuyi 215276af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 215376af099aSliuyi if (!bRet) { 215476af099aSliuyi if (pScan) 215576af099aSliuyi delete pScan; 215676af099aSliuyi ERROR_COLOR_ATTR; 215776af099aSliuyi printf("Creating Comm Object failed!"); 215876af099aSliuyi NORMAL_COLOR_ATTR; 215976af099aSliuyi printf("\r\n"); 216076af099aSliuyi return bSuccess; 216176af099aSliuyi } 216276af099aSliuyi 216376af099aSliuyi pDevice = new CRKDevice(dev); 216476af099aSliuyi if (!pDevice) { 216576af099aSliuyi if (pComm) 216676af099aSliuyi delete pComm; 216776af099aSliuyi if (pScan) 216876af099aSliuyi delete pScan; 216976af099aSliuyi ERROR_COLOR_ATTR; 217076af099aSliuyi printf("Creating device object failed!"); 217176af099aSliuyi NORMAL_COLOR_ATTR; 217276af099aSliuyi printf("\r\n"); 217376af099aSliuyi return bSuccess; 217476af099aSliuyi } 217576af099aSliuyi 217676af099aSliuyi pDevice->SetObject(pImage, pComm, g_pLogObject); 217776af099aSliuyi pDevice->CallBackPointer = ProgressInfoProc; 217876af099aSliuyi 217932268622SAndreas Färber printf("Starting to erase flash...\r\n"); 21806502326dSliuyi bRet = pDevice->GetFlashInfo(); 21816502326dSliuyi if (!bRet) { 21826502326dSliuyi if (pDevice) 21836502326dSliuyi delete pDevice; 21846502326dSliuyi if (pScan) 21856502326dSliuyi delete pScan; 21866502326dSliuyi ERROR_COLOR_ATTR; 21876502326dSliuyi printf("Getting flash info from device failed!"); 21886502326dSliuyi NORMAL_COLOR_ATTR; 21896502326dSliuyi printf("\r\n"); 21906502326dSliuyi return bSuccess; 21916502326dSliuyi } 219276af099aSliuyi iRet = pDevice->EraseAllBlocks(); 219376af099aSliuyi if (pDevice) 219476af099aSliuyi delete pDevice; 219576af099aSliuyi 219676af099aSliuyi if (iRet == 0) { 219776af099aSliuyi if (pScan) { 219876af099aSliuyi pScan->SetVidPid(); 219976af099aSliuyi pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 220076af099aSliuyi delete pScan; 220176af099aSliuyi } 220276af099aSliuyi CURSOR_MOVEUP_LINE(1); 220376af099aSliuyi CURSOR_DEL_LINE; 220476af099aSliuyi bSuccess = true; 220532268622SAndreas Färber printf("Erasing flash complete.\r\n"); 220676af099aSliuyi } 220776af099aSliuyi 220876af099aSliuyi return bSuccess; 220976af099aSliuyi } 221076af099aSliuyi 221176af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev) 221276af099aSliuyi { 221376af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 221476af099aSliuyi return false; 221576af099aSliuyi CRKUsbComm *pComm = NULL; 221676af099aSliuyi bool bRet, bSuccess = false; 221776af099aSliuyi int iRet; 221876af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 221976af099aSliuyi if (bRet) { 222076af099aSliuyi iRet = pComm->RKU_TestDeviceReady(); 222176af099aSliuyi if (iRet != ERR_SUCCESS) { 222276af099aSliuyi if (g_pLogObject) 222376af099aSliuyi g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 222432268622SAndreas Färber printf("Test Device failed!\r\n"); 222576af099aSliuyi } else { 222676af099aSliuyi bSuccess = true; 222776af099aSliuyi printf("Test Device OK.\r\n"); 222876af099aSliuyi } 222976af099aSliuyi } else { 223032268622SAndreas Färber printf("Test Device quit, creating comm object failed!\r\n"); 223176af099aSliuyi } 223276af099aSliuyi if (pComm) { 223376af099aSliuyi delete pComm; 223476af099aSliuyi pComm = NULL; 223576af099aSliuyi } 223676af099aSliuyi return bSuccess; 223776af099aSliuyi } 223876af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 223976af099aSliuyi { 224076af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 224176af099aSliuyi return false; 224276af099aSliuyi CRKUsbComm *pComm = NULL; 224376af099aSliuyi bool bRet, bSuccess = false; 224476af099aSliuyi int iRet; 224576af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 224676af099aSliuyi if (bRet) { 224776af099aSliuyi iRet = pComm->RKU_ResetDevice(subCode); 224876af099aSliuyi if (iRet != ERR_SUCCESS) { 224976af099aSliuyi if (g_pLogObject) 225076af099aSliuyi g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 225132268622SAndreas Färber printf("Reset Device failed!\r\n"); 225276af099aSliuyi } else { 225376af099aSliuyi bSuccess = true; 225476af099aSliuyi printf("Reset Device OK.\r\n"); 225576af099aSliuyi } 225676af099aSliuyi } else { 225732268622SAndreas Färber printf("Reset Device quit, creating comm object failed!\r\n"); 225876af099aSliuyi } 225976af099aSliuyi if (pComm) { 226076af099aSliuyi delete pComm; 226176af099aSliuyi pComm = NULL; 226276af099aSliuyi } 226376af099aSliuyi return bSuccess; 226476af099aSliuyi } 226576af099aSliuyi 226676af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 226776af099aSliuyi { 226876af099aSliuyi CRKUsbComm *pComm = NULL; 226976af099aSliuyi bool bRet, bSuccess = false; 227076af099aSliuyi int iRet; 227176af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 227276af099aSliuyi return bSuccess; 227376af099aSliuyi 227476af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 227576af099aSliuyi if (bRet) { 227676af099aSliuyi BYTE flashID[5]; 227776af099aSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 227876af099aSliuyi if (iRet != ERR_SUCCESS) { 227976af099aSliuyi if (g_pLogObject) 228076af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 228132268622SAndreas Färber printf("Reading flash ID failed!\r\n"); 228276af099aSliuyi } else { 228376af099aSliuyi printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 228476af099aSliuyi bSuccess = true; 228576af099aSliuyi } 228676af099aSliuyi } else { 228732268622SAndreas Färber printf("Read Flash ID quit, creating comm object failed!\r\n"); 228876af099aSliuyi } 228976af099aSliuyi if (pComm) { 229076af099aSliuyi delete pComm; 229176af099aSliuyi pComm = NULL; 229276af099aSliuyi } 229376af099aSliuyi return bSuccess; 229476af099aSliuyi } 229576af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 229676af099aSliuyi { 229776af099aSliuyi CRKUsbComm *pComm = NULL; 229876af099aSliuyi bool bRet, bSuccess = false; 229976af099aSliuyi int iRet; 230076af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 230176af099aSliuyi return bSuccess; 230276af099aSliuyi 230376af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 230476af099aSliuyi if (bRet) { 230576af099aSliuyi STRUCT_FLASHINFO_CMD info; 230676af099aSliuyi UINT uiRead; 230776af099aSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 230876af099aSliuyi if (iRet != ERR_SUCCESS) { 230976af099aSliuyi if (g_pLogObject) 231076af099aSliuyi g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 231132268622SAndreas Färber printf("Read Flash Info failed!\r\n"); 231276af099aSliuyi } else { 231376af099aSliuyi printf("Flash Info:\r\n"); 231476af099aSliuyi if (info.bManufCode <= 7) { 231576af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 231676af099aSliuyi } 231776af099aSliuyi else 231876af099aSliuyi printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 231976af099aSliuyi 232076af099aSliuyi printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 23210dcb0a4cSliuyi printf("\tFlash Size: %d Sectors\r\n", info.uiFlashSize); 232276af099aSliuyi printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 232376af099aSliuyi printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 232476af099aSliuyi printf("\tECC Bits: %d\r\n", info.bECCBits); 232576af099aSliuyi printf("\tAccess Time: %d\r\n", info.bAccessTime); 232676af099aSliuyi printf("\tFlash CS: "); 232776af099aSliuyi for(int i = 0; i < 8; i++) { 232876af099aSliuyi if( info.bFlashCS & (1 << i) ) 232976af099aSliuyi printf("Flash<%d> ", i); 233076af099aSliuyi } 233176af099aSliuyi printf("\r\n"); 233276af099aSliuyi bSuccess = true; 233376af099aSliuyi } 233476af099aSliuyi }else { 233532268622SAndreas Färber printf("Read Flash Info quit, creating comm object failed!\r\n"); 233676af099aSliuyi } 233776af099aSliuyi if (pComm) { 233876af099aSliuyi delete pComm; 233976af099aSliuyi pComm = NULL; 234076af099aSliuyi } 234176af099aSliuyi return bSuccess; 234276af099aSliuyi } 234376af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 234476af099aSliuyi { 234576af099aSliuyi CRKUsbComm *pComm = NULL; 234676af099aSliuyi bool bRet, bSuccess = false; 234776af099aSliuyi int iRet; 234876af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 234976af099aSliuyi return bSuccess; 235076af099aSliuyi 235176af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 235276af099aSliuyi if (bRet) { 235376af099aSliuyi BYTE chipInfo[16]; 235476af099aSliuyi iRet = pComm->RKU_ReadChipInfo(chipInfo); 235576af099aSliuyi if (iRet != ERR_SUCCESS) { 235676af099aSliuyi if (g_pLogObject) 235776af099aSliuyi g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 235832268622SAndreas Färber printf("Read Chip Info failed!\r\n"); 235976af099aSliuyi } else { 236076af099aSliuyi string strChipInfo; 236176af099aSliuyi g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 236276af099aSliuyi printf("Chip Info: %s\r\n", strChipInfo.c_str()); 236376af099aSliuyi bSuccess = true; 236476af099aSliuyi } 236576af099aSliuyi } else { 236632268622SAndreas Färber printf("Read Chip Info quit, creating comm object failed!\r\n"); 236776af099aSliuyi } 236876af099aSliuyi if (pComm) { 236976af099aSliuyi delete pComm; 237076af099aSliuyi pComm = NULL; 237176af099aSliuyi } 237276af099aSliuyi return bSuccess; 237376af099aSliuyi } 2374081d237aSliuyi bool read_capability(STRUCT_RKDEVICE_DESC &dev) 2375081d237aSliuyi { 2376081d237aSliuyi CRKUsbComm *pComm = NULL; 2377081d237aSliuyi bool bRet, bSuccess = false; 2378081d237aSliuyi int iRet; 2379081d237aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2380081d237aSliuyi return bSuccess; 2381081d237aSliuyi 2382081d237aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2383081d237aSliuyi if (bRet) { 2384081d237aSliuyi 2385081d237aSliuyi BYTE capability[8]; 2386081d237aSliuyi iRet = pComm->RKU_ReadCapability(capability); 2387081d237aSliuyi if (iRet != ERR_SUCCESS) 2388081d237aSliuyi { 2389081d237aSliuyi if (g_pLogObject) 2390081d237aSliuyi g_pLogObject->Record("Error:read_capability failed,err=%d", iRet); 2391081d237aSliuyi printf("Read capability Fail!\r\n"); 2392081d237aSliuyi } else { 2393081d237aSliuyi printf("Capability:%02X %02X %02X %02X %02X %02X %02X %02X \r\n", 2394081d237aSliuyi capability[0], capability[1], capability[2], capability[3], 2395081d237aSliuyi capability[4], capability[5], capability[6], capability[7]); 2396081d237aSliuyi if (capability[0] & 1) 2397081d237aSliuyi { 2398081d237aSliuyi printf("Direct LBA:\tenabled\r\n"); 2399081d237aSliuyi } 2400081d237aSliuyi 2401081d237aSliuyi if (capability[0] & 2) 2402081d237aSliuyi { 2403081d237aSliuyi printf("Vendor Storage:\tenabled\r\n"); 2404081d237aSliuyi } 2405081d237aSliuyi 2406081d237aSliuyi if (capability[0] & 4) 2407081d237aSliuyi { 2408081d237aSliuyi printf("First 4m Access:\tenabled\r\n"); 2409081d237aSliuyi } 241046bb4c07Sliuyi if (capability[0] & 8) 241146bb4c07Sliuyi { 241246bb4c07Sliuyi printf("Read LBA:\tenabled\r\n"); 241346bb4c07Sliuyi } 241446bb4c07Sliuyi 241546bb4c07Sliuyi if (capability[0] & 20) 241646bb4c07Sliuyi { 241746bb4c07Sliuyi printf("Read Com Log:\tenabled\r\n"); 241846bb4c07Sliuyi } 241946bb4c07Sliuyi 242046bb4c07Sliuyi if (capability[0] & 40) 242146bb4c07Sliuyi { 242246bb4c07Sliuyi printf("Read IDB Config:\tenabled\r\n"); 242346bb4c07Sliuyi } 242446bb4c07Sliuyi 242546bb4c07Sliuyi if (capability[0] & 80) 242646bb4c07Sliuyi { 242746bb4c07Sliuyi printf("Read Secure Mode:\tenabled\r\n"); 242846bb4c07Sliuyi } 242946bb4c07Sliuyi 243046bb4c07Sliuyi if (capability[1] & 1) 243146bb4c07Sliuyi { 243246bb4c07Sliuyi printf("New IDB:\tenabled\r\n"); 243346bb4c07Sliuyi } 2434081d237aSliuyi bSuccess = true; 2435081d237aSliuyi } 2436081d237aSliuyi } else { 2437081d237aSliuyi printf("Read capability quit, creating comm object failed!\r\n"); 2438081d237aSliuyi } 2439081d237aSliuyi if (pComm) { 2440081d237aSliuyi delete pComm; 2441081d237aSliuyi pComm = NULL; 2442081d237aSliuyi } 2443081d237aSliuyi return bSuccess; 2444081d237aSliuyi } 2445081d237aSliuyi bool read_param(STRUCT_RKDEVICE_DESC &dev, u8 *pParam) 2446081d237aSliuyi { 2447081d237aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2448081d237aSliuyi return false; 2449081d237aSliuyi CRKUsbComm *pComm = NULL; 2450081d237aSliuyi bool bRet, bSuccess = false; 2451081d237aSliuyi int iRet; 2452081d237aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2453081d237aSliuyi if (bRet) { 2454081d237aSliuyi iRet = pComm->RKU_ReadLBA( 0x2000, 512, pParam); 2455081d237aSliuyi if(ERR_SUCCESS == iRet) { 2456081d237aSliuyi if (*(u32 *)pParam != 0x4D524150) { 2457081d237aSliuyi goto Exit_ReadParam; 2458081d237aSliuyi } 2459081d237aSliuyi } else { 2460081d237aSliuyi if (g_pLogObject) 2461081d237aSliuyi g_pLogObject->Record("Error: read parameter failed, err=%d", iRet); 2462081d237aSliuyi printf("Read parameter failed!\r\n"); 2463081d237aSliuyi goto Exit_ReadParam; 2464081d237aSliuyi } 2465081d237aSliuyi bSuccess = true; 2466081d237aSliuyi } 2467081d237aSliuyi Exit_ReadParam: 2468081d237aSliuyi if (pComm) { 2469081d237aSliuyi delete pComm; 2470081d237aSliuyi pComm = NULL; 2471081d237aSliuyi } 2472081d237aSliuyi return bSuccess; 2473081d237aSliuyi } 2474081d237aSliuyi 2475081d237aSliuyi 24766ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt) 24776ae612beSliuyi { 24786ae612beSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 24796ae612beSliuyi return false; 24806ae612beSliuyi gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE); 24816ae612beSliuyi CRKUsbComm *pComm = NULL; 24826ae612beSliuyi bool bRet, bSuccess = false; 24836ae612beSliuyi int iRet; 24846ae612beSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 24856ae612beSliuyi if (bRet) { 24866ae612beSliuyi iRet = pComm->RKU_ReadLBA( 0, 34, pGpt); 24876ae612beSliuyi if(ERR_SUCCESS == iRet) { 24886ae612beSliuyi if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 24896ae612beSliuyi goto Exit_ReadGPT; 24906ae612beSliuyi } 24916ae612beSliuyi } else { 24926ae612beSliuyi if (g_pLogObject) 24936ae612beSliuyi g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 24946ae612beSliuyi printf("Read GPT failed!\r\n"); 24956ae612beSliuyi goto Exit_ReadGPT; 24966ae612beSliuyi } 24976ae612beSliuyi bSuccess = true; 24986ae612beSliuyi } 24996ae612beSliuyi Exit_ReadGPT: 25006ae612beSliuyi if (pComm) { 25016ae612beSliuyi delete pComm; 25026ae612beSliuyi pComm = NULL; 25036ae612beSliuyi } 25046ae612beSliuyi return bSuccess; 25056ae612beSliuyi } 250676af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 250776af099aSliuyi { 250876af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 250976af099aSliuyi return false; 251076af099aSliuyi CRKUsbComm *pComm = NULL; 251176af099aSliuyi FILE *file = NULL; 251276af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 251376af099aSliuyi int iRet; 251476af099aSliuyi UINT iTotalRead = 0,iRead = 0; 251576af099aSliuyi int nSectorSize = 512; 251676af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 251776af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 251876af099aSliuyi if (bRet) { 251976af099aSliuyi if(szFile) { 252076af099aSliuyi file = fopen(szFile, "wb+"); 252176af099aSliuyi if( !file ) { 252276af099aSliuyi printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 252376af099aSliuyi goto Exit_ReadLBA; 252476af099aSliuyi } 252576af099aSliuyi } 252676af099aSliuyi 252776af099aSliuyi while(uiLen > 0) { 252876af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 252976af099aSliuyi iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 253076af099aSliuyi iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 253176af099aSliuyi if(ERR_SUCCESS == iRet) { 253276af099aSliuyi uiLen -= iRead; 253376af099aSliuyi iTotalRead += iRead; 253476af099aSliuyi 253576af099aSliuyi if(szFile) { 253676af099aSliuyi fwrite(pBuf, 1, iRead * nSectorSize, file); 253776af099aSliuyi if (bFirst){ 253876af099aSliuyi if (iTotalRead >= 1024) 253932268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 254076af099aSliuyi else 254132268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 254276af099aSliuyi bFirst = false; 254376af099aSliuyi } else { 254476af099aSliuyi CURSOR_MOVEUP_LINE(1); 254576af099aSliuyi CURSOR_DEL_LINE; 254676af099aSliuyi if (iTotalRead >= 1024) 254732268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 254876af099aSliuyi else 254932268622SAndreas Färber printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 255076af099aSliuyi } 255176af099aSliuyi } 255276af099aSliuyi else 255376af099aSliuyi PrintData(pBuf, nSectorSize * iRead); 255476af099aSliuyi } else { 255576af099aSliuyi if (g_pLogObject) 255676af099aSliuyi g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 255776af099aSliuyi 255876af099aSliuyi printf("Read LBA failed!\r\n"); 255976af099aSliuyi goto Exit_ReadLBA; 256076af099aSliuyi } 256176af099aSliuyi } 256276af099aSliuyi bSuccess = true; 256376af099aSliuyi } else { 256432268622SAndreas Färber printf("Read LBA quit, creating comm object failed!\r\n"); 256576af099aSliuyi } 256676af099aSliuyi Exit_ReadLBA: 256776af099aSliuyi if (pComm) { 256876af099aSliuyi delete pComm; 256976af099aSliuyi pComm = NULL; 257076af099aSliuyi } 257176af099aSliuyi if (file) 257276af099aSliuyi fclose(file); 257376af099aSliuyi return bSuccess; 257476af099aSliuyi } 25750dcb0a4cSliuyi bool erase_ubi_block(STRUCT_RKDEVICE_DESC &dev, u32 uiOffset, u32 uiPartSize) 25760dcb0a4cSliuyi { 25770dcb0a4cSliuyi STRUCT_FLASHINFO_CMD info; 25780dcb0a4cSliuyi CRKComm *pComm = NULL; 25790dcb0a4cSliuyi BYTE flashID[5]; 25800dcb0a4cSliuyi bool bRet,bSuccess=false; 25810dcb0a4cSliuyi UINT uiReadCount,uiStartBlock,uiEraseBlock,uiBlockCount,uiErasePos; 25820dcb0a4cSliuyi int iRet; 25830dcb0a4cSliuyi DWORD *pID=NULL; 25841e890c4fSliuyi 2585e541b7bbSliuyi printf("Erase ubi in, offset=0x%08x,size=0x%08x!\r\n",uiOffset,uiPartSize); 25860dcb0a4cSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 25870dcb0a4cSliuyi return false; 25880dcb0a4cSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 25890dcb0a4cSliuyi if (!bRet) 25900dcb0a4cSliuyi { 25910dcb0a4cSliuyi printf("Erase ubi quit, creating comm object failed!\r\n"); 25920dcb0a4cSliuyi goto EXIT_UBI_ERASE; 25930dcb0a4cSliuyi } 25940dcb0a4cSliuyi iRet = pComm->RKU_ReadFlashID(flashID); 25950dcb0a4cSliuyi if(iRet!=ERR_SUCCESS) 25960dcb0a4cSliuyi { 25970dcb0a4cSliuyi if (g_pLogObject) 25980dcb0a4cSliuyi { 25990dcb0a4cSliuyi g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashID failed,RetCode(%d)",iRet); 26000dcb0a4cSliuyi } 26010dcb0a4cSliuyi goto EXIT_UBI_ERASE; 26020dcb0a4cSliuyi } 26030dcb0a4cSliuyi pID = (DWORD *)flashID; 26041e890c4fSliuyi 26050dcb0a4cSliuyi if (*pID==0x434d4d45)//emmc 26060dcb0a4cSliuyi { 26070dcb0a4cSliuyi bSuccess = true; 26080dcb0a4cSliuyi goto EXIT_UBI_ERASE; 26090dcb0a4cSliuyi } 26100dcb0a4cSliuyi 26110dcb0a4cSliuyi iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info,&uiReadCount); 26120dcb0a4cSliuyi if (iRet!=ERR_SUCCESS) 26130dcb0a4cSliuyi { 26140dcb0a4cSliuyi if (g_pLogObject) 26150dcb0a4cSliuyi g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashInfo err=%d", iRet); 26160dcb0a4cSliuyi goto EXIT_UBI_ERASE; 26170dcb0a4cSliuyi } 26180dcb0a4cSliuyi if (uiPartSize==0xFFFFFFFF) 2619e607a5d6Sliuyi uiPartSize = info.uiFlashSize - uiOffset; 26200dcb0a4cSliuyi 26210dcb0a4cSliuyi uiStartBlock = uiOffset / info.usBlockSize; 2622e607a5d6Sliuyi uiEraseBlock = (uiPartSize + info.usBlockSize -1) / info.usBlockSize; 2623e607a5d6Sliuyi 26240dcb0a4cSliuyi 2625e541b7bbSliuyi printf("Erase block start, offset=0x%08x,count=0x%08x!\r\n",uiStartBlock,uiEraseBlock); 26260dcb0a4cSliuyi uiErasePos=uiStartBlock; 26270dcb0a4cSliuyi while (uiEraseBlock>0) 26280dcb0a4cSliuyi { 26290dcb0a4cSliuyi uiBlockCount = (uiEraseBlock<MAX_ERASE_BLOCKS)?uiEraseBlock:MAX_ERASE_BLOCKS; 26300dcb0a4cSliuyi 26310dcb0a4cSliuyi iRet = pComm->RKU_EraseBlock(0,uiErasePos,uiBlockCount,ERASE_FORCE); 26320dcb0a4cSliuyi if ((iRet!=ERR_SUCCESS)&&(iRet!=ERR_FOUND_BAD_BLOCK)) 26330dcb0a4cSliuyi { 26340dcb0a4cSliuyi if (g_pLogObject) 26350dcb0a4cSliuyi { 26360dcb0a4cSliuyi g_pLogObject->Record("Error:EraseUBIBlock-->RKU_EraseBlock failed,RetCode(%d)",iRet); 26370dcb0a4cSliuyi } 26380dcb0a4cSliuyi goto EXIT_UBI_ERASE; 26390dcb0a4cSliuyi } 26400dcb0a4cSliuyi 26410dcb0a4cSliuyi uiErasePos += uiBlockCount; 26420dcb0a4cSliuyi uiEraseBlock -= uiBlockCount; 26430dcb0a4cSliuyi } 26440dcb0a4cSliuyi bSuccess = true; 26450dcb0a4cSliuyi EXIT_UBI_ERASE: 26460dcb0a4cSliuyi if (pComm) 26470dcb0a4cSliuyi delete pComm; 26480dcb0a4cSliuyi return bSuccess; 26490dcb0a4cSliuyi } 26506ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize) 26516ae612beSliuyi { 2652ae4252f0Sliuyi UINT uiErase=1024*32; 26536ae612beSliuyi bool bSuccess = true; 26546ae612beSliuyi int iRet; 26556ae612beSliuyi while (uiSize) 26566ae612beSliuyi { 26576ae612beSliuyi if (uiSize>=uiErase) 26586ae612beSliuyi { 26596ae612beSliuyi iRet = pComm->RKU_EraseLBA(uiOffset,uiErase); 26606ae612beSliuyi uiSize -= uiErase; 26616ae612beSliuyi uiOffset += uiErase; 26626ae612beSliuyi } 26636ae612beSliuyi else 26646ae612beSliuyi { 26656ae612beSliuyi iRet = pComm->RKU_EraseLBA(uiOffset,uiSize); 26666ae612beSliuyi uiSize = 0; 26676ae612beSliuyi uiOffset += uiSize; 26686ae612beSliuyi } 26696ae612beSliuyi if (iRet!=ERR_SUCCESS) 26706ae612beSliuyi { 26716ae612beSliuyi if (g_pLogObject) 26726ae612beSliuyi { 26736ae612beSliuyi g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet); 26746ae612beSliuyi } 26756ae612beSliuyi bSuccess = false; 26766ae612beSliuyi break; 26776ae612beSliuyi } 26786ae612beSliuyi } 26796ae612beSliuyi return bSuccess; 26806ae612beSliuyi 26816ae612beSliuyi } 26826ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk) 26836ae612beSliuyi { 26846ae612beSliuyi UINT uiRead; 26856ae612beSliuyi uiRead = fread(&chunk, 1, sizeof(chunk_header), file); 26866ae612beSliuyi if (uiRead != sizeof(chunk_header)) { 26876ae612beSliuyi if (g_pLogObject) 26886ae612beSliuyi { 26896ae612beSliuyi g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno); 26906ae612beSliuyi } 26916ae612beSliuyi return false; 26926ae612beSliuyi } 26936ae612beSliuyi return true; 26946ae612beSliuyi } 26956ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize) 26966ae612beSliuyi { 26976ae612beSliuyi UINT uiRead; 26986ae612beSliuyi uiRead = fread(pBuf, 1, dwSize, file); 26996ae612beSliuyi if (uiRead!=dwSize) 27006ae612beSliuyi { 27016ae612beSliuyi if (g_pLogObject) 27026ae612beSliuyi { 27036ae612beSliuyi g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno); 27046ae612beSliuyi } 27056ae612beSliuyi return false; 27066ae612beSliuyi } 27076ae612beSliuyi return true; 27086ae612beSliuyi } 27096ae612beSliuyi 27106ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile) 27116ae612beSliuyi { 27126ae612beSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 27136ae612beSliuyi return false; 27146ae612beSliuyi CRKUsbComm *pComm = NULL; 27156ae612beSliuyi FILE *file = NULL; 27166ae612beSliuyi bool bRet, bSuccess = false, bFirst = true; 27176ae612beSliuyi int iRet; 2718e541b7bbSliuyi u64 iTotalWrite = 0, iFileSize = 0,dwChunkDataSize; 27196ae612beSliuyi UINT iRead = 0, uiTransferSec, curChunk, i; 2720e541b7bbSliuyi UINT dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc; 27216ae612beSliuyi BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA]; 27226ae612beSliuyi sparse_header header; 27236ae612beSliuyi chunk_header chunk; 27246ae612beSliuyi dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE; 27256ae612beSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 27266ae612beSliuyi if (bRet) { 2727ae4252f0Sliuyi 27286ae612beSliuyi file = fopen(szFile, "rb"); 27296ae612beSliuyi if( !file ) { 27306ae612beSliuyi printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile); 27316ae612beSliuyi goto Exit_WriteSparseLBA; 27326ae612beSliuyi } 27336ae612beSliuyi fseeko(file, 0, SEEK_SET); 27346ae612beSliuyi iRead = fread(&header, 1, sizeof(header), file); 27356ae612beSliuyi if (iRead != sizeof(sparse_header)) 27366ae612beSliuyi { 27376ae612beSliuyi if (g_pLogObject) 27386ae612beSliuyi { 27396ae612beSliuyi g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno); 27406ae612beSliuyi } 27416ae612beSliuyi goto Exit_WriteSparseLBA; 27426ae612beSliuyi } 27436ae612beSliuyi iFileSize = header.blk_sz * (u64)header.total_blks; 27446ae612beSliuyi iTotalWrite = 0; 27456ae612beSliuyi curChunk = 0; 2746ae4252f0Sliuyi if (uiSize==(u32)-1) 2747ae4252f0Sliuyi uiSize = ALIGN(iFileSize, SECTOR_SIZE); 2748ae4252f0Sliuyi bRet = erase_partition(pComm, uiBegin, uiSize); 2749ae4252f0Sliuyi if (!bRet) { 2750ae4252f0Sliuyi printf("%s failed, erase partition error\r\n", __func__); 2751ae4252f0Sliuyi goto Exit_WriteSparseLBA; 2752ae4252f0Sliuyi } 27536ae612beSliuyi while(curChunk < header.total_chunks) 27546ae612beSliuyi { 27556ae612beSliuyi if (!EatSparseChunk(file, chunk)) { 27566ae612beSliuyi goto Exit_WriteSparseLBA; 27576ae612beSliuyi } 27586ae612beSliuyi curChunk++; 27596ae612beSliuyi switch (chunk.chunk_type) { 27606ae612beSliuyi case CHUNK_TYPE_RAW: 27616ae612beSliuyi dwChunkDataSize = chunk.total_sz - sizeof(chunk_header); 27626ae612beSliuyi while (dwChunkDataSize) { 27636ae612beSliuyi memset(pBuf, 0, dwMaxReadWriteBytes); 27646ae612beSliuyi if (dwChunkDataSize >= dwMaxReadWriteBytes) { 27656ae612beSliuyi dwTransferBytes = dwMaxReadWriteBytes; 27666ae612beSliuyi uiTransferSec = DEFAULT_RW_LBA; 27676ae612beSliuyi } else { 27686ae612beSliuyi dwTransferBytes = dwChunkDataSize; 27696ae612beSliuyi uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 27706ae612beSliuyi } 27716ae612beSliuyi if (!EatSparseData(file, pBuf, dwTransferBytes)) { 27726ae612beSliuyi goto Exit_WriteSparseLBA; 27736ae612beSliuyi } 27746ae612beSliuyi iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 27756ae612beSliuyi if( ERR_SUCCESS == iRet ) { 27766ae612beSliuyi dwChunkDataSize -= dwTransferBytes; 27776ae612beSliuyi iTotalWrite += dwTransferBytes; 27786ae612beSliuyi uiBegin += uiTransferSec; 27796ae612beSliuyi } else { 27806ae612beSliuyi if (g_pLogObject) { 27816ae612beSliuyi g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)", __func__, iTotalWrite, iRet); 27826ae612beSliuyi } 27836ae612beSliuyi goto Exit_WriteSparseLBA; 27846ae612beSliuyi } 27856ae612beSliuyi if (bFirst) { 27866ae612beSliuyi if (iTotalWrite >= 1024) 27876ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 27886ae612beSliuyi else 27896ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 27906ae612beSliuyi bFirst = false; 27916ae612beSliuyi } else { 27926ae612beSliuyi CURSOR_MOVEUP_LINE(1); 27936ae612beSliuyi CURSOR_DEL_LINE; 27946ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 27956ae612beSliuyi } 27966ae612beSliuyi } 27976ae612beSliuyi break; 27986ae612beSliuyi case CHUNK_TYPE_FILL: 2799e541b7bbSliuyi dwChunkDataSize = (u64)chunk.chunk_sz * header.blk_sz; 28006ae612beSliuyi if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) { 28016ae612beSliuyi goto Exit_WriteSparseLBA; 28026ae612beSliuyi } 28036ae612beSliuyi while (dwChunkDataSize) { 28046ae612beSliuyi memset(pBuf, 0, dwMaxReadWriteBytes); 28056ae612beSliuyi if (dwChunkDataSize >= dwMaxReadWriteBytes) { 28066ae612beSliuyi dwTransferBytes = dwMaxReadWriteBytes; 28076ae612beSliuyi uiTransferSec = DEFAULT_RW_LBA; 28086ae612beSliuyi } else { 28096ae612beSliuyi dwTransferBytes = dwChunkDataSize; 28106ae612beSliuyi uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 28116ae612beSliuyi } 28126ae612beSliuyi for (i = 0; i < dwTransferBytes / 4; i++) { 28136ae612beSliuyi *(DWORD *)(pBuf + i * 4) = dwFillByte; 28146ae612beSliuyi } 28156ae612beSliuyi iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 28166ae612beSliuyi if( ERR_SUCCESS == iRet ) { 28176ae612beSliuyi dwChunkDataSize -= dwTransferBytes; 28186ae612beSliuyi iTotalWrite += dwTransferBytes; 28196ae612beSliuyi uiBegin += uiTransferSec; 28206ae612beSliuyi } else { 28216ae612beSliuyi if (g_pLogObject) { 28226ae612beSliuyi g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet); 28236ae612beSliuyi } 28246ae612beSliuyi goto Exit_WriteSparseLBA; 28256ae612beSliuyi } 28266ae612beSliuyi if (bFirst) { 28276ae612beSliuyi if (iTotalWrite >= 1024) 28286ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 28296ae612beSliuyi else 28306ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 28316ae612beSliuyi bFirst = false; 28326ae612beSliuyi } else { 28336ae612beSliuyi CURSOR_MOVEUP_LINE(1); 28346ae612beSliuyi CURSOR_DEL_LINE; 28356ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 28366ae612beSliuyi } 28376ae612beSliuyi } 28386ae612beSliuyi break; 28396ae612beSliuyi case CHUNK_TYPE_DONT_CARE: 2840e541b7bbSliuyi dwChunkDataSize = (u64)chunk.chunk_sz * header.blk_sz; 28416ae612beSliuyi iTotalWrite += dwChunkDataSize; 28426ae612beSliuyi uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1)); 28436ae612beSliuyi uiBegin += uiTransferSec; 28446ae612beSliuyi if (bFirst) { 28456ae612beSliuyi if (iTotalWrite >= 1024) 28466ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 28476ae612beSliuyi else 28486ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 28496ae612beSliuyi bFirst = false; 28506ae612beSliuyi } else { 28516ae612beSliuyi CURSOR_MOVEUP_LINE(1); 28526ae612beSliuyi CURSOR_DEL_LINE; 28536ae612beSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 28546ae612beSliuyi } 28556ae612beSliuyi break; 28566ae612beSliuyi case CHUNK_TYPE_CRC32: 28576ae612beSliuyi EatSparseData(file,(PBYTE)&dwCrc,4); 28586ae612beSliuyi break; 28596ae612beSliuyi } 28606ae612beSliuyi } 28616ae612beSliuyi bSuccess = true; 28626ae612beSliuyi } else { 28636ae612beSliuyi printf("Write LBA quit, creating comm object failed!\r\n"); 28646ae612beSliuyi } 28656ae612beSliuyi Exit_WriteSparseLBA: 28666ae612beSliuyi if (pComm) { 28676ae612beSliuyi delete pComm; 28686ae612beSliuyi pComm = NULL; 28696ae612beSliuyi } 28706ae612beSliuyi if (file) 28716ae612beSliuyi fclose(file); 28726ae612beSliuyi return bSuccess; 28736ae612beSliuyi 28746ae612beSliuyi } 28756ae612beSliuyi 287676af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 287776af099aSliuyi { 287876af099aSliuyi if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 287976af099aSliuyi return false; 288076af099aSliuyi CRKUsbComm *pComm = NULL; 288176af099aSliuyi FILE *file = NULL; 288276af099aSliuyi bool bRet, bFirst = true, bSuccess = false; 288376af099aSliuyi int iRet; 288476af099aSliuyi long long iTotalWrite = 0, iFileSize = 0; 288576af099aSliuyi UINT iWrite = 0, iRead = 0; 288676af099aSliuyi UINT uiLen; 288776af099aSliuyi int nSectorSize = 512; 288876af099aSliuyi BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 288976af099aSliuyi 28900dcb0a4cSliuyi 289176af099aSliuyi pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 289276af099aSliuyi if (bRet) { 289376af099aSliuyi file = fopen(szFile, "rb"); 289476af099aSliuyi if( !file ) { 289576af099aSliuyi printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 289676af099aSliuyi goto Exit_WriteLBA; 289776af099aSliuyi } 289876af099aSliuyi 289976af099aSliuyi iRet = fseeko(file, 0, SEEK_END); 290076af099aSliuyi iFileSize = ftello(file); 290176af099aSliuyi fseeko(file, 0, SEEK_SET); 290276af099aSliuyi while(iTotalWrite < iFileSize) { 290376af099aSliuyi memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 290476af099aSliuyi iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 290576af099aSliuyi uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 290676af099aSliuyi iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 290776af099aSliuyi if(ERR_SUCCESS == iRet) { 290876af099aSliuyi uiBegin += uiLen; 290976af099aSliuyi iTotalWrite += iWrite; 291076af099aSliuyi if (bFirst) { 291176af099aSliuyi if (iTotalWrite >= 1024) 291276af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 291376af099aSliuyi else 291432268622SAndreas Färber printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 291576af099aSliuyi bFirst = false; 291676af099aSliuyi } else { 291776af099aSliuyi CURSOR_MOVEUP_LINE(1); 291876af099aSliuyi CURSOR_DEL_LINE; 291976af099aSliuyi printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 292076af099aSliuyi } 292176af099aSliuyi } else { 292276af099aSliuyi if (g_pLogObject) 292376af099aSliuyi g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 292476af099aSliuyi 292576af099aSliuyi printf("Write LBA failed!\r\n"); 292676af099aSliuyi goto Exit_WriteLBA; 292776af099aSliuyi } 292876af099aSliuyi } 292976af099aSliuyi bSuccess = true; 293076af099aSliuyi } else { 293132268622SAndreas Färber printf("Write LBA quit, creating comm object failed!\r\n"); 293276af099aSliuyi } 293376af099aSliuyi Exit_WriteLBA: 293476af099aSliuyi if (pComm) { 293576af099aSliuyi delete pComm; 293676af099aSliuyi pComm = NULL; 293776af099aSliuyi } 293876af099aSliuyi if (file) 293976af099aSliuyi fclose(file); 294076af099aSliuyi return bSuccess; 294176af099aSliuyi } 294276af099aSliuyi 294376af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems) 294476af099aSliuyi { 294576af099aSliuyi string strItem; 294676af099aSliuyi char szItem[100]; 294776af099aSliuyi char *pos = NULL, *pStart; 294876af099aSliuyi pStart = pszItems; 294976af099aSliuyi pos = strchr(pStart, ','); 295076af099aSliuyi while(pos != NULL) { 295102bc7763SChristoph Muellner memset(szItem, 0, sizeof(szItem)); 295276af099aSliuyi strncpy(szItem, pStart, pos - pStart); 295376af099aSliuyi strItem = szItem; 295476af099aSliuyi vecItems.push_back(strItem); 295576af099aSliuyi pStart = pos + 1; 295676af099aSliuyi if (*pStart == 0) 295776af099aSliuyi break; 295876af099aSliuyi pos = strchr(pStart, ','); 295976af099aSliuyi } 296076af099aSliuyi if (strlen(pStart) > 0) { 296102bc7763SChristoph Muellner memset(szItem, 0, sizeof(szItem)); 296202bc7763SChristoph Muellner strncpy(szItem, pStart, sizeof(szItem)-1); 296376af099aSliuyi strItem = szItem; 296476af099aSliuyi vecItems.push_back(strItem); 296576af099aSliuyi } 296676af099aSliuyi } 2967c30d921cSKever Yang 2968d71e8c20SEddie Cai void tag_spl(char *tag, char *spl) 2969d71e8c20SEddie Cai { 2970d71e8c20SEddie Cai FILE *file = NULL; 2971d71e8c20SEddie Cai int len; 2972d71e8c20SEddie Cai 2973d71e8c20SEddie Cai if(!tag || !spl) 2974d71e8c20SEddie Cai return; 2975d71e8c20SEddie Cai len = strlen(tag); 2976d71e8c20SEddie Cai printf("tag len=%d\n",len); 2977d71e8c20SEddie Cai file = fopen(spl, "rb"); 2978d71e8c20SEddie Cai if( !file ){ 2979d71e8c20SEddie Cai return; 2980d71e8c20SEddie Cai } 2981d71e8c20SEddie Cai int iFileSize; 2982d71e8c20SEddie Cai fseek(file, 0, SEEK_END); 2983d71e8c20SEddie Cai iFileSize = ftell(file); 2984d71e8c20SEddie Cai fseek(file, 0, SEEK_SET); 2985d71e8c20SEddie Cai char *Buf = NULL; 2986d71e8c20SEddie Cai Buf = new char[iFileSize + len + 1]; 2987d71e8c20SEddie Cai if (!Buf){ 2988d71e8c20SEddie Cai fclose(file); 2989d71e8c20SEddie Cai return; 2990d71e8c20SEddie Cai } 2991d71e8c20SEddie Cai memset(Buf, 0, iFileSize + 1); 2992d71e8c20SEddie Cai memcpy(Buf, tag, len); 2993d71e8c20SEddie Cai int iRead; 2994d71e8c20SEddie Cai iRead = fread(Buf+len, 1, iFileSize, file); 2995d71e8c20SEddie Cai if (iRead != iFileSize){ 2996d71e8c20SEddie Cai fclose(file); 2997d71e8c20SEddie Cai delete []Buf; 2998d71e8c20SEddie Cai return; 2999d71e8c20SEddie Cai } 3000d71e8c20SEddie Cai fclose(file); 3001d71e8c20SEddie Cai 3002d71e8c20SEddie Cai len = strlen(spl); 300332268622SAndreas Färber char *taggedspl = new char[len + 5]; 300432268622SAndreas Färber strcpy(taggedspl, spl); 300532268622SAndreas Färber strcpy(taggedspl + len, ".tag"); 300632268622SAndreas Färber taggedspl[len+4] = 0; 300732268622SAndreas Färber printf("Writing tagged spl to %s\n", taggedspl); 3008d71e8c20SEddie Cai 300932268622SAndreas Färber file = fopen(taggedspl, "wb"); 3010d71e8c20SEddie Cai if( !file ){ 301132268622SAndreas Färber delete []taggedspl; 3012d71e8c20SEddie Cai delete []Buf; 3013d71e8c20SEddie Cai return; 3014d71e8c20SEddie Cai } 3015d71e8c20SEddie Cai fwrite(Buf, 1, iFileSize+len, file); 3016d71e8c20SEddie Cai fclose(file); 301732268622SAndreas Färber delete []taggedspl; 3018d71e8c20SEddie Cai delete []Buf; 3019d71e8c20SEddie Cai printf("done\n"); 3020d71e8c20SEddie Cai return; 3021d71e8c20SEddie Cai } 3022081d237aSliuyi void list_device(CRKScan *pScan) 3023081d237aSliuyi { 3024081d237aSliuyi STRUCT_RKDEVICE_DESC desc; 3025081d237aSliuyi string strDevType; 3026081d237aSliuyi int i,cnt; 3027081d237aSliuyi cnt = pScan->DEVICE_COUNTS; 3028081d237aSliuyi if (cnt == 0) { 3029081d237aSliuyi printf("not found any devices!\r\n"); 3030081d237aSliuyi return; 3031081d237aSliuyi } 3032081d237aSliuyi for (i=0;i<cnt;i++) 3033081d237aSliuyi { 3034081d237aSliuyi pScan->GetDevice(desc, i); 3035081d237aSliuyi if (desc.emUsbType==RKUSB_MASKROM) 3036081d237aSliuyi strDevType = "Maskrom"; 3037081d237aSliuyi else if (desc.emUsbType==RKUSB_LOADER) 3038081d237aSliuyi strDevType = "Loader"; 3039081d237aSliuyi else 3040081d237aSliuyi strDevType = "Unknown"; 3041081d237aSliuyi printf("DevNo=%d\tVid=0x%x,Pid=0x%x,LocationID=%x\t%s\r\n",i+1,desc.usVid, 3042081d237aSliuyi desc.usPid,desc.uiLocationID,strDevType.c_str()); 3043081d237aSliuyi } 3044081d237aSliuyi 3045081d237aSliuyi } 3046081d237aSliuyi 3047d71e8c20SEddie Cai 304876af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan) 304976af099aSliuyi { 305076af099aSliuyi string strCmd; 305176af099aSliuyi strCmd = argv[1]; 305276af099aSliuyi ssize_t cnt; 305376af099aSliuyi bool bRet,bSuccess = false; 30548df2d64aSEddie Cai char *s; 30558df2d64aSEddie Cai int i, ret; 305676af099aSliuyi STRUCT_RKDEVICE_DESC dev; 3057081d237aSliuyi u8 master_gpt[34 * SECTOR_SIZE], param_buffer[512 * SECTOR_SIZE]; 30586ae612beSliuyi u64 lba, lba_end; 3059081d237aSliuyi u32 part_size, part_offset; 306076af099aSliuyi 306176af099aSliuyi transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 30628df2d64aSEddie Cai s = (char*)strCmd.c_str(); 30638df2d64aSEddie Cai for(i = 0; i < (int)strlen(s); i++) 30648df2d64aSEddie Cai s[i] = toupper(s[i]); 306578884ef4SEddie Cai 30668df2d64aSEddie Cai if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 306776af099aSliuyi usage(); 306876af099aSliuyi return true; 30698df2d64aSEddie Cai } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 3070c30d921cSKever Yang printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 307176af099aSliuyi return true; 307278884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 307378884ef4SEddie Cai mergeBoot(); 307478884ef4SEddie Cai return true; 307578884ef4SEddie Cai } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 307678884ef4SEddie Cai string strLoader = argv[2]; 307778884ef4SEddie Cai unpackBoot((char*)strLoader.c_str()); 307878884ef4SEddie Cai return true; 3079d71e8c20SEddie Cai } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 3080d71e8c20SEddie Cai if (argc == 4) { 3081d71e8c20SEddie Cai string tag = argv[2]; 3082d71e8c20SEddie Cai string spl = argv[3]; 3083d71e8c20SEddie Cai printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 3084d71e8c20SEddie Cai tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 3085d71e8c20SEddie Cai return true; 3086d71e8c20SEddie Cai } 3087d71e8c20SEddie Cai printf("tagspl: parameter error\n"); 3088d71e8c20SEddie Cai usage(); 308976af099aSliuyi } 309076af099aSliuyi cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 3091081d237aSliuyi if(strcmp(strCmd.c_str(), "LD") == 0) { 3092081d237aSliuyi list_device(pScan); 30930dcb0a4cSliuyi return (cnt>0)?true:false; 3094081d237aSliuyi } 3095081d237aSliuyi 309676af099aSliuyi if (cnt < 1) { 309776af099aSliuyi ERROR_COLOR_ATTR; 309832268622SAndreas Färber printf("Did not find any rockusb device, please plug device in!"); 309976af099aSliuyi NORMAL_COLOR_ATTR; 310076af099aSliuyi printf("\r\n"); 310176af099aSliuyi return bSuccess; 310276af099aSliuyi } else if (cnt > 1) { 310376af099aSliuyi ERROR_COLOR_ATTR; 310432268622SAndreas Färber printf("Found too many rockusb devices, please plug devices out!"); 310576af099aSliuyi NORMAL_COLOR_ATTR; 310676af099aSliuyi printf("\r\n"); 310776af099aSliuyi return bSuccess; 310876af099aSliuyi } 310976af099aSliuyi 311076af099aSliuyi bRet = pScan->GetDevice(dev, 0); 311176af099aSliuyi if (!bRet) { 311276af099aSliuyi ERROR_COLOR_ATTR; 311332268622SAndreas Färber printf("Getting information about rockusb device failed!"); 311476af099aSliuyi NORMAL_COLOR_ATTR; 311576af099aSliuyi printf("\r\n"); 311676af099aSliuyi return bSuccess; 311776af099aSliuyi } 311876af099aSliuyi 311976af099aSliuyi if(strcmp(strCmd.c_str(), "RD") == 0) { 312076af099aSliuyi if ((argc != 2) && (argc != 3)) 312176af099aSliuyi printf("Parameter of [RD] command is invalid, please check help!\r\n"); 312276af099aSliuyi else { 312376af099aSliuyi if (argc == 2) 312476af099aSliuyi bSuccess = reset_device(dev); 312576af099aSliuyi else { 312676af099aSliuyi UINT uiSubCode; 312776af099aSliuyi char *pszEnd; 312876af099aSliuyi uiSubCode = strtoul(argv[2], &pszEnd, 0); 312976af099aSliuyi if (*pszEnd) 313076af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 313176af099aSliuyi else { 313276af099aSliuyi if (uiSubCode <= 5) 313376af099aSliuyi bSuccess = reset_device(dev, uiSubCode); 313476af099aSliuyi else 313576af099aSliuyi printf("Subcode is invalid, please check!\r\n"); 313676af099aSliuyi } 313776af099aSliuyi } 313876af099aSliuyi } 313976af099aSliuyi } else if(strcmp(strCmd.c_str(), "TD") == 0) { 314076af099aSliuyi bSuccess = test_device(dev); 314176af099aSliuyi } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 314276af099aSliuyi bSuccess = read_flash_id(dev); 314376af099aSliuyi } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 314476af099aSliuyi bSuccess = read_flash_info(dev); 314576af099aSliuyi } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 314676af099aSliuyi bSuccess = read_chip_info(dev); 3147081d237aSliuyi } else if (strcmp(strCmd.c_str(), "RCB") == 0) {//Read Capability 3148081d237aSliuyi bSuccess = read_capability(dev); 314976af099aSliuyi } else if(strcmp(strCmd.c_str(), "DB") == 0) { 315076af099aSliuyi if (argc > 2) { 315176af099aSliuyi string strLoader; 315276af099aSliuyi strLoader = argv[2]; 315376af099aSliuyi bSuccess = download_boot(dev, (char *)strLoader.c_str()); 315476af099aSliuyi } else if (argc == 2) { 3155c29e5f0fSliuyi ret = find_config_item(g_ConfigItemVec, "loader"); 315676af099aSliuyi if (ret == -1) 315732268622SAndreas Färber printf("Did not find loader item in config!\r\n"); 315876af099aSliuyi else 315976af099aSliuyi bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 316076af099aSliuyi } else 316176af099aSliuyi printf("Parameter of [DB] command is invalid, please check help!\r\n"); 3162c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 3163c30d921cSKever Yang if (argc > 2) { 3164c30d921cSKever Yang string strParameter; 3165c30d921cSKever Yang strParameter = argv[2]; 3166c30d921cSKever Yang bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 3167c30d921cSKever Yang } else 3168c30d921cSKever Yang printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 3169081d237aSliuyi } else if(strcmp(strCmd.c_str(), "PRM") == 0) { 3170081d237aSliuyi if (argc > 2) { 3171081d237aSliuyi string strParameter; 3172081d237aSliuyi strParameter = argv[2]; 3173081d237aSliuyi bSuccess = write_parameter(dev, (char *)strParameter.c_str()); 3174081d237aSliuyi } else 3175081d237aSliuyi printf("Parameter of [PRM] command is invalid, please check help!\r\n"); 3176c30d921cSKever Yang } else if(strcmp(strCmd.c_str(), "UL") == 0) { 3177c30d921cSKever Yang if (argc > 2) { 3178c30d921cSKever Yang string strLoader; 3179c30d921cSKever Yang strLoader = argv[2]; 3180c30d921cSKever Yang bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 3181c30d921cSKever Yang } else 3182c30d921cSKever Yang printf("Parameter of [UL] command is invalid, please check help!\r\n"); 318376af099aSliuyi } else if(strcmp(strCmd.c_str(), "EF") == 0) { 318476af099aSliuyi if (argc == 2) { 318576af099aSliuyi bSuccess = erase_flash(dev); 318676af099aSliuyi } else 318776af099aSliuyi printf("Parameter of [EF] command is invalid, please check help!\r\n"); 318876af099aSliuyi } else if(strcmp(strCmd.c_str(), "WL") == 0) { 318976af099aSliuyi if (argc == 4) { 319076af099aSliuyi UINT uiBegin; 319176af099aSliuyi char *pszEnd; 319276af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 319376af099aSliuyi if (*pszEnd) 319476af099aSliuyi printf("Begin is invalid, please check!\r\n"); 3195ae4252f0Sliuyi else { 3196ae4252f0Sliuyi if (is_sparse_image(argv[3])) 3197ae4252f0Sliuyi bSuccess = write_sparse_lba(dev, (u32)uiBegin, (u32)-1, argv[3]); 31980dcb0a4cSliuyi else { 31990dcb0a4cSliuyi bSuccess = true; 32000dcb0a4cSliuyi if (is_ubifs_image(argv[3])) 32010dcb0a4cSliuyi bSuccess = erase_ubi_block(dev, (u32)uiBegin, (u32)-1); 32020dcb0a4cSliuyi if (bSuccess) 3203ae4252f0Sliuyi bSuccess = write_lba(dev, (u32)uiBegin, argv[3]); 32040dcb0a4cSliuyi else 32050dcb0a4cSliuyi printf("Failure of Erase for writing ubi image!\r\n"); 32060dcb0a4cSliuyi } 3207ae4252f0Sliuyi } 320876af099aSliuyi } else 320976af099aSliuyi printf("Parameter of [WL] command is invalid, please check help!\r\n"); 32106ae612beSliuyi } else if(strcmp(strCmd.c_str(), "WLX") == 0) { 32116ae612beSliuyi if (argc == 4) { 32126ae612beSliuyi bRet = read_gpt(dev, master_gpt); 32136ae612beSliuyi if (bRet) { 32146ae612beSliuyi bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end); 32156ae612beSliuyi if (bRet) { 32166ae612beSliuyi if (is_sparse_image(argv[3])) 32176ae612beSliuyi bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]); 32180dcb0a4cSliuyi else { 32190dcb0a4cSliuyi bSuccess = true; 32200dcb0a4cSliuyi if (is_ubifs_image(argv[3])) 3221e607a5d6Sliuyi { 3222e607a5d6Sliuyi if (lba_end == 0xFFFFFFFF) 3223e607a5d6Sliuyi bSuccess = erase_ubi_block(dev, (u32)lba, (u32)lba_end); 3224e607a5d6Sliuyi else 32250dcb0a4cSliuyi bSuccess = erase_ubi_block(dev, (u32)lba, (u32)(lba_end - lba + 1)); 3226e607a5d6Sliuyi } 32270dcb0a4cSliuyi if (bSuccess) 32286ae612beSliuyi bSuccess = write_lba(dev, (u32)lba, argv[3]); 32290dcb0a4cSliuyi else 32300dcb0a4cSliuyi printf("Failure of Erase for writing ubi image!\r\n"); 32310dcb0a4cSliuyi } 32326ae612beSliuyi } else 32336ae612beSliuyi printf("No found %s partition\r\n", argv[2]); 3234081d237aSliuyi } else { 3235081d237aSliuyi bRet = read_param(dev, param_buffer); 3236081d237aSliuyi if (bRet) { 3237081d237aSliuyi bRet = get_lba_from_param(param_buffer+8, argv[2], &part_offset, &part_size); 3238081d237aSliuyi if (bRet) { 3239081d237aSliuyi if (is_sparse_image(argv[3])) 3240081d237aSliuyi bSuccess = write_sparse_lba(dev, part_offset, part_size, argv[3]); 32410dcb0a4cSliuyi else { 32421e890c4fSliuyi 32430dcb0a4cSliuyi bSuccess = true; 32440dcb0a4cSliuyi if (is_ubifs_image(argv[3])) 32450dcb0a4cSliuyi bSuccess = erase_ubi_block(dev, part_offset, part_size); 32460dcb0a4cSliuyi if (bSuccess) 3247081d237aSliuyi bSuccess = write_lba(dev, part_offset, argv[3]); 32480dcb0a4cSliuyi else 32490dcb0a4cSliuyi printf("Failure of Erase for writing ubi image!\r\n"); 32500dcb0a4cSliuyi } 3251081d237aSliuyi } else 3252081d237aSliuyi printf("No found %s partition\r\n", argv[2]); 32536ae612beSliuyi } 3254081d237aSliuyi else 3255081d237aSliuyi printf("Not found any partition table!\r\n"); 3256081d237aSliuyi } 3257081d237aSliuyi 32586ae612beSliuyi } else 32596ae612beSliuyi printf("Parameter of [WLX] command is invalid, please check help!\r\n"); 326076af099aSliuyi } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 326176af099aSliuyi char *pszEnd; 326276af099aSliuyi UINT uiBegin, uiLen; 326376af099aSliuyi if (argc != 5) 326476af099aSliuyi printf("Parameter of [RL] command is invalid, please check help!\r\n"); 326576af099aSliuyi else { 326676af099aSliuyi uiBegin = strtoul(argv[2], &pszEnd, 0); 326776af099aSliuyi if (*pszEnd) 326876af099aSliuyi printf("Begin is invalid, please check!\r\n"); 326976af099aSliuyi else { 327076af099aSliuyi uiLen = strtoul(argv[3], &pszEnd, 0); 327176af099aSliuyi if (*pszEnd) 327276af099aSliuyi printf("Len is invalid, please check!\r\n"); 327376af099aSliuyi else { 327476af099aSliuyi bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 327576af099aSliuyi } 327676af099aSliuyi } 327776af099aSliuyi } 3278081d237aSliuyi } else if(strcmp(strCmd.c_str(), "PPT") == 0) { 32793dc7e3ceSliuyi if (argc == 2) { 32803dc7e3ceSliuyi bSuccess = print_gpt(dev); 3281081d237aSliuyi if (!bSuccess) { 3282081d237aSliuyi bSuccess = print_parameter(dev); 3283081d237aSliuyi if (!bSuccess) 3284081d237aSliuyi printf("Not found any partition table!\r\n"); 3285081d237aSliuyi } 32863dc7e3ceSliuyi } else 3287081d237aSliuyi printf("Parameter of [PPT] command is invalid, please check help!\r\n"); 328876af099aSliuyi } else { 32899bc231bdSAndreas Färber printf("command is invalid!\r\n"); 32909bc231bdSAndreas Färber usage(); 329176af099aSliuyi } 329276af099aSliuyi return bSuccess; 329376af099aSliuyi } 329476af099aSliuyi 329576af099aSliuyi 329676af099aSliuyi int main(int argc, char* argv[]) 329776af099aSliuyi { 329876af099aSliuyi CRKScan *pScan = NULL; 329976af099aSliuyi int ret; 330076af099aSliuyi char szProgramProcPath[100]; 330176af099aSliuyi char szProgramDir[256]; 330276af099aSliuyi string strLogDir,strConfigFile; 330376af099aSliuyi struct stat statBuf; 330476af099aSliuyi 330576af099aSliuyi g_ConfigItemVec.clear(); 330676af099aSliuyi sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 330776af099aSliuyi if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 330876af099aSliuyi strcpy(szProgramDir, "."); 330976af099aSliuyi else { 331076af099aSliuyi char *pSlash; 331176af099aSliuyi pSlash = strrchr(szProgramDir, '/'); 331276af099aSliuyi if (pSlash) 331376af099aSliuyi *pSlash = '\0'; 331476af099aSliuyi } 331576af099aSliuyi strLogDir = szProgramDir; 331676af099aSliuyi strLogDir += "/log/"; 331776af099aSliuyi strConfigFile = szProgramDir; 331876af099aSliuyi strConfigFile += "/config.ini"; 331976af099aSliuyi if (opendir(strLogDir.c_str()) == NULL) 332076af099aSliuyi mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 3321e5ee8cc0Sliuyi g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 332276af099aSliuyi 332376af099aSliuyi if(stat(strConfigFile.c_str(), &statBuf) < 0) { 332476af099aSliuyi if (g_pLogObject) { 332576af099aSliuyi g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 332676af099aSliuyi } 332776af099aSliuyi } else if (S_ISREG(statBuf.st_mode)) { 332876af099aSliuyi parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 332976af099aSliuyi } 333076af099aSliuyi 333176af099aSliuyi ret = libusb_init(NULL); 333276af099aSliuyi if (ret < 0) { 333376af099aSliuyi if (g_pLogObject) { 333476af099aSliuyi g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 333576af099aSliuyi delete g_pLogObject; 333676af099aSliuyi } 333776af099aSliuyi return -1; 333876af099aSliuyi } 333976af099aSliuyi 334076af099aSliuyi pScan = new CRKScan(); 334176af099aSliuyi if (!pScan) { 334276af099aSliuyi if (g_pLogObject) { 334332268622SAndreas Färber g_pLogObject->Record("Error: failed to create object for searching device"); 334476af099aSliuyi delete g_pLogObject; 334576af099aSliuyi } 334676af099aSliuyi libusb_exit(NULL); 334776af099aSliuyi return -2; 334876af099aSliuyi } 334976af099aSliuyi pScan->SetVidPid(); 335076af099aSliuyi 335176af099aSliuyi if (argc == 1) 335276af099aSliuyi usage(); 335376af099aSliuyi else if (!handle_command(argc, argv, pScan)) 335476af099aSliuyi return -0xFF; 335576af099aSliuyi if (pScan) 335676af099aSliuyi delete pScan; 335776af099aSliuyi if (g_pLogObject) 335876af099aSliuyi delete g_pLogObject; 335976af099aSliuyi libusb_exit(NULL); 336076af099aSliuyi return 0; 336176af099aSliuyi } 3362