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