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 pComm->Reset_Usb_Device(); 1499 CRKScan *pScan = NULL; 1500 pScan = new CRKScan(); 1501 if (pScan) { 1502 pScan->SetVidPid(); 1503 pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 1504 delete pScan; 1505 } 1506 bSuccess = true; 1507 printf("Download boot ok.\r\n"); 1508 } 1509 else 1510 printf("Download boot failed!\r\n"); 1511 1512 if (pImage) 1513 delete pImage; 1514 if(pDevice) 1515 delete pDevice; 1516 } 1517 return bSuccess; 1518 } 1519 bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1520 { 1521 if (!check_device_type(dev, RKUSB_MASKROM)) 1522 return false; 1523 CRKImage *pImage = NULL; 1524 CRKBoot *pBoot = NULL; 1525 CRKComm *pComm = NULL; 1526 bool bRet, bSuccess = false; 1527 int iRet; 1528 char index; 1529 USHORT usFlashDataSec, usFlashBootSec; 1530 DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1531 char loaderCodeName[] = "FlashBoot"; 1532 char loaderDataName[] = "FlashData"; 1533 PBYTE loaderCodeBuffer = NULL; 1534 PBYTE loaderDataBuffer = NULL; 1535 PBYTE pIDBData = NULL; 1536 pImage = new CRKImage(szLoader, bRet); 1537 if (!bRet){ 1538 ERROR_COLOR_ATTR; 1539 printf("Open loader failed,exit upgrade loader!"); 1540 NORMAL_COLOR_ATTR; 1541 printf("\r\n"); 1542 goto Exit_UpgradeLoader; 1543 } else { 1544 pBoot = (CRKBoot *)pImage->m_bootObject; 1545 dev.emDeviceType = pBoot->SupportDevice; 1546 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1547 if (!bRet) { 1548 ERROR_COLOR_ATTR; 1549 printf("Creating Comm Object failed!"); 1550 NORMAL_COLOR_ATTR; 1551 printf("\r\n"); 1552 goto Exit_UpgradeLoader; 1553 } 1554 1555 printf("Upgrade loader...\r\n"); 1556 index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1557 if (index == -1) { 1558 if (g_pLogObject) { 1559 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry failed"); 1560 } 1561 goto Exit_UpgradeLoader; 1562 } 1563 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1564 if (!bRet) { 1565 if (g_pLogObject) { 1566 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry Size failed"); 1567 } 1568 goto Exit_UpgradeLoader; 1569 } 1570 1571 loaderCodeBuffer = new BYTE[dwLoaderSize]; 1572 memset(loaderCodeBuffer, 0, dwLoaderSize); 1573 if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1574 if (g_pLogObject) { 1575 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Data failed"); 1576 } 1577 goto Exit_UpgradeLoader; 1578 } 1579 1580 index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1581 if (index == -1) { 1582 if (g_pLogObject) { 1583 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry failed"); 1584 } 1585 delete []loaderCodeBuffer; 1586 return -4; 1587 } 1588 1589 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1590 if (!bRet) { 1591 if (g_pLogObject) { 1592 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry Size failed"); 1593 } 1594 goto Exit_UpgradeLoader; 1595 } 1596 1597 loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1598 memset(loaderDataBuffer, 0, dwLoaderDataSize); 1599 if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1600 if (g_pLogObject) { 1601 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Data failed"); 1602 } 1603 goto Exit_UpgradeLoader; 1604 } 1605 1606 usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1607 usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1608 dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1609 pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1610 if (!pIDBData) { 1611 ERROR_COLOR_ATTR; 1612 printf("New memory failed!"); 1613 NORMAL_COLOR_ATTR; 1614 printf("\r\n"); 1615 goto Exit_UpgradeLoader; 1616 } 1617 memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1618 iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize); 1619 if (iRet != 0) { 1620 ERROR_COLOR_ATTR; 1621 printf("Make idblock failed!"); 1622 NORMAL_COLOR_ATTR; 1623 printf("\r\n"); 1624 goto Exit_UpgradeLoader; 1625 } 1626 iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1627 CURSOR_MOVEUP_LINE(1); 1628 CURSOR_DEL_LINE; 1629 if (iRet == ERR_SUCCESS) { 1630 pComm->Reset_Usb_Device(); 1631 bSuccess = true; 1632 printf("Upgrade loader ok.\r\n"); 1633 } else { 1634 printf("Upgrade loader failed!\r\n"); 1635 goto Exit_UpgradeLoader; 1636 } 1637 } 1638 Exit_UpgradeLoader: 1639 if (pImage) 1640 delete pImage; 1641 if (pComm) 1642 delete pComm; 1643 if (loaderCodeBuffer) 1644 delete []loaderCodeBuffer; 1645 if (loaderDataBuffer) 1646 delete []loaderDataBuffer; 1647 if (pIDBData) 1648 delete []pIDBData; 1649 return bSuccess; 1650 } 1651 1652 bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 1653 { 1654 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1655 return false; 1656 CRKImage *pImage = NULL; 1657 bool bRet, bSuccess = false; 1658 int iRet; 1659 CRKScan *pScan = NULL; 1660 pScan = new CRKScan(); 1661 pScan->SetVidPid(); 1662 1663 CRKComm *pComm = NULL; 1664 CRKDevice *pDevice = NULL; 1665 1666 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1667 if (!bRet) { 1668 if (pScan) 1669 delete pScan; 1670 ERROR_COLOR_ATTR; 1671 printf("Creating Comm Object failed!"); 1672 NORMAL_COLOR_ATTR; 1673 printf("\r\n"); 1674 return bSuccess; 1675 } 1676 1677 pDevice = new CRKDevice(dev); 1678 if (!pDevice) { 1679 if (pComm) 1680 delete pComm; 1681 if (pScan) 1682 delete pScan; 1683 ERROR_COLOR_ATTR; 1684 printf("Creating device object failed!"); 1685 NORMAL_COLOR_ATTR; 1686 printf("\r\n"); 1687 return bSuccess; 1688 } 1689 1690 pDevice->SetObject(pImage, pComm, g_pLogObject); 1691 pDevice->CallBackPointer = ProgressInfoProc; 1692 1693 printf("Start to erase flash...\r\n"); 1694 iRet = pDevice->EraseAllBlocks(); 1695 if (pDevice) 1696 delete pDevice; 1697 1698 if (iRet == 0) { 1699 if (pScan) { 1700 pScan->SetVidPid(); 1701 pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 1702 delete pScan; 1703 } 1704 CURSOR_MOVEUP_LINE(1); 1705 CURSOR_DEL_LINE; 1706 bSuccess = true; 1707 printf("Erase flash ok.\r\n"); 1708 } 1709 1710 return bSuccess; 1711 } 1712 1713 bool test_device(STRUCT_RKDEVICE_DESC &dev) 1714 { 1715 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1716 return false; 1717 CRKUsbComm *pComm = NULL; 1718 bool bRet, bSuccess = false; 1719 int iRet; 1720 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1721 if (bRet) { 1722 iRet = pComm->RKU_TestDeviceReady(); 1723 if (iRet != ERR_SUCCESS) { 1724 if (g_pLogObject) 1725 g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet); 1726 printf("Test Device Fail!\r\n"); 1727 } else { 1728 bSuccess = true; 1729 printf("Test Device OK.\r\n"); 1730 } 1731 } else { 1732 printf("Test Device quit,Creating comm object failed!\r\n"); 1733 } 1734 if (pComm) { 1735 delete pComm; 1736 pComm = NULL; 1737 } 1738 return bSuccess; 1739 } 1740 bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 1741 { 1742 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1743 return false; 1744 CRKUsbComm *pComm = NULL; 1745 bool bRet, bSuccess = false; 1746 int iRet; 1747 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1748 if (bRet) { 1749 iRet = pComm->RKU_ResetDevice(subCode); 1750 if (iRet != ERR_SUCCESS) { 1751 if (g_pLogObject) 1752 g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet); 1753 printf("Reset Device Fail!\r\n"); 1754 } else { 1755 bSuccess = true; 1756 printf("Reset Device OK.\r\n"); 1757 } 1758 } else { 1759 printf("Reset Device quit,Creating comm object failed!\r\n"); 1760 } 1761 if (pComm) { 1762 delete pComm; 1763 pComm = NULL; 1764 } 1765 return bSuccess; 1766 } 1767 1768 bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 1769 { 1770 CRKUsbComm *pComm = NULL; 1771 bool bRet, bSuccess = false; 1772 int iRet; 1773 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1774 return bSuccess; 1775 1776 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1777 if (bRet) { 1778 BYTE flashID[5]; 1779 iRet = pComm->RKU_ReadFlashID(flashID); 1780 if (iRet != ERR_SUCCESS) { 1781 if (g_pLogObject) 1782 g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet); 1783 printf("Read flash ID Fail!\r\n"); 1784 } else { 1785 printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 1786 bSuccess = true; 1787 } 1788 } else { 1789 printf("Read flash ID quit,Creating comm object failed!\r\n"); 1790 } 1791 if (pComm) { 1792 delete pComm; 1793 pComm = NULL; 1794 } 1795 return bSuccess; 1796 } 1797 bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 1798 { 1799 CRKUsbComm *pComm = NULL; 1800 bool bRet, bSuccess = false; 1801 int iRet; 1802 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1803 return bSuccess; 1804 1805 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1806 if (bRet) { 1807 STRUCT_FLASHINFO_CMD info; 1808 UINT uiRead; 1809 iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 1810 if (iRet != ERR_SUCCESS) { 1811 if (g_pLogObject) 1812 g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet); 1813 printf("Read flash Info Fail!\r\n"); 1814 } else { 1815 printf("Flash Info:\r\n"); 1816 if (info.bManufCode <= 7) { 1817 printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 1818 } 1819 else 1820 printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode); 1821 1822 printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024); 1823 printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2); 1824 printf("\tPage Size: %dKB\r\n", info.bPageSize / 2); 1825 printf("\tECC Bits: %d\r\n", info.bECCBits); 1826 printf("\tAccess Time: %d\r\n", info.bAccessTime); 1827 printf("\tFlash CS: "); 1828 for(int i = 0; i < 8; i++) { 1829 if( info.bFlashCS & (1 << i) ) 1830 printf("Flash<%d> ", i); 1831 } 1832 printf("\r\n"); 1833 bSuccess = true; 1834 } 1835 }else { 1836 printf("Read flash Info quit,Creating comm object failed!\r\n"); 1837 } 1838 if (pComm) { 1839 delete pComm; 1840 pComm = NULL; 1841 } 1842 return bSuccess; 1843 } 1844 bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 1845 { 1846 CRKUsbComm *pComm = NULL; 1847 bool bRet, bSuccess = false; 1848 int iRet; 1849 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1850 return bSuccess; 1851 1852 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1853 if (bRet) { 1854 BYTE chipInfo[16]; 1855 iRet = pComm->RKU_ReadChipInfo(chipInfo); 1856 if (iRet != ERR_SUCCESS) { 1857 if (g_pLogObject) 1858 g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet); 1859 printf("Read Chip Info Fail!\r\n"); 1860 } else { 1861 string strChipInfo; 1862 g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 1863 printf("Chip Info:%s\r\n", strChipInfo.c_str()); 1864 bSuccess = true; 1865 } 1866 } else { 1867 printf("Read Chip Info quit,Creating comm object failed!\r\n"); 1868 } 1869 if (pComm) { 1870 delete pComm; 1871 pComm = NULL; 1872 } 1873 return bSuccess; 1874 } 1875 bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 1876 { 1877 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1878 return false; 1879 CRKUsbComm *pComm = NULL; 1880 FILE *file = NULL; 1881 bool bRet, bFirst = true, bSuccess = false; 1882 int iRet; 1883 UINT iTotalRead = 0,iRead = 0; 1884 int nSectorSize = 512; 1885 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 1886 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1887 if (bRet) { 1888 if(szFile) { 1889 file = fopen(szFile, "wb+"); 1890 if( !file ) { 1891 printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile); 1892 goto Exit_ReadLBA; 1893 } 1894 } 1895 1896 while(uiLen > 0) { 1897 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 1898 iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 1899 iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 1900 if(ERR_SUCCESS == iRet) { 1901 uiLen -= iRead; 1902 iTotalRead += iRead; 1903 1904 if(szFile) { 1905 fwrite(pBuf, 1, iRead * nSectorSize, file); 1906 if (bFirst){ 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 bFirst = false; 1912 } else { 1913 CURSOR_MOVEUP_LINE(1); 1914 CURSOR_DEL_LINE; 1915 if (iTotalRead >= 1024) 1916 printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 1917 else 1918 printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 1919 } 1920 } 1921 else 1922 PrintData(pBuf, nSectorSize * iRead); 1923 } else { 1924 if (g_pLogObject) 1925 g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet); 1926 1927 printf("Read LBA failed!\r\n"); 1928 goto Exit_ReadLBA; 1929 } 1930 } 1931 bSuccess = true; 1932 } else { 1933 printf("Read LBA quit,Creating comm object failed!\r\n"); 1934 } 1935 Exit_ReadLBA: 1936 if (pComm) { 1937 delete pComm; 1938 pComm = NULL; 1939 } 1940 if (file) 1941 fclose(file); 1942 return bSuccess; 1943 } 1944 bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 1945 { 1946 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1947 return false; 1948 CRKUsbComm *pComm = NULL; 1949 FILE *file = NULL; 1950 bool bRet, bFirst = true, bSuccess = false; 1951 int iRet; 1952 long long iTotalWrite = 0, iFileSize = 0; 1953 UINT iWrite = 0, iRead = 0; 1954 UINT uiLen; 1955 int nSectorSize = 512; 1956 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 1957 1958 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1959 if (bRet) { 1960 file = fopen(szFile, "rb"); 1961 if( !file ) { 1962 printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile); 1963 goto Exit_WriteLBA; 1964 } 1965 1966 iRet = fseeko(file, 0, SEEK_END); 1967 iFileSize = ftello(file); 1968 fseeko(file, 0, SEEK_SET); 1969 while(iTotalWrite < iFileSize) { 1970 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 1971 iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 1972 uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 1973 iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 1974 if(ERR_SUCCESS == iRet) { 1975 uiBegin += uiLen; 1976 iTotalWrite += iWrite; 1977 if (bFirst) { 1978 if (iTotalWrite >= 1024) 1979 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 1980 else 1981 printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize); 1982 bFirst = false; 1983 } else { 1984 CURSOR_MOVEUP_LINE(1); 1985 CURSOR_DEL_LINE; 1986 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 1987 } 1988 } else { 1989 if (g_pLogObject) 1990 g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet); 1991 1992 printf("Write LBA failed!\r\n"); 1993 goto Exit_WriteLBA; 1994 } 1995 } 1996 bSuccess = true; 1997 } else { 1998 printf("Write LBA quit,Creating comm object failed!\r\n"); 1999 } 2000 Exit_WriteLBA: 2001 if (pComm) { 2002 delete pComm; 2003 pComm = NULL; 2004 } 2005 if (file) 2006 fclose(file); 2007 return bSuccess; 2008 } 2009 2010 void split_item(STRING_VECTOR &vecItems, char *pszItems) 2011 { 2012 string strItem; 2013 char szItem[100]; 2014 char *pos = NULL, *pStart; 2015 pStart = pszItems; 2016 pos = strchr(pStart, ','); 2017 while(pos != NULL) { 2018 memset(szItem, 0, 100); 2019 strncpy(szItem, pStart, pos - pStart); 2020 strItem = szItem; 2021 vecItems.push_back(strItem); 2022 pStart = pos + 1; 2023 if (*pStart == 0) 2024 break; 2025 pos = strchr(pStart, ','); 2026 } 2027 if (strlen(pStart) > 0) { 2028 memset(szItem, 0, 100); 2029 strncpy(szItem, pStart, strlen(pStart)); 2030 strItem = szItem; 2031 vecItems.push_back(strItem); 2032 } 2033 } 2034 2035 bool handle_command(int argc, char* argv[], CRKScan *pScan) 2036 { 2037 string strCmd; 2038 strCmd = argv[1]; 2039 ssize_t cnt; 2040 bool bRet,bSuccess = false; 2041 char *s; 2042 int i, ret; 2043 STRUCT_RKDEVICE_DESC dev; 2044 2045 transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 2046 s = (char*)strCmd.c_str(); 2047 for(i = 0; i < (int)strlen(s); i++) 2048 s[i] = toupper(s[i]); 2049 2050 if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 2051 usage(); 2052 return true; 2053 } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2054 printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 2055 return true; 2056 } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 2057 mergeBoot(); 2058 2059 return true; 2060 } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 2061 string strLoader = argv[2]; 2062 2063 unpackBoot((char*)strLoader.c_str()); 2064 return true; 2065 } 2066 cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 2067 if (cnt < 1) { 2068 ERROR_COLOR_ATTR; 2069 printf("No found any rockusb device,please plug device in!"); 2070 NORMAL_COLOR_ATTR; 2071 printf("\r\n"); 2072 return bSuccess; 2073 } else if (cnt > 1) { 2074 ERROR_COLOR_ATTR; 2075 printf("Found many rockusb devices,please plug device out!"); 2076 NORMAL_COLOR_ATTR; 2077 printf("\r\n"); 2078 return bSuccess; 2079 } 2080 2081 bRet = pScan->GetDevice(dev, 0); 2082 if (!bRet) { 2083 ERROR_COLOR_ATTR; 2084 printf("Getting information of rockusb device failed!"); 2085 NORMAL_COLOR_ATTR; 2086 printf("\r\n"); 2087 return bSuccess; 2088 } 2089 2090 if(strcmp(strCmd.c_str(), "RD") == 0) { 2091 if ((argc != 2) && (argc != 3)) 2092 printf("Parameter of [RD] command is invalid,please check help!\r\n"); 2093 else { 2094 if (argc == 2) 2095 bSuccess = reset_device(dev); 2096 else { 2097 UINT uiSubCode; 2098 char *pszEnd; 2099 uiSubCode = strtoul(argv[2], &pszEnd, 0); 2100 if (*pszEnd) 2101 printf("Subcode is invalid,please check!\r\n"); 2102 else { 2103 if (uiSubCode <= 5) 2104 bSuccess = reset_device(dev, uiSubCode); 2105 else 2106 printf("Subcode is invalid,please check!\r\n"); 2107 } 2108 } 2109 } 2110 } else if(strcmp(strCmd.c_str(), "TD") == 0) { 2111 bSuccess = test_device(dev); 2112 } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 2113 bSuccess = read_flash_id(dev); 2114 } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 2115 bSuccess = read_flash_info(dev); 2116 } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 2117 bSuccess = read_chip_info(dev); 2118 } else if(strcmp(strCmd.c_str(), "DB") == 0) { 2119 if (argc > 2) { 2120 string strLoader; 2121 strLoader = argv[2]; 2122 bSuccess = download_boot(dev, (char *)strLoader.c_str()); 2123 } else if (argc == 2) { 2124 ret = find_config_item("loader"); 2125 if (ret == -1) 2126 printf("No found loader item from config!\r\n"); 2127 else 2128 bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 2129 } else 2130 printf("Parameter of [DB] command is invalid,please check help!\r\n"); 2131 } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2132 if (argc > 2) { 2133 string strParameter; 2134 strParameter = argv[2]; 2135 bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2136 } else 2137 printf("Parameter of [GPT] command is invalid,please check help!\r\n"); 2138 } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2139 if (argc > 2) { 2140 string strLoader; 2141 strLoader = argv[2]; 2142 bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2143 } else 2144 printf("Parameter of [UL] command is invalid,please check help!\r\n"); 2145 } else if(strcmp(strCmd.c_str(), "EF") == 0) { 2146 if (argc == 2) { 2147 bSuccess = erase_flash(dev); 2148 } else 2149 printf("Parameter of [EF] command is invalid,please check help!\r\n"); 2150 } else if(strcmp(strCmd.c_str(), "WL") == 0) { 2151 if (argc == 4) { 2152 UINT uiBegin; 2153 char *pszEnd; 2154 uiBegin = strtoul(argv[2], &pszEnd, 0); 2155 if (*pszEnd) 2156 printf("Begin is invalid,please check!\r\n"); 2157 else 2158 bSuccess = write_lba(dev, uiBegin, argv[3]); 2159 } else 2160 printf("Parameter of [WL] command is invalid,please check help!\r\n"); 2161 } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 2162 char *pszEnd; 2163 UINT uiBegin, uiLen; 2164 if (argc != 5) 2165 printf("Parameter of [RL] command is invalid,please check help!\r\n"); 2166 else { 2167 uiBegin = strtoul(argv[2], &pszEnd, 0); 2168 if (*pszEnd) 2169 printf("Begin is invalid,please check!\r\n"); 2170 else { 2171 uiLen = strtoul(argv[3], &pszEnd, 0); 2172 if (*pszEnd) 2173 printf("Len is invalid,please check!\r\n"); 2174 else { 2175 bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 2176 } 2177 } 2178 } 2179 } else { 2180 printf("command is invalid,please press rkDevelopTool -h to check usage!\r\n"); 2181 } 2182 return bSuccess; 2183 } 2184 2185 2186 int main(int argc, char* argv[]) 2187 { 2188 CRKScan *pScan = NULL; 2189 int ret; 2190 char szProgramProcPath[100]; 2191 char szProgramDir[256]; 2192 string strLogDir,strConfigFile; 2193 struct stat statBuf; 2194 2195 g_ConfigItemVec.clear(); 2196 sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 2197 if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 2198 strcpy(szProgramDir, "."); 2199 else { 2200 char *pSlash; 2201 pSlash = strrchr(szProgramDir, '/'); 2202 if (pSlash) 2203 *pSlash = '\0'; 2204 } 2205 strLogDir = szProgramDir; 2206 strLogDir += "/log/"; 2207 strConfigFile = szProgramDir; 2208 strConfigFile += "/config.ini"; 2209 if (opendir(strLogDir.c_str()) == NULL) 2210 mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 2211 g_pLogObject = new CRKLog(strLogDir.c_str(), "log"); 2212 2213 if(stat(strConfigFile.c_str(), &statBuf) < 0) { 2214 if (g_pLogObject) { 2215 g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno); 2216 } 2217 } else if (S_ISREG(statBuf.st_mode)) { 2218 parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 2219 } 2220 2221 ret = libusb_init(NULL); 2222 if (ret < 0) { 2223 if (g_pLogObject) { 2224 g_pLogObject->Record("Error:libusb_init failed,err=%d", ret); 2225 delete g_pLogObject; 2226 } 2227 return -1; 2228 } 2229 2230 pScan = new CRKScan(); 2231 if (!pScan) { 2232 if (g_pLogObject) { 2233 g_pLogObject->Record("Error:failed to Create object for searching device"); 2234 delete g_pLogObject; 2235 } 2236 libusb_exit(NULL); 2237 return -2; 2238 } 2239 pScan->SetVidPid(); 2240 2241 if (argc == 1) 2242 usage(); 2243 else if (!handle_command(argc, argv, pScan)) 2244 return -0xFF; 2245 if (pScan) 2246 delete pScan; 2247 if (g_pLogObject) 2248 delete g_pLogObject; 2249 libusb_exit(NULL); 2250 return 0; 2251 } 2252