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 iRet = pDevice->EraseAllBlocks(); 1931 if (pDevice) 1932 delete pDevice; 1933 1934 if (iRet == 0) { 1935 if (pScan) { 1936 pScan->SetVidPid(); 1937 pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 1938 delete pScan; 1939 } 1940 CURSOR_MOVEUP_LINE(1); 1941 CURSOR_DEL_LINE; 1942 bSuccess = true; 1943 printf("Erasing flash complete.\r\n"); 1944 } 1945 1946 return bSuccess; 1947 } 1948 1949 bool test_device(STRUCT_RKDEVICE_DESC &dev) 1950 { 1951 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1952 return false; 1953 CRKUsbComm *pComm = NULL; 1954 bool bRet, bSuccess = false; 1955 int iRet; 1956 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1957 if (bRet) { 1958 iRet = pComm->RKU_TestDeviceReady(); 1959 if (iRet != ERR_SUCCESS) { 1960 if (g_pLogObject) 1961 g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 1962 printf("Test Device failed!\r\n"); 1963 } else { 1964 bSuccess = true; 1965 printf("Test Device OK.\r\n"); 1966 } 1967 } else { 1968 printf("Test Device quit, creating comm object failed!\r\n"); 1969 } 1970 if (pComm) { 1971 delete pComm; 1972 pComm = NULL; 1973 } 1974 return bSuccess; 1975 } 1976 bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 1977 { 1978 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1979 return false; 1980 CRKUsbComm *pComm = NULL; 1981 bool bRet, bSuccess = false; 1982 int iRet; 1983 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1984 if (bRet) { 1985 iRet = pComm->RKU_ResetDevice(subCode); 1986 if (iRet != ERR_SUCCESS) { 1987 if (g_pLogObject) 1988 g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 1989 printf("Reset Device failed!\r\n"); 1990 } else { 1991 bSuccess = true; 1992 printf("Reset Device OK.\r\n"); 1993 } 1994 } else { 1995 printf("Reset Device quit, creating comm object failed!\r\n"); 1996 } 1997 if (pComm) { 1998 delete pComm; 1999 pComm = NULL; 2000 } 2001 return bSuccess; 2002 } 2003 2004 bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 2005 { 2006 CRKUsbComm *pComm = NULL; 2007 bool bRet, bSuccess = false; 2008 int iRet; 2009 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2010 return bSuccess; 2011 2012 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2013 if (bRet) { 2014 BYTE flashID[5]; 2015 iRet = pComm->RKU_ReadFlashID(flashID); 2016 if (iRet != ERR_SUCCESS) { 2017 if (g_pLogObject) 2018 g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 2019 printf("Reading flash ID failed!\r\n"); 2020 } else { 2021 printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 2022 bSuccess = true; 2023 } 2024 } else { 2025 printf("Read Flash ID quit, creating comm object failed!\r\n"); 2026 } 2027 if (pComm) { 2028 delete pComm; 2029 pComm = NULL; 2030 } 2031 return bSuccess; 2032 } 2033 bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 2034 { 2035 CRKUsbComm *pComm = NULL; 2036 bool bRet, bSuccess = false; 2037 int iRet; 2038 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2039 return bSuccess; 2040 2041 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2042 if (bRet) { 2043 STRUCT_FLASHINFO_CMD info; 2044 UINT uiRead; 2045 iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 2046 if (iRet != ERR_SUCCESS) { 2047 if (g_pLogObject) 2048 g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 2049 printf("Read Flash Info failed!\r\n"); 2050 } else { 2051 printf("Flash Info:\r\n"); 2052 if (info.bManufCode <= 7) { 2053 printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 2054 } 2055 else 2056 printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 2057 2058 printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 2059 printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 2060 printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 2061 printf("\tECC Bits: %d\r\n", info.bECCBits); 2062 printf("\tAccess Time: %d\r\n", info.bAccessTime); 2063 printf("\tFlash CS: "); 2064 for(int i = 0; i < 8; i++) { 2065 if( info.bFlashCS & (1 << i) ) 2066 printf("Flash<%d> ", i); 2067 } 2068 printf("\r\n"); 2069 bSuccess = true; 2070 } 2071 }else { 2072 printf("Read Flash Info quit, creating comm object failed!\r\n"); 2073 } 2074 if (pComm) { 2075 delete pComm; 2076 pComm = NULL; 2077 } 2078 return bSuccess; 2079 } 2080 bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 2081 { 2082 CRKUsbComm *pComm = NULL; 2083 bool bRet, bSuccess = false; 2084 int iRet; 2085 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2086 return bSuccess; 2087 2088 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2089 if (bRet) { 2090 BYTE chipInfo[16]; 2091 iRet = pComm->RKU_ReadChipInfo(chipInfo); 2092 if (iRet != ERR_SUCCESS) { 2093 if (g_pLogObject) 2094 g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 2095 printf("Read Chip Info failed!\r\n"); 2096 } else { 2097 string strChipInfo; 2098 g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 2099 printf("Chip Info: %s\r\n", strChipInfo.c_str()); 2100 bSuccess = true; 2101 } 2102 } else { 2103 printf("Read Chip Info quit, creating comm object failed!\r\n"); 2104 } 2105 if (pComm) { 2106 delete pComm; 2107 pComm = NULL; 2108 } 2109 return bSuccess; 2110 } 2111 bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt) 2112 { 2113 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2114 return false; 2115 gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE); 2116 CRKUsbComm *pComm = NULL; 2117 bool bRet, bSuccess = false; 2118 int iRet; 2119 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2120 if (bRet) { 2121 iRet = pComm->RKU_ReadLBA( 0, 34, pGpt); 2122 if(ERR_SUCCESS == iRet) { 2123 if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 2124 if (g_pLogObject) 2125 g_pLogObject->Record("Error: invalid gpt signature"); 2126 printf("Invalid GPT signature!\r\n"); 2127 goto Exit_ReadGPT; 2128 } 2129 2130 } else { 2131 if (g_pLogObject) 2132 g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 2133 printf("Read GPT failed!\r\n"); 2134 goto Exit_ReadGPT; 2135 } 2136 bSuccess = true; 2137 } 2138 Exit_ReadGPT: 2139 if (pComm) { 2140 delete pComm; 2141 pComm = NULL; 2142 } 2143 return bSuccess; 2144 } 2145 bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 2146 { 2147 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2148 return false; 2149 CRKUsbComm *pComm = NULL; 2150 FILE *file = NULL; 2151 bool bRet, bFirst = true, bSuccess = false; 2152 int iRet; 2153 UINT iTotalRead = 0,iRead = 0; 2154 int nSectorSize = 512; 2155 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 2156 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2157 if (bRet) { 2158 if(szFile) { 2159 file = fopen(szFile, "wb+"); 2160 if( !file ) { 2161 printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 2162 goto Exit_ReadLBA; 2163 } 2164 } 2165 2166 while(uiLen > 0) { 2167 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 2168 iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 2169 iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 2170 if(ERR_SUCCESS == iRet) { 2171 uiLen -= iRead; 2172 iTotalRead += iRead; 2173 2174 if(szFile) { 2175 fwrite(pBuf, 1, iRead * nSectorSize, file); 2176 if (bFirst){ 2177 if (iTotalRead >= 1024) 2178 printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 2179 else 2180 printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 2181 bFirst = false; 2182 } else { 2183 CURSOR_MOVEUP_LINE(1); 2184 CURSOR_DEL_LINE; 2185 if (iTotalRead >= 1024) 2186 printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 2187 else 2188 printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 2189 } 2190 } 2191 else 2192 PrintData(pBuf, nSectorSize * iRead); 2193 } else { 2194 if (g_pLogObject) 2195 g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 2196 2197 printf("Read LBA failed!\r\n"); 2198 goto Exit_ReadLBA; 2199 } 2200 } 2201 bSuccess = true; 2202 } else { 2203 printf("Read LBA quit, creating comm object failed!\r\n"); 2204 } 2205 Exit_ReadLBA: 2206 if (pComm) { 2207 delete pComm; 2208 pComm = NULL; 2209 } 2210 if (file) 2211 fclose(file); 2212 return bSuccess; 2213 } 2214 bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize) 2215 { 2216 UINT uiErase=2048*64; 2217 bool bSuccess = true; 2218 int iRet; 2219 while (uiSize) 2220 { 2221 if (uiSize>=uiErase) 2222 { 2223 iRet = pComm->RKU_EraseLBA(uiOffset,uiErase); 2224 uiSize -= uiErase; 2225 uiOffset += uiErase; 2226 } 2227 else 2228 { 2229 iRet = pComm->RKU_EraseLBA(uiOffset,uiSize); 2230 uiSize = 0; 2231 uiOffset += uiSize; 2232 } 2233 if (iRet!=ERR_SUCCESS) 2234 { 2235 if (g_pLogObject) 2236 { 2237 g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet); 2238 } 2239 bSuccess = false; 2240 break; 2241 } 2242 } 2243 return bSuccess; 2244 2245 } 2246 bool EatSparseChunk(FILE *file, chunk_header &chunk) 2247 { 2248 UINT uiRead; 2249 uiRead = fread(&chunk, 1, sizeof(chunk_header), file); 2250 if (uiRead != sizeof(chunk_header)) { 2251 if (g_pLogObject) 2252 { 2253 g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno); 2254 } 2255 return false; 2256 } 2257 return true; 2258 } 2259 bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize) 2260 { 2261 UINT uiRead; 2262 uiRead = fread(pBuf, 1, dwSize, file); 2263 if (uiRead!=dwSize) 2264 { 2265 if (g_pLogObject) 2266 { 2267 g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno); 2268 } 2269 return false; 2270 } 2271 return true; 2272 } 2273 2274 bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile) 2275 { 2276 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2277 return false; 2278 CRKUsbComm *pComm = NULL; 2279 FILE *file = NULL; 2280 bool bRet, bSuccess = false, bFirst = true; 2281 int iRet; 2282 u64 iTotalWrite = 0, iFileSize = 0; 2283 UINT iRead = 0, uiTransferSec, curChunk, i; 2284 UINT dwChunkDataSize, dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc; 2285 BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA]; 2286 sparse_header header; 2287 chunk_header chunk; 2288 dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE; 2289 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2290 if (bRet) { 2291 bRet = erase_partition(pComm, uiBegin, uiSize); 2292 if (!bRet) { 2293 printf("%s failed, erase partition error\r\n", __func__); 2294 goto Exit_WriteSparseLBA; 2295 } 2296 file = fopen(szFile, "rb"); 2297 if( !file ) { 2298 printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile); 2299 goto Exit_WriteSparseLBA; 2300 } 2301 fseeko(file, 0, SEEK_SET); 2302 iRead = fread(&header, 1, sizeof(header), file); 2303 if (iRead != sizeof(sparse_header)) 2304 { 2305 if (g_pLogObject) 2306 { 2307 g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno); 2308 } 2309 goto Exit_WriteSparseLBA; 2310 } 2311 iFileSize = header.blk_sz * (u64)header.total_blks; 2312 iTotalWrite = 0; 2313 curChunk = 0; 2314 2315 while(curChunk < header.total_chunks) 2316 { 2317 if (!EatSparseChunk(file, chunk)) { 2318 goto Exit_WriteSparseLBA; 2319 } 2320 curChunk++; 2321 switch (chunk.chunk_type) { 2322 case CHUNK_TYPE_RAW: 2323 dwChunkDataSize = chunk.total_sz - sizeof(chunk_header); 2324 while (dwChunkDataSize) { 2325 memset(pBuf, 0, dwMaxReadWriteBytes); 2326 if (dwChunkDataSize >= dwMaxReadWriteBytes) { 2327 dwTransferBytes = dwMaxReadWriteBytes; 2328 uiTransferSec = DEFAULT_RW_LBA; 2329 } else { 2330 dwTransferBytes = dwChunkDataSize; 2331 uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 2332 } 2333 if (!EatSparseData(file, pBuf, dwTransferBytes)) { 2334 goto Exit_WriteSparseLBA; 2335 } 2336 iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 2337 if( ERR_SUCCESS == iRet ) { 2338 dwChunkDataSize -= dwTransferBytes; 2339 iTotalWrite += dwTransferBytes; 2340 uiBegin += uiTransferSec; 2341 } else { 2342 if (g_pLogObject) { 2343 g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)", __func__, iTotalWrite, iRet); 2344 } 2345 goto Exit_WriteSparseLBA; 2346 } 2347 if (bFirst) { 2348 if (iTotalWrite >= 1024) 2349 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2350 else 2351 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2352 bFirst = false; 2353 } else { 2354 CURSOR_MOVEUP_LINE(1); 2355 CURSOR_DEL_LINE; 2356 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2357 } 2358 } 2359 break; 2360 case CHUNK_TYPE_FILL: 2361 dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 2362 if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) { 2363 goto Exit_WriteSparseLBA; 2364 } 2365 while (dwChunkDataSize) { 2366 memset(pBuf, 0, dwMaxReadWriteBytes); 2367 if (dwChunkDataSize >= dwMaxReadWriteBytes) { 2368 dwTransferBytes = dwMaxReadWriteBytes; 2369 uiTransferSec = DEFAULT_RW_LBA; 2370 } else { 2371 dwTransferBytes = dwChunkDataSize; 2372 uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 2373 } 2374 for (i = 0; i < dwTransferBytes / 4; i++) { 2375 *(DWORD *)(pBuf + i * 4) = dwFillByte; 2376 } 2377 iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 2378 if( ERR_SUCCESS == iRet ) { 2379 dwChunkDataSize -= dwTransferBytes; 2380 iTotalWrite += dwTransferBytes; 2381 uiBegin += uiTransferSec; 2382 } else { 2383 if (g_pLogObject) { 2384 g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet); 2385 } 2386 goto Exit_WriteSparseLBA; 2387 } 2388 if (bFirst) { 2389 if (iTotalWrite >= 1024) 2390 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2391 else 2392 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2393 bFirst = false; 2394 } else { 2395 CURSOR_MOVEUP_LINE(1); 2396 CURSOR_DEL_LINE; 2397 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2398 } 2399 } 2400 break; 2401 case CHUNK_TYPE_DONT_CARE: 2402 dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 2403 iTotalWrite += dwChunkDataSize; 2404 uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1)); 2405 uiBegin += uiTransferSec; 2406 if (bFirst) { 2407 if (iTotalWrite >= 1024) 2408 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2409 else 2410 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2411 bFirst = false; 2412 } else { 2413 CURSOR_MOVEUP_LINE(1); 2414 CURSOR_DEL_LINE; 2415 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2416 } 2417 break; 2418 case CHUNK_TYPE_CRC32: 2419 EatSparseData(file,(PBYTE)&dwCrc,4); 2420 break; 2421 } 2422 } 2423 bSuccess = true; 2424 } else { 2425 printf("Write LBA quit, creating comm object failed!\r\n"); 2426 } 2427 Exit_WriteSparseLBA: 2428 if (pComm) { 2429 delete pComm; 2430 pComm = NULL; 2431 } 2432 if (file) 2433 fclose(file); 2434 return bSuccess; 2435 2436 } 2437 2438 bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 2439 { 2440 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2441 return false; 2442 CRKUsbComm *pComm = NULL; 2443 FILE *file = NULL; 2444 bool bRet, bFirst = true, bSuccess = false; 2445 int iRet; 2446 long long iTotalWrite = 0, iFileSize = 0; 2447 UINT iWrite = 0, iRead = 0; 2448 UINT uiLen; 2449 int nSectorSize = 512; 2450 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 2451 2452 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2453 if (bRet) { 2454 file = fopen(szFile, "rb"); 2455 if( !file ) { 2456 printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 2457 goto Exit_WriteLBA; 2458 } 2459 2460 iRet = fseeko(file, 0, SEEK_END); 2461 iFileSize = ftello(file); 2462 fseeko(file, 0, SEEK_SET); 2463 while(iTotalWrite < iFileSize) { 2464 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 2465 iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 2466 uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 2467 iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 2468 if(ERR_SUCCESS == iRet) { 2469 uiBegin += uiLen; 2470 iTotalWrite += iWrite; 2471 if (bFirst) { 2472 if (iTotalWrite >= 1024) 2473 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2474 else 2475 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2476 bFirst = false; 2477 } else { 2478 CURSOR_MOVEUP_LINE(1); 2479 CURSOR_DEL_LINE; 2480 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2481 } 2482 } else { 2483 if (g_pLogObject) 2484 g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 2485 2486 printf("Write LBA failed!\r\n"); 2487 goto Exit_WriteLBA; 2488 } 2489 } 2490 bSuccess = true; 2491 } else { 2492 printf("Write LBA quit, creating comm object failed!\r\n"); 2493 } 2494 Exit_WriteLBA: 2495 if (pComm) { 2496 delete pComm; 2497 pComm = NULL; 2498 } 2499 if (file) 2500 fclose(file); 2501 return bSuccess; 2502 } 2503 2504 void split_item(STRING_VECTOR &vecItems, char *pszItems) 2505 { 2506 string strItem; 2507 char szItem[100]; 2508 char *pos = NULL, *pStart; 2509 pStart = pszItems; 2510 pos = strchr(pStart, ','); 2511 while(pos != NULL) { 2512 memset(szItem, 0, 100); 2513 strncpy(szItem, pStart, pos - pStart); 2514 strItem = szItem; 2515 vecItems.push_back(strItem); 2516 pStart = pos + 1; 2517 if (*pStart == 0) 2518 break; 2519 pos = strchr(pStart, ','); 2520 } 2521 if (strlen(pStart) > 0) { 2522 memset(szItem, 0, 100); 2523 strncpy(szItem, pStart, strlen(pStart)); 2524 strItem = szItem; 2525 vecItems.push_back(strItem); 2526 } 2527 } 2528 2529 void tag_spl(char *tag, char *spl) 2530 { 2531 FILE *file = NULL; 2532 int len; 2533 2534 if(!tag || !spl) 2535 return; 2536 len = strlen(tag); 2537 printf("tag len=%d\n",len); 2538 file = fopen(spl, "rb"); 2539 if( !file ){ 2540 return; 2541 } 2542 int iFileSize; 2543 fseek(file, 0, SEEK_END); 2544 iFileSize = ftell(file); 2545 fseek(file, 0, SEEK_SET); 2546 char *Buf = NULL; 2547 Buf = new char[iFileSize + len + 1]; 2548 if (!Buf){ 2549 fclose(file); 2550 return; 2551 } 2552 memset(Buf, 0, iFileSize + 1); 2553 memcpy(Buf, tag, len); 2554 int iRead; 2555 iRead = fread(Buf+len, 1, iFileSize, file); 2556 if (iRead != iFileSize){ 2557 fclose(file); 2558 delete []Buf; 2559 return; 2560 } 2561 fclose(file); 2562 2563 len = strlen(spl); 2564 char *taggedspl = new char[len + 5]; 2565 strcpy(taggedspl, spl); 2566 strcpy(taggedspl + len, ".tag"); 2567 taggedspl[len+4] = 0; 2568 printf("Writing tagged spl to %s\n", taggedspl); 2569 2570 file = fopen(taggedspl, "wb"); 2571 if( !file ){ 2572 delete []taggedspl; 2573 delete []Buf; 2574 return; 2575 } 2576 fwrite(Buf, 1, iFileSize+len, file); 2577 fclose(file); 2578 delete []taggedspl; 2579 delete []Buf; 2580 printf("done\n"); 2581 return; 2582 } 2583 2584 bool handle_command(int argc, char* argv[], CRKScan *pScan) 2585 { 2586 string strCmd; 2587 strCmd = argv[1]; 2588 ssize_t cnt; 2589 bool bRet,bSuccess = false; 2590 char *s; 2591 int i, ret; 2592 STRUCT_RKDEVICE_DESC dev; 2593 u8 master_gpt[34 * SECTOR_SIZE]; 2594 u64 lba, lba_end; 2595 2596 transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 2597 s = (char*)strCmd.c_str(); 2598 for(i = 0; i < (int)strlen(s); i++) 2599 s[i] = toupper(s[i]); 2600 2601 if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 2602 usage(); 2603 return true; 2604 } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2605 printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 2606 return true; 2607 } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 2608 mergeBoot(); 2609 2610 return true; 2611 } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 2612 string strLoader = argv[2]; 2613 2614 unpackBoot((char*)strLoader.c_str()); 2615 return true; 2616 } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 2617 if (argc == 4) { 2618 string tag = argv[2]; 2619 string spl = argv[3]; 2620 printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 2621 tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 2622 return true; 2623 } 2624 printf("tagspl: parameter error\n"); 2625 usage(); 2626 } 2627 cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 2628 if (cnt < 1) { 2629 ERROR_COLOR_ATTR; 2630 printf("Did not find any rockusb device, please plug device in!"); 2631 NORMAL_COLOR_ATTR; 2632 printf("\r\n"); 2633 return bSuccess; 2634 } else if (cnt > 1) { 2635 ERROR_COLOR_ATTR; 2636 printf("Found too many rockusb devices, please plug devices out!"); 2637 NORMAL_COLOR_ATTR; 2638 printf("\r\n"); 2639 return bSuccess; 2640 } 2641 2642 bRet = pScan->GetDevice(dev, 0); 2643 if (!bRet) { 2644 ERROR_COLOR_ATTR; 2645 printf("Getting information about rockusb device failed!"); 2646 NORMAL_COLOR_ATTR; 2647 printf("\r\n"); 2648 return bSuccess; 2649 } 2650 2651 if(strcmp(strCmd.c_str(), "RD") == 0) { 2652 if ((argc != 2) && (argc != 3)) 2653 printf("Parameter of [RD] command is invalid, please check help!\r\n"); 2654 else { 2655 if (argc == 2) 2656 bSuccess = reset_device(dev); 2657 else { 2658 UINT uiSubCode; 2659 char *pszEnd; 2660 uiSubCode = strtoul(argv[2], &pszEnd, 0); 2661 if (*pszEnd) 2662 printf("Subcode is invalid, please check!\r\n"); 2663 else { 2664 if (uiSubCode <= 5) 2665 bSuccess = reset_device(dev, uiSubCode); 2666 else 2667 printf("Subcode is invalid, please check!\r\n"); 2668 } 2669 } 2670 } 2671 } else if(strcmp(strCmd.c_str(), "TD") == 0) { 2672 bSuccess = test_device(dev); 2673 } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 2674 bSuccess = read_flash_id(dev); 2675 } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 2676 bSuccess = read_flash_info(dev); 2677 } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 2678 bSuccess = read_chip_info(dev); 2679 } else if(strcmp(strCmd.c_str(), "DB") == 0) { 2680 if (argc > 2) { 2681 string strLoader; 2682 strLoader = argv[2]; 2683 bSuccess = download_boot(dev, (char *)strLoader.c_str()); 2684 } else if (argc == 2) { 2685 ret = find_config_item(g_ConfigItemVec, "loader"); 2686 if (ret == -1) 2687 printf("Did not find loader item in config!\r\n"); 2688 else 2689 bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 2690 } else 2691 printf("Parameter of [DB] command is invalid, please check help!\r\n"); 2692 } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2693 if (argc > 2) { 2694 string strParameter; 2695 strParameter = argv[2]; 2696 bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2697 } else 2698 printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 2699 } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2700 if (argc > 2) { 2701 string strLoader; 2702 strLoader = argv[2]; 2703 bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2704 } else 2705 printf("Parameter of [UL] command is invalid, please check help!\r\n"); 2706 } else if(strcmp(strCmd.c_str(), "EF") == 0) { 2707 if (argc == 2) { 2708 bSuccess = erase_flash(dev); 2709 } else 2710 printf("Parameter of [EF] command is invalid, please check help!\r\n"); 2711 } else if(strcmp(strCmd.c_str(), "WL") == 0) { 2712 if (argc == 4) { 2713 UINT uiBegin; 2714 char *pszEnd; 2715 uiBegin = strtoul(argv[2], &pszEnd, 0); 2716 if (*pszEnd) 2717 printf("Begin is invalid, please check!\r\n"); 2718 else 2719 bSuccess = write_lba(dev, uiBegin, argv[3]); 2720 } else 2721 printf("Parameter of [WL] command is invalid, please check help!\r\n"); 2722 } else if(strcmp(strCmd.c_str(), "WLX") == 0) { 2723 if (argc == 4) { 2724 bRet = read_gpt(dev, master_gpt); 2725 if (bRet) { 2726 bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end); 2727 if (bRet) { 2728 if (is_sparse_image(argv[3])) 2729 bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]); 2730 else 2731 bSuccess = write_lba(dev, (u32)lba, argv[3]); 2732 } else 2733 printf("No found %s partition\r\n", argv[2]); 2734 } 2735 } else 2736 printf("Parameter of [WLX] command is invalid, please check help!\r\n"); 2737 } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 2738 char *pszEnd; 2739 UINT uiBegin, uiLen; 2740 if (argc != 5) 2741 printf("Parameter of [RL] command is invalid, please check help!\r\n"); 2742 else { 2743 uiBegin = strtoul(argv[2], &pszEnd, 0); 2744 if (*pszEnd) 2745 printf("Begin is invalid, please check!\r\n"); 2746 else { 2747 uiLen = strtoul(argv[3], &pszEnd, 0); 2748 if (*pszEnd) 2749 printf("Len is invalid, please check!\r\n"); 2750 else { 2751 bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 2752 } 2753 } 2754 } 2755 } else { 2756 printf("command is invalid!\r\n"); 2757 usage(); 2758 } 2759 return bSuccess; 2760 } 2761 2762 2763 int main(int argc, char* argv[]) 2764 { 2765 CRKScan *pScan = NULL; 2766 int ret; 2767 char szProgramProcPath[100]; 2768 char szProgramDir[256]; 2769 string strLogDir,strConfigFile; 2770 struct stat statBuf; 2771 2772 g_ConfigItemVec.clear(); 2773 sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 2774 if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 2775 strcpy(szProgramDir, "."); 2776 else { 2777 char *pSlash; 2778 pSlash = strrchr(szProgramDir, '/'); 2779 if (pSlash) 2780 *pSlash = '\0'; 2781 } 2782 strLogDir = szProgramDir; 2783 strLogDir += "/log/"; 2784 strConfigFile = szProgramDir; 2785 strConfigFile += "/config.ini"; 2786 if (opendir(strLogDir.c_str()) == NULL) 2787 mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 2788 g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 2789 2790 if(stat(strConfigFile.c_str(), &statBuf) < 0) { 2791 if (g_pLogObject) { 2792 g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 2793 } 2794 } else if (S_ISREG(statBuf.st_mode)) { 2795 parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 2796 } 2797 2798 ret = libusb_init(NULL); 2799 if (ret < 0) { 2800 if (g_pLogObject) { 2801 g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 2802 delete g_pLogObject; 2803 } 2804 return -1; 2805 } 2806 2807 pScan = new CRKScan(); 2808 if (!pScan) { 2809 if (g_pLogObject) { 2810 g_pLogObject->Record("Error: failed to create object for searching device"); 2811 delete g_pLogObject; 2812 } 2813 libusb_exit(NULL); 2814 return -2; 2815 } 2816 pScan->SetVidPid(); 2817 2818 if (argc == 1) 2819 usage(); 2820 else if (!handle_command(argc, argv, pScan)) 2821 return -0xFF; 2822 if (pScan) 2823 delete pScan; 2824 if (g_pLogObject) 2825 delete g_pLogObject; 2826 libusb_exit(NULL); 2827 return 0; 2828 } 2829