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