1 /* 2 * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 3 * Seth Liu 2017.03.01 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <unistd.h> 9 #include <dirent.h> 10 #include "config.h" 11 #include "DefineHeader.h" 12 #include "gpt.h" 13 #include "RKLog.h" 14 #include "RKScan.h" 15 #include "RKComm.h" 16 #include "RKDevice.h" 17 #include "RKImage.h" 18 extern const char *szManufName[]; 19 CRKLog *g_pLogObject=NULL; 20 CONFIG_ITEM_VECTOR g_ConfigItemVec; 21 #define DEFAULT_RW_LBA 128 22 #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n) 23 #define CURSOR_DEL_LINE printf("%c[2K", 0x1B) 24 #define CURSOR_MOVE_HOME printf("%c[H", 0x1B) 25 #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B) 26 #define ERROR_COLOR_ATTR printf("%c[30;41m", 0x1B); 27 #define NORMAL_COLOR_ATTR printf("%c[0m", 0x1B); 28 extern UINT CRC_32(unsigned char* pData, UINT ulSize); 29 extern unsigned short CRC_16(unsigned char* aData, UINT aSize); 30 extern void P_RC4(unsigned char* buf, unsigned short len); 31 extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len); 32 /* 33 u8 test_gpt_head[] = { 34 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00, 35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B, 38 0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08}; 40 */ 41 42 void usage() 43 { 44 printf("\r\n---------------------Tool Usage ---------------------\r\n"); 45 printf("Help:\t\t\t-h or --version\r\n"); 46 printf("Version:\t\t-v or --version\r\n"); 47 printf("DownloadBoot:\t\tdb <Loader>\r\n"); 48 printf("UpgradeLoader:\t\tul <Loader>\r\n"); 49 printf("ReadLBA:\t\trl <BeginSec> <SectorLen> <File>\r\n"); 50 printf("WriteLBA:\t\twl <BeginSec> <File>\r\n"); 51 printf("WriteGPT:\t\tgpt <gpt partition table>\r\n"); 52 printf("EraseFlash:\t\tef \r\n"); 53 printf("TestDevice:\t\ttd\r\n"); 54 printf("ResetDevice:\t\trd [subcode]\r\n"); 55 printf("ReadFlashID:\t\trid\r\n"); 56 printf("ReadFlashInfo:\t\trfi\r\n"); 57 printf("ReadChipInfo:\t\trci\r\n"); 58 printf("PackBootLoader:\t\tpack\r\n"); 59 printf("UnpackBootLoader:\tunpack <boot loader>\r\n"); 60 printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n"); 61 printf("-------------------------------------------------------\r\n\r\n"); 62 } 63 void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall) 64 { 65 string strInfoText=""; 66 char szText[256]; 67 switch (promptID) { 68 case TESTDEVICE_PROGRESS: 69 sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue); 70 strInfoText = szText; 71 break; 72 case LOWERFORMAT_PROGRESS: 73 sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue); 74 strInfoText = szText; 75 break; 76 case DOWNLOADIMAGE_PROGRESS: 77 sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 78 strInfoText = szText; 79 break; 80 case CHECKIMAGE_PROGRESS: 81 sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 82 strInfoText = szText; 83 break; 84 case TAGBADBLOCK_PROGRESS: 85 sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue); 86 strInfoText = szText; 87 break; 88 case TESTBLOCK_PROGRESS: 89 sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue); 90 strInfoText = szText; 91 break; 92 case ERASEFLASH_PROGRESS: 93 sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue); 94 strInfoText = szText; 95 break; 96 case ERASESYSTEM_PROGRESS: 97 sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue); 98 strInfoText = szText; 99 break; 100 case ERASEUSERDATA_PROGRESS: 101 sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue); 102 strInfoText = szText; 103 break; 104 } 105 if (strInfoText.size() > 0){ 106 CURSOR_MOVEUP_LINE(1); 107 CURSOR_DEL_LINE; 108 printf("%s\r\n", strInfoText.c_str()); 109 } 110 if (emCall == CALL_LAST) 111 deviceLayer = 0; 112 } 113 114 char *strupr(char *szSrc) 115 { 116 char *p = szSrc; 117 while(*p){ 118 if ((*p >= 'a') && (*p <= 'z')) 119 *p = *p - 'a' + 'A'; 120 p++; 121 } 122 return szSrc; 123 } 124 void PrintData(PBYTE pData, int nSize) 125 { 126 char szPrint[17] = "\0"; 127 int i; 128 for( i = 0; i < nSize; i++){ 129 if(i % 16 == 0){ 130 if(i / 16 > 0) 131 printf(" %s\r\n", szPrint); 132 printf("%08d ", i / 16); 133 } 134 printf("%02X ", pData[i]); 135 szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.'; 136 } 137 if(i / 16 > 0) 138 printf(" %s\r\n", szPrint); 139 } 140 141 bool StringToWideString(char *pszSrc, wchar_t *&pszDest) 142 { 143 if (!pszSrc) 144 return false; 145 int nSrcLen = strlen(pszSrc); 146 int nDestLen = nSrcLen * 2; 147 148 pszDest = NULL; 149 pszDest = new wchar_t[nDestLen]; 150 if (!pszDest) 151 return false; 152 nDestLen = nDestLen * sizeof(wchar_t); 153 memset(pszDest, 0, nDestLen); 154 int iRet; 155 iconv_t cd; 156 cd = iconv_open("UTF-32", "UTF-8"); 157 if((iconv_t)-1 == cd) { 158 delete []pszDest; 159 pszDest = NULL; 160 return false; 161 } 162 char *pIn, *pOut; 163 pIn = (char *)pszSrc; 164 pOut = (char *)pszDest; 165 166 iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 167 168 if(iRet == -1) { 169 delete []pszDest; 170 pszDest = NULL; 171 iconv_close(cd); 172 return false; 173 } 174 175 iconv_close(cd); 176 177 return true; 178 } 179 bool WideStringToString(wchar_t *pszSrc, char *&pszDest) 180 { 181 if (!pszSrc) 182 return false; 183 int nSrcLen = wcslen(pszSrc); 184 int nDestLen = nSrcLen * 2; 185 nSrcLen = nSrcLen * sizeof(wchar_t); 186 pszDest = NULL; 187 pszDest = new char[nDestLen]; 188 if (!pszDest) 189 return false; 190 memset(pszDest, 0, nDestLen); 191 int iRet; 192 iconv_t cd; 193 cd = iconv_open("UTF-8", "UTF-32"); 194 195 if((iconv_t)-1 == cd) { 196 delete []pszDest; 197 pszDest = NULL; 198 return false; 199 } 200 char *pIn, *pOut; 201 pIn = (char *)pszSrc; 202 pOut = (char *)pszDest; 203 iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 204 205 if(iRet == -1) { 206 delete []pszDest; 207 pszDest = NULL; 208 iconv_close(cd); 209 return false; 210 } 211 212 iconv_close(cd); 213 214 return true; 215 } 216 int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName) 217 { 218 unsigned int i; 219 for(i = 0; i < vecItems.size(); i++){ 220 if (strcasecmp(pszName, vecItems[i].szItemName) == 0){ 221 return i; 222 } 223 } 224 return -1; 225 } 226 void string_to_uuid(string strUUid, char *uuid) 227 { 228 unsigned int i; 229 char value; 230 memset(uuid, 0, 16); 231 for (i =0; i < strUUid.size(); i++) { 232 value = 0; 233 if ((strUUid[i] >= '0')&&(strUUid[i] <= '9')) 234 value = strUUid[i] - '0'; 235 if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f')) 236 value = strUUid[i] - 'a' + 10; 237 if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F')) 238 value = strUUid[i] - 'A' + 10; 239 if ((i % 2) == 0) 240 uuid[i / 2] += (value << 4); 241 else 242 uuid[i / 2] += value; 243 } 244 unsigned int *p32; 245 unsigned short *p16; 246 p32 = (unsigned int*)uuid; 247 *p32 = cpu_to_be32(*p32); 248 p16 = (unsigned short *)(uuid + 4); 249 *p16 = cpu_to_be16(*p16); 250 p16 = (unsigned short *)(uuid + 6); 251 *p16 = cpu_to_be16(*p16); 252 } 253 254 bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 255 { 256 257 stringstream configStream(pConfig); 258 string strLine, strItemName, strItemValue; 259 string::size_type line_size,pos; 260 STRUCT_CONFIG_ITEM item; 261 vecItem.clear(); 262 while (!configStream.eof()){ 263 getline(configStream, strLine); 264 line_size = strLine.size(); 265 if (line_size == 0) 266 continue; 267 if (strLine[line_size-1] == '\r'){ 268 strLine = strLine.substr(0, line_size-1); 269 } 270 strLine.erase(0, strLine.find_first_not_of(" ")); 271 strLine.erase(strLine.find_last_not_of(" ") + 1); 272 if (strLine.size()==0 ) 273 continue; 274 if (strLine[0] == '#') 275 continue; 276 pos = strLine.find("="); 277 if (pos == string::npos){ 278 continue; 279 } 280 strItemName = strLine.substr(0, pos); 281 strItemValue = strLine.substr(pos + 1); 282 strItemName.erase(0, strItemName.find_first_not_of(" ")); 283 strItemName.erase(strItemName.find_last_not_of(" ") + 1); 284 strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 285 strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 286 if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 287 strcpy(item.szItemName, strItemName.c_str()); 288 strcpy(item.szItemValue, strItemValue.c_str()); 289 vecItem.push_back(item); 290 } 291 } 292 return true; 293 294 } 295 bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 296 { 297 FILE *file = NULL; 298 file = fopen(pConfigFile, "rb"); 299 if( !file ){ 300 if (g_pLogObject) 301 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile); 302 return false; 303 } 304 int iFileSize; 305 fseek(file, 0, SEEK_END); 306 iFileSize = ftell(file); 307 fseek(file, 0, SEEK_SET); 308 char *pConfigBuf = NULL; 309 pConfigBuf = new char[iFileSize + 1]; 310 if (!pConfigBuf){ 311 fclose(file); 312 return false; 313 } 314 memset(pConfigBuf, 0, iFileSize + 1); 315 int iRead; 316 iRead = fread(pConfigBuf, 1, iFileSize, file); 317 if (iRead != iFileSize){ 318 if (g_pLogObject) 319 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize); 320 fclose(file); 321 delete []pConfigBuf; 322 return false; 323 } 324 fclose(file); 325 bool bRet; 326 bRet = parse_config(pConfigBuf, vecItem); 327 delete []pConfigBuf; 328 return bRet; 329 } 330 bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 331 { 332 string::size_type pos,prevPos; 333 string strOffset,strLen; 334 int iCount; 335 prevPos = pos = 0; 336 if (strPartInfo.size() <= 0) { 337 return false; 338 } 339 pos = strPartInfo.find('@'); 340 if (pos == string::npos) { 341 return false; 342 } 343 strLen = strPartInfo.substr(prevPos, pos - prevPos); 344 strLen.erase(0, strLen.find_first_not_of(" ")); 345 strLen.erase(strLen.find_last_not_of(" ") + 1); 346 if (strchr(strLen.c_str(), '-')) { 347 uiLen = 0xFFFFFFFF; 348 } else { 349 iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 350 if (iCount != 1) { 351 return false; 352 } 353 } 354 355 prevPos = pos + 1; 356 pos = strPartInfo.find('(',prevPos); 357 if (pos == string::npos) { 358 return false; 359 } 360 strOffset = strPartInfo.substr(prevPos, pos - prevPos); 361 strOffset.erase(0, strOffset.find_first_not_of(" ")); 362 strOffset.erase(strOffset.find_last_not_of(" ") + 1); 363 iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 364 if (iCount != 1) { 365 return false; 366 } 367 prevPos = pos + 1; 368 pos = strPartInfo.find(')', prevPos); 369 if (pos == string::npos) { 370 return false; 371 } 372 strName = strPartInfo.substr(prevPos, pos - prevPos); 373 strName.erase(0, strName.find_first_not_of(" ")); 374 strName.erase(strName.find_last_not_of(" ") + 1); 375 376 return true; 377 } 378 bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid) 379 { 380 string::size_type pos(0); 381 382 if (strUuidInfo.size() <= 0) { 383 return false; 384 } 385 pos = strUuidInfo.find('='); 386 if (pos == string::npos) { 387 return false; 388 } 389 strName = strUuidInfo.substr(0, pos); 390 strName.erase(0, strName.find_first_not_of(" ")); 391 strName.erase(strName.find_last_not_of(" ") + 1); 392 393 strUUid = strUuidInfo.substr(pos+1); 394 strUUid.erase(0, strUUid.find_first_not_of(" ")); 395 strUUid.erase(strUUid.find_last_not_of(" ") + 1); 396 397 while(true) { 398 pos = 0; 399 if( (pos = strUUid.find("-")) != string::npos) 400 strUUid.replace(pos,1,""); 401 else 402 break; 403 } 404 if (strUUid.size() != 32) 405 return false; 406 return true; 407 } 408 409 410 bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 411 { 412 stringstream paramStream(pParameter); 413 bool bRet,bFind = false; 414 string strLine, strPartition, strPartInfo, strPartName, strUUid; 415 string::size_type line_size, pos, posColon, posComma; 416 UINT uiPartOffset, uiPartSize; 417 STRUCT_PARAM_ITEM item; 418 STRUCT_CONFIG_ITEM uuid_item; 419 vecItem.clear(); 420 vecUuidItem.clear(); 421 while (!paramStream.eof()) { 422 getline(paramStream,strLine); 423 line_size = strLine.size(); 424 if (line_size == 0) 425 continue; 426 if (strLine[line_size - 1] == '\r'){ 427 strLine = strLine.substr(0, line_size - 1); 428 } 429 strLine.erase(0, strLine.find_first_not_of(" ")); 430 strLine.erase(strLine.find_last_not_of(" ") + 1); 431 if (strLine.size()==0 ) 432 continue; 433 if (strLine[0] == '#') 434 continue; 435 pos = strLine.find("uuid:"); 436 if (pos != string::npos) { 437 strPartInfo = strLine.substr(pos+5); 438 bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid); 439 if (bRet) { 440 strcpy(uuid_item.szItemName, strPartName.c_str()); 441 string_to_uuid(strUUid,uuid_item.szItemValue); 442 vecUuidItem.push_back(uuid_item); 443 } 444 continue; 445 } 446 447 pos = strLine.find("mtdparts"); 448 if (pos == string::npos) { 449 continue; 450 } 451 bFind = true; 452 posColon = strLine.find(':', pos); 453 if (posColon == string::npos) { 454 continue; 455 } 456 strPartition = strLine.substr(posColon + 1); 457 pos = 0; 458 posComma = strPartition.find(',', pos); 459 while (posComma != string::npos) { 460 strPartInfo = strPartition.substr(pos, posComma - pos); 461 bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 462 if (bRet) { 463 strcpy(item.szItemName, strPartName.c_str()); 464 item.uiItemOffset = uiPartOffset; 465 item.uiItemSize = uiPartSize; 466 vecItem.push_back(item); 467 } 468 pos = posComma + 1; 469 posComma = strPartition.find(',', pos); 470 } 471 strPartInfo = strPartition.substr(pos); 472 if (strPartInfo.size() > 0) { 473 bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 474 if (bRet) { 475 strcpy(item.szItemName, strPartName.c_str()); 476 item.uiItemOffset = uiPartOffset; 477 item.uiItemSize = uiPartSize; 478 vecItem.push_back(item); 479 } 480 } 481 break; 482 } 483 return bFind; 484 485 } 486 bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 487 { 488 FILE *file = NULL; 489 file = fopen(pParamFile, "rb"); 490 if( !file ) { 491 if (g_pLogObject) 492 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 493 return false; 494 } 495 int iFileSize; 496 fseek(file, 0, SEEK_END); 497 iFileSize = ftell(file); 498 fseek(file, 0, SEEK_SET); 499 char *pParamBuf = NULL; 500 pParamBuf = new char[iFileSize]; 501 if (!pParamBuf) { 502 fclose(file); 503 return false; 504 } 505 int iRead; 506 iRead = fread(pParamBuf, 1, iFileSize, file); 507 if (iRead != iFileSize) { 508 if (g_pLogObject) 509 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize); 510 fclose(file); 511 delete []pParamBuf; 512 return false; 513 } 514 fclose(file); 515 bool bRet; 516 bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem); 517 delete []pParamBuf; 518 return bRet; 519 } 520 void gen_rand_uuid(unsigned char *uuid_bin) 521 { 522 efi_guid_t id; 523 unsigned int *ptr = (unsigned int *)&id; 524 unsigned int i; 525 526 /* Set all fields randomly */ 527 for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 528 *(ptr + i) = cpu_to_be32(rand()); 529 530 id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 531 id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 532 533 memcpy(uuid_bin, id.raw, sizeof(id)); 534 } 535 536 void prepare_gpt_backup(u8 *master, u8 *backup) 537 { 538 gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 539 gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE); 540 u32 calc_crc32; 541 u64 val; 542 543 /* recalculate the values for the Backup GPT Header */ 544 val = le64_to_cpu(gptMasterHead->my_lba); 545 gptBackupHead->my_lba = gptMasterHead->alternate_lba; 546 gptBackupHead->alternate_lba = cpu_to_le64(val); 547 gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1); 548 gptBackupHead->header_crc32 = 0; 549 550 calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size)); 551 gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32); 552 } 553 void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector) 554 { 555 gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 556 gpt_entry *gptLastPartEntry = NULL; 557 u32 i; 558 u64 old_disksize; 559 u8 zerobuf[GPT_ENTRY_SIZE]; 560 561 memset(zerobuf,0,GPT_ENTRY_SIZE); 562 old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1; 563 for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 564 gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 565 if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0) 566 break; 567 } 568 i--; 569 gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry)); 570 571 gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1); 572 gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34); 573 574 if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition 575 gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34); 576 gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 577 } 578 gptMasterHead->header_crc32 = 0; 579 gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header))); 580 memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS); 581 memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE); 582 prepare_gpt_backup(master, backup); 583 584 } 585 bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup) 586 { 587 FILE *file = NULL; 588 file = fopen(pParamFile, "rb"); 589 if( !file ) { 590 if (g_pLogObject) 591 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 592 return false; 593 } 594 int iFileSize; 595 fseek(file, 0, SEEK_END); 596 iFileSize = ftell(file); 597 fseek(file, 0, SEEK_SET); 598 if (iFileSize != 67 * SECTOR_SIZE) { 599 if (g_pLogObject) 600 g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile); 601 fclose(file); 602 return false; 603 } 604 605 int iRead; 606 iRead = fread(master, 1, 34 * SECTOR_SIZE, file); 607 if (iRead != 34 * SECTOR_SIZE) { 608 if (g_pLogObject) 609 g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE); 610 fclose(file); 611 return false; 612 } 613 iRead = fread(backup, 1, 33 * SECTOR_SIZE, file); 614 if (iRead != 33 * SECTOR_SIZE) { 615 if (g_pLogObject) 616 g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE); 617 fclose(file); 618 return false; 619 } 620 fclose(file); 621 return true; 622 } 623 void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors) 624 { 625 legacy_mbr *mbr = (legacy_mbr *)gpt; 626 gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 627 gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 628 u32 i,j; 629 int pos; 630 string strPartName; 631 string::size_type colonPos; 632 /*1.protective mbr*/ 633 memset(gpt, 0, SECTOR_SIZE); 634 mbr->signature = MSDOS_MBR_SIGNATURE; 635 mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 636 mbr->partition_record[0].start_sect = 1; 637 mbr->partition_record[0].nr_sects = (u32)-1; 638 /*2.gpt header*/ 639 memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 640 gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 641 gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 642 gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 643 gptHead->my_lba = cpu_to_le64(1); 644 gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 645 gptHead->first_usable_lba = cpu_to_le64(34); 646 gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 647 gptHead->partition_entry_lba = cpu_to_le64(2); 648 gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 649 gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 650 gptHead->header_crc32 = 0; 651 gptHead->partition_entry_array_crc32 = 0; 652 gen_rand_uuid(gptHead->disk_guid.raw); 653 654 /*3.gpt partition entry*/ 655 memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 656 for (i = 0; i < vecParts.size(); i++) { 657 gen_rand_uuid(gptEntry->partition_type_guid.raw); 658 gen_rand_uuid(gptEntry->unique_partition_guid.raw); 659 gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 660 gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 661 gptEntry->attributes.raw = 0; 662 strPartName = vecParts[i].szItemName; 663 colonPos = strPartName.find_first_of(':'); 664 if (colonPos != string::npos) { 665 if (strPartName.find("bootable") != string::npos) 666 gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 667 if (strPartName.find("grow") != string::npos) 668 gptEntry->ending_lba = cpu_to_le64(diskSectors - 34); 669 strPartName = strPartName.substr(0, colonPos); 670 vecParts[i].szItemName[strPartName.size()] = 0; 671 } 672 for (j = 0; j < strlen(vecParts[i].szItemName); j++) 673 gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 674 if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1) 675 memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16); 676 gptEntry++; 677 } 678 679 gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 680 gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 681 682 } 683 bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag) 684 { 685 PRK28_IDB_SEC0 pSec0; 686 memset(pSector, 0, SECTOR_SIZE); 687 pSec0 = (PRK28_IDB_SEC0)pSector; 688 689 pSec0->dwTag = 0x0FF0AA55; 690 pSec0->uiRc4Flag = rc4Flag; 691 pSec0->usBootCode1Offset = 0x4; 692 pSec0->usBootCode2Offset = 0x4; 693 pSec0->usBootDataSize = usFlashDataSec; 694 pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 695 return true; 696 } 697 698 699 bool MakeSector1(PBYTE pSector) 700 { 701 PRK28_IDB_SEC1 pSec1; 702 memset(pSector, 0, SECTOR_SIZE); 703 pSec1 = (PRK28_IDB_SEC1)pSector; 704 705 pSec1->usSysReservedBlock = 0xC; 706 pSec1->usDisk0Size = 0xFFFF; 707 pSec1->uiChipTag = 0x38324B52; 708 return true; 709 } 710 711 bool MakeSector2(PBYTE pSector) 712 { 713 PRK28_IDB_SEC2 pSec2; 714 memset(pSector, 0, SECTOR_SIZE); 715 pSec2 = (PRK28_IDB_SEC2)pSector; 716 717 strcpy(pSec2->szVcTag, "VC"); 718 strcpy(pSec2->szCrcTag, "CRC"); 719 return true; 720 } 721 722 bool MakeSector3(PBYTE pSector) 723 { 724 memset(pSector,0,SECTOR_SIZE); 725 return true; 726 } 727 728 int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag) 729 { 730 RK28_IDB_SEC0 sector0Info; 731 RK28_IDB_SEC1 sector1Info; 732 RK28_IDB_SEC2 sector2Info; 733 RK28_IDB_SEC3 sector3Info; 734 UINT i; 735 MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag); 736 MakeSector1((PBYTE)§or1Info); 737 if (!MakeSector2((PBYTE)§or2Info)) { 738 return -6; 739 } 740 if (!MakeSector3((PBYTE)§or3Info)) { 741 return -7; 742 } 743 sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 744 sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 745 sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 746 747 memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 748 memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 749 memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 750 751 if (rc4Flag) { 752 for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++) 753 P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE); 754 for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++) 755 P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE); 756 } 757 758 memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 759 memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 760 761 sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 762 memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 763 for(i = 0; i < 4; i++) { 764 if(i == 1) { 765 continue; 766 } else { 767 P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 768 } 769 } 770 return 0; 771 } 772 773 774 775 bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 776 { 777 if ((dev.emUsbType & uiSupportType) == dev.emUsbType) 778 return true; 779 else 780 { 781 ERROR_COLOR_ATTR; 782 printf("The device does not support this operation!"); 783 NORMAL_COLOR_ATTR; 784 printf("\r\n"); 785 return false; 786 } 787 } 788 bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 789 { 790 u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 791 u32 total_size_sector; 792 CRKComm *pComm = NULL; 793 PARAM_ITEM_VECTOR vecItems; 794 CONFIG_ITEM_VECTOR vecUuid; 795 int iRet; 796 bool bRet, bSuccess = false; 797 if (!check_device_type(dev, RKUSB_MASKROM)) 798 return false; 799 800 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 801 if (!bRet) { 802 ERROR_COLOR_ATTR; 803 printf("Creating Comm Object failed!"); 804 NORMAL_COLOR_ATTR; 805 printf("\r\n"); 806 return bSuccess; 807 } 808 printf("Writing gpt...\r\n"); 809 //1.get flash info 810 iRet = pComm->RKU_ReadFlashInfo(flash_info); 811 if (iRet != ERR_SUCCESS) { 812 ERROR_COLOR_ATTR; 813 printf("Reading Flash Info failed!"); 814 NORMAL_COLOR_ATTR; 815 printf("\r\n"); 816 return bSuccess; 817 } 818 total_size_sector = *(u32 *)flash_info; 819 if (strstr(szParameter, ".img")) { 820 if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) { 821 ERROR_COLOR_ATTR; 822 printf("Loading partition image failed!"); 823 NORMAL_COLOR_ATTR; 824 printf("\r\n"); 825 return bSuccess; 826 } 827 update_gpt_disksize(master_gpt, backup_gpt, total_size_sector); 828 } else { 829 //2.get partition from parameter 830 bRet = parse_parameter_file(szParameter, vecItems, vecUuid); 831 if (!bRet) { 832 ERROR_COLOR_ATTR; 833 printf("Parsing parameter failed!"); 834 NORMAL_COLOR_ATTR; 835 printf("\r\n"); 836 return bSuccess; 837 } 838 vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33; 839 //3.generate gpt info 840 create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector); 841 memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 842 memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 843 prepare_gpt_backup(master_gpt, backup_gpt); 844 } 845 846 //4. write gpt 847 iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 848 if (iRet != ERR_SUCCESS) { 849 ERROR_COLOR_ATTR; 850 printf("Writing master gpt failed!"); 851 NORMAL_COLOR_ATTR; 852 printf("\r\n"); 853 return bSuccess; 854 } 855 iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt); 856 if (iRet != ERR_SUCCESS) { 857 ERROR_COLOR_ATTR; 858 printf("Writing backup gpt failed!"); 859 NORMAL_COLOR_ATTR; 860 printf("\r\n"); 861 return bSuccess; 862 } 863 864 bSuccess = true; 865 CURSOR_MOVEUP_LINE(1); 866 CURSOR_DEL_LINE; 867 printf("Writing gpt succeeded.\r\n"); 868 return bSuccess; 869 } 870 871 #include "boot_merger.h" 872 #define ENTRY_ALIGN (2048) 873 options gOpts; 874 875 876 char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 877 char* gConfigPath; 878 uint8_t gBuf[MAX_MERGE_SIZE]; 879 880 static inline void fixPath(char* path) { 881 int i, len = strlen(path); 882 for(i=0; i<len; i++) { 883 if (path[i] == '\\') 884 path[i] = '/'; 885 else if (path[i] == '\r' || path[i] == '\n') 886 path[i] = '\0'; 887 } 888 } 889 890 static bool parseChip(FILE* file) { 891 if (SCANF_EAT(file) != 0) { 892 return false; 893 } 894 if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 895 return false; 896 } 897 printf("chip: %s\n", gOpts.chip); 898 return true; 899 } 900 901 static bool parseVersion(FILE* file) { 902 if (SCANF_EAT(file) != 0) { 903 return false; 904 } 905 if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 906 return false; 907 if (SCANF_EAT(file) != 0) { 908 return false; 909 } 910 if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 911 return false; 912 printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor); 913 return true; 914 } 915 916 static bool parse471(FILE* file) { 917 int i, index, pos; 918 char buf[MAX_LINE_LEN]; 919 920 if (SCANF_EAT(file) != 0) { 921 return false; 922 } 923 if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 924 return false; 925 printf("num: %d\n", gOpts.code471Num); 926 if (!gOpts.code471Num) 927 return true; 928 if (gOpts.code471Num < 0) 929 return false; 930 gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 931 for (i=0; i<gOpts.code471Num; i++) { 932 if (SCANF_EAT(file) != 0) { 933 return false; 934 } 935 if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 936 != 2) 937 return false; 938 index--; 939 fixPath(buf); 940 strcpy((char*)gOpts.code471Path[index], buf); 941 printf("path%i: %s\n", index, gOpts.code471Path[index]); 942 } 943 pos = ftell(file); 944 if (SCANF_EAT(file) != 0) { 945 return false; 946 } 947 if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 948 fseek(file, pos, SEEK_SET); 949 printf("sleep: %d\n", gOpts.code471Sleep); 950 return true; 951 } 952 953 static bool parse472(FILE* file) { 954 int i, index, pos; 955 char buf[MAX_LINE_LEN]; 956 957 if (SCANF_EAT(file) != 0) { 958 return false; 959 } 960 if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 961 return false; 962 printf("num: %d\n", gOpts.code472Num); 963 if (!gOpts.code472Num) 964 return true; 965 if (gOpts.code472Num < 0) 966 return false; 967 gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 968 for (i=0; i<gOpts.code472Num; i++) { 969 if (SCANF_EAT(file) != 0) { 970 return false; 971 } 972 if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 973 != 2) 974 return false; 975 fixPath(buf); 976 index--; 977 strcpy((char*)gOpts.code472Path[index], buf); 978 printf("path%i: %s\n", index, gOpts.code472Path[index]); 979 } 980 pos = ftell(file); 981 if (SCANF_EAT(file) != 0) { 982 return false; 983 } 984 if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 985 fseek(file, pos, SEEK_SET); 986 printf("sleep: %d\n", gOpts.code472Sleep); 987 return true; 988 } 989 990 static bool parseLoader(FILE* file) { 991 int i, j, index, pos; 992 char buf[MAX_LINE_LEN]; 993 char buf2[MAX_LINE_LEN]; 994 995 if (SCANF_EAT(file) != 0) { 996 return false; 997 } 998 pos = ftell(file); 999 if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 1000 fseek(file, pos, SEEK_SET); 1001 if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 1002 return false; 1003 } 1004 } 1005 printf("num: %d\n", gOpts.loaderNum); 1006 if (!gOpts.loaderNum) 1007 return false; 1008 if (gOpts.loaderNum < 0) 1009 return false; 1010 gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 1011 for (i=0; i<gOpts.loaderNum; i++) { 1012 if (SCANF_EAT(file) != 0) { 1013 return false; 1014 } 1015 if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 1016 != 2) 1017 return false; 1018 index--; 1019 strcpy(gOpts.loader[index].name, buf); 1020 printf("name%d: %s\n", index, gOpts.loader[index].name); 1021 } 1022 for (i=0; i<gOpts.loaderNum; i++) { 1023 if (SCANF_EAT(file) != 0) { 1024 return false; 1025 } 1026 if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 1027 != 2) 1028 return false; 1029 for (j=0; j<gOpts.loaderNum; j++) { 1030 if (!strcmp(gOpts.loader[j].name, buf)) { 1031 fixPath(buf2); 1032 strcpy(gOpts.loader[j].path, buf2); 1033 printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 1034 break; 1035 } 1036 } 1037 if (j >= gOpts.loaderNum) { 1038 return false; 1039 } 1040 } 1041 return true; 1042 } 1043 1044 static bool parseOut(FILE* file) { 1045 if (SCANF_EAT(file) != 0) { 1046 return false; 1047 } 1048 if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 1049 return false; 1050 fixPath(gOpts.outPath); 1051 printf("out: %s\n", gOpts.outPath); 1052 return true; 1053 } 1054 1055 1056 void printOpts(FILE* out) { 1057 int i; 1058 fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 1059 fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 1060 "=%d\n", gOpts.major, gOpts.minor); 1061 1062 fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 1063 for (i=0 ;i<gOpts.code471Num ;i++) { 1064 fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 1065 } 1066 if (gOpts.code471Sleep > 0) 1067 fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 1068 1069 fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 1070 for (i=0 ;i<gOpts.code472Num ;i++) { 1071 fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 1072 } 1073 if (gOpts.code472Sleep > 0) 1074 fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 1075 1076 fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 1077 for (i=0 ;i<gOpts.loaderNum ;i++) { 1078 fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 1079 } 1080 for (i=0 ;i<gOpts.loaderNum ;i++) { 1081 fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 1082 } 1083 1084 fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 1085 } 1086 1087 static bool parseOpts(void) { 1088 bool ret = false; 1089 bool chipOk = false; 1090 bool versionOk = false; 1091 bool code471Ok = true; 1092 bool code472Ok = true; 1093 bool loaderOk = false; 1094 bool outOk = false; 1095 char buf[MAX_LINE_LEN]; 1096 1097 char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 1098 FILE* file; 1099 file = fopen(configPath, "r"); 1100 if (!file) { 1101 fprintf(stderr, "config (%s) not found!\n", configPath); 1102 if (configPath == (char*)DEF_CONFIG_FILE) { 1103 file = fopen(DEF_CONFIG_FILE, "w"); 1104 if (file) { 1105 fprintf(stderr, "creating defconfig\n"); 1106 printOpts(file); 1107 } 1108 } 1109 goto end; 1110 } 1111 1112 printf("Starting to parse...\n"); 1113 1114 if (SCANF_EAT(file) != 0) { 1115 goto end; 1116 } 1117 while(fscanf(file, "%s", buf) == 1) { 1118 if (!strcmp(buf, SEC_CHIP)) { 1119 chipOk = parseChip(file); 1120 if (!chipOk) { 1121 printf("parseChip failed!\n"); 1122 goto end; 1123 } 1124 } else if (!strcmp(buf, SEC_VERSION)) { 1125 versionOk = parseVersion(file); 1126 if (!versionOk) { 1127 printf("parseVersion failed!\n"); 1128 goto end; 1129 } 1130 } else if (!strcmp(buf, SEC_471)) { 1131 code471Ok = parse471(file); 1132 if (!code471Ok) { 1133 printf("parse471 failed!\n"); 1134 goto end; 1135 } 1136 } else if (!strcmp(buf, SEC_472)) { 1137 code472Ok = parse472(file); 1138 if (!code472Ok) { 1139 printf("parse472 failed!\n"); 1140 goto end; 1141 } 1142 } else if (!strcmp(buf, SEC_LOADER)) { 1143 loaderOk = parseLoader(file); 1144 if (!loaderOk) { 1145 printf("parseLoader failed!\n"); 1146 goto end; 1147 } 1148 } else if (!strcmp(buf, SEC_OUT)) { 1149 outOk = parseOut(file); 1150 if (!outOk) { 1151 printf("parseOut failed!\n"); 1152 goto end; 1153 } 1154 } else if (buf[0] == '#') { 1155 continue; 1156 } else { 1157 printf("unknown sec: %s!\n", buf); 1158 goto end; 1159 } 1160 if (SCANF_EAT(file) != 0) { 1161 goto end; 1162 } 1163 } 1164 1165 if (chipOk && versionOk && code471Ok && code472Ok 1166 && loaderOk && outOk) 1167 ret = true; 1168 end: 1169 if (file) 1170 fclose(file); 1171 return ret; 1172 } 1173 1174 bool initOpts(void) { 1175 //set default opts 1176 gOpts.major = DEF_MAJOR; 1177 gOpts.minor = DEF_MINOR; 1178 strcpy(gOpts.chip, DEF_CHIP); 1179 gOpts.code471Sleep = DEF_CODE471_SLEEP; 1180 gOpts.code472Sleep = DEF_CODE472_SLEEP; 1181 gOpts.code471Num = DEF_CODE471_NUM; 1182 gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 1183 strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 1184 gOpts.code472Num = DEF_CODE472_NUM; 1185 gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 1186 strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 1187 gOpts.loaderNum = DEF_LOADER_NUM; 1188 gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 1189 strcpy(gOpts.loader[0].name, DEF_LOADER0); 1190 strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 1191 strcpy(gOpts.loader[1].name, DEF_LOADER1); 1192 strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 1193 strcpy(gOpts.outPath, DEF_OUT_PATH); 1194 1195 return parseOpts(); 1196 } 1197 1198 /************merge code****************/ 1199 1200 static inline uint32_t getBCD(unsigned short value) { 1201 uint8_t tmp[2] = {0}; 1202 int i; 1203 uint32_t ret; 1204 //if (value > 0xFFFF) { 1205 // return 0; 1206 //} 1207 for(i=0; i < 2; i++) { 1208 tmp[i] = (((value/10)%10)<<4) | (value%10); 1209 value /= 100; 1210 } 1211 ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 1212 1213 printf("ret: %x\n",ret); 1214 return ret&0xFF; 1215 } 1216 1217 static inline void str2wide(const char* str, uint16_t* wide, int len) 1218 { 1219 int i; 1220 for (i = 0; i < len; i++) { 1221 wide[i] = (uint16_t) str[i]; 1222 } 1223 wide[len] = 0; 1224 } 1225 1226 static inline void getName(char* path, uint16_t* dst) { 1227 char* end; 1228 char* start; 1229 int len; 1230 if (!path || !dst) 1231 return; 1232 start = strrchr(path, '/'); 1233 if (!start) 1234 start = path; 1235 else 1236 start++; 1237 end = strrchr(path, '.'); 1238 if (!end || (end < start)) 1239 end = path + strlen(path); 1240 len = end - start; 1241 if (len >= MAX_NAME_LEN) 1242 len = MAX_NAME_LEN -1; 1243 str2wide(start, dst, len); 1244 1245 1246 char name[MAX_NAME_LEN]; 1247 memset(name, 0, sizeof(name)); 1248 memcpy(name, start, len); 1249 printf("path: %s, name: %s\n", path, name); 1250 1251 } 1252 1253 static inline bool getFileSize(const char *path, uint32_t* size) { 1254 struct stat st; 1255 if(stat(path, &st) < 0) 1256 return false; 1257 *size = st.st_size; 1258 printf("path: %s, size: %d\n", path, *size); 1259 return true; 1260 } 1261 1262 static inline rk_time getTime(void) { 1263 rk_time rkTime; 1264 1265 struct tm *tm; 1266 time_t tt = time(NULL); 1267 tm = localtime(&tt); 1268 rkTime.year = tm->tm_year + 1900; 1269 rkTime.month = tm->tm_mon + 1; 1270 rkTime.day = tm->tm_mday; 1271 rkTime.hour = tm->tm_hour; 1272 rkTime.minute = tm->tm_min; 1273 rkTime.second = tm->tm_sec; 1274 printf("%d-%d-%d %02d:%02d:%02d\n", 1275 rkTime.year, rkTime.month, rkTime.day, 1276 rkTime.hour, rkTime.minute, rkTime.second); 1277 return rkTime; 1278 } 1279 1280 static bool writeFile(FILE* outFile, const char* path, bool fix) { 1281 bool ret = false; 1282 uint32_t size = 0, fixSize = 0; 1283 uint8_t* buf; 1284 1285 FILE* inFile = fopen(path, "rb"); 1286 if (!inFile) 1287 goto end; 1288 1289 if (!getFileSize(path, &size)) 1290 goto end; 1291 if (fix) { 1292 fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 1293 uint32_t tmp = fixSize % ENTRY_ALIGN; 1294 tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 1295 fixSize +=tmp; 1296 memset(gBuf, 0, fixSize); 1297 } else { 1298 memset(gBuf, 0, size+ENTRY_ALIGN); 1299 } 1300 if (!fread(gBuf, size, 1, inFile)) 1301 goto end; 1302 1303 if (fix) { 1304 1305 buf = gBuf; 1306 size = fixSize; 1307 while(1) { 1308 P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 1309 buf += SMALL_PACKET; 1310 if (fixSize <= SMALL_PACKET) 1311 break; 1312 fixSize -= SMALL_PACKET; 1313 } 1314 } else { 1315 uint32_t tmp = size % ENTRY_ALIGN; 1316 tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 1317 size +=tmp; 1318 P_RC4(gBuf, size); 1319 } 1320 1321 if (!fwrite(gBuf, size, 1, outFile)) 1322 goto end; 1323 ret = true; 1324 end: 1325 if (inFile) 1326 fclose(inFile); 1327 if (!ret) 1328 printf("writing entry (%s) failed\n", path); 1329 return ret; 1330 } 1331 1332 static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 1333 uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 1334 uint32_t size; 1335 rk_boot_entry entry; 1336 1337 printf("writing: %s\n", path); 1338 memset(&entry, 0, sizeof(rk_boot_entry)); 1339 getName(fixName ? fixName: path, entry.name); 1340 entry.size = sizeof(rk_boot_entry); 1341 entry.type = type; 1342 entry.dataOffset = *offset; 1343 if (!getFileSize(path, &size)) { 1344 printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path); 1345 return false; 1346 } 1347 if (fix) 1348 size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 1349 uint32_t tmp = size % ENTRY_ALIGN; 1350 size += tmp ? (ENTRY_ALIGN - tmp): 0; 1351 printf("alignment size: %d\n", size); 1352 entry.dataSize = size; 1353 entry.dataDelay = delay; 1354 *offset += size; 1355 fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 1356 return true; 1357 } 1358 1359 static inline uint32_t convertChipType(const char* chip) { 1360 char buffer[5]; 1361 memset(buffer, 0, sizeof(buffer)); 1362 snprintf(buffer, sizeof(buffer), "%s", chip); 1363 return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 1364 } 1365 1366 static inline uint32_t getChipType(const char* chip) { 1367 printf("chip: %s\n", chip); 1368 int chipType = RKNONE_DEVICE; 1369 if(!chip) { 1370 goto end; 1371 } 1372 if (!strcmp(chip, CHIP_RK28)) { 1373 chipType = RK28_DEVICE; 1374 } else if (!strcmp(chip, CHIP_RK28)) { 1375 chipType = RK28_DEVICE; 1376 } else if (!strcmp(chip, CHIP_RK281X)) { 1377 chipType = RK281X_DEVICE; 1378 } else if (!strcmp(chip, CHIP_RKPANDA)) { 1379 chipType = RKPANDA_DEVICE; 1380 } else if (!strcmp(chip, CHIP_RK27)) { 1381 chipType = RK27_DEVICE; 1382 } else if (!strcmp(chip, CHIP_RKNANO)) { 1383 chipType = RKNANO_DEVICE; 1384 } else if (!strcmp(chip, CHIP_RKSMART)) { 1385 chipType = RKSMART_DEVICE; 1386 } else if (!strcmp(chip, CHIP_RKCROWN)) { 1387 chipType = RKCROWN_DEVICE; 1388 } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 1389 chipType = RKCAYMAN_DEVICE; 1390 } else if (!strcmp(chip, CHIP_RK29)) { 1391 chipType = RK29_DEVICE; 1392 } else if (!strcmp(chip, CHIP_RK292X)) { 1393 chipType = RK292X_DEVICE; 1394 } else if (!strcmp(chip, CHIP_RK30)) { 1395 chipType = RK30_DEVICE; 1396 } else if (!strcmp(chip, CHIP_RK30B)) { 1397 chipType = RK30B_DEVICE; 1398 } else if (!strcmp(chip, CHIP_RK31)) { 1399 chipType = RK31_DEVICE; 1400 } else if (!strcmp(chip, CHIP_RK32)) { 1401 chipType = RK32_DEVICE; 1402 } else { 1403 chipType = convertChipType(chip + 2); 1404 } 1405 1406 end: 1407 printf("type: 0x%x\n", chipType); 1408 if (chipType == RKNONE_DEVICE) { 1409 printf("chip type not supported!\n"); 1410 } 1411 return chipType; 1412 } 1413 1414 static inline void getBoothdr(rk_boot_header* hdr) { 1415 memset(hdr, 0, sizeof(rk_boot_header)); 1416 hdr->tag = TAG; 1417 hdr->size = sizeof(rk_boot_header); 1418 hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 1419 hdr->mergerVersion = MERGER_VERSION; 1420 hdr->releaseTime = getTime(); 1421 hdr->chipType = getChipType(gOpts.chip); 1422 1423 hdr->code471Num = gOpts.code471Num; 1424 hdr->code471Offset = sizeof(rk_boot_header); 1425 hdr->code471Size = sizeof(rk_boot_entry); 1426 1427 hdr->code472Num = gOpts.code472Num; 1428 hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 1429 hdr->code472Size = sizeof(rk_boot_entry); 1430 1431 hdr->loaderNum = gOpts.loaderNum; 1432 hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 1433 hdr->loaderSize = sizeof(rk_boot_entry); 1434 #ifndef USE_P_RC4 1435 hdr->rc4Flag = 1; 1436 #endif 1437 } 1438 1439 static inline uint32_t getCrc(const char* path) { 1440 uint32_t size = 0; 1441 uint32_t crc = 0; 1442 1443 FILE* file = fopen(path, "rb"); 1444 getFileSize(path, &size); 1445 if (!file) 1446 goto end; 1447 if (!fread(gBuf, size, 1, file)) 1448 goto end; 1449 crc = CRC_32(gBuf, size); 1450 printf("crc: 0x%08x\n", crc); 1451 end: 1452 if (file) 1453 fclose(file); 1454 return crc; 1455 } 1456 1457 bool mergeBoot(void) { 1458 uint32_t dataOffset; 1459 bool ret = false; 1460 int i; 1461 FILE* outFile; 1462 uint32_t crc; 1463 rk_boot_header hdr; 1464 1465 if (!initOpts()) 1466 return false; 1467 { 1468 char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 1469 char version[MAX_LINE_LEN]; 1470 snprintf(version, sizeof(version), "%s", gSubfix); 1471 if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 1472 subfix[0] = '\0'; 1473 } 1474 strcat(gOpts.outPath, version); 1475 printf("fix opt: %s\n", gOpts.outPath); 1476 } 1477 1478 printf("---------------\nUSING CONFIG:\n"); 1479 printOpts(stdout); 1480 printf("---------------\n\n"); 1481 1482 1483 outFile = fopen(gOpts.outPath, "wb+"); 1484 if (!outFile) { 1485 printf("Opening output file (%s) failed\n", gOpts.outPath); 1486 goto end; 1487 } 1488 1489 getBoothdr(&hdr); 1490 printf("Writing header...\n"); 1491 fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 1492 1493 dataOffset = sizeof(rk_boot_header) + 1494 (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 1495 sizeof(rk_boot_entry); 1496 1497 printf("Writing code 471 entry...\n"); 1498 for (i=0; i<gOpts.code471Num; i++) { 1499 if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 1500 &dataOffset, NULL, false)) 1501 goto end; 1502 } 1503 printf("Writing code 472 entry...\n"); 1504 for (i=0; i<gOpts.code472Num; i++) { 1505 if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 1506 &dataOffset, NULL, false)) 1507 goto end; 1508 } 1509 printf("Writing loader entry...\n"); 1510 for (i=0; i<gOpts.loaderNum; i++) { 1511 if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 1512 &dataOffset, gOpts.loader[i].name, true)) 1513 goto end; 1514 } 1515 1516 printf("Writing code 471...\n"); 1517 for (i=0; i<gOpts.code471Num; i++) { 1518 if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 1519 goto end; 1520 } 1521 printf("Writing code 472...\n"); 1522 for (i=0; i<gOpts.code472Num; i++) { 1523 if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 1524 goto end; 1525 } 1526 printf("Writing loader...\n"); 1527 for (i=0; i<gOpts.loaderNum; i++) { 1528 if (!writeFile(outFile, gOpts.loader[i].path, true)) 1529 goto end; 1530 } 1531 fflush(outFile); 1532 1533 printf("Writing crc...\n"); 1534 crc = getCrc(gOpts.outPath); 1535 if (!fwrite(&crc, sizeof(crc), 1, outFile)) 1536 goto end; 1537 printf("Done.\n"); 1538 ret = true; 1539 end: 1540 if (outFile) 1541 fclose(outFile); 1542 return ret; 1543 } 1544 1545 /************merge code end************/ 1546 /************unpack code***************/ 1547 1548 static inline void wide2str(const uint16_t* wide, char* str, int len) 1549 { 1550 int i; 1551 for (i = 0; i < len; i++) { 1552 str[i] = (char) (wide[i] & 0xFF); 1553 } 1554 str[len] = 0; 1555 } 1556 1557 static bool unpackEntry(rk_boot_entry* entry, const char* name, 1558 FILE* inFile) { 1559 bool ret = false; 1560 int size, i; 1561 FILE* outFile = fopen(name, "wb+"); 1562 if (!outFile) 1563 goto end; 1564 printf("unpacking entry (%s)\n", name); 1565 fseek(inFile, entry->dataOffset, SEEK_SET); 1566 size = entry->dataSize; 1567 if (!fread(gBuf, size, 1, inFile)) 1568 goto end; 1569 if (entry->type == ENTRY_LOADER) { 1570 for(i=0; i<size/SMALL_PACKET; i++) 1571 P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 1572 if (size % SMALL_PACKET) 1573 { 1574 P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 1575 } 1576 } else { 1577 P_RC4(gBuf, size); 1578 } 1579 if (!fwrite(gBuf, size, 1, outFile)) 1580 goto end; 1581 ret = true; 1582 end: 1583 if (outFile) 1584 fclose(outFile); 1585 return ret; 1586 } 1587 1588 bool unpackBoot(char* path) { 1589 bool ret = false; 1590 FILE* inFile = fopen(path, "rb"); 1591 int entryNum, i; 1592 char name[MAX_NAME_LEN]; 1593 rk_boot_entry* entrys; 1594 if (!inFile) { 1595 fprintf(stderr, "loader (%s) not found\n", path); 1596 goto end; 1597 } 1598 1599 rk_boot_header hdr; 1600 if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 1601 fprintf(stderr, "reading header failed\n"); 1602 goto end; 1603 } 1604 printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 1605 entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 1606 entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 1607 if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 1608 fprintf(stderr, "reading data failed\n"); 1609 goto end; 1610 } 1611 1612 printf("entry num: %d\n", entryNum); 1613 for (i=0; i<entryNum; i++) { 1614 wide2str(entrys[i].name, name, MAX_NAME_LEN); 1615 1616 printf("entry: t=%d, name=%s, off=%d, size=%d\n", 1617 entrys[i].type, name, entrys[i].dataOffset, 1618 entrys[i].dataSize); 1619 if (!unpackEntry(entrys + i, name, inFile)) { 1620 fprintf(stderr, "unpacking entry (%s) failed\n", name); 1621 goto end; 1622 } 1623 } 1624 printf("done\n"); 1625 ret = true; 1626 end: 1627 if (inFile) 1628 fclose(inFile); 1629 return ret; 1630 } 1631 1632 bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1633 { 1634 if (!check_device_type(dev, RKUSB_MASKROM)) 1635 return false; 1636 CRKImage *pImage = NULL; 1637 CRKBoot *pBoot = NULL; 1638 bool bRet, bSuccess = false; 1639 int iRet; 1640 1641 pImage = new CRKImage(szLoader, bRet); 1642 if (!bRet){ 1643 ERROR_COLOR_ATTR; 1644 printf("Opening loader failed, exiting download boot!"); 1645 NORMAL_COLOR_ATTR; 1646 printf("\r\n"); 1647 return bSuccess; 1648 } else { 1649 pBoot = (CRKBoot *)pImage->m_bootObject; 1650 CRKComm *pComm = NULL; 1651 CRKDevice *pDevice = NULL; 1652 1653 dev.emDeviceType = pBoot->SupportDevice; 1654 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1655 if (!bRet) { 1656 if (pImage) 1657 delete pImage; 1658 ERROR_COLOR_ATTR; 1659 printf("Creating Comm Object failed!"); 1660 NORMAL_COLOR_ATTR; 1661 printf("\r\n"); 1662 return bSuccess; 1663 } 1664 1665 pDevice = new CRKDevice(dev); 1666 if (!pDevice) { 1667 if (pImage) 1668 delete pImage; 1669 if (pComm) 1670 delete pComm; 1671 ERROR_COLOR_ATTR; 1672 printf("Creating device object failed!"); 1673 NORMAL_COLOR_ATTR; 1674 printf("\r\n"); 1675 return bSuccess; 1676 } 1677 1678 pDevice->SetObject(pImage, pComm, g_pLogObject); 1679 printf("Downloading bootloader...\r\n"); 1680 iRet = pDevice->DownloadBoot(); 1681 1682 CURSOR_MOVEUP_LINE(1); 1683 CURSOR_DEL_LINE; 1684 if (iRet == 0) { 1685 bSuccess = true; 1686 printf("Downloading bootloader succeeded.\r\n"); 1687 } 1688 else 1689 printf("Downloading bootloader failed!\r\n"); 1690 1691 if (pImage) 1692 delete pImage; 1693 if(pDevice) 1694 delete pDevice; 1695 } 1696 return bSuccess; 1697 } 1698 bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1699 { 1700 if (!check_device_type(dev, RKUSB_MASKROM)) 1701 return false; 1702 CRKImage *pImage = NULL; 1703 CRKBoot *pBoot = NULL; 1704 CRKComm *pComm = NULL; 1705 bool bRet, bSuccess = false; 1706 int iRet; 1707 char index; 1708 USHORT usFlashDataSec, usFlashBootSec; 1709 DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1710 char loaderCodeName[] = "FlashBoot"; 1711 char loaderDataName[] = "FlashData"; 1712 PBYTE loaderCodeBuffer = NULL; 1713 PBYTE loaderDataBuffer = NULL; 1714 PBYTE pIDBData = NULL; 1715 pImage = new CRKImage(szLoader, bRet); 1716 if (!bRet){ 1717 ERROR_COLOR_ATTR; 1718 printf("Opening loader failed, exiting upgrade loader!"); 1719 NORMAL_COLOR_ATTR; 1720 printf("\r\n"); 1721 goto Exit_UpgradeLoader; 1722 } else { 1723 pBoot = (CRKBoot *)pImage->m_bootObject; 1724 dev.emDeviceType = pBoot->SupportDevice; 1725 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1726 if (!bRet) { 1727 ERROR_COLOR_ATTR; 1728 printf("Creating Comm Object failed!"); 1729 NORMAL_COLOR_ATTR; 1730 printf("\r\n"); 1731 goto Exit_UpgradeLoader; 1732 } 1733 1734 printf("Upgrading loader...\r\n"); 1735 index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1736 if (index == -1) { 1737 if (g_pLogObject) { 1738 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__); 1739 } 1740 goto Exit_UpgradeLoader; 1741 } 1742 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1743 if (!bRet) { 1744 if (g_pLogObject) { 1745 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__); 1746 } 1747 goto Exit_UpgradeLoader; 1748 } 1749 1750 loaderCodeBuffer = new BYTE[dwLoaderSize]; 1751 memset(loaderCodeBuffer, 0, dwLoaderSize); 1752 if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1753 if (g_pLogObject) { 1754 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__); 1755 } 1756 goto Exit_UpgradeLoader; 1757 } 1758 1759 index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1760 if (index == -1) { 1761 if (g_pLogObject) { 1762 g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__); 1763 } 1764 delete []loaderCodeBuffer; 1765 return -4; 1766 } 1767 1768 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1769 if (!bRet) { 1770 if (g_pLogObject) { 1771 g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__); 1772 } 1773 goto Exit_UpgradeLoader; 1774 } 1775 1776 loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1777 memset(loaderDataBuffer, 0, dwLoaderDataSize); 1778 if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1779 if (g_pLogObject) { 1780 g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__); 1781 } 1782 goto Exit_UpgradeLoader; 1783 } 1784 1785 usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1786 usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1787 dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1788 pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1789 if (!pIDBData) { 1790 ERROR_COLOR_ATTR; 1791 printf("Allocating memory failed!"); 1792 NORMAL_COLOR_ATTR; 1793 printf("\r\n"); 1794 goto Exit_UpgradeLoader; 1795 } 1796 memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1797 iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag); 1798 if (iRet != 0) { 1799 ERROR_COLOR_ATTR; 1800 printf("Making idblock failed!"); 1801 NORMAL_COLOR_ATTR; 1802 printf("\r\n"); 1803 goto Exit_UpgradeLoader; 1804 } 1805 iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1806 CURSOR_MOVEUP_LINE(1); 1807 CURSOR_DEL_LINE; 1808 if (iRet == ERR_SUCCESS) { 1809 //pComm->Reset_Usb_Device(); 1810 bSuccess = true; 1811 printf("Upgrading loader succeeded.\r\n"); 1812 } else { 1813 printf("Upgrading loader failed!\r\n"); 1814 goto Exit_UpgradeLoader; 1815 } 1816 } 1817 Exit_UpgradeLoader: 1818 if (pImage) 1819 delete pImage; 1820 if (pComm) 1821 delete pComm; 1822 if (loaderCodeBuffer) 1823 delete []loaderCodeBuffer; 1824 if (loaderDataBuffer) 1825 delete []loaderDataBuffer; 1826 if (pIDBData) 1827 delete []pIDBData; 1828 return bSuccess; 1829 } 1830 1831 bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 1832 { 1833 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1834 return false; 1835 CRKImage *pImage = NULL; 1836 bool bRet, bSuccess = false; 1837 int iRet; 1838 CRKScan *pScan = NULL; 1839 pScan = new CRKScan(); 1840 pScan->SetVidPid(); 1841 1842 CRKComm *pComm = NULL; 1843 CRKDevice *pDevice = NULL; 1844 1845 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1846 if (!bRet) { 1847 if (pScan) 1848 delete pScan; 1849 ERROR_COLOR_ATTR; 1850 printf("Creating Comm Object failed!"); 1851 NORMAL_COLOR_ATTR; 1852 printf("\r\n"); 1853 return bSuccess; 1854 } 1855 1856 pDevice = new CRKDevice(dev); 1857 if (!pDevice) { 1858 if (pComm) 1859 delete pComm; 1860 if (pScan) 1861 delete pScan; 1862 ERROR_COLOR_ATTR; 1863 printf("Creating device object failed!"); 1864 NORMAL_COLOR_ATTR; 1865 printf("\r\n"); 1866 return bSuccess; 1867 } 1868 1869 pDevice->SetObject(pImage, pComm, g_pLogObject); 1870 pDevice->CallBackPointer = ProgressInfoProc; 1871 1872 printf("Starting to erase flash...\r\n"); 1873 iRet = pDevice->EraseAllBlocks(); 1874 if (pDevice) 1875 delete pDevice; 1876 1877 if (iRet == 0) { 1878 if (pScan) { 1879 pScan->SetVidPid(); 1880 pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 1881 delete pScan; 1882 } 1883 CURSOR_MOVEUP_LINE(1); 1884 CURSOR_DEL_LINE; 1885 bSuccess = true; 1886 printf("Erasing flash complete.\r\n"); 1887 } 1888 1889 return bSuccess; 1890 } 1891 1892 bool test_device(STRUCT_RKDEVICE_DESC &dev) 1893 { 1894 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1895 return false; 1896 CRKUsbComm *pComm = NULL; 1897 bool bRet, bSuccess = false; 1898 int iRet; 1899 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1900 if (bRet) { 1901 iRet = pComm->RKU_TestDeviceReady(); 1902 if (iRet != ERR_SUCCESS) { 1903 if (g_pLogObject) 1904 g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 1905 printf("Test Device failed!\r\n"); 1906 } else { 1907 bSuccess = true; 1908 printf("Test Device OK.\r\n"); 1909 } 1910 } else { 1911 printf("Test Device quit, creating comm object failed!\r\n"); 1912 } 1913 if (pComm) { 1914 delete pComm; 1915 pComm = NULL; 1916 } 1917 return bSuccess; 1918 } 1919 bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 1920 { 1921 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1922 return false; 1923 CRKUsbComm *pComm = NULL; 1924 bool bRet, bSuccess = false; 1925 int iRet; 1926 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1927 if (bRet) { 1928 iRet = pComm->RKU_ResetDevice(subCode); 1929 if (iRet != ERR_SUCCESS) { 1930 if (g_pLogObject) 1931 g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 1932 printf("Reset Device failed!\r\n"); 1933 } else { 1934 bSuccess = true; 1935 printf("Reset Device OK.\r\n"); 1936 } 1937 } else { 1938 printf("Reset Device quit, creating comm object failed!\r\n"); 1939 } 1940 if (pComm) { 1941 delete pComm; 1942 pComm = NULL; 1943 } 1944 return bSuccess; 1945 } 1946 1947 bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 1948 { 1949 CRKUsbComm *pComm = NULL; 1950 bool bRet, bSuccess = false; 1951 int iRet; 1952 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1953 return bSuccess; 1954 1955 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1956 if (bRet) { 1957 BYTE flashID[5]; 1958 iRet = pComm->RKU_ReadFlashID(flashID); 1959 if (iRet != ERR_SUCCESS) { 1960 if (g_pLogObject) 1961 g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 1962 printf("Reading flash ID failed!\r\n"); 1963 } else { 1964 printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 1965 bSuccess = true; 1966 } 1967 } else { 1968 printf("Read Flash ID quit, creating comm object failed!\r\n"); 1969 } 1970 if (pComm) { 1971 delete pComm; 1972 pComm = NULL; 1973 } 1974 return bSuccess; 1975 } 1976 bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 1977 { 1978 CRKUsbComm *pComm = NULL; 1979 bool bRet, bSuccess = false; 1980 int iRet; 1981 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1982 return bSuccess; 1983 1984 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1985 if (bRet) { 1986 STRUCT_FLASHINFO_CMD info; 1987 UINT uiRead; 1988 iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 1989 if (iRet != ERR_SUCCESS) { 1990 if (g_pLogObject) 1991 g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 1992 printf("Read Flash Info failed!\r\n"); 1993 } else { 1994 printf("Flash Info:\r\n"); 1995 if (info.bManufCode <= 7) { 1996 printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 1997 } 1998 else 1999 printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 2000 2001 printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 2002 printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 2003 printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 2004 printf("\tECC Bits: %d\r\n", info.bECCBits); 2005 printf("\tAccess Time: %d\r\n", info.bAccessTime); 2006 printf("\tFlash CS: "); 2007 for(int i = 0; i < 8; i++) { 2008 if( info.bFlashCS & (1 << i) ) 2009 printf("Flash<%d> ", i); 2010 } 2011 printf("\r\n"); 2012 bSuccess = true; 2013 } 2014 }else { 2015 printf("Read Flash Info quit, creating comm object failed!\r\n"); 2016 } 2017 if (pComm) { 2018 delete pComm; 2019 pComm = NULL; 2020 } 2021 return bSuccess; 2022 } 2023 bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 2024 { 2025 CRKUsbComm *pComm = NULL; 2026 bool bRet, bSuccess = false; 2027 int iRet; 2028 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2029 return bSuccess; 2030 2031 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2032 if (bRet) { 2033 BYTE chipInfo[16]; 2034 iRet = pComm->RKU_ReadChipInfo(chipInfo); 2035 if (iRet != ERR_SUCCESS) { 2036 if (g_pLogObject) 2037 g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 2038 printf("Read Chip Info failed!\r\n"); 2039 } else { 2040 string strChipInfo; 2041 g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 2042 printf("Chip Info: %s\r\n", strChipInfo.c_str()); 2043 bSuccess = true; 2044 } 2045 } else { 2046 printf("Read Chip Info quit, creating comm object failed!\r\n"); 2047 } 2048 if (pComm) { 2049 delete pComm; 2050 pComm = NULL; 2051 } 2052 return bSuccess; 2053 } 2054 bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 2055 { 2056 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2057 return false; 2058 CRKUsbComm *pComm = NULL; 2059 FILE *file = NULL; 2060 bool bRet, bFirst = true, bSuccess = false; 2061 int iRet; 2062 UINT iTotalRead = 0,iRead = 0; 2063 int nSectorSize = 512; 2064 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 2065 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2066 if (bRet) { 2067 if(szFile) { 2068 file = fopen(szFile, "wb+"); 2069 if( !file ) { 2070 printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 2071 goto Exit_ReadLBA; 2072 } 2073 } 2074 2075 while(uiLen > 0) { 2076 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 2077 iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 2078 iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 2079 if(ERR_SUCCESS == iRet) { 2080 uiLen -= iRead; 2081 iTotalRead += iRead; 2082 2083 if(szFile) { 2084 fwrite(pBuf, 1, iRead * nSectorSize, file); 2085 if (bFirst){ 2086 if (iTotalRead >= 1024) 2087 printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 2088 else 2089 printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 2090 bFirst = false; 2091 } else { 2092 CURSOR_MOVEUP_LINE(1); 2093 CURSOR_DEL_LINE; 2094 if (iTotalRead >= 1024) 2095 printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 2096 else 2097 printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 2098 } 2099 } 2100 else 2101 PrintData(pBuf, nSectorSize * iRead); 2102 } else { 2103 if (g_pLogObject) 2104 g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 2105 2106 printf("Read LBA failed!\r\n"); 2107 goto Exit_ReadLBA; 2108 } 2109 } 2110 bSuccess = true; 2111 } else { 2112 printf("Read LBA quit, creating comm object failed!\r\n"); 2113 } 2114 Exit_ReadLBA: 2115 if (pComm) { 2116 delete pComm; 2117 pComm = NULL; 2118 } 2119 if (file) 2120 fclose(file); 2121 return bSuccess; 2122 } 2123 bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 2124 { 2125 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2126 return false; 2127 CRKUsbComm *pComm = NULL; 2128 FILE *file = NULL; 2129 bool bRet, bFirst = true, bSuccess = false; 2130 int iRet; 2131 long long iTotalWrite = 0, iFileSize = 0; 2132 UINT iWrite = 0, iRead = 0; 2133 UINT uiLen; 2134 int nSectorSize = 512; 2135 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 2136 2137 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2138 if (bRet) { 2139 file = fopen(szFile, "rb"); 2140 if( !file ) { 2141 printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 2142 goto Exit_WriteLBA; 2143 } 2144 2145 iRet = fseeko(file, 0, SEEK_END); 2146 iFileSize = ftello(file); 2147 fseeko(file, 0, SEEK_SET); 2148 while(iTotalWrite < iFileSize) { 2149 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 2150 iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 2151 uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 2152 iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 2153 if(ERR_SUCCESS == iRet) { 2154 uiBegin += uiLen; 2155 iTotalWrite += iWrite; 2156 if (bFirst) { 2157 if (iTotalWrite >= 1024) 2158 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2159 else 2160 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2161 bFirst = false; 2162 } else { 2163 CURSOR_MOVEUP_LINE(1); 2164 CURSOR_DEL_LINE; 2165 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2166 } 2167 } else { 2168 if (g_pLogObject) 2169 g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 2170 2171 printf("Write LBA failed!\r\n"); 2172 goto Exit_WriteLBA; 2173 } 2174 } 2175 bSuccess = true; 2176 } else { 2177 printf("Write LBA quit, creating comm object failed!\r\n"); 2178 } 2179 Exit_WriteLBA: 2180 if (pComm) { 2181 delete pComm; 2182 pComm = NULL; 2183 } 2184 if (file) 2185 fclose(file); 2186 return bSuccess; 2187 } 2188 2189 void split_item(STRING_VECTOR &vecItems, char *pszItems) 2190 { 2191 string strItem; 2192 char szItem[100]; 2193 char *pos = NULL, *pStart; 2194 pStart = pszItems; 2195 pos = strchr(pStart, ','); 2196 while(pos != NULL) { 2197 memset(szItem, 0, 100); 2198 strncpy(szItem, pStart, pos - pStart); 2199 strItem = szItem; 2200 vecItems.push_back(strItem); 2201 pStart = pos + 1; 2202 if (*pStart == 0) 2203 break; 2204 pos = strchr(pStart, ','); 2205 } 2206 if (strlen(pStart) > 0) { 2207 memset(szItem, 0, 100); 2208 strncpy(szItem, pStart, strlen(pStart)); 2209 strItem = szItem; 2210 vecItems.push_back(strItem); 2211 } 2212 } 2213 2214 void tag_spl(char *tag, char *spl) 2215 { 2216 FILE *file = NULL; 2217 int len; 2218 2219 if(!tag || !spl) 2220 return; 2221 len = strlen(tag); 2222 printf("tag len=%d\n",len); 2223 file = fopen(spl, "rb"); 2224 if( !file ){ 2225 return; 2226 } 2227 int iFileSize; 2228 fseek(file, 0, SEEK_END); 2229 iFileSize = ftell(file); 2230 fseek(file, 0, SEEK_SET); 2231 char *Buf = NULL; 2232 Buf = new char[iFileSize + len + 1]; 2233 if (!Buf){ 2234 fclose(file); 2235 return; 2236 } 2237 memset(Buf, 0, iFileSize + 1); 2238 memcpy(Buf, tag, len); 2239 int iRead; 2240 iRead = fread(Buf+len, 1, iFileSize, file); 2241 if (iRead != iFileSize){ 2242 fclose(file); 2243 delete []Buf; 2244 return; 2245 } 2246 fclose(file); 2247 2248 len = strlen(spl); 2249 char *taggedspl = new char[len + 5]; 2250 strcpy(taggedspl, spl); 2251 strcpy(taggedspl + len, ".tag"); 2252 taggedspl[len+4] = 0; 2253 printf("Writing tagged spl to %s\n", taggedspl); 2254 2255 file = fopen(taggedspl, "wb"); 2256 if( !file ){ 2257 delete []taggedspl; 2258 delete []Buf; 2259 return; 2260 } 2261 fwrite(Buf, 1, iFileSize+len, file); 2262 fclose(file); 2263 delete []taggedspl; 2264 delete []Buf; 2265 printf("done\n"); 2266 return; 2267 } 2268 2269 bool handle_command(int argc, char* argv[], CRKScan *pScan) 2270 { 2271 string strCmd; 2272 strCmd = argv[1]; 2273 ssize_t cnt; 2274 bool bRet,bSuccess = false; 2275 char *s; 2276 int i, ret; 2277 STRUCT_RKDEVICE_DESC dev; 2278 2279 transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 2280 s = (char*)strCmd.c_str(); 2281 for(i = 0; i < (int)strlen(s); i++) 2282 s[i] = toupper(s[i]); 2283 2284 if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 2285 usage(); 2286 return true; 2287 } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2288 printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 2289 return true; 2290 } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 2291 mergeBoot(); 2292 2293 return true; 2294 } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 2295 string strLoader = argv[2]; 2296 2297 unpackBoot((char*)strLoader.c_str()); 2298 return true; 2299 } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 2300 if (argc == 4) { 2301 string tag = argv[2]; 2302 string spl = argv[3]; 2303 printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 2304 tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 2305 return true; 2306 } 2307 printf("tagspl: parameter error\n"); 2308 usage(); 2309 } 2310 cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 2311 if (cnt < 1) { 2312 ERROR_COLOR_ATTR; 2313 printf("Did not find any rockusb device, please plug device in!"); 2314 NORMAL_COLOR_ATTR; 2315 printf("\r\n"); 2316 return bSuccess; 2317 } else if (cnt > 1) { 2318 ERROR_COLOR_ATTR; 2319 printf("Found too many rockusb devices, please plug devices out!"); 2320 NORMAL_COLOR_ATTR; 2321 printf("\r\n"); 2322 return bSuccess; 2323 } 2324 2325 bRet = pScan->GetDevice(dev, 0); 2326 if (!bRet) { 2327 ERROR_COLOR_ATTR; 2328 printf("Getting information about rockusb device failed!"); 2329 NORMAL_COLOR_ATTR; 2330 printf("\r\n"); 2331 return bSuccess; 2332 } 2333 2334 if(strcmp(strCmd.c_str(), "RD") == 0) { 2335 if ((argc != 2) && (argc != 3)) 2336 printf("Parameter of [RD] command is invalid, please check help!\r\n"); 2337 else { 2338 if (argc == 2) 2339 bSuccess = reset_device(dev); 2340 else { 2341 UINT uiSubCode; 2342 char *pszEnd; 2343 uiSubCode = strtoul(argv[2], &pszEnd, 0); 2344 if (*pszEnd) 2345 printf("Subcode is invalid, please check!\r\n"); 2346 else { 2347 if (uiSubCode <= 5) 2348 bSuccess = reset_device(dev, uiSubCode); 2349 else 2350 printf("Subcode is invalid, please check!\r\n"); 2351 } 2352 } 2353 } 2354 } else if(strcmp(strCmd.c_str(), "TD") == 0) { 2355 bSuccess = test_device(dev); 2356 } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 2357 bSuccess = read_flash_id(dev); 2358 } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 2359 bSuccess = read_flash_info(dev); 2360 } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 2361 bSuccess = read_chip_info(dev); 2362 } else if(strcmp(strCmd.c_str(), "DB") == 0) { 2363 if (argc > 2) { 2364 string strLoader; 2365 strLoader = argv[2]; 2366 bSuccess = download_boot(dev, (char *)strLoader.c_str()); 2367 } else if (argc == 2) { 2368 ret = find_config_item(g_ConfigItemVec, "loader"); 2369 if (ret == -1) 2370 printf("Did not find loader item in config!\r\n"); 2371 else 2372 bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 2373 } else 2374 printf("Parameter of [DB] command is invalid, please check help!\r\n"); 2375 } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2376 if (argc > 2) { 2377 string strParameter; 2378 strParameter = argv[2]; 2379 bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2380 } else 2381 printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 2382 } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2383 if (argc > 2) { 2384 string strLoader; 2385 strLoader = argv[2]; 2386 bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2387 } else 2388 printf("Parameter of [UL] command is invalid, please check help!\r\n"); 2389 } else if(strcmp(strCmd.c_str(), "EF") == 0) { 2390 if (argc == 2) { 2391 bSuccess = erase_flash(dev); 2392 } else 2393 printf("Parameter of [EF] command is invalid, please check help!\r\n"); 2394 } else if(strcmp(strCmd.c_str(), "WL") == 0) { 2395 if (argc == 4) { 2396 UINT uiBegin; 2397 char *pszEnd; 2398 uiBegin = strtoul(argv[2], &pszEnd, 0); 2399 if (*pszEnd) 2400 printf("Begin is invalid, please check!\r\n"); 2401 else 2402 bSuccess = write_lba(dev, uiBegin, argv[3]); 2403 } else 2404 printf("Parameter of [WL] command is invalid, please check help!\r\n"); 2405 } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 2406 char *pszEnd; 2407 UINT uiBegin, uiLen; 2408 if (argc != 5) 2409 printf("Parameter of [RL] command is invalid, please check help!\r\n"); 2410 else { 2411 uiBegin = strtoul(argv[2], &pszEnd, 0); 2412 if (*pszEnd) 2413 printf("Begin is invalid, please check!\r\n"); 2414 else { 2415 uiLen = strtoul(argv[3], &pszEnd, 0); 2416 if (*pszEnd) 2417 printf("Len is invalid, please check!\r\n"); 2418 else { 2419 bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 2420 } 2421 } 2422 } 2423 } else { 2424 printf("command is invalid!\r\n"); 2425 usage(); 2426 } 2427 return bSuccess; 2428 } 2429 2430 2431 int main(int argc, char* argv[]) 2432 { 2433 CRKScan *pScan = NULL; 2434 int ret; 2435 char szProgramProcPath[100]; 2436 char szProgramDir[256]; 2437 string strLogDir,strConfigFile; 2438 struct stat statBuf; 2439 2440 g_ConfigItemVec.clear(); 2441 sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 2442 if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 2443 strcpy(szProgramDir, "."); 2444 else { 2445 char *pSlash; 2446 pSlash = strrchr(szProgramDir, '/'); 2447 if (pSlash) 2448 *pSlash = '\0'; 2449 } 2450 strLogDir = szProgramDir; 2451 strLogDir += "/log/"; 2452 strConfigFile = szProgramDir; 2453 strConfigFile += "/config.ini"; 2454 if (opendir(strLogDir.c_str()) == NULL) 2455 mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 2456 g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 2457 2458 if(stat(strConfigFile.c_str(), &statBuf) < 0) { 2459 if (g_pLogObject) { 2460 g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 2461 } 2462 } else if (S_ISREG(statBuf.st_mode)) { 2463 parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 2464 } 2465 2466 ret = libusb_init(NULL); 2467 if (ret < 0) { 2468 if (g_pLogObject) { 2469 g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 2470 delete g_pLogObject; 2471 } 2472 return -1; 2473 } 2474 2475 pScan = new CRKScan(); 2476 if (!pScan) { 2477 if (g_pLogObject) { 2478 g_pLogObject->Record("Error: failed to create object for searching device"); 2479 delete g_pLogObject; 2480 } 2481 libusb_exit(NULL); 2482 return -2; 2483 } 2484 pScan->SetVidPid(); 2485 2486 if (argc == 1) 2487 usage(); 2488 else if (!handle_command(argc, argv, pScan)) 2489 return -0xFF; 2490 if (pScan) 2491 delete pScan; 2492 if (g_pLogObject) 2493 delete g_pLogObject; 2494 libusb_exit(NULL); 2495 return 0; 2496 } 2497