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