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) 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 printf("write:%s\n", path); 1148 uint32_t size; 1149 rk_boot_entry entry; 1150 memset(&entry, 0, sizeof(rk_boot_entry)); 1151 1152 printf("write:%s\n", path); 1153 1154 getName(fixName ? fixName: path, entry.name); 1155 entry.size = sizeof(rk_boot_entry); 1156 entry.type = type; 1157 entry.dataOffset = *offset; 1158 if (!getFileSize(path, &size)) { 1159 printf("save entry(%s) failed:\n\tcannot get file size.\n", path); 1160 return false; 1161 } 1162 if (fix) 1163 size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 1164 uint32_t tmp = size % ENTRY_ALIGN; 1165 size += tmp ? (ENTRY_ALIGN - tmp): 0; 1166 printf("align size:%d\n", size); 1167 entry.dataSize = size; 1168 entry.dataDelay = delay; 1169 *offset += size; 1170 fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 1171 return true; 1172 } 1173 1174 static inline uint32_t convertChipType(const char* chip) { 1175 char buffer[5]; 1176 memset(buffer, 0, sizeof(buffer)); 1177 snprintf(buffer, sizeof(buffer), "%s", chip); 1178 return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 1179 } 1180 1181 static inline uint32_t getChipType(const char* chip) { 1182 printf("chip:%s\n", chip); 1183 int chipType = RKNONE_DEVICE; 1184 if(!chip) { 1185 goto end; 1186 } 1187 if (!strcmp(chip, CHIP_RK28)) { 1188 chipType = RK28_DEVICE; 1189 } else if (!strcmp(chip, CHIP_RK28)) { 1190 chipType = RK28_DEVICE; 1191 } else if (!strcmp(chip, CHIP_RK281X)) { 1192 chipType = RK281X_DEVICE; 1193 } else if (!strcmp(chip, CHIP_RKPANDA)) { 1194 chipType = RKPANDA_DEVICE; 1195 } else if (!strcmp(chip, CHIP_RK27)) { 1196 chipType = RK27_DEVICE; 1197 } else if (!strcmp(chip, CHIP_RKNANO)) { 1198 chipType = RKNANO_DEVICE; 1199 } else if (!strcmp(chip, CHIP_RKSMART)) { 1200 chipType = RKSMART_DEVICE; 1201 } else if (!strcmp(chip, CHIP_RKCROWN)) { 1202 chipType = RKCROWN_DEVICE; 1203 } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 1204 chipType = RKCAYMAN_DEVICE; 1205 } else if (!strcmp(chip, CHIP_RK29)) { 1206 chipType = RK29_DEVICE; 1207 } else if (!strcmp(chip, CHIP_RK292X)) { 1208 chipType = RK292X_DEVICE; 1209 } else if (!strcmp(chip, CHIP_RK30)) { 1210 chipType = RK30_DEVICE; 1211 } else if (!strcmp(chip, CHIP_RK30B)) { 1212 chipType = RK30B_DEVICE; 1213 } else if (!strcmp(chip, CHIP_RK31)) { 1214 chipType = RK31_DEVICE; 1215 } else if (!strcmp(chip, CHIP_RK32)) { 1216 chipType = RK32_DEVICE; 1217 } else { 1218 chipType = convertChipType(chip + 2); 1219 } 1220 1221 end: 1222 printf("type:0x%x\n", chipType); 1223 if (chipType == RKNONE_DEVICE) { 1224 printf("chip type not support!\n"); 1225 } 1226 return chipType; 1227 } 1228 1229 static inline void getBoothdr(rk_boot_header* hdr) { 1230 memset(hdr, 0, sizeof(rk_boot_header)); 1231 hdr->tag = TAG; 1232 hdr->size = sizeof(rk_boot_header); 1233 hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 1234 hdr->mergerVersion = MERGER_VERSION; 1235 hdr->releaseTime = getTime(); 1236 hdr->chipType = getChipType(gOpts.chip); 1237 1238 hdr->code471Num = gOpts.code471Num; 1239 hdr->code471Offset = sizeof(rk_boot_header); 1240 hdr->code471Size = sizeof(rk_boot_entry); 1241 1242 hdr->code472Num = gOpts.code472Num; 1243 hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 1244 hdr->code472Size = sizeof(rk_boot_entry); 1245 1246 hdr->loaderNum = gOpts.loaderNum; 1247 hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 1248 hdr->loaderSize = sizeof(rk_boot_entry); 1249 #ifndef USE_P_RC4 1250 hdr->rc4Flag = 1; 1251 #endif 1252 } 1253 1254 static inline uint32_t getCrc(const char* path) { 1255 uint32_t size = 0; 1256 uint32_t crc = 0; 1257 1258 FILE* file = fopen(path, "rb"); 1259 getFileSize(path, &size); 1260 if (!file) 1261 goto end; 1262 if (!fread(gBuf, size, 1, file)) 1263 goto end; 1264 crc = CRC_32(gBuf, size); 1265 printf("crc:0x%08x\n", crc); 1266 end: 1267 if (file) 1268 fclose(file); 1269 return crc; 1270 } 1271 1272 bool mergeBoot(void) { 1273 uint32_t dataOffset; 1274 bool ret = false; 1275 int i; 1276 FILE* outFile; 1277 uint32_t crc; 1278 rk_boot_header hdr; 1279 1280 if (!initOpts()) 1281 return false; 1282 { 1283 char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 1284 char version[MAX_LINE_LEN]; 1285 snprintf(version, sizeof(version), "%s", gSubfix); 1286 if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 1287 subfix[0] = '\0'; 1288 } 1289 strcat(gOpts.outPath, version); 1290 printf("fix opt:%s\n", gOpts.outPath); 1291 } 1292 1293 printf("---------------\nUSING CONFIG:\n"); 1294 printOpts(stdout); 1295 printf("---------------\n\n"); 1296 1297 1298 outFile = fopen(gOpts.outPath, "wb+"); 1299 if (!outFile) { 1300 printf("open out file(%s) failed\n", gOpts.outPath); 1301 goto end; 1302 } 1303 1304 getBoothdr(&hdr); 1305 printf("write hdr\n"); 1306 fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 1307 1308 dataOffset = sizeof(rk_boot_header) + 1309 (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 1310 sizeof(rk_boot_entry); 1311 1312 printf("write code 471 entry\n"); 1313 for (i=0; i<gOpts.code471Num; i++) { 1314 if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 1315 &dataOffset, NULL, false)) 1316 goto end; 1317 } 1318 printf("write code 472 entry\n"); 1319 for (i=0; i<gOpts.code472Num; i++) { 1320 if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 1321 &dataOffset, NULL, false)) 1322 goto end; 1323 } 1324 printf("write loader entry\n"); 1325 for (i=0; i<gOpts.loaderNum; i++) { 1326 if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 1327 &dataOffset, gOpts.loader[i].name, true)) 1328 goto end; 1329 } 1330 1331 printf("write code 471\n"); 1332 for (i=0; i<gOpts.code471Num; i++) { 1333 if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 1334 goto end; 1335 } 1336 printf("write code 472\n"); 1337 for (i=0; i<gOpts.code472Num; i++) { 1338 if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 1339 goto end; 1340 } 1341 printf("write loader\n"); 1342 for (i=0; i<gOpts.loaderNum; i++) { 1343 if (!writeFile(outFile, gOpts.loader[i].path, true)) 1344 goto end; 1345 } 1346 fflush(outFile); 1347 1348 printf("write crc\n"); 1349 crc = getCrc(gOpts.outPath); 1350 if (!fwrite(&crc, sizeof(crc), 1, outFile)) 1351 goto end; 1352 printf("done\n"); 1353 ret = true; 1354 end: 1355 if (outFile) 1356 fclose(outFile); 1357 return ret; 1358 } 1359 1360 /************merge code end************/ 1361 /************unpack code***************/ 1362 1363 static inline void wide2str(const uint16_t* wide, char* str, int len) 1364 { 1365 int i; 1366 for (i = 0; i < len; i++) { 1367 str[i] = (char) (wide[i] & 0xFF); 1368 } 1369 str[len] = 0; 1370 } 1371 1372 static bool unpackEntry(rk_boot_entry* entry, const char* name, 1373 FILE* inFile) { 1374 bool ret = false; 1375 int size, i; 1376 FILE* outFile = fopen(name, "wb+"); 1377 if (!outFile) 1378 goto end; 1379 printf("unpack entry(%s)\n", name); 1380 fseek(inFile, entry->dataOffset, SEEK_SET); 1381 size = entry->dataSize; 1382 if (!fread(gBuf, size, 1, inFile)) 1383 goto end; 1384 if (entry->type == ENTRY_LOADER) { 1385 for(i=0; i<size/SMALL_PACKET; i++) 1386 P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 1387 if (size % SMALL_PACKET) 1388 { 1389 P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 1390 } 1391 } else { 1392 P_RC4(gBuf, size); 1393 } 1394 if (!fwrite(gBuf, size, 1, outFile)) 1395 goto end; 1396 ret = true; 1397 end: 1398 if (outFile) 1399 fclose(outFile); 1400 return ret; 1401 } 1402 1403 bool unpackBoot(char* path) { 1404 bool ret = false; 1405 FILE* inFile = fopen(path, "rb"); 1406 int entryNum, i; 1407 char name[MAX_NAME_LEN]; 1408 rk_boot_entry* entrys; 1409 if (!inFile) { 1410 fprintf(stderr, "loader(%s) not found\n", path); 1411 goto end; 1412 } 1413 1414 rk_boot_header hdr; 1415 if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 1416 fprintf(stderr, "read header failed\n"); 1417 goto end; 1418 } 1419 printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 1420 entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 1421 entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 1422 if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 1423 fprintf(stderr, "read data failed\n"); 1424 goto end; 1425 } 1426 1427 printf("entry num:%d\n", entryNum); 1428 for (i=0; i<entryNum; i++) { 1429 wide2str(entrys[i].name, name, MAX_NAME_LEN); 1430 1431 printf("entry:t=%d, name=%s, off=%d, size=%d\n", 1432 entrys[i].type, name, entrys[i].dataOffset, 1433 entrys[i].dataSize); 1434 if (!unpackEntry(entrys + i, name, inFile)) { 1435 fprintf(stderr, "unpack entry(%s) failed\n", name); 1436 goto end; 1437 } 1438 } 1439 printf("done\n"); 1440 ret = true; 1441 end: 1442 if (inFile) 1443 fclose(inFile); 1444 return ret; 1445 } 1446 1447 bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1448 { 1449 if (!check_device_type(dev, RKUSB_MASKROM)) 1450 return false; 1451 CRKImage *pImage = NULL; 1452 CRKBoot *pBoot = NULL; 1453 bool bRet, bSuccess = false; 1454 int iRet; 1455 1456 pImage = new CRKImage(szLoader, bRet); 1457 if (!bRet){ 1458 ERROR_COLOR_ATTR; 1459 printf("Open loader failed,exit download boot!"); 1460 NORMAL_COLOR_ATTR; 1461 printf("\r\n"); 1462 return bSuccess; 1463 } else { 1464 pBoot = (CRKBoot *)pImage->m_bootObject; 1465 CRKComm *pComm = NULL; 1466 CRKDevice *pDevice = NULL; 1467 1468 dev.emDeviceType = pBoot->SupportDevice; 1469 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1470 if (!bRet) { 1471 if (pImage) 1472 delete pImage; 1473 ERROR_COLOR_ATTR; 1474 printf("Creating Comm Object failed!"); 1475 NORMAL_COLOR_ATTR; 1476 printf("\r\n"); 1477 return bSuccess; 1478 } 1479 1480 pDevice = new CRKDevice(dev); 1481 if (!pDevice) { 1482 if (pImage) 1483 delete pImage; 1484 if (pComm) 1485 delete pComm; 1486 ERROR_COLOR_ATTR; 1487 printf("Creating device object failed!"); 1488 NORMAL_COLOR_ATTR; 1489 printf("\r\n"); 1490 return bSuccess; 1491 } 1492 1493 pDevice->SetObject(pImage, pComm, g_pLogObject); 1494 printf("Download boot...\r\n"); 1495 iRet = pDevice->DownloadBoot(); 1496 1497 CURSOR_MOVEUP_LINE(1); 1498 CURSOR_DEL_LINE; 1499 if (iRet == 0) { 1500 pComm->Reset_Usb_Device(); 1501 CRKScan *pScan = NULL; 1502 pScan = new CRKScan(); 1503 if (pScan) { 1504 pScan->SetVidPid(); 1505 pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 1506 delete pScan; 1507 } 1508 bSuccess = true; 1509 printf("Download boot ok.\r\n"); 1510 } 1511 else 1512 printf("Download boot failed!\r\n"); 1513 1514 if (pImage) 1515 delete pImage; 1516 if(pDevice) 1517 delete pDevice; 1518 } 1519 return bSuccess; 1520 } 1521 bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1522 { 1523 if (!check_device_type(dev, RKUSB_MASKROM)) 1524 return false; 1525 CRKImage *pImage = NULL; 1526 CRKBoot *pBoot = NULL; 1527 CRKComm *pComm = NULL; 1528 bool bRet, bSuccess = false; 1529 int iRet; 1530 char index; 1531 USHORT usFlashDataSec, usFlashBootSec; 1532 DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1533 char loaderCodeName[] = "FlashBoot"; 1534 char loaderDataName[] = "FlashData"; 1535 PBYTE loaderCodeBuffer = NULL; 1536 PBYTE loaderDataBuffer = NULL; 1537 PBYTE pIDBData = NULL; 1538 pImage = new CRKImage(szLoader, bRet); 1539 if (!bRet){ 1540 ERROR_COLOR_ATTR; 1541 printf("Open loader failed,exit upgrade loader!"); 1542 NORMAL_COLOR_ATTR; 1543 printf("\r\n"); 1544 goto Exit_UpgradeLoader; 1545 } else { 1546 pBoot = (CRKBoot *)pImage->m_bootObject; 1547 dev.emDeviceType = pBoot->SupportDevice; 1548 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1549 if (!bRet) { 1550 ERROR_COLOR_ATTR; 1551 printf("Creating Comm Object failed!"); 1552 NORMAL_COLOR_ATTR; 1553 printf("\r\n"); 1554 goto Exit_UpgradeLoader; 1555 } 1556 1557 printf("Upgrade loader...\r\n"); 1558 index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1559 if (index == -1) { 1560 if (g_pLogObject) { 1561 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry failed"); 1562 } 1563 goto Exit_UpgradeLoader; 1564 } 1565 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1566 if (!bRet) { 1567 if (g_pLogObject) { 1568 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry Size failed"); 1569 } 1570 goto Exit_UpgradeLoader; 1571 } 1572 1573 loaderCodeBuffer = new BYTE[dwLoaderSize]; 1574 memset(loaderCodeBuffer, 0, dwLoaderSize); 1575 if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1576 if (g_pLogObject) { 1577 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Data failed"); 1578 } 1579 goto Exit_UpgradeLoader; 1580 } 1581 1582 index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1583 if (index == -1) { 1584 if (g_pLogObject) { 1585 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry failed"); 1586 } 1587 delete []loaderCodeBuffer; 1588 return -4; 1589 } 1590 1591 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1592 if (!bRet) { 1593 if (g_pLogObject) { 1594 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry Size failed"); 1595 } 1596 goto Exit_UpgradeLoader; 1597 } 1598 1599 loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1600 memset(loaderDataBuffer, 0, dwLoaderDataSize); 1601 if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1602 if (g_pLogObject) { 1603 g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Data failed"); 1604 } 1605 goto Exit_UpgradeLoader; 1606 } 1607 1608 usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1609 usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1610 dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1611 pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1612 if (!pIDBData) { 1613 ERROR_COLOR_ATTR; 1614 printf("New memory failed!"); 1615 NORMAL_COLOR_ATTR; 1616 printf("\r\n"); 1617 goto Exit_UpgradeLoader; 1618 } 1619 memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1620 iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize); 1621 if (iRet != 0) { 1622 ERROR_COLOR_ATTR; 1623 printf("Make idblock failed!"); 1624 NORMAL_COLOR_ATTR; 1625 printf("\r\n"); 1626 goto Exit_UpgradeLoader; 1627 } 1628 iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1629 CURSOR_MOVEUP_LINE(1); 1630 CURSOR_DEL_LINE; 1631 if (iRet == ERR_SUCCESS) { 1632 pComm->Reset_Usb_Device(); 1633 bSuccess = true; 1634 printf("Upgrade loader ok.\r\n"); 1635 } else { 1636 printf("Upgrade loader failed!\r\n"); 1637 goto Exit_UpgradeLoader; 1638 } 1639 } 1640 Exit_UpgradeLoader: 1641 if (pImage) 1642 delete pImage; 1643 if (pComm) 1644 delete pComm; 1645 if (loaderCodeBuffer) 1646 delete []loaderCodeBuffer; 1647 if (loaderDataBuffer) 1648 delete []loaderDataBuffer; 1649 if (pIDBData) 1650 delete []pIDBData; 1651 return bSuccess; 1652 } 1653 1654 bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 1655 { 1656 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1657 return false; 1658 CRKImage *pImage = NULL; 1659 bool bRet, bSuccess = false; 1660 int iRet; 1661 CRKScan *pScan = NULL; 1662 pScan = new CRKScan(); 1663 pScan->SetVidPid(); 1664 1665 CRKComm *pComm = NULL; 1666 CRKDevice *pDevice = NULL; 1667 1668 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1669 if (!bRet) { 1670 if (pScan) 1671 delete pScan; 1672 ERROR_COLOR_ATTR; 1673 printf("Creating Comm Object failed!"); 1674 NORMAL_COLOR_ATTR; 1675 printf("\r\n"); 1676 return bSuccess; 1677 } 1678 1679 pDevice = new CRKDevice(dev); 1680 if (!pDevice) { 1681 if (pComm) 1682 delete pComm; 1683 if (pScan) 1684 delete pScan; 1685 ERROR_COLOR_ATTR; 1686 printf("Creating device object failed!"); 1687 NORMAL_COLOR_ATTR; 1688 printf("\r\n"); 1689 return bSuccess; 1690 } 1691 1692 pDevice->SetObject(pImage, pComm, g_pLogObject); 1693 pDevice->CallBackPointer = ProgressInfoProc; 1694 1695 printf("Start to erase flash...\r\n"); 1696 iRet = pDevice->EraseAllBlocks(); 1697 if (pDevice) 1698 delete pDevice; 1699 1700 if (iRet == 0) { 1701 if (pScan) { 1702 pScan->SetVidPid(); 1703 pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 1704 delete pScan; 1705 } 1706 CURSOR_MOVEUP_LINE(1); 1707 CURSOR_DEL_LINE; 1708 bSuccess = true; 1709 printf("Erase flash ok.\r\n"); 1710 } 1711 1712 return bSuccess; 1713 } 1714 1715 bool test_device(STRUCT_RKDEVICE_DESC &dev) 1716 { 1717 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1718 return false; 1719 CRKUsbComm *pComm = NULL; 1720 bool bRet, bSuccess = false; 1721 int iRet; 1722 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1723 if (bRet) { 1724 iRet = pComm->RKU_TestDeviceReady(); 1725 if (iRet != ERR_SUCCESS) { 1726 if (g_pLogObject) 1727 g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet); 1728 printf("Test Device Fail!\r\n"); 1729 } else { 1730 bSuccess = true; 1731 printf("Test Device OK.\r\n"); 1732 } 1733 } else { 1734 printf("Test Device quit,Creating comm object failed!\r\n"); 1735 } 1736 if (pComm) { 1737 delete pComm; 1738 pComm = NULL; 1739 } 1740 return bSuccess; 1741 } 1742 bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 1743 { 1744 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1745 return false; 1746 CRKUsbComm *pComm = NULL; 1747 bool bRet, bSuccess = false; 1748 int iRet; 1749 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1750 if (bRet) { 1751 iRet = pComm->RKU_ResetDevice(subCode); 1752 if (iRet != ERR_SUCCESS) { 1753 if (g_pLogObject) 1754 g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet); 1755 printf("Reset Device Fail!\r\n"); 1756 } else { 1757 bSuccess = true; 1758 printf("Reset Device OK.\r\n"); 1759 } 1760 } else { 1761 printf("Reset Device quit,Creating comm object failed!\r\n"); 1762 } 1763 if (pComm) { 1764 delete pComm; 1765 pComm = NULL; 1766 } 1767 return bSuccess; 1768 } 1769 1770 bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 1771 { 1772 CRKUsbComm *pComm = NULL; 1773 bool bRet, bSuccess = false; 1774 int iRet; 1775 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1776 return bSuccess; 1777 1778 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1779 if (bRet) { 1780 BYTE flashID[5]; 1781 iRet = pComm->RKU_ReadFlashID(flashID); 1782 if (iRet != ERR_SUCCESS) { 1783 if (g_pLogObject) 1784 g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet); 1785 printf("Read flash ID Fail!\r\n"); 1786 } else { 1787 printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 1788 bSuccess = true; 1789 } 1790 } else { 1791 printf("Read flash ID quit,Creating comm object failed!\r\n"); 1792 } 1793 if (pComm) { 1794 delete pComm; 1795 pComm = NULL; 1796 } 1797 return bSuccess; 1798 } 1799 bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 1800 { 1801 CRKUsbComm *pComm = NULL; 1802 bool bRet, bSuccess = false; 1803 int iRet; 1804 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1805 return bSuccess; 1806 1807 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1808 if (bRet) { 1809 STRUCT_FLASHINFO_CMD info; 1810 UINT uiRead; 1811 iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 1812 if (iRet != ERR_SUCCESS) { 1813 if (g_pLogObject) 1814 g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet); 1815 printf("Read flash Info Fail!\r\n"); 1816 } else { 1817 printf("Flash Info:\r\n"); 1818 if (info.bManufCode <= 7) { 1819 printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 1820 } 1821 else 1822 printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode); 1823 1824 printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024); 1825 printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2); 1826 printf("\tPage Size: %dKB\r\n", info.bPageSize / 2); 1827 printf("\tECC Bits: %d\r\n", info.bECCBits); 1828 printf("\tAccess Time: %d\r\n", info.bAccessTime); 1829 printf("\tFlash CS: "); 1830 for(int i = 0; i < 8; i++) { 1831 if( info.bFlashCS & (1 << i) ) 1832 printf("Flash<%d> ", i); 1833 } 1834 printf("\r\n"); 1835 bSuccess = true; 1836 } 1837 }else { 1838 printf("Read flash Info quit,Creating comm object failed!\r\n"); 1839 } 1840 if (pComm) { 1841 delete pComm; 1842 pComm = NULL; 1843 } 1844 return bSuccess; 1845 } 1846 bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 1847 { 1848 CRKUsbComm *pComm = NULL; 1849 bool bRet, bSuccess = false; 1850 int iRet; 1851 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1852 return bSuccess; 1853 1854 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1855 if (bRet) { 1856 BYTE chipInfo[16]; 1857 iRet = pComm->RKU_ReadChipInfo(chipInfo); 1858 if (iRet != ERR_SUCCESS) { 1859 if (g_pLogObject) 1860 g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet); 1861 printf("Read Chip Info Fail!\r\n"); 1862 } else { 1863 string strChipInfo; 1864 g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 1865 printf("Chip Info:%s\r\n", strChipInfo.c_str()); 1866 bSuccess = true; 1867 } 1868 } else { 1869 printf("Read Chip Info quit,Creating comm object failed!\r\n"); 1870 } 1871 if (pComm) { 1872 delete pComm; 1873 pComm = NULL; 1874 } 1875 return bSuccess; 1876 } 1877 bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 1878 { 1879 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1880 return false; 1881 CRKUsbComm *pComm = NULL; 1882 FILE *file = NULL; 1883 bool bRet, bFirst = true, bSuccess = false; 1884 int iRet; 1885 UINT iTotalRead = 0,iRead = 0; 1886 int nSectorSize = 512; 1887 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 1888 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1889 if (bRet) { 1890 if(szFile) { 1891 file = fopen(szFile, "wb+"); 1892 if( !file ) { 1893 printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile); 1894 goto Exit_ReadLBA; 1895 } 1896 } 1897 1898 while(uiLen > 0) { 1899 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 1900 iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 1901 iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 1902 if(ERR_SUCCESS == iRet) { 1903 uiLen -= iRead; 1904 iTotalRead += iRead; 1905 1906 if(szFile) { 1907 fwrite(pBuf, 1, iRead * nSectorSize, file); 1908 if (bFirst){ 1909 if (iTotalRead >= 1024) 1910 printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 1911 else 1912 printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 1913 bFirst = false; 1914 } else { 1915 CURSOR_MOVEUP_LINE(1); 1916 CURSOR_DEL_LINE; 1917 if (iTotalRead >= 1024) 1918 printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 1919 else 1920 printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 1921 } 1922 } 1923 else 1924 PrintData(pBuf, nSectorSize * iRead); 1925 } else { 1926 if (g_pLogObject) 1927 g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet); 1928 1929 printf("Read LBA failed!\r\n"); 1930 goto Exit_ReadLBA; 1931 } 1932 } 1933 bSuccess = true; 1934 } else { 1935 printf("Read LBA quit,Creating comm object failed!\r\n"); 1936 } 1937 Exit_ReadLBA: 1938 if (pComm) { 1939 delete pComm; 1940 pComm = NULL; 1941 } 1942 if (file) 1943 fclose(file); 1944 return bSuccess; 1945 } 1946 bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 1947 { 1948 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 1949 return false; 1950 CRKUsbComm *pComm = NULL; 1951 FILE *file = NULL; 1952 bool bRet, bFirst = true, bSuccess = false; 1953 int iRet; 1954 long long iTotalWrite = 0, iFileSize = 0; 1955 UINT iWrite = 0, iRead = 0; 1956 UINT uiLen; 1957 int nSectorSize = 512; 1958 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 1959 1960 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1961 if (bRet) { 1962 file = fopen(szFile, "rb"); 1963 if( !file ) { 1964 printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile); 1965 goto Exit_WriteLBA; 1966 } 1967 1968 iRet = fseeko(file, 0, SEEK_END); 1969 iFileSize = ftello(file); 1970 fseeko(file, 0, SEEK_SET); 1971 while(iTotalWrite < iFileSize) { 1972 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 1973 iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 1974 uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 1975 iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 1976 if(ERR_SUCCESS == iRet) { 1977 uiBegin += uiLen; 1978 iTotalWrite += iWrite; 1979 if (bFirst) { 1980 if (iTotalWrite >= 1024) 1981 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 1982 else 1983 printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize); 1984 bFirst = false; 1985 } else { 1986 CURSOR_MOVEUP_LINE(1); 1987 CURSOR_DEL_LINE; 1988 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 1989 } 1990 } else { 1991 if (g_pLogObject) 1992 g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet); 1993 1994 printf("Write LBA failed!\r\n"); 1995 goto Exit_WriteLBA; 1996 } 1997 } 1998 bSuccess = true; 1999 } else { 2000 printf("Write LBA quit,Creating comm object failed!\r\n"); 2001 } 2002 Exit_WriteLBA: 2003 if (pComm) { 2004 delete pComm; 2005 pComm = NULL; 2006 } 2007 if (file) 2008 fclose(file); 2009 return bSuccess; 2010 } 2011 2012 void split_item(STRING_VECTOR &vecItems, char *pszItems) 2013 { 2014 string strItem; 2015 char szItem[100]; 2016 char *pos = NULL, *pStart; 2017 pStart = pszItems; 2018 pos = strchr(pStart, ','); 2019 while(pos != NULL) { 2020 memset(szItem, 0, 100); 2021 strncpy(szItem, pStart, pos - pStart); 2022 strItem = szItem; 2023 vecItems.push_back(strItem); 2024 pStart = pos + 1; 2025 if (*pStart == 0) 2026 break; 2027 pos = strchr(pStart, ','); 2028 } 2029 if (strlen(pStart) > 0) { 2030 memset(szItem, 0, 100); 2031 strncpy(szItem, pStart, strlen(pStart)); 2032 strItem = szItem; 2033 vecItems.push_back(strItem); 2034 } 2035 } 2036 2037 bool handle_command(int argc, char* argv[], CRKScan *pScan) 2038 { 2039 string strCmd; 2040 strCmd = argv[1]; 2041 ssize_t cnt; 2042 bool bRet,bSuccess = false; 2043 char *s; 2044 int i, ret; 2045 STRUCT_RKDEVICE_DESC dev; 2046 2047 transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 2048 s = (char*)strCmd.c_str(); 2049 for(i = 0; i < (int)strlen(s); i++) 2050 s[i] = toupper(s[i]); 2051 2052 if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 2053 usage(); 2054 return true; 2055 } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2056 printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 2057 return true; 2058 } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 2059 mergeBoot(); 2060 2061 return true; 2062 } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 2063 string strLoader = argv[2]; 2064 2065 unpackBoot((char*)strLoader.c_str()); 2066 return true; 2067 } 2068 cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 2069 if (cnt < 1) { 2070 ERROR_COLOR_ATTR; 2071 printf("No found any rockusb device,please plug device in!"); 2072 NORMAL_COLOR_ATTR; 2073 printf("\r\n"); 2074 return bSuccess; 2075 } else if (cnt > 1) { 2076 ERROR_COLOR_ATTR; 2077 printf("Found many rockusb devices,please plug device out!"); 2078 NORMAL_COLOR_ATTR; 2079 printf("\r\n"); 2080 return bSuccess; 2081 } 2082 2083 bRet = pScan->GetDevice(dev, 0); 2084 if (!bRet) { 2085 ERROR_COLOR_ATTR; 2086 printf("Getting information of rockusb device failed!"); 2087 NORMAL_COLOR_ATTR; 2088 printf("\r\n"); 2089 return bSuccess; 2090 } 2091 2092 if(strcmp(strCmd.c_str(), "RD") == 0) { 2093 if ((argc != 2) && (argc != 3)) 2094 printf("Parameter of [RD] command is invalid,please check help!\r\n"); 2095 else { 2096 if (argc == 2) 2097 bSuccess = reset_device(dev); 2098 else { 2099 UINT uiSubCode; 2100 char *pszEnd; 2101 uiSubCode = strtoul(argv[2], &pszEnd, 0); 2102 if (*pszEnd) 2103 printf("Subcode is invalid,please check!\r\n"); 2104 else { 2105 if (uiSubCode <= 5) 2106 bSuccess = reset_device(dev, uiSubCode); 2107 else 2108 printf("Subcode is invalid,please check!\r\n"); 2109 } 2110 } 2111 } 2112 } else if(strcmp(strCmd.c_str(), "TD") == 0) { 2113 bSuccess = test_device(dev); 2114 } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 2115 bSuccess = read_flash_id(dev); 2116 } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 2117 bSuccess = read_flash_info(dev); 2118 } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 2119 bSuccess = read_chip_info(dev); 2120 } else if(strcmp(strCmd.c_str(), "DB") == 0) { 2121 if (argc > 2) { 2122 string strLoader; 2123 strLoader = argv[2]; 2124 bSuccess = download_boot(dev, (char *)strLoader.c_str()); 2125 } else if (argc == 2) { 2126 ret = find_config_item("loader"); 2127 if (ret == -1) 2128 printf("No found loader item from config!\r\n"); 2129 else 2130 bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 2131 } else 2132 printf("Parameter of [DB] command is invalid,please check help!\r\n"); 2133 } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 2134 if (argc > 2) { 2135 string strParameter; 2136 strParameter = argv[2]; 2137 bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 2138 } else 2139 printf("Parameter of [GPT] command is invalid,please check help!\r\n"); 2140 } else if(strcmp(strCmd.c_str(), "UL") == 0) { 2141 if (argc > 2) { 2142 string strLoader; 2143 strLoader = argv[2]; 2144 bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 2145 } else 2146 printf("Parameter of [UL] command is invalid,please check help!\r\n"); 2147 } else if(strcmp(strCmd.c_str(), "EF") == 0) { 2148 if (argc == 2) { 2149 bSuccess = erase_flash(dev); 2150 } else 2151 printf("Parameter of [EF] command is invalid,please check help!\r\n"); 2152 } else if(strcmp(strCmd.c_str(), "WL") == 0) { 2153 if (argc == 4) { 2154 UINT uiBegin; 2155 char *pszEnd; 2156 uiBegin = strtoul(argv[2], &pszEnd, 0); 2157 if (*pszEnd) 2158 printf("Begin is invalid,please check!\r\n"); 2159 else 2160 bSuccess = write_lba(dev, uiBegin, argv[3]); 2161 } else 2162 printf("Parameter of [WL] command is invalid,please check help!\r\n"); 2163 } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 2164 char *pszEnd; 2165 UINT uiBegin, uiLen; 2166 if (argc != 5) 2167 printf("Parameter of [RL] command is invalid,please check help!\r\n"); 2168 else { 2169 uiBegin = strtoul(argv[2], &pszEnd, 0); 2170 if (*pszEnd) 2171 printf("Begin is invalid,please check!\r\n"); 2172 else { 2173 uiLen = strtoul(argv[3], &pszEnd, 0); 2174 if (*pszEnd) 2175 printf("Len is invalid,please check!\r\n"); 2176 else { 2177 bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 2178 } 2179 } 2180 } 2181 } else { 2182 printf("command is invalid,please press rkDevelopTool -h to check usage!\r\n"); 2183 } 2184 return bSuccess; 2185 } 2186 2187 2188 int main(int argc, char* argv[]) 2189 { 2190 CRKScan *pScan = NULL; 2191 int ret; 2192 char szProgramProcPath[100]; 2193 char szProgramDir[256]; 2194 string strLogDir,strConfigFile; 2195 struct stat statBuf; 2196 2197 g_ConfigItemVec.clear(); 2198 sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 2199 if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 2200 strcpy(szProgramDir, "."); 2201 else { 2202 char *pSlash; 2203 pSlash = strrchr(szProgramDir, '/'); 2204 if (pSlash) 2205 *pSlash = '\0'; 2206 } 2207 strLogDir = szProgramDir; 2208 strLogDir += "/log/"; 2209 strConfigFile = szProgramDir; 2210 strConfigFile += "/config.ini"; 2211 if (opendir(strLogDir.c_str()) == NULL) 2212 mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 2213 g_pLogObject = new CRKLog(strLogDir.c_str(), "log"); 2214 2215 if(stat(strConfigFile.c_str(), &statBuf) < 0) { 2216 if (g_pLogObject) { 2217 g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno); 2218 } 2219 } else if (S_ISREG(statBuf.st_mode)) { 2220 parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 2221 } 2222 2223 ret = libusb_init(NULL); 2224 if (ret < 0) { 2225 if (g_pLogObject) { 2226 g_pLogObject->Record("Error:libusb_init failed,err=%d", ret); 2227 delete g_pLogObject; 2228 } 2229 return -1; 2230 } 2231 2232 pScan = new CRKScan(); 2233 if (!pScan) { 2234 if (g_pLogObject) { 2235 g_pLogObject->Record("Error:failed to Create object for searching device"); 2236 delete g_pLogObject; 2237 } 2238 libusb_exit(NULL); 2239 return -2; 2240 } 2241 pScan->SetVidPid(); 2242 2243 if (argc == 1) 2244 usage(); 2245 else if (!handle_command(argc, argv, pScan)) 2246 return -0xFF; 2247 if (pScan) 2248 delete pScan; 2249 if (g_pLogObject) 2250 delete g_pLogObject; 2251 libusb_exit(NULL); 2252 return 0; 2253 } 2254