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