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