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