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