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 --version\r\n"); 46 printf("Version:\t\t-v or --version\r\n"); 47 printf("DownloadBoot:\t\tdb <Loader>\r\n"); 48 printf("UpgradeLoader:\t\tul <Loader>\r\n"); 49 printf("ReadLBA:\t\trl <BeginSec> <SectorLen> <File>\r\n"); 50 printf("WriteLBA:\t\twl <BeginSec> <File>\r\n"); 51 printf("WriteGPT:\t\tgpt <gpt partition table>\r\n"); 52 printf("EraseFlash:\t\tef \r\n"); 53 printf("TestDevice:\t\ttd\r\n"); 54 printf("ResetDevice:\t\trd [subcode]\r\n"); 55 printf("ReadFlashID:\t\trid\r\n"); 56 printf("ReadFlashInfo:\t\trfi\r\n"); 57 printf("ReadChipInfo:\t\trci\r\n"); 58 printf("PackBootLoader:\t\tpack\r\n"); 59 printf("UnpackBootLoader:\tunpack <boot loader>\r\n"); 60 printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n"); 61 printf("-------------------------------------------------------\r\n\r\n"); 62 } 63 void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall) 64 { 65 string strInfoText=""; 66 char szText[256]; 67 switch (promptID) { 68 case TESTDEVICE_PROGRESS: 69 sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue); 70 strInfoText = szText; 71 break; 72 case LOWERFORMAT_PROGRESS: 73 sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue); 74 strInfoText = szText; 75 break; 76 case DOWNLOADIMAGE_PROGRESS: 77 sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 78 strInfoText = szText; 79 break; 80 case CHECKIMAGE_PROGRESS: 81 sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 82 strInfoText = szText; 83 break; 84 case TAGBADBLOCK_PROGRESS: 85 sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue); 86 strInfoText = szText; 87 break; 88 case TESTBLOCK_PROGRESS: 89 sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue); 90 strInfoText = szText; 91 break; 92 case ERASEFLASH_PROGRESS: 93 sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue); 94 strInfoText = szText; 95 break; 96 case ERASESYSTEM_PROGRESS: 97 sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue); 98 strInfoText = szText; 99 break; 100 case ERASEUSERDATA_PROGRESS: 101 sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue); 102 strInfoText = szText; 103 break; 104 } 105 if (strInfoText.size() > 0){ 106 CURSOR_MOVEUP_LINE(1); 107 CURSOR_DEL_LINE; 108 printf("%s\r\n", strInfoText.c_str()); 109 } 110 if (emCall == CALL_LAST) 111 deviceLayer = 0; 112 } 113 114 char *strupr(char *szSrc) 115 { 116 char *p = szSrc; 117 while(*p){ 118 if ((*p >= 'a') && (*p <= 'z')) 119 *p = *p - 'a' + 'A'; 120 p++; 121 } 122 return szSrc; 123 } 124 void PrintData(PBYTE pData, int nSize) 125 { 126 char szPrint[17] = "\0"; 127 int i; 128 for( i = 0; i < nSize; i++){ 129 if(i % 16 == 0){ 130 if(i / 16 > 0) 131 printf(" %s\r\n", szPrint); 132 printf("%08d ", i / 16); 133 } 134 printf("%02X ", pData[i]); 135 szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.'; 136 } 137 if(i / 16 > 0) 138 printf(" %s\r\n", szPrint); 139 } 140 141 bool StringToWideString(char *pszSrc, wchar_t *&pszDest) 142 { 143 if (!pszSrc) 144 return false; 145 int nSrcLen = strlen(pszSrc); 146 int nDestLen = nSrcLen * 2; 147 148 pszDest = NULL; 149 pszDest = new wchar_t[nDestLen]; 150 if (!pszDest) 151 return false; 152 nDestLen = nDestLen * sizeof(wchar_t); 153 memset(pszDest, 0, nDestLen); 154 int iRet; 155 iconv_t cd; 156 cd = iconv_open("UTF-32", "UTF-8"); 157 if((iconv_t)-1 == cd) { 158 delete []pszDest; 159 pszDest = NULL; 160 return false; 161 } 162 char *pIn, *pOut; 163 pIn = (char *)pszSrc; 164 pOut = (char *)pszDest; 165 166 iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 167 168 if(iRet == -1) { 169 delete []pszDest; 170 pszDest = NULL; 171 iconv_close(cd); 172 return false; 173 } 174 175 iconv_close(cd); 176 177 return true; 178 } 179 bool WideStringToString(wchar_t *pszSrc, char *&pszDest) 180 { 181 if (!pszSrc) 182 return false; 183 int nSrcLen = wcslen(pszSrc); 184 int nDestLen = nSrcLen * 2; 185 nSrcLen = nSrcLen * sizeof(wchar_t); 186 pszDest = NULL; 187 pszDest = new char[nDestLen]; 188 if (!pszDest) 189 return false; 190 memset(pszDest, 0, nDestLen); 191 int iRet; 192 iconv_t cd; 193 cd = iconv_open("UTF-8", "UTF-32"); 194 195 if((iconv_t)-1 == cd) { 196 delete []pszDest; 197 pszDest = NULL; 198 return false; 199 } 200 char *pIn, *pOut; 201 pIn = (char *)pszSrc; 202 pOut = (char *)pszDest; 203 iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 204 205 if(iRet == -1) { 206 delete []pszDest; 207 pszDest = NULL; 208 iconv_close(cd); 209 return false; 210 } 211 212 iconv_close(cd); 213 214 return true; 215 } 216 int find_config_item(const char *pszName) 217 { 218 unsigned int i; 219 for(i = 0; i < g_ConfigItemVec.size(); i++){ 220 if (strcasecmp(pszName, g_ConfigItemVec[i].szItemName) == 0){ 221 return i; 222 } 223 } 224 return -1; 225 } 226 227 bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 228 { 229 230 stringstream configStream(pConfig); 231 string strLine, strItemName, strItemValue; 232 string::size_type line_size,pos; 233 STRUCT_CONFIG_ITEM item; 234 vecItem.clear(); 235 while (!configStream.eof()){ 236 getline(configStream, strLine); 237 line_size = strLine.size(); 238 if (line_size == 0) 239 continue; 240 if (strLine[line_size-1] == '\r'){ 241 strLine = strLine.substr(0, line_size-1); 242 } 243 strLine.erase(0, strLine.find_first_not_of(" ")); 244 strLine.erase(strLine.find_last_not_of(" ") + 1); 245 if (strLine.size()==0 ) 246 continue; 247 if (strLine[0] == '#') 248 continue; 249 pos = strLine.find("="); 250 if (pos == string::npos){ 251 continue; 252 } 253 strItemName = strLine.substr(0, pos); 254 strItemValue = strLine.substr(pos + 1); 255 strItemName.erase(0, strItemName.find_first_not_of(" ")); 256 strItemName.erase(strItemName.find_last_not_of(" ") + 1); 257 strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 258 strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 259 if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 260 strcpy(item.szItemName, strItemName.c_str()); 261 strcpy(item.szItemValue, strItemValue.c_str()); 262 vecItem.push_back(item); 263 } 264 } 265 return true; 266 267 } 268 bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 269 { 270 FILE *file = NULL; 271 file = fopen(pConfigFile, "rb"); 272 if( !file ){ 273 if (g_pLogObject) 274 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile); 275 return false; 276 } 277 int iFileSize; 278 fseek(file, 0, SEEK_END); 279 iFileSize = ftell(file); 280 fseek(file, 0, SEEK_SET); 281 char *pConfigBuf = NULL; 282 pConfigBuf = new char[iFileSize + 1]; 283 if (!pConfigBuf){ 284 fclose(file); 285 return false; 286 } 287 memset(pConfigBuf, 0, iFileSize + 1); 288 int iRead; 289 iRead = fread(pConfigBuf, 1, iFileSize, file); 290 if (iRead != iFileSize){ 291 if (g_pLogObject) 292 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize); 293 fclose(file); 294 delete []pConfigBuf; 295 return false; 296 } 297 fclose(file); 298 bool bRet; 299 bRet = parse_config(pConfigBuf, vecItem); 300 delete []pConfigBuf; 301 return bRet; 302 } 303 bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 304 { 305 string::size_type pos,prevPos; 306 string strOffset,strLen; 307 int iCount; 308 prevPos = pos = 0; 309 if (strPartInfo.size() <= 0) { 310 return false; 311 } 312 pos = strPartInfo.find('@'); 313 if (pos == string::npos) { 314 return false; 315 } 316 strLen = strPartInfo.substr(prevPos, pos - prevPos); 317 strLen.erase(0, strLen.find_first_not_of(" ")); 318 strLen.erase(strLen.find_last_not_of(" ") + 1); 319 if (strchr(strLen.c_str(), '-')) { 320 uiLen = 0xFFFFFFFF; 321 } else { 322 iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 323 if (iCount != 1) { 324 return false; 325 } 326 } 327 328 prevPos = pos + 1; 329 pos = strPartInfo.find('(',prevPos); 330 if (pos == string::npos) { 331 return false; 332 } 333 strOffset = strPartInfo.substr(prevPos, pos - prevPos); 334 strOffset.erase(0, strOffset.find_first_not_of(" ")); 335 strOffset.erase(strOffset.find_last_not_of(" ") + 1); 336 iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 337 if (iCount != 1) { 338 return false; 339 } 340 prevPos = pos + 1; 341 pos = strPartInfo.find(')', prevPos); 342 if (pos == string::npos) { 343 return false; 344 } 345 strName = strPartInfo.substr(prevPos, pos - prevPos); 346 strName.erase(0, strName.find_first_not_of(" ")); 347 strName.erase(strName.find_last_not_of(" ") + 1); 348 349 return true; 350 } 351 352 bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem) 353 { 354 stringstream paramStream(pParameter); 355 bool bRet,bFind = false; 356 string strLine, strPartition, strPartInfo, strPartName; 357 string::size_type line_size, pos, posColon, posComma; 358 UINT uiPartOffset, uiPartSize; 359 STRUCT_PARAM_ITEM item; 360 vecItem.clear(); 361 while (!paramStream.eof()) { 362 getline(paramStream,strLine); 363 line_size = strLine.size(); 364 if (line_size == 0) 365 continue; 366 if (strLine[line_size - 1] == '\r'){ 367 strLine = strLine.substr(0, line_size - 1); 368 } 369 strLine.erase(0, strLine.find_first_not_of(" ")); 370 strLine.erase(strLine.find_last_not_of(" ") + 1); 371 if (strLine.size()==0 ) 372 continue; 373 if (strLine[0] == '#') 374 continue; 375 pos = strLine.find("mtdparts"); 376 if (pos == string::npos) { 377 continue; 378 } 379 bFind = true; 380 posColon = strLine.find(':', pos); 381 if (posColon == string::npos) { 382 continue; 383 } 384 strPartition = strLine.substr(posColon + 1); 385 pos = 0; 386 posComma = strPartition.find(',', pos); 387 while (posComma != string::npos) { 388 strPartInfo = strPartition.substr(pos, posComma - pos); 389 bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 390 if (bRet) { 391 strcpy(item.szItemName, strPartName.c_str()); 392 item.uiItemOffset = uiPartOffset; 393 item.uiItemSize = uiPartSize; 394 vecItem.push_back(item); 395 } 396 pos = posComma + 1; 397 posComma = strPartition.find(',', pos); 398 } 399 strPartInfo = strPartition.substr(pos); 400 if (strPartInfo.size() > 0) { 401 bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 402 if (bRet) { 403 strcpy(item.szItemName, strPartName.c_str()); 404 item.uiItemOffset = uiPartOffset; 405 item.uiItemSize = uiPartSize; 406 vecItem.push_back(item); 407 } 408 } 409 break; 410 } 411 return bFind; 412 413 } 414 bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem) 415 { 416 FILE *file = NULL; 417 file = fopen(pParamFile, "rb"); 418 if( !file ) { 419 if (g_pLogObject) 420 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 421 return false; 422 } 423 int iFileSize; 424 fseek(file, 0, SEEK_END); 425 iFileSize = ftell(file); 426 fseek(file, 0, SEEK_SET); 427 char *pParamBuf = NULL; 428 pParamBuf = new char[iFileSize]; 429 if (!pParamBuf) { 430 fclose(file); 431 return false; 432 } 433 int iRead; 434 iRead = fread(pParamBuf, 1, iFileSize, file); 435 if (iRead != iFileSize) { 436 if (g_pLogObject) 437 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize); 438 fclose(file); 439 delete []pParamBuf; 440 return false; 441 } 442 fclose(file); 443 bool bRet; 444 bRet = parse_parameter(pParamBuf, vecItem); 445 delete []pParamBuf; 446 return bRet; 447 } 448 void gen_rand_uuid(unsigned char *uuid_bin) 449 { 450 efi_guid_t id; 451 unsigned int *ptr = (unsigned int *)&id; 452 unsigned int i; 453 454 /* Set all fields randomly */ 455 for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 456 *(ptr + i) = cpu_to_be32(rand()); 457 458 id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 459 id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 460 461 memcpy(uuid_bin, id.raw, sizeof(id)); 462 } 463 464 void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, u64 diskSectors) 465 { 466 legacy_mbr *mbr = (legacy_mbr *)gpt; 467 gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 468 gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 469 u32 i,j; 470 string strPartName; 471 string::size_type colonPos; 472 /*1.protective mbr*/ 473 memset(gpt, 0, SECTOR_SIZE); 474 mbr->signature = MSDOS_MBR_SIGNATURE; 475 mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 476 mbr->partition_record[0].start_sect = 1; 477 mbr->partition_record[0].nr_sects = (u32)-1; 478 /*2.gpt header*/ 479 memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 480 gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 481 gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 482 gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 483 gptHead->my_lba = cpu_to_le64(1); 484 gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 485 gptHead->first_usable_lba = cpu_to_le64(34); 486 gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 487 gptHead->partition_entry_lba = cpu_to_le64(2); 488 gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 489 gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 490 gptHead->header_crc32 = 0; 491 gptHead->partition_entry_array_crc32 = 0; 492 gen_rand_uuid(gptHead->disk_guid.raw); 493 494 /*3.gpt partition entry*/ 495 memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 496 for (i = 0; i < vecParts.size(); i++) { 497 gen_rand_uuid(gptEntry->partition_type_guid.raw); 498 gen_rand_uuid(gptEntry->unique_partition_guid.raw); 499 gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 500 gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 501 gptEntry->attributes.raw = 0; 502 strPartName = vecParts[i].szItemName; 503 colonPos = strPartName.find_first_of(':'); 504 if (colonPos != string::npos) { 505 if (strPartName.find("bootable") != string::npos) 506 gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 507 strPartName = strPartName.substr(0, colonPos); 508 vecParts[i].szItemName[strPartName.size()] = 0; 509 } 510 for (j = 0; j < strlen(vecParts[i].szItemName); j++) 511 gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 512 gptEntry++; 513 } 514 515 gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 516 gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 517 518 } 519 bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag) 520 { 521 PRK28_IDB_SEC0 pSec0; 522 memset(pSector, 0, SECTOR_SIZE); 523 pSec0 = (PRK28_IDB_SEC0)pSector; 524 525 pSec0->dwTag = 0x0FF0AA55; 526 pSec0->uiRc4Flag = rc4Flag; 527 pSec0->usBootCode1Offset = 0x4; 528 pSec0->usBootCode2Offset = 0x4; 529 pSec0->usBootDataSize = usFlashDataSec; 530 pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 531 return true; 532 } 533 534 535 bool MakeSector1(PBYTE pSector) 536 { 537 PRK28_IDB_SEC1 pSec1; 538 memset(pSector, 0, SECTOR_SIZE); 539 pSec1 = (PRK28_IDB_SEC1)pSector; 540 541 pSec1->usSysReservedBlock = 0xC; 542 pSec1->usDisk0Size = 0xFFFF; 543 pSec1->uiChipTag = 0x38324B52; 544 return true; 545 } 546 547 bool MakeSector2(PBYTE pSector) 548 { 549 PRK28_IDB_SEC2 pSec2; 550 memset(pSector, 0, SECTOR_SIZE); 551 pSec2 = (PRK28_IDB_SEC2)pSector; 552 553 strcpy(pSec2->szVcTag, "VC"); 554 strcpy(pSec2->szCrcTag, "CRC"); 555 return true; 556 } 557 558 bool MakeSector3(PBYTE pSector) 559 { 560 memset(pSector,0,SECTOR_SIZE); 561 return true; 562 } 563 564 int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag) 565 { 566 RK28_IDB_SEC0 sector0Info; 567 RK28_IDB_SEC1 sector1Info; 568 RK28_IDB_SEC2 sector2Info; 569 RK28_IDB_SEC3 sector3Info; 570 UINT i; 571 printf("rc4=%d\r\n\r\n\r\n",rc4Flag); 572 MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag); 573 MakeSector1((PBYTE)§or1Info); 574 if (!MakeSector2((PBYTE)§or2Info)) { 575 return -6; 576 } 577 if (!MakeSector3((PBYTE)§or3Info)) { 578 return -7; 579 } 580 sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 581 sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 582 sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 583 584 memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 585 memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 586 memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 587 588 if (rc4Flag) { 589 for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++) 590 P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE); 591 for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++) 592 P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE); 593 } 594 595 memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 596 memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 597 598 sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 599 memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 600 for(i = 0; i < 4; i++) { 601 if(i == 1) { 602 continue; 603 } else { 604 P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 605 } 606 } 607 return 0; 608 } 609 610 611 612 bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 613 { 614 if ((dev.emUsbType & uiSupportType) == dev.emUsbType) 615 return true; 616 else 617 { 618 ERROR_COLOR_ATTR; 619 printf("The device does not support this operation!"); 620 NORMAL_COLOR_ATTR; 621 printf("\r\n"); 622 return false; 623 } 624 } 625 bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 626 { 627 u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 628 u32 total_size_sector; 629 CRKComm *pComm = NULL; 630 PARAM_ITEM_VECTOR vecItems; 631 int iRet; 632 bool bRet, bSuccess = false; 633 if (!check_device_type(dev, RKUSB_MASKROM)) 634 return false; 635 636 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 637 if (!bRet) { 638 ERROR_COLOR_ATTR; 639 printf("Creating Comm Object failed!"); 640 NORMAL_COLOR_ATTR; 641 printf("\r\n"); 642 return bSuccess; 643 } 644 printf("Writing gpt...\r\n"); 645 //1.get flash info 646 iRet = pComm->RKU_ReadFlashInfo(flash_info); 647 if (iRet != ERR_SUCCESS) { 648 ERROR_COLOR_ATTR; 649 printf("Reading Flash Info failed!"); 650 NORMAL_COLOR_ATTR; 651 printf("\r\n"); 652 return bSuccess; 653 } 654 total_size_sector = *(u32 *)flash_info; 655 //2.get partition from parameter 656 bRet = parse_parameter_file(szParameter, vecItems); 657 if (!bRet) { 658 ERROR_COLOR_ATTR; 659 printf("Parsing parameter failed!"); 660 NORMAL_COLOR_ATTR; 661 printf("\r\n"); 662 return bSuccess; 663 } 664 vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 34; 665 //3.generate gpt info 666 create_gpt_buffer(master_gpt, vecItems, total_size_sector); 667 memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 668 memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 669 //4. write gpt 670 iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 671 if (iRet != ERR_SUCCESS) { 672 ERROR_COLOR_ATTR; 673 printf("Writing master gpt failed!"); 674 NORMAL_COLOR_ATTR; 675 printf("\r\n"); 676 return bSuccess; 677 } 678 iRet = pComm->RKU_WriteLBA(total_size_sector - 34, 33, backup_gpt); 679 if (iRet != ERR_SUCCESS) { 680 ERROR_COLOR_ATTR; 681 printf("Writing backup gpt failed!"); 682 NORMAL_COLOR_ATTR; 683 printf("\r\n"); 684 return bSuccess; 685 } 686 bSuccess = true; 687 CURSOR_MOVEUP_LINE(1); 688 CURSOR_DEL_LINE; 689 printf("Writing gpt succeeded.\r\n"); 690 return bSuccess; 691 } 692 693 #include "boot_merger.h" 694 #define ENTRY_ALIGN (2048) 695 options gOpts; 696 697 698 char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 699 char* gConfigPath; 700 uint8_t gBuf[MAX_MERGE_SIZE]; 701 702 static inline void fixPath(char* path) { 703 int i, len = strlen(path); 704 for(i=0; i<len; i++) { 705 if (path[i] == '\\') 706 path[i] = '/'; 707 else if (path[i] == '\r' || path[i] == '\n') 708 path[i] = '\0'; 709 } 710 } 711 712 static bool parseChip(FILE* file) { 713 if (SCANF_EAT(file) != 0) { 714 return false; 715 } 716 if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 717 return false; 718 } 719 printf("chip: %s\n", gOpts.chip); 720 return true; 721 } 722 723 static bool parseVersion(FILE* file) { 724 if (SCANF_EAT(file) != 0) { 725 return false; 726 } 727 if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 728 return false; 729 if (SCANF_EAT(file) != 0) { 730 return false; 731 } 732 if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 733 return false; 734 printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor); 735 return true; 736 } 737 738 static bool parse471(FILE* file) { 739 int i, index, pos; 740 char buf[MAX_LINE_LEN]; 741 742 if (SCANF_EAT(file) != 0) { 743 return false; 744 } 745 if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 746 return false; 747 printf("num: %d\n", gOpts.code471Num); 748 if (!gOpts.code471Num) 749 return true; 750 if (gOpts.code471Num < 0) 751 return false; 752 gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 753 for (i=0; i<gOpts.code471Num; i++) { 754 if (SCANF_EAT(file) != 0) { 755 return false; 756 } 757 if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 758 != 2) 759 return false; 760 index--; 761 fixPath(buf); 762 strcpy((char*)gOpts.code471Path[index], buf); 763 printf("path%i: %s\n", index, gOpts.code471Path[index]); 764 } 765 pos = ftell(file); 766 if (SCANF_EAT(file) != 0) { 767 return false; 768 } 769 if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 770 fseek(file, pos, SEEK_SET); 771 printf("sleep: %d\n", gOpts.code471Sleep); 772 return true; 773 } 774 775 static bool parse472(FILE* file) { 776 int i, index, pos; 777 char buf[MAX_LINE_LEN]; 778 779 if (SCANF_EAT(file) != 0) { 780 return false; 781 } 782 if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 783 return false; 784 printf("num: %d\n", gOpts.code472Num); 785 if (!gOpts.code472Num) 786 return true; 787 if (gOpts.code472Num < 0) 788 return false; 789 gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 790 for (i=0; i<gOpts.code472Num; i++) { 791 if (SCANF_EAT(file) != 0) { 792 return false; 793 } 794 if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 795 != 2) 796 return false; 797 fixPath(buf); 798 index--; 799 strcpy((char*)gOpts.code472Path[index], buf); 800 printf("path%i: %s\n", index, gOpts.code472Path[index]); 801 } 802 pos = ftell(file); 803 if (SCANF_EAT(file) != 0) { 804 return false; 805 } 806 if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 807 fseek(file, pos, SEEK_SET); 808 printf("sleep: %d\n", gOpts.code472Sleep); 809 return true; 810 } 811 812 static bool parseLoader(FILE* file) { 813 int i, j, index, pos; 814 char buf[MAX_LINE_LEN]; 815 char buf2[MAX_LINE_LEN]; 816 817 if (SCANF_EAT(file) != 0) { 818 return false; 819 } 820 pos = ftell(file); 821 if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 822 fseek(file, pos, SEEK_SET); 823 if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 824 return false; 825 } 826 } 827 printf("num: %d\n", gOpts.loaderNum); 828 if (!gOpts.loaderNum) 829 return false; 830 if (gOpts.loaderNum < 0) 831 return false; 832 gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 833 for (i=0; i<gOpts.loaderNum; i++) { 834 if (SCANF_EAT(file) != 0) { 835 return false; 836 } 837 if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 838 != 2) 839 return false; 840 index--; 841 strcpy(gOpts.loader[index].name, buf); 842 printf("name%d: %s\n", index, gOpts.loader[index].name); 843 } 844 for (i=0; i<gOpts.loaderNum; i++) { 845 if (SCANF_EAT(file) != 0) { 846 return false; 847 } 848 if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 849 != 2) 850 return false; 851 for (j=0; j<gOpts.loaderNum; j++) { 852 if (!strcmp(gOpts.loader[j].name, buf)) { 853 fixPath(buf2); 854 strcpy(gOpts.loader[j].path, buf2); 855 printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 856 break; 857 } 858 } 859 if (j >= gOpts.loaderNum) { 860 return false; 861 } 862 } 863 return true; 864 } 865 866 static bool parseOut(FILE* file) { 867 if (SCANF_EAT(file) != 0) { 868 return false; 869 } 870 if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 871 return false; 872 fixPath(gOpts.outPath); 873 printf("out: %s\n", gOpts.outPath); 874 return true; 875 } 876 877 878 void printOpts(FILE* out) { 879 int i; 880 fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 881 fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 882 "=%d\n", gOpts.major, gOpts.minor); 883 884 fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 885 for (i=0 ;i<gOpts.code471Num ;i++) { 886 fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 887 } 888 if (gOpts.code471Sleep > 0) 889 fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 890 891 fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 892 for (i=0 ;i<gOpts.code472Num ;i++) { 893 fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 894 } 895 if (gOpts.code472Sleep > 0) 896 fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 897 898 fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 899 for (i=0 ;i<gOpts.loaderNum ;i++) { 900 fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 901 } 902 for (i=0 ;i<gOpts.loaderNum ;i++) { 903 fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 904 } 905 906 fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 907 } 908 909 static bool parseOpts(void) { 910 bool ret = false; 911 bool chipOk = false; 912 bool versionOk = false; 913 bool code471Ok = true; 914 bool code472Ok = true; 915 bool loaderOk = false; 916 bool outOk = false; 917 char buf[MAX_LINE_LEN]; 918 919 char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 920 FILE* file; 921 file = fopen(configPath, "r"); 922 if (!file) { 923 fprintf(stderr, "config (%s) not found!\n", configPath); 924 if (configPath == (char*)DEF_CONFIG_FILE) { 925 file = fopen(DEF_CONFIG_FILE, "w"); 926 if (file) { 927 fprintf(stderr, "creating defconfig\n"); 928 printOpts(file); 929 } 930 } 931 goto end; 932 } 933 934 printf("Starting to parse...\n"); 935 936 if (SCANF_EAT(file) != 0) { 937 goto end; 938 } 939 while(fscanf(file, "%s", buf) == 1) { 940 if (!strcmp(buf, SEC_CHIP)) { 941 chipOk = parseChip(file); 942 if (!chipOk) { 943 printf("parseChip failed!\n"); 944 goto end; 945 } 946 } else if (!strcmp(buf, SEC_VERSION)) { 947 versionOk = parseVersion(file); 948 if (!versionOk) { 949 printf("parseVersion failed!\n"); 950 goto end; 951 } 952 } else if (!strcmp(buf, SEC_471)) { 953 code471Ok = parse471(file); 954 if (!code471Ok) { 955 printf("parse471 failed!\n"); 956 goto end; 957 } 958 } else if (!strcmp(buf, SEC_472)) { 959 code472Ok = parse472(file); 960 if (!code472Ok) { 961 printf("parse472 failed!\n"); 962 goto end; 963 } 964 } else if (!strcmp(buf, SEC_LOADER)) { 965 loaderOk = parseLoader(file); 966 if (!loaderOk) { 967 printf("parseLoader failed!\n"); 968 goto end; 969 } 970 } else if (!strcmp(buf, SEC_OUT)) { 971 outOk = parseOut(file); 972 if (!outOk) { 973 printf("parseOut failed!\n"); 974 goto end; 975 } 976 } else if (buf[0] == '#') { 977 continue; 978 } else { 979 printf("unknown sec: %s!\n", buf); 980 goto end; 981 } 982 if (SCANF_EAT(file) != 0) { 983 goto end; 984 } 985 } 986 987 if (chipOk && versionOk && code471Ok && code472Ok 988 && loaderOk && outOk) 989 ret = true; 990 end: 991 if (file) 992 fclose(file); 993 return ret; 994 } 995 996 bool initOpts(void) { 997 //set default opts 998 gOpts.major = DEF_MAJOR; 999 gOpts.minor = DEF_MINOR; 1000 strcpy(gOpts.chip, DEF_CHIP); 1001 gOpts.code471Sleep = DEF_CODE471_SLEEP; 1002 gOpts.code472Sleep = DEF_CODE472_SLEEP; 1003 gOpts.code471Num = DEF_CODE471_NUM; 1004 gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 1005 strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 1006 gOpts.code472Num = DEF_CODE472_NUM; 1007 gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 1008 strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 1009 gOpts.loaderNum = DEF_LOADER_NUM; 1010 gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 1011 strcpy(gOpts.loader[0].name, DEF_LOADER0); 1012 strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 1013 strcpy(gOpts.loader[1].name, DEF_LOADER1); 1014 strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 1015 strcpy(gOpts.outPath, DEF_OUT_PATH); 1016 1017 return parseOpts(); 1018 } 1019 1020 /************merge code****************/ 1021 1022 static inline uint32_t getBCD(unsigned short value) { 1023 uint8_t tmp[2] = {0}; 1024 int i; 1025 uint32_t ret; 1026 //if (value > 0xFFFF) { 1027 // return 0; 1028 //} 1029 for(i=0; i < 2; i++) { 1030 tmp[i] = (((value/10)%10)<<4) | (value%10); 1031 value /= 100; 1032 } 1033 ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 1034 1035 printf("ret: %x\n",ret); 1036 return ret&0xFF; 1037 } 1038 1039 static inline void str2wide(const char* str, uint16_t* wide, int len) 1040 { 1041 int i; 1042 for (i = 0; i < len; i++) { 1043 wide[i] = (uint16_t) str[i]; 1044 } 1045 wide[len] = 0; 1046 } 1047 1048 static inline void getName(char* path, uint16_t* dst) { 1049 char* end; 1050 char* start; 1051 int len; 1052 if (!path || !dst) 1053 return; 1054 start = strrchr(path, '/'); 1055 if (!start) 1056 start = path; 1057 else 1058 start++; 1059 end = strrchr(path, '.'); 1060 if (!end || (end < start)) 1061 end = path + strlen(path); 1062 len = end - start; 1063 if (len >= MAX_NAME_LEN) 1064 len = MAX_NAME_LEN -1; 1065 str2wide(start, dst, len); 1066 1067 1068 char name[MAX_NAME_LEN]; 1069 memset(name, 0, sizeof(name)); 1070 memcpy(name, start, len); 1071 printf("path: %s, name: %s\n", path, name); 1072 1073 } 1074 1075 static inline bool getFileSize(const char *path, uint32_t* size) { 1076 struct stat st; 1077 if(stat(path, &st) < 0) 1078 return false; 1079 *size = st.st_size; 1080 printf("path: %s, size: %d\n", path, *size); 1081 return true; 1082 } 1083 1084 static inline rk_time getTime(void) { 1085 rk_time rkTime; 1086 1087 struct tm *tm; 1088 time_t tt = time(NULL); 1089 tm = localtime(&tt); 1090 rkTime.year = tm->tm_year + 1900; 1091 rkTime.month = tm->tm_mon + 1; 1092 rkTime.day = tm->tm_mday; 1093 rkTime.hour = tm->tm_hour; 1094 rkTime.minute = tm->tm_min; 1095 rkTime.second = tm->tm_sec; 1096 printf("%d-%d-%d %02d:%02d:%02d\n", 1097 rkTime.year, rkTime.month, rkTime.day, 1098 rkTime.hour, rkTime.minute, rkTime.second); 1099 return rkTime; 1100 } 1101 1102 static bool writeFile(FILE* outFile, const char* path, bool fix) { 1103 bool ret = false; 1104 uint32_t size = 0, fixSize = 0; 1105 uint8_t* buf; 1106 1107 FILE* inFile = fopen(path, "rb"); 1108 if (!inFile) 1109 goto end; 1110 1111 if (!getFileSize(path, &size)) 1112 goto end; 1113 if (fix) { 1114 fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 1115 uint32_t tmp = fixSize % ENTRY_ALIGN; 1116 tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 1117 fixSize +=tmp; 1118 memset(gBuf, 0, fixSize); 1119 } else { 1120 memset(gBuf, 0, size+ENTRY_ALIGN); 1121 } 1122 if (!fread(gBuf, size, 1, inFile)) 1123 goto end; 1124 1125 if (fix) { 1126 1127 buf = gBuf; 1128 size = fixSize; 1129 while(1) { 1130 P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 1131 buf += SMALL_PACKET; 1132 if (fixSize <= SMALL_PACKET) 1133 break; 1134 fixSize -= SMALL_PACKET; 1135 } 1136 } else { 1137 uint32_t tmp = size % ENTRY_ALIGN; 1138 tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 1139 size +=tmp; 1140 P_RC4(gBuf, size); 1141 } 1142 1143 if (!fwrite(gBuf, size, 1, outFile)) 1144 goto end; 1145 ret = true; 1146 end: 1147 if (inFile) 1148 fclose(inFile); 1149 if (!ret) 1150 printf("writing entry (%s) failed\n", path); 1151 return ret; 1152 } 1153 1154 static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 1155 uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 1156 uint32_t size; 1157 rk_boot_entry entry; 1158 1159 printf("writing: %s\n", path); 1160 memset(&entry, 0, sizeof(rk_boot_entry)); 1161 getName(fixName ? fixName: path, entry.name); 1162 entry.size = sizeof(rk_boot_entry); 1163 entry.type = type; 1164 entry.dataOffset = *offset; 1165 if (!getFileSize(path, &size)) { 1166 printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path); 1167 return false; 1168 } 1169 if (fix) 1170 size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 1171 uint32_t tmp = size % ENTRY_ALIGN; 1172 size += tmp ? (ENTRY_ALIGN - tmp): 0; 1173 printf("alignment size: %d\n", size); 1174 entry.dataSize = size; 1175 entry.dataDelay = delay; 1176 *offset += size; 1177 fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 1178 return true; 1179 } 1180 1181 static inline uint32_t convertChipType(const char* chip) { 1182 char buffer[5]; 1183 memset(buffer, 0, sizeof(buffer)); 1184 snprintf(buffer, sizeof(buffer), "%s", chip); 1185 return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 1186 } 1187 1188 static inline uint32_t getChipType(const char* chip) { 1189 printf("chip: %s\n", chip); 1190 int chipType = RKNONE_DEVICE; 1191 if(!chip) { 1192 goto end; 1193 } 1194 if (!strcmp(chip, CHIP_RK28)) { 1195 chipType = RK28_DEVICE; 1196 } else if (!strcmp(chip, CHIP_RK28)) { 1197 chipType = RK28_DEVICE; 1198 } else if (!strcmp(chip, CHIP_RK281X)) { 1199 chipType = RK281X_DEVICE; 1200 } else if (!strcmp(chip, CHIP_RKPANDA)) { 1201 chipType = RKPANDA_DEVICE; 1202 } else if (!strcmp(chip, CHIP_RK27)) { 1203 chipType = RK27_DEVICE; 1204 } else if (!strcmp(chip, CHIP_RKNANO)) { 1205 chipType = RKNANO_DEVICE; 1206 } else if (!strcmp(chip, CHIP_RKSMART)) { 1207 chipType = RKSMART_DEVICE; 1208 } else if (!strcmp(chip, CHIP_RKCROWN)) { 1209 chipType = RKCROWN_DEVICE; 1210 } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 1211 chipType = RKCAYMAN_DEVICE; 1212 } else if (!strcmp(chip, CHIP_RK29)) { 1213 chipType = RK29_DEVICE; 1214 } else if (!strcmp(chip, CHIP_RK292X)) { 1215 chipType = RK292X_DEVICE; 1216 } else if (!strcmp(chip, CHIP_RK30)) { 1217 chipType = RK30_DEVICE; 1218 } else if (!strcmp(chip, CHIP_RK30B)) { 1219 chipType = RK30B_DEVICE; 1220 } else if (!strcmp(chip, CHIP_RK31)) { 1221 chipType = RK31_DEVICE; 1222 } else if (!strcmp(chip, CHIP_RK32)) { 1223 chipType = RK32_DEVICE; 1224 } else { 1225 chipType = convertChipType(chip + 2); 1226 } 1227 1228 end: 1229 printf("type: 0x%x\n", chipType); 1230 if (chipType == RKNONE_DEVICE) { 1231 printf("chip type not supported!\n"); 1232 } 1233 return chipType; 1234 } 1235 1236 static inline void getBoothdr(rk_boot_header* hdr) { 1237 memset(hdr, 0, sizeof(rk_boot_header)); 1238 hdr->tag = TAG; 1239 hdr->size = sizeof(rk_boot_header); 1240 hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 1241 hdr->mergerVersion = MERGER_VERSION; 1242 hdr->releaseTime = getTime(); 1243 hdr->chipType = getChipType(gOpts.chip); 1244 1245 hdr->code471Num = gOpts.code471Num; 1246 hdr->code471Offset = sizeof(rk_boot_header); 1247 hdr->code471Size = sizeof(rk_boot_entry); 1248 1249 hdr->code472Num = gOpts.code472Num; 1250 hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 1251 hdr->code472Size = sizeof(rk_boot_entry); 1252 1253 hdr->loaderNum = gOpts.loaderNum; 1254 hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 1255 hdr->loaderSize = sizeof(rk_boot_entry); 1256 #ifndef USE_P_RC4 1257 hdr->rc4Flag = 1; 1258 #endif 1259 } 1260 1261 static inline uint32_t getCrc(const char* path) { 1262 uint32_t size = 0; 1263 uint32_t crc = 0; 1264 1265 FILE* file = fopen(path, "rb"); 1266 getFileSize(path, &size); 1267 if (!file) 1268 goto end; 1269 if (!fread(gBuf, size, 1, file)) 1270 goto end; 1271 crc = CRC_32(gBuf, size); 1272 printf("crc: 0x%08x\n", crc); 1273 end: 1274 if (file) 1275 fclose(file); 1276 return crc; 1277 } 1278 1279 bool mergeBoot(void) { 1280 uint32_t dataOffset; 1281 bool ret = false; 1282 int i; 1283 FILE* outFile; 1284 uint32_t crc; 1285 rk_boot_header hdr; 1286 1287 if (!initOpts()) 1288 return false; 1289 { 1290 char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 1291 char version[MAX_LINE_LEN]; 1292 snprintf(version, sizeof(version), "%s", gSubfix); 1293 if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 1294 subfix[0] = '\0'; 1295 } 1296 strcat(gOpts.outPath, version); 1297 printf("fix opt: %s\n", gOpts.outPath); 1298 } 1299 1300 printf("---------------\nUSING CONFIG:\n"); 1301 printOpts(stdout); 1302 printf("---------------\n\n"); 1303 1304 1305 outFile = fopen(gOpts.outPath, "wb+"); 1306 if (!outFile) { 1307 printf("Opening output file (%s) failed\n", gOpts.outPath); 1308 goto end; 1309 } 1310 1311 getBoothdr(&hdr); 1312 printf("Writing header...\n"); 1313 fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 1314 1315 dataOffset = sizeof(rk_boot_header) + 1316 (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 1317 sizeof(rk_boot_entry); 1318 1319 printf("Writing code 471 entry...\n"); 1320 for (i=0; i<gOpts.code471Num; i++) { 1321 if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 1322 &dataOffset, NULL, false)) 1323 goto end; 1324 } 1325 printf("Writing code 472 entry...\n"); 1326 for (i=0; i<gOpts.code472Num; i++) { 1327 if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 1328 &dataOffset, NULL, false)) 1329 goto end; 1330 } 1331 printf("Writing loader entry...\n"); 1332 for (i=0; i<gOpts.loaderNum; i++) { 1333 if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 1334 &dataOffset, gOpts.loader[i].name, true)) 1335 goto end; 1336 } 1337 1338 printf("Writing code 471...\n"); 1339 for (i=0; i<gOpts.code471Num; i++) { 1340 if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 1341 goto end; 1342 } 1343 printf("Writing code 472...\n"); 1344 for (i=0; i<gOpts.code472Num; i++) { 1345 if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 1346 goto end; 1347 } 1348 printf("Writing loader...\n"); 1349 for (i=0; i<gOpts.loaderNum; i++) { 1350 if (!writeFile(outFile, gOpts.loader[i].path, true)) 1351 goto end; 1352 } 1353 fflush(outFile); 1354 1355 printf("Writing crc...\n"); 1356 crc = getCrc(gOpts.outPath); 1357 if (!fwrite(&crc, sizeof(crc), 1, outFile)) 1358 goto end; 1359 printf("Done.\n"); 1360 ret = true; 1361 end: 1362 if (outFile) 1363 fclose(outFile); 1364 return ret; 1365 } 1366 1367 /************merge code end************/ 1368 /************unpack code***************/ 1369 1370 static inline void wide2str(const uint16_t* wide, char* str, int len) 1371 { 1372 int i; 1373 for (i = 0; i < len; i++) { 1374 str[i] = (char) (wide[i] & 0xFF); 1375 } 1376 str[len] = 0; 1377 } 1378 1379 static bool unpackEntry(rk_boot_entry* entry, const char* name, 1380 FILE* inFile) { 1381 bool ret = false; 1382 int size, i; 1383 FILE* outFile = fopen(name, "wb+"); 1384 if (!outFile) 1385 goto end; 1386 printf("unpacking entry (%s)\n", name); 1387 fseek(inFile, entry->dataOffset, SEEK_SET); 1388 size = entry->dataSize; 1389 if (!fread(gBuf, size, 1, inFile)) 1390 goto end; 1391 if (entry->type == ENTRY_LOADER) { 1392 for(i=0; i<size/SMALL_PACKET; i++) 1393 P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 1394 if (size % SMALL_PACKET) 1395 { 1396 P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 1397 } 1398 } else { 1399 P_RC4(gBuf, size); 1400 } 1401 if (!fwrite(gBuf, size, 1, outFile)) 1402 goto end; 1403 ret = true; 1404 end: 1405 if (outFile) 1406 fclose(outFile); 1407 return ret; 1408 } 1409 1410 bool unpackBoot(char* path) { 1411 bool ret = false; 1412 FILE* inFile = fopen(path, "rb"); 1413 int entryNum, i; 1414 char name[MAX_NAME_LEN]; 1415 rk_boot_entry* entrys; 1416 if (!inFile) { 1417 fprintf(stderr, "loader (%s) not found\n", path); 1418 goto end; 1419 } 1420 1421 rk_boot_header hdr; 1422 if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 1423 fprintf(stderr, "reading header failed\n"); 1424 goto end; 1425 } 1426 printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 1427 entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 1428 entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 1429 if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 1430 fprintf(stderr, "reading data failed\n"); 1431 goto end; 1432 } 1433 1434 printf("entry num: %d\n", entryNum); 1435 for (i=0; i<entryNum; i++) { 1436 wide2str(entrys[i].name, name, MAX_NAME_LEN); 1437 1438 printf("entry: t=%d, name=%s, off=%d, size=%d\n", 1439 entrys[i].type, name, entrys[i].dataOffset, 1440 entrys[i].dataSize); 1441 if (!unpackEntry(entrys + i, name, inFile)) { 1442 fprintf(stderr, "unpacking entry (%s) failed\n", name); 1443 goto end; 1444 } 1445 } 1446 printf("done\n"); 1447 ret = true; 1448 end: 1449 if (inFile) 1450 fclose(inFile); 1451 return ret; 1452 } 1453 1454 bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1455 { 1456 if (!check_device_type(dev, RKUSB_MASKROM)) 1457 return false; 1458 CRKImage *pImage = NULL; 1459 CRKBoot *pBoot = NULL; 1460 bool bRet, bSuccess = false; 1461 int iRet; 1462 1463 pImage = new CRKImage(szLoader, bRet); 1464 if (!bRet){ 1465 ERROR_COLOR_ATTR; 1466 printf("Opening loader failed, exiting download boot!"); 1467 NORMAL_COLOR_ATTR; 1468 printf("\r\n"); 1469 return bSuccess; 1470 } else { 1471 pBoot = (CRKBoot *)pImage->m_bootObject; 1472 CRKComm *pComm = NULL; 1473 CRKDevice *pDevice = NULL; 1474 1475 dev.emDeviceType = pBoot->SupportDevice; 1476 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1477 if (!bRet) { 1478 if (pImage) 1479 delete pImage; 1480 ERROR_COLOR_ATTR; 1481 printf("Creating Comm Object failed!"); 1482 NORMAL_COLOR_ATTR; 1483 printf("\r\n"); 1484 return bSuccess; 1485 } 1486 1487 pDevice = new CRKDevice(dev); 1488 if (!pDevice) { 1489 if (pImage) 1490 delete pImage; 1491 if (pComm) 1492 delete pComm; 1493 ERROR_COLOR_ATTR; 1494 printf("Creating device object failed!"); 1495 NORMAL_COLOR_ATTR; 1496 printf("\r\n"); 1497 return bSuccess; 1498 } 1499 1500 pDevice->SetObject(pImage, pComm, g_pLogObject); 1501 printf("Downloading bootloader...\r\n"); 1502 iRet = pDevice->DownloadBoot(); 1503 1504 CURSOR_MOVEUP_LINE(1); 1505 CURSOR_DEL_LINE; 1506 if (iRet == 0) { 1507 bSuccess = true; 1508 printf("Downloading bootloader succeeded.\r\n"); 1509 } 1510 else 1511 printf("Downloading bootloader failed!\r\n"); 1512 1513 if (pImage) 1514 delete pImage; 1515 if(pDevice) 1516 delete pDevice; 1517 } 1518 return bSuccess; 1519 } 1520 bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1521 { 1522 if (!check_device_type(dev, RKUSB_MASKROM)) 1523 return false; 1524 CRKImage *pImage = NULL; 1525 CRKBoot *pBoot = NULL; 1526 CRKComm *pComm = NULL; 1527 bool bRet, bSuccess = false; 1528 int iRet; 1529 char index; 1530 USHORT usFlashDataSec, usFlashBootSec; 1531 DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1532 char loaderCodeName[] = "FlashBoot"; 1533 char loaderDataName[] = "FlashData"; 1534 PBYTE loaderCodeBuffer = NULL; 1535 PBYTE loaderDataBuffer = NULL; 1536 PBYTE pIDBData = NULL; 1537 pImage = new CRKImage(szLoader, bRet); 1538 if (!bRet){ 1539 ERROR_COLOR_ATTR; 1540 printf("Opening loader failed, exiting upgrade loader!"); 1541 NORMAL_COLOR_ATTR; 1542 printf("\r\n"); 1543 goto Exit_UpgradeLoader; 1544 } else { 1545 pBoot = (CRKBoot *)pImage->m_bootObject; 1546 dev.emDeviceType = pBoot->SupportDevice; 1547 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1548 if (!bRet) { 1549 ERROR_COLOR_ATTR; 1550 printf("Creating Comm Object failed!"); 1551 NORMAL_COLOR_ATTR; 1552 printf("\r\n"); 1553 goto Exit_UpgradeLoader; 1554 } 1555 1556 printf("Upgrading loader...\r\n"); 1557 index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1558 if (index == -1) { 1559 if (g_pLogObject) { 1560 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__); 1561 } 1562 goto Exit_UpgradeLoader; 1563 } 1564 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1565 if (!bRet) { 1566 if (g_pLogObject) { 1567 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__); 1568 } 1569 goto Exit_UpgradeLoader; 1570 } 1571 1572 loaderCodeBuffer = new BYTE[dwLoaderSize]; 1573 memset(loaderCodeBuffer, 0, dwLoaderSize); 1574 if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1575 if (g_pLogObject) { 1576 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__); 1577 } 1578 goto Exit_UpgradeLoader; 1579 } 1580 1581 index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1582 if (index == -1) { 1583 if (g_pLogObject) { 1584 g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__); 1585 } 1586 delete []loaderCodeBuffer; 1587 return -4; 1588 } 1589 1590 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1591 if (!bRet) { 1592 if (g_pLogObject) { 1593 g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__); 1594 } 1595 goto Exit_UpgradeLoader; 1596 } 1597 1598 loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1599 memset(loaderDataBuffer, 0, dwLoaderDataSize); 1600 if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1601 if (g_pLogObject) { 1602 g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__); 1603 } 1604 goto Exit_UpgradeLoader; 1605 } 1606 1607 usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1608 usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1609 dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1610 pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1611 if (!pIDBData) { 1612 ERROR_COLOR_ATTR; 1613 printf("Allocating memory failed!"); 1614 NORMAL_COLOR_ATTR; 1615 printf("\r\n"); 1616 goto Exit_UpgradeLoader; 1617 } 1618 memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1619 iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag); 1620 if (iRet != 0) { 1621 ERROR_COLOR_ATTR; 1622 printf("Making idblock failed!"); 1623 NORMAL_COLOR_ATTR; 1624 printf("\r\n"); 1625 goto Exit_UpgradeLoader; 1626 } 1627 if (g_pLogObject) 1628 g_pLogObject->SaveBuffer("idblock.bin",pIDBData,dwSectorNum*SECTOR_SIZE); 1629 iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1630 CURSOR_MOVEUP_LINE(1); 1631 CURSOR_DEL_LINE; 1632 if (iRet == ERR_SUCCESS) { 1633 //pComm->Reset_Usb_Device(); 1634 bSuccess = true; 1635 printf("Upgrading loader succeeded.\r\n"); 1636 } else { 1637 printf("Upgrading loader failed!\r\n"); 1638 goto Exit_UpgradeLoader; 1639 } 1640 } 1641 Exit_UpgradeLoader: 1642 if (pImage) 1643 delete pImage; 1644 if (pComm) 1645 delete pComm; 1646 if (loaderCodeBuffer) 1647 delete []loaderCodeBuffer; 1648 if (loaderDataBuffer) 1649 delete []loaderDataBuffer; 1650 if (pIDBData) 1651 delete []pIDBData; 1652 return bSuccess; 1653 } 1654 1655 bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 1656 { 1657 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1658 return false; 1659 CRKImage *pImage = NULL; 1660 bool bRet, bSuccess = false; 1661 int iRet; 1662 CRKScan *pScan = NULL; 1663 pScan = new CRKScan(); 1664 pScan->SetVidPid(); 1665 1666 CRKComm *pComm = NULL; 1667 CRKDevice *pDevice = NULL; 1668 1669 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1670 if (!bRet) { 1671 if (pScan) 1672 delete pScan; 1673 ERROR_COLOR_ATTR; 1674 printf("Creating Comm Object failed!"); 1675 NORMAL_COLOR_ATTR; 1676 printf("\r\n"); 1677 return bSuccess; 1678 } 1679 1680 pDevice = new CRKDevice(dev); 1681 if (!pDevice) { 1682 if (pComm) 1683 delete pComm; 1684 if (pScan) 1685 delete pScan; 1686 ERROR_COLOR_ATTR; 1687 printf("Creating device object failed!"); 1688 NORMAL_COLOR_ATTR; 1689 printf("\r\n"); 1690 return bSuccess; 1691 } 1692 1693 pDevice->SetObject(pImage, pComm, g_pLogObject); 1694 pDevice->CallBackPointer = ProgressInfoProc; 1695 1696 printf("Starting to erase flash...\r\n"); 1697 iRet = pDevice->EraseAllBlocks(); 1698 if (pDevice) 1699 delete pDevice; 1700 1701 if (iRet == 0) { 1702 if (pScan) { 1703 pScan->SetVidPid(); 1704 pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 1705 delete pScan; 1706 } 1707 CURSOR_MOVEUP_LINE(1); 1708 CURSOR_DEL_LINE; 1709 bSuccess = true; 1710 printf("Erasing flash complete.\r\n"); 1711 } 1712 1713 return bSuccess; 1714 } 1715 1716 bool test_device(STRUCT_RKDEVICE_DESC &dev) 1717 { 1718 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1719 return false; 1720 CRKUsbComm *pComm = NULL; 1721 bool bRet, bSuccess = false; 1722 int iRet; 1723 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1724 if (bRet) { 1725 iRet = pComm->RKU_TestDeviceReady(); 1726 if (iRet != ERR_SUCCESS) { 1727 if (g_pLogObject) 1728 g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 1729 printf("Test Device failed!\r\n"); 1730 } else { 1731 bSuccess = true; 1732 printf("Test Device OK.\r\n"); 1733 } 1734 } else { 1735 printf("Test Device quit, creating comm object failed!\r\n"); 1736 } 1737 if (pComm) { 1738 delete pComm; 1739 pComm = NULL; 1740 } 1741 return bSuccess; 1742 } 1743 bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 1744 { 1745 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1746 return false; 1747 CRKUsbComm *pComm = NULL; 1748 bool bRet, bSuccess = false; 1749 int iRet; 1750 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1751 if (bRet) { 1752 iRet = pComm->RKU_ResetDevice(subCode); 1753 if (iRet != ERR_SUCCESS) { 1754 if (g_pLogObject) 1755 g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 1756 printf("Reset Device failed!\r\n"); 1757 } else { 1758 bSuccess = true; 1759 printf("Reset Device OK.\r\n"); 1760 } 1761 } else { 1762 printf("Reset Device quit, creating comm object failed!\r\n"); 1763 } 1764 if (pComm) { 1765 delete pComm; 1766 pComm = NULL; 1767 } 1768 return bSuccess; 1769 } 1770 1771 bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 1772 { 1773 CRKUsbComm *pComm = NULL; 1774 bool bRet, bSuccess = false; 1775 int iRet; 1776 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1777 return bSuccess; 1778 1779 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1780 if (bRet) { 1781 BYTE flashID[5]; 1782 iRet = pComm->RKU_ReadFlashID(flashID); 1783 if (iRet != ERR_SUCCESS) { 1784 if (g_pLogObject) 1785 g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 1786 printf("Reading flash ID failed!\r\n"); 1787 } else { 1788 printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 1789 bSuccess = true; 1790 } 1791 } else { 1792 printf("Read Flash ID quit, creating comm object failed!\r\n"); 1793 } 1794 if (pComm) { 1795 delete pComm; 1796 pComm = NULL; 1797 } 1798 return bSuccess; 1799 } 1800 bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 1801 { 1802 CRKUsbComm *pComm = NULL; 1803 bool bRet, bSuccess = false; 1804 int iRet; 1805 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1806 return bSuccess; 1807 1808 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1809 if (bRet) { 1810 STRUCT_FLASHINFO_CMD info; 1811 UINT uiRead; 1812 iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 1813 if (iRet != ERR_SUCCESS) { 1814 if (g_pLogObject) 1815 g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 1816 printf("Read Flash Info failed!\r\n"); 1817 } else { 1818 printf("Flash Info:\r\n"); 1819 if (info.bManufCode <= 7) { 1820 printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 1821 } 1822 else 1823 printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 1824 1825 printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 1826 printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 1827 printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 1828 printf("\tECC Bits: %d\r\n", info.bECCBits); 1829 printf("\tAccess Time: %d\r\n", info.bAccessTime); 1830 printf("\tFlash CS: "); 1831 for(int i = 0; i < 8; i++) { 1832 if( info.bFlashCS & (1 << i) ) 1833 printf("Flash<%d> ", i); 1834 } 1835 printf("\r\n"); 1836 bSuccess = true; 1837 } 1838 }else { 1839 printf("Read Flash Info quit, creating comm object failed!\r\n"); 1840 } 1841 if (pComm) { 1842 delete pComm; 1843 pComm = NULL; 1844 } 1845 return bSuccess; 1846 } 1847 bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 1848 { 1849 CRKUsbComm *pComm = NULL; 1850 bool bRet, bSuccess = false; 1851 int iRet; 1852 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1853 return bSuccess; 1854 1855 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1856 if (bRet) { 1857 BYTE chipInfo[16]; 1858 iRet = pComm->RKU_ReadChipInfo(chipInfo); 1859 if (iRet != ERR_SUCCESS) { 1860 if (g_pLogObject) 1861 g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 1862 printf("Read Chip Info failed!\r\n"); 1863 } else { 1864 string strChipInfo; 1865 g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 1866 printf("Chip Info: %s\r\n", strChipInfo.c_str()); 1867 bSuccess = true; 1868 } 1869 } else { 1870 printf("Read Chip Info quit, creating comm object failed!\r\n"); 1871 } 1872 if (pComm) { 1873 delete pComm; 1874 pComm = NULL; 1875 } 1876 return bSuccess; 1877 } 1878 bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 1879 { 1880 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1881 return false; 1882 CRKUsbComm *pComm = NULL; 1883 FILE *file = NULL; 1884 bool bRet, bFirst = true, bSuccess = false; 1885 int iRet; 1886 UINT iTotalRead = 0,iRead = 0; 1887 int nSectorSize = 512; 1888 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 1889 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1890 if (bRet) { 1891 if(szFile) { 1892 file = fopen(szFile, "wb+"); 1893 if( !file ) { 1894 printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 1895 goto Exit_ReadLBA; 1896 } 1897 } 1898 1899 while(uiLen > 0) { 1900 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 1901 iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 1902 iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 1903 if(ERR_SUCCESS == iRet) { 1904 uiLen -= iRead; 1905 iTotalRead += iRead; 1906 1907 if(szFile) { 1908 fwrite(pBuf, 1, iRead * nSectorSize, file); 1909 if (bFirst){ 1910 if (iTotalRead >= 1024) 1911 printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 1912 else 1913 printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 1914 bFirst = false; 1915 } else { 1916 CURSOR_MOVEUP_LINE(1); 1917 CURSOR_DEL_LINE; 1918 if (iTotalRead >= 1024) 1919 printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 1920 else 1921 printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 1922 } 1923 } 1924 else 1925 PrintData(pBuf, nSectorSize * iRead); 1926 } else { 1927 if (g_pLogObject) 1928 g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 1929 1930 printf("Read LBA failed!\r\n"); 1931 goto Exit_ReadLBA; 1932 } 1933 } 1934 bSuccess = true; 1935 } else { 1936 printf("Read LBA quit, creating comm object failed!\r\n"); 1937 } 1938 Exit_ReadLBA: 1939 if (pComm) { 1940 delete pComm; 1941 pComm = NULL; 1942 } 1943 if (file) 1944 fclose(file); 1945 return bSuccess; 1946 } 1947 bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 1948 { 1949 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1950 return false; 1951 CRKUsbComm *pComm = NULL; 1952 FILE *file = NULL; 1953 bool bRet, bFirst = true, bSuccess = false; 1954 int iRet; 1955 long long iTotalWrite = 0, iFileSize = 0; 1956 UINT iWrite = 0, iRead = 0; 1957 UINT uiLen; 1958 int nSectorSize = 512; 1959 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 1960 1961 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1962 if (bRet) { 1963 file = fopen(szFile, "rb"); 1964 if( !file ) { 1965 printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 1966 goto Exit_WriteLBA; 1967 } 1968 1969 iRet = fseeko(file, 0, SEEK_END); 1970 iFileSize = ftello(file); 1971 fseeko(file, 0, SEEK_SET); 1972 while(iTotalWrite < iFileSize) { 1973 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 1974 iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 1975 uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 1976 iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 1977 if(ERR_SUCCESS == iRet) { 1978 uiBegin += uiLen; 1979 iTotalWrite += iWrite; 1980 if (bFirst) { 1981 if (iTotalWrite >= 1024) 1982 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 1983 else 1984 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 1985 bFirst = false; 1986 } else { 1987 CURSOR_MOVEUP_LINE(1); 1988 CURSOR_DEL_LINE; 1989 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 1990 } 1991 } else { 1992 if (g_pLogObject) 1993 g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 1994 1995 printf("Write LBA failed!\r\n"); 1996 goto Exit_WriteLBA; 1997 } 1998 } 1999 bSuccess = true; 2000 } else { 2001 printf("Write LBA quit, creating comm object failed!\r\n"); 2002 } 2003 Exit_WriteLBA: 2004 if (pComm) { 2005 delete pComm; 2006 pComm = NULL; 2007 } 2008 if (file) 2009 fclose(file); 2010 return bSuccess; 2011 } 2012 2013 void split_item(STRING_VECTOR &vecItems, char *pszItems) 2014 { 2015 string strItem; 2016 char szItem[100]; 2017 char *pos = NULL, *pStart; 2018 pStart = pszItems; 2019 pos = strchr(pStart, ','); 2020 while(pos != NULL) { 2021 memset(szItem, 0, 100); 2022 strncpy(szItem, pStart, pos - pStart); 2023 strItem = szItem; 2024 vecItems.push_back(strItem); 2025 pStart = pos + 1; 2026 if (*pStart == 0) 2027 break; 2028 pos = strchr(pStart, ','); 2029 } 2030 if (strlen(pStart) > 0) { 2031 memset(szItem, 0, 100); 2032 strncpy(szItem, pStart, strlen(pStart)); 2033 strItem = szItem; 2034 vecItems.push_back(strItem); 2035 } 2036 } 2037 2038 void tag_spl(char *tag, char *spl) 2039 { 2040 FILE *file = NULL; 2041 int len; 2042 2043 if(!tag || !spl) 2044 return; 2045 len = strlen(tag); 2046 printf("tag len=%d\n",len); 2047 file = fopen(spl, "rb"); 2048 if( !file ){ 2049 return; 2050 } 2051 int iFileSize; 2052 fseek(file, 0, SEEK_END); 2053 iFileSize = ftell(file); 2054 fseek(file, 0, SEEK_SET); 2055 char *Buf = NULL; 2056 Buf = new char[iFileSize + len + 1]; 2057 if (!Buf){ 2058 fclose(file); 2059 return; 2060 } 2061 memset(Buf, 0, iFileSize + 1); 2062 memcpy(Buf, tag, len); 2063 int iRead; 2064 iRead = fread(Buf+len, 1, iFileSize, file); 2065 if (iRead != iFileSize){ 2066 fclose(file); 2067 delete []Buf; 2068 return; 2069 } 2070 fclose(file); 2071 2072 len = strlen(spl); 2073 char *taggedspl = new char[len + 5]; 2074 strcpy(taggedspl, spl); 2075 strcpy(taggedspl + len, ".tag"); 2076 taggedspl[len+4] = 0; 2077 printf("Writing tagged spl to %s\n", taggedspl); 2078 2079 file = fopen(taggedspl, "wb"); 2080 if( !file ){ 2081 delete []taggedspl; 2082 delete []Buf; 2083 return; 2084 } 2085 fwrite(Buf, 1, iFileSize+len, file); 2086 fclose(file); 2087 delete []taggedspl; 2088 delete []Buf; 2089 printf("done\n"); 2090 return; 2091 } 2092 2093 bool handle_command(int argc, char* argv[], CRKScan *pScan) 2094 { 2095 string strCmd; 2096 strCmd = argv[1]; 2097 ssize_t cnt; 2098 bool bRet,bSuccess = false; 2099 char *s; 2100 int i, ret; 2101 STRUCT_RKDEVICE_DESC dev; 2102 2103 transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 2104 s = (char*)strCmd.c_str(); 2105 for(i = 0; i < (int)strlen(s); i++) 2106 s[i] = toupper(s[i]); 2107 2108 if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 2109 usage(); 2110 return true; 2111 } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2112 printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 2113 return true; 2114 } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 2115 mergeBoot(); 2116 2117 return true; 2118 } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 2119 string strLoader = argv[2]; 2120 2121 unpackBoot((char*)strLoader.c_str()); 2122 return true; 2123 } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 2124 if (argc == 4) { 2125 string tag = argv[2]; 2126 string spl = argv[3]; 2127 printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 2128 tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 2129 return true; 2130 } 2131 printf("tagspl: parameter error\n"); 2132 usage(); 2133 } 2134 cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 2135 if (cnt < 1) { 2136 ERROR_COLOR_ATTR; 2137 printf("Did not find any rockusb device, please plug device in!"); 2138 NORMAL_COLOR_ATTR; 2139 printf("\r\n"); 2140 return bSuccess; 2141 } else if (cnt > 1) { 2142 ERROR_COLOR_ATTR; 2143 printf("Found too many rockusb devices, please plug devices out!"); 2144 NORMAL_COLOR_ATTR; 2145 printf("\r\n"); 2146 return bSuccess; 2147 } 2148 2149 bRet = pScan->GetDevice(dev, 0); 2150 if (!bRet) { 2151 ERROR_COLOR_ATTR; 2152 printf("Getting information about rockusb device failed!"); 2153 NORMAL_COLOR_ATTR; 2154 printf("\r\n"); 2155 return bSuccess; 2156 } 2157 2158 if(strcmp(strCmd.c_str(), "RD") == 0) { 2159 if ((argc != 2) && (argc != 3)) 2160 printf("Parameter of [RD] command is invalid, please check help!\r\n"); 2161 else { 2162 if (argc == 2) 2163 bSuccess = reset_device(dev); 2164 else { 2165 UINT uiSubCode; 2166 char *pszEnd; 2167 uiSubCode = strtoul(argv[2], &pszEnd, 0); 2168 if (*pszEnd) 2169 printf("Subcode is invalid, please check!\r\n"); 2170 else { 2171 if (uiSubCode <= 5) 2172 bSuccess = reset_device(dev, uiSubCode); 2173 else 2174 printf("Subcode is invalid, please check!\r\n"); 2175 } 2176 } 2177 } 2178 } else if(strcmp(strCmd.c_str(), "TD") == 0) { 2179 bSuccess = test_device(dev); 2180 } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 2181 bSuccess = read_flash_id(dev); 2182 } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 2183 bSuccess = read_flash_info(dev); 2184 } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 2185 bSuccess = read_chip_info(dev); 2186 } else if(strcmp(strCmd.c_str(), "DB") == 0) { 2187 if (argc > 2) { 2188 string strLoader; 2189 strLoader = argv[2]; 2190 bSuccess = download_boot(dev, (char *)strLoader.c_str()); 2191 } else if (argc == 2) { 2192 ret = find_config_item("loader"); 2193 if (ret == -1) 2194 printf("Did not find loader item in config!\r\n"); 2195 else 2196 bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 2197 } else 2198 printf("Parameter of [DB] command is invalid, please check help!\r\n"); 2199 } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2200 if (argc > 2) { 2201 string strParameter; 2202 strParameter = argv[2]; 2203 bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2204 } else 2205 printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 2206 } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2207 if (argc > 2) { 2208 string strLoader; 2209 strLoader = argv[2]; 2210 bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2211 } else 2212 printf("Parameter of [UL] command is invalid, please check help!\r\n"); 2213 } else if(strcmp(strCmd.c_str(), "EF") == 0) { 2214 if (argc == 2) { 2215 bSuccess = erase_flash(dev); 2216 } else 2217 printf("Parameter of [EF] command is invalid, please check help!\r\n"); 2218 } else if(strcmp(strCmd.c_str(), "WL") == 0) { 2219 if (argc == 4) { 2220 UINT uiBegin; 2221 char *pszEnd; 2222 uiBegin = strtoul(argv[2], &pszEnd, 0); 2223 if (*pszEnd) 2224 printf("Begin is invalid, please check!\r\n"); 2225 else 2226 bSuccess = write_lba(dev, uiBegin, argv[3]); 2227 } else 2228 printf("Parameter of [WL] command is invalid, please check help!\r\n"); 2229 } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 2230 char *pszEnd; 2231 UINT uiBegin, uiLen; 2232 if (argc != 5) 2233 printf("Parameter of [RL] command is invalid, please check help!\r\n"); 2234 else { 2235 uiBegin = strtoul(argv[2], &pszEnd, 0); 2236 if (*pszEnd) 2237 printf("Begin is invalid, please check!\r\n"); 2238 else { 2239 uiLen = strtoul(argv[3], &pszEnd, 0); 2240 if (*pszEnd) 2241 printf("Len is invalid, please check!\r\n"); 2242 else { 2243 bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 2244 } 2245 } 2246 } 2247 } else { 2248 printf("command is invalid!\r\n"); 2249 usage(); 2250 } 2251 return bSuccess; 2252 } 2253 2254 2255 int main(int argc, char* argv[]) 2256 { 2257 CRKScan *pScan = NULL; 2258 int ret; 2259 char szProgramProcPath[100]; 2260 char szProgramDir[256]; 2261 string strLogDir,strConfigFile; 2262 struct stat statBuf; 2263 2264 g_ConfigItemVec.clear(); 2265 sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 2266 if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 2267 strcpy(szProgramDir, "."); 2268 else { 2269 char *pSlash; 2270 pSlash = strrchr(szProgramDir, '/'); 2271 if (pSlash) 2272 *pSlash = '\0'; 2273 } 2274 strLogDir = szProgramDir; 2275 strLogDir += "/log/"; 2276 strConfigFile = szProgramDir; 2277 strConfigFile += "/config.ini"; 2278 if (opendir(strLogDir.c_str()) == NULL) 2279 mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 2280 g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 2281 2282 if(stat(strConfigFile.c_str(), &statBuf) < 0) { 2283 if (g_pLogObject) { 2284 g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 2285 } 2286 } else if (S_ISREG(statBuf.st_mode)) { 2287 parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 2288 } 2289 2290 ret = libusb_init(NULL); 2291 if (ret < 0) { 2292 if (g_pLogObject) { 2293 g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 2294 delete g_pLogObject; 2295 } 2296 return -1; 2297 } 2298 2299 pScan = new CRKScan(); 2300 if (!pScan) { 2301 if (g_pLogObject) { 2302 g_pLogObject->Record("Error: failed to create object for searching device"); 2303 delete g_pLogObject; 2304 } 2305 libusb_exit(NULL); 2306 return -2; 2307 } 2308 pScan->SetVidPid(); 2309 2310 if (argc == 1) 2311 usage(); 2312 else if (!handle_command(argc, argv, pScan)) 2313 return -0xFF; 2314 if (pScan) 2315 delete pScan; 2316 if (g_pLogObject) 2317 delete g_pLogObject; 2318 libusb_exit(NULL); 2319 return 0; 2320 } 2321