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