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