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