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