├── .gitignore ├── 99-rk-rockusb.rules ├── CMakeLists.txt ├── DefineHeader.h ├── Endian.h ├── Makefile.am ├── Property.hpp ├── RKBoot.cpp ├── RKBoot.h ├── RKComm.cpp ├── RKComm.h ├── RKDevice.cpp ├── RKDevice.h ├── RKImage.cpp ├── RKImage.h ├── RKLog.cpp ├── RKLog.h ├── RKScan.cpp ├── RKScan.h ├── Readme.txt ├── autogen.sh ├── boot_merger.h ├── cfg ├── .gitignore └── Makefile.am ├── config.h.in ├── config.ini ├── configure.ac ├── crc.cpp ├── gpt.h ├── license.txt ├── main.cpp └── parameter_gpt.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | .deps 3 | Makefile 4 | Makefile.in 5 | aclocal.m4 6 | autom4te.cache 7 | config.log 8 | config.status 9 | configure 10 | rkdeveloptool 11 | rkdeveloptool*bz2 12 | -------------------------------------------------------------------------------- /99-rk-rockusb.rules: -------------------------------------------------------------------------------- 1 | SUBSYSTEM!="usb", GOTO="end_rules" 2 | 3 | # RK3036 4 | ATTRS{idVendor}=="2207", ATTRS{idProduct}=="301a", MODE="0666", GROUP="users" 5 | # RK3128 6 | ATTRS{idVendor}=="2207", ATTRS{idProduct}=="310c", MODE="0666", GROUP="users" 7 | # RK3229 8 | ATTRS{idVendor}=="2207", ATTRS{idProduct}=="320b", MODE="0666", GROUP="users" 9 | # RK3288 10 | ATTRS{idVendor}=="2207", ATTRS{idProduct}=="320a", MODE="0666", GROUP="users" 11 | # RK3328 12 | ATTRS{idVendor}=="2207", ATTRS{idProduct}=="320c", MODE="0666", GROUP="users" 13 | # RK3368 14 | ATTRS{idVendor}=="2207", ATTRS{idProduct}=="330a", MODE="0666", GROUP="users" 15 | # RK3399 16 | ATTRS{idVendor}=="2207", ATTRS{idProduct}=="330c", MODE="0666", GROUP="users" 17 | # RK3566 18 | ATTRS{idVendor}=="2207", ATTRS{idProduct}=="350a", MODE="0666", GROUP="users" 19 | 20 | LABEL="end_rules" 21 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project name 2 | set (PROJECT_NAME "rkDevelopTool_Mac") 3 | 4 | # The version number. 5 | set (RKDevelopTool_Mac_PACKAGE_VERSION "1.3") 6 | 7 | file (GLOB LOCAL_CPP_FILES *.cpp) 8 | set (SOURCE_FILES ${SOURCE_FILES} ${LOCAL_CPP_FILES}) 9 | 10 | file (GLOB LOCAL_H_FILES *.h) 11 | set (HEADER_FILES ${HEADER_FILES} ${LOCAL_H_FILES}) 12 | 13 | # Set your libusb path 14 | set (libusb_INCLUDE_DIR "/usr/local/Cellar/libusb/1.0.22/include/libusb-1.0/") 15 | set (libusb_STATIC "/usr/local/Cellar/libusb/1.0.22/lib/") 16 | 17 | # Set your libiconv path 18 | set (libiconv_INCLUDE_DIR "/usr/local/opt/libiconv/include/") 19 | set (libiconv_STATIC "/usr/local/opt/libiconv/lib/") 20 | 21 | cmake_minimum_required (VERSION 2.6) 22 | project (${PROJECT_NAME}) 23 | 24 | 25 | # Turn off build log 26 | # set (CMAKE_VERBOSE_MAKEFILE ON) 27 | 28 | # Configure a header file to pass some of the CMake settings 29 | # to the source code 30 | configure_file ( 31 | "${PROJECT_SOURCE_DIR}/config.h.in" 32 | "${PROJECT_BINARY_DIR}/config.h" 33 | ) 34 | 35 | # add the binary tree to the search path for include files 36 | # so that we will find config.h 37 | include_directories ( 38 | "${PROJECT_BINARY_DIR}" 39 | "${PROJECT_SOURCE_DIR}" 40 | "${libusb_INCLUDE_DIR}" 41 | "${libiconv_INCLUDE_DIR}" 42 | ) 43 | 44 | link_directories ( 45 | ${libusb_STATIC} 46 | ${libiconv_STATIC} 47 | ) 48 | 49 | add_executable (${PROJECT_NAME} ${SOURCE_FILES}) 50 | 51 | target_link_libraries ( 52 | "${PROJECT_NAME}" 53 | "${libusb_STATIC}/libusb-1.0.dylib" 54 | "${libiconv_STATIC}/libiconv.dylib" 55 | ) 56 | 57 | -------------------------------------------------------------------------------- /DefineHeader.h: -------------------------------------------------------------------------------- 1 | #ifndef DEFINE_HEADER 2 | #define DEFINE_HEADER 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "Property.hpp" 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | using namespace std; 24 | #ifndef __MINGW32__ 25 | typedef unsigned char BYTE, *PBYTE; 26 | typedef unsigned char UCHAR; 27 | typedef unsigned short WCHAR; 28 | typedef unsigned short USHORT; 29 | typedef unsigned int UINT; 30 | typedef unsigned int DWORD; 31 | #endif 32 | #define ALIGN(x, a) __ALIGN_MASK((x), (a) - 1) 33 | #define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) 34 | #define RK28_SEC2_RESERVED_LEN 473 35 | #define CHIPINFO_LEN 16 36 | #define RK28_SEC3_RESERVED_LEN 382 37 | #define RKDEVICE_SN_LEN 60 38 | #define RKDEVICE_UID_LEN 30 39 | #define RKDEVICE_MAC_LEN 6 40 | #define RKDEVICE_WIFI_LEN 6 41 | #define RKDEVICE_BT_LEN 6 42 | #define RKDEVICE_IMEI_LEN 15 43 | typedef enum{ 44 | RKNONE_DEVICE = 0, 45 | RK27_DEVICE = 0x10, 46 | RKCAYMAN_DEVICE, 47 | RK28_DEVICE = 0x20, 48 | RK281X_DEVICE, 49 | RKPANDA_DEVICE, 50 | RKNANO_DEVICE = 0x30, 51 | RKSMART_DEVICE, 52 | RKCROWN_DEVICE = 0x40, 53 | RK29_DEVICE = 0x50, 54 | RK292X_DEVICE, 55 | RK30_DEVICE = 0x60, 56 | RK30B_DEVICE, 57 | RK31_DEVICE = 0x70, 58 | RK32_DEVICE = 0x80 59 | } ENUM_RKDEVICE_TYPE; 60 | typedef enum{ 61 | RK_OS = 0, 62 | ANDROID_OS = 0x1 63 | } ENUM_OS_TYPE; 64 | 65 | typedef enum{ 66 | RKUSB_NONE = 0x0, 67 | RKUSB_MASKROM = 0x01, 68 | RKUSB_LOADER = 0x02, 69 | RKUSB_MSC = 0x04 70 | } ENUM_RKUSB_TYPE; 71 | typedef enum{ 72 | ENTRY471 = 1, 73 | ENTRY472 = 2, 74 | ENTRYLOADER = 4 75 | } ENUM_RKBOOTENTRY; 76 | 77 | #pragma pack(1) 78 | typedef struct sparse_header_t { 79 | UINT magic; /* 0xed26ff3a */ 80 | USHORT major_version; /* (0x1) - reject images with higher major versions */ 81 | USHORT minor_version; /* (0x0) - allow images with higer minor versions */ 82 | USHORT file_hdr_sz; /* 28 bytes for first revision of the file format */ 83 | USHORT chunk_hdr_sz; /* 12 bytes for first revision of the file format */ 84 | UINT blk_sz; /* block size in bytes, must be a multiple of 4 (4096) */ 85 | UINT total_blks; /* total blocks in the non-sparse output image */ 86 | UINT total_chunks; /* total chunks in the sparse input image */ 87 | UINT image_checksum; /* CRC32 checksum of the original data, counting "don't care" */ 88 | /* as 0. Standard 802.3 polynomial, use a Public Domain */ 89 | /* table implementation */ 90 | } sparse_header; 91 | #define SPARSE_HEADER_MAGIC 0xed26ff3a 92 | #define UBI_HEADER_MAGIC 0x23494255 93 | #define CHUNK_TYPE_RAW 0xCAC1 94 | #define CHUNK_TYPE_FILL 0xCAC2 95 | #define CHUNK_TYPE_DONT_CARE 0xCAC3 96 | #define CHUNK_TYPE_CRC32 0xCAC4 97 | typedef struct chunk_header_t { 98 | USHORT chunk_type; /* 0xCAC1 -> raw; 0xCAC2 -> fill; 0xCAC3 -> don't care */ 99 | USHORT reserved1; 100 | UINT chunk_sz; /* in blocks in output image */ 101 | UINT total_sz; /* in bytes of chunk input file including chunk header and data */ 102 | } chunk_header; 103 | 104 | typedef struct{ 105 | USHORT usYear; 106 | BYTE ucMonth; 107 | BYTE ucDay; 108 | BYTE ucHour; 109 | BYTE ucMinute; 110 | BYTE ucSecond; 111 | } STRUCT_RKTIME, *PSTRUCT_RKTIME; 112 | 113 | typedef struct{ 114 | char szItemName[20]; 115 | char szItemValue[256]; 116 | } STRUCT_CONFIG_ITEM, *PSTRUCT_CONFIG_ITEM; 117 | typedef struct 118 | { 119 | char szItemName[64]; 120 | UINT uiItemOffset; 121 | UINT uiItemSize; 122 | }STRUCT_PARAM_ITEM,*PSTRUCT_PARAM_ITEM; 123 | typedef struct _STRUCT_RKDEVICE_DESC{ 124 | USHORT usVid; 125 | USHORT usPid; 126 | USHORT usbcdUsb; 127 | UINT uiLocationID; 128 | ENUM_RKUSB_TYPE emUsbType; 129 | ENUM_RKDEVICE_TYPE emDeviceType; 130 | void *pUsbHandle; 131 | } STRUCT_RKDEVICE_DESC, *PSTRUCT_RKDEVICE_DESC; 132 | typedef struct { 133 | DWORD dwTag; 134 | BYTE reserved[4]; 135 | UINT uiRc4Flag; 136 | USHORT usBootCode1Offset; 137 | USHORT usBootCode2Offset; 138 | BYTE reserved1[490]; 139 | USHORT usBootDataSize; 140 | USHORT usBootCodeSize; 141 | USHORT usCrc; 142 | } RK28_IDB_SEC0, *PRK28_IDB_SEC0; 143 | 144 | typedef struct { 145 | USHORT usSysReservedBlock; 146 | USHORT usDisk0Size; 147 | USHORT usDisk1Size; 148 | USHORT usDisk2Size; 149 | USHORT usDisk3Size; 150 | UINT uiChipTag; 151 | UINT uiMachineId; 152 | USHORT usLoaderYear; 153 | USHORT usLoaderDate; 154 | USHORT usLoaderVer; 155 | USHORT usLastLoaderVer; 156 | USHORT usReadWriteTimes; 157 | DWORD dwFwVer; 158 | USHORT usMachineInfoLen; 159 | UCHAR ucMachineInfo[30]; 160 | USHORT usManufactoryInfoLen; 161 | UCHAR ucManufactoryInfo[30]; 162 | USHORT usFlashInfoOffset; 163 | USHORT usFlashInfoLen; 164 | UCHAR reserved[384]; 165 | UINT uiFlashSize; 166 | BYTE reserved1; 167 | BYTE bAccessTime; 168 | USHORT usBlockSize; 169 | BYTE bPageSize; 170 | BYTE bECCBits; 171 | BYTE reserved2[8]; 172 | USHORT usIdBlock0; 173 | USHORT usIdBlock1; 174 | USHORT usIdBlock2; 175 | USHORT usIdBlock3; 176 | USHORT usIdBlock4; 177 | } RK28_IDB_SEC1, *PRK28_IDB_SEC1; 178 | 179 | typedef struct { 180 | USHORT usInfoSize; 181 | BYTE bChipInfo[CHIPINFO_LEN]; 182 | BYTE reserved[RK28_SEC2_RESERVED_LEN]; 183 | char szVcTag[3]; 184 | USHORT usSec0Crc; 185 | USHORT usSec1Crc; 186 | UINT uiBootCodeCrc; 187 | USHORT usSec3CustomDataOffset; 188 | USHORT usSec3CustomDataSize; 189 | char szCrcTag[4]; 190 | USHORT usSec3Crc; 191 | } RK28_IDB_SEC2, *PRK28_IDB_SEC2; 192 | 193 | typedef struct { 194 | USHORT usSNSize; 195 | BYTE sn[RKDEVICE_SN_LEN]; 196 | BYTE reserved[RK28_SEC3_RESERVED_LEN]; 197 | BYTE wifiSize; 198 | BYTE wifiAddr[RKDEVICE_WIFI_LEN]; 199 | BYTE imeiSize; 200 | BYTE imei[RKDEVICE_IMEI_LEN]; 201 | BYTE uidSize; 202 | BYTE uid[RKDEVICE_UID_LEN]; 203 | BYTE blueToothSize; 204 | BYTE blueToothAddr[RKDEVICE_BT_LEN]; 205 | BYTE macSize; 206 | BYTE macAddr[RKDEVICE_MAC_LEN]; 207 | } RK28_IDB_SEC3, *PRK28_IDB_SEC3; 208 | #pragma pack() 209 | typedef list RKDEVICE_DESC_SET; 210 | typedef RKDEVICE_DESC_SET::iterator device_list_iter; 211 | typedef vector STRING_VECTOR; 212 | typedef vector UINT_VECTOR; 213 | typedef vector CONFIG_ITEM_VECTOR; 214 | typedef vector PARAM_ITEM_VECTOR; 215 | typedef enum{ 216 | TESTDEVICE_PROGRESS, 217 | DOWNLOADIMAGE_PROGRESS, 218 | CHECKIMAGE_PROGRESS, 219 | TAGBADBLOCK_PROGRESS, 220 | TESTBLOCK_PROGRESS, 221 | ERASEFLASH_PROGRESS, 222 | ERASESYSTEM_PROGRESS, 223 | LOWERFORMAT_PROGRESS, 224 | ERASEUSERDATA_PROGRESS 225 | } ENUM_PROGRESS_PROMPT; 226 | 227 | typedef enum{ 228 | CALL_FIRST, 229 | CALL_MIDDLE, 230 | CALL_LAST 231 | } ENUM_CALL_STEP; 232 | 233 | typedef void (*ProgressPromptCB)(UINT deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall); 234 | 235 | // bool WideStringToString(wchar_t *pszSrc, char *&pszDest); 236 | // bool StringToWideString(char *pszSrc, wchar_t *&pszDest); 237 | #endif 238 | -------------------------------------------------------------------------------- /Endian.h: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HEADER 2 | #define ENDIAN_HEADER 3 | 4 | #define Endian16_Swap(value) (((((unsigned short)value) << 8) & 0xFF00)|\ 5 | ((((unsigned short)value) >> 8) & 0x00FF)) 6 | 7 | #define Endian32_Swap(value) (((((unsigned int)value) << 24) & 0xFF000000) |\ 8 | ((((unsigned int)value) << 8) & 0x00FF0000) |\ 9 | ((((unsigned int)value) >> 8) & 0x0000FF00) |\ 10 | ((((unsigned int)value) >> 24) & 0x000000FF)) 11 | 12 | #define EndianS16_LtoB(value) ((short)Endian16_Swap(value)) 13 | #define EndianS16_BtoL(value) ((short)Endian16_Swap(value)) 14 | #define EndianU16_LtoB(value) ((unsigned short)Endian16_Swap(value)) 15 | #define EndianU16_BtoL(value) ((unsigned short)Endian16_Swap(value)) 16 | #define EndianS32_LtoB(value) ((int)Endian32_Swap(value)) 17 | #define EndianS32_BtoL(value) ((int)Endian32_Swap(value)) 18 | #define EndianU32_LtoB(value) ((unsigned int)Endian32_Swap(value)) 19 | #define EndianU32_BtoL(value) ((unsigned int)Endian32_Swap(value)) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2017 Trevor Woerner 2 | 3 | SUBDIRS = 4 | DIST_SUBDIRS = cfg 5 | 6 | AM_CPPFLAGS = -Wall -Werror -Wextra -Wreturn-type -fno-strict-aliasing -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE $(LIBUSB1_CFLAGS) 7 | 8 | bin_PROGRAMS = rkdeveloptool 9 | rkdeveloptool_SOURCES = main.cpp \ 10 | crc.cpp DefineHeader.h Endian.h DefineHeader.h Property.hpp \ 11 | RKBoot.cpp RKBoot.h \ 12 | RKComm.cpp RKComm.h \ 13 | RKDevice.cpp RKDevice.h \ 14 | RKImage.cpp RKImage.h \ 15 | RKLog.cpp RKLog.h \ 16 | RKScan.cpp RKScan.h \ 17 | gpt.h 18 | rkdeveloptool_LDADD = $(LIBUSB1_LIBS) 19 | 20 | clean-local:: 21 | rm -fr log 22 | -------------------------------------------------------------------------------- /Property.hpp: -------------------------------------------------------------------------------- 1 | //-- Property.hpp -- 2 | 3 | /*-------------------------------------------------------------------------- 4 | Class Library 5 | 6 | Copyrights Emad Barsoum (ebarsoum@msn.com) 2003. All rights reserved. 7 | ________________________________________________________________ 8 | 9 | 10 | PROJECT : General 11 | MODULE : property 12 | FILENAME : Property.hpp 13 | BUILD : 1 14 | 15 | History of Modifications: 16 | 17 | Date(dd/mm/yyyy)Person Description 18 | ---- ------ ----------- 19 | 25/03/2003 Emad Barsoum Initial design and coding 20 | 21 | CLASS NAME: property 22 | VERSION: 1.0 23 | 24 | DESCRIPTION: 25 | This class try to simulate property for C++, using template technique. 26 | 27 | LICENSE: 28 | You are free to change or modify or redistribute the code, just keep the header. 29 | And you can use this class in any application you want without any warranty. 30 | */ 31 | #include 32 | #include 33 | #if !defined INC_PROPERTY_HPP 34 | #define INC_PROPERTY_HPP 35 | 36 | #define READ_ONLY 1 37 | #define WRITE_ONLY 2 38 | #define READ_WRITE 3 39 | 40 | template 41 | class property 42 | { 43 | public: 44 | property() 45 | { 46 | m_cObject = NULL; 47 | Set = NULL; 48 | Get = NULL; 49 | } 50 | //-- This to set a pointer to the class that contain the property -- 51 | void setContainer(Container* cObject) 52 | { 53 | m_cObject = cObject; 54 | } 55 | //-- Set the set member function that will change the value -- 56 | void setter(void (Container::*pSet)(ValueType value)) 57 | { 58 | if((nPropType == WRITE_ONLY) || (nPropType == READ_WRITE)) 59 | Set = pSet; 60 | else 61 | Set = NULL; 62 | } 63 | //-- Set the get member function that will retrieve the value -- 64 | void getter(ValueType (Container::*pGet)()) 65 | { 66 | if((nPropType == READ_ONLY) || (nPropType == READ_WRITE)) 67 | Get = pGet; 68 | else 69 | Get = NULL; 70 | } 71 | //-- Overload the '=' sign to set the value using the set member -- 72 | ValueType operator =(const ValueType& value) 73 | { 74 | assert(m_cObject != NULL); 75 | assert(Set != NULL); 76 | (m_cObject->*Set)(value); 77 | return value; 78 | } 79 | 80 | //-- To make possible to cast the property class to the internal type -- 81 | operator ValueType() 82 | { 83 | assert(m_cObject != NULL); 84 | assert(Get != NULL); 85 | return (m_cObject->*Get)(); 86 | } 87 | 88 | private: 89 | Container* m_cObject;//-- Pointer to the module that contain the property -- 90 | void (Container::*Set)(ValueType value);//-- Pointer to set member function -- 91 | ValueType (Container::*Get)();//-- Pointer to get member function -- 92 | }; 93 | 94 | #endif -------------------------------------------------------------------------------- /RKBoot.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockchip-linux/rkdeveloptool/304f073752fd25c854e1bcf05d8e7f925b1f4e14/RKBoot.cpp -------------------------------------------------------------------------------- /RKBoot.h: -------------------------------------------------------------------------------- 1 | #ifndef RKBOOT_HEADER 2 | #define RKBOOT_HEADER 3 | #include "DefineHeader.h" 4 | 5 | #define BOOT_RESERVED_SIZE 57 6 | #pragma pack(1) 7 | typedef struct { 8 | UINT uiTag; 9 | USHORT usSize; 10 | DWORD dwVersion; 11 | DWORD dwMergeVersion; 12 | STRUCT_RKTIME stReleaseTime; 13 | ENUM_RKDEVICE_TYPE emSupportChip; 14 | UCHAR uc471EntryCount; 15 | DWORD dw471EntryOffset; 16 | UCHAR uc471EntrySize; 17 | UCHAR uc472EntryCount; 18 | DWORD dw472EntryOffset; 19 | UCHAR uc472EntrySize; 20 | UCHAR ucLoaderEntryCount; 21 | DWORD dwLoaderEntryOffset; 22 | UCHAR ucLoaderEntrySize; 23 | UCHAR ucSignFlag; 24 | UCHAR ucRc4Flag; 25 | UCHAR reserved[BOOT_RESERVED_SIZE]; 26 | } STRUCT_RKBOOT_HEAD, *PSTRUCT_RKBOOT_HEAD; 27 | 28 | typedef struct { 29 | UCHAR ucSize; 30 | ENUM_RKBOOTENTRY emType; 31 | WCHAR szName[20]; 32 | DWORD dwDataOffset; 33 | DWORD dwDataSize; 34 | DWORD dwDataDelay; 35 | } STRUCT_RKBOOT_ENTRY, *PSTRUCT_RKBOOT_ENTRY; 36 | 37 | 38 | #pragma pack() 39 | class CRKBoot { 40 | public: 41 | bool GetRc4DisableFlag(); 42 | property Rc4DisableFlag; 43 | bool GetSignFlag(); 44 | property SignFlag; 45 | UINT GetVersion(); 46 | property Version; 47 | UINT GetMergeVersion(); 48 | property MergeVersion; 49 | STRUCT_RKTIME GetReleaseTime(); 50 | property ReleaseTime; 51 | ENUM_RKDEVICE_TYPE GetSupportDevice(); 52 | property SupportDevice; 53 | unsigned char GetEntry471Count(); 54 | property Entry471Count; 55 | unsigned char GetEntry472Count(); 56 | property Entry472Count; 57 | unsigned char GetEntryLoaderCount(); 58 | property EntryLoaderCount; 59 | bool CrcCheck(); 60 | bool SaveEntryFile(ENUM_RKBOOTENTRY type, UCHAR ucIndex, string fileName); 61 | bool GetEntryProperty(ENUM_RKBOOTENTRY type, UCHAR ucIndex, DWORD &dwSize, DWORD &dwDelay, char *pName = NULL); 62 | char GetIndexByName(ENUM_RKBOOTENTRY type, char *pName); 63 | bool GetEntryData(ENUM_RKBOOTENTRY type, UCHAR ucIndex, PBYTE lpData); 64 | CRKBoot(PBYTE lpBootData, DWORD dwBootSize, bool &bCheck); 65 | ~CRKBoot(); 66 | protected: 67 | private: 68 | bool m_bRc4Disable; 69 | bool m_bSignFlag; 70 | DWORD m_version; 71 | DWORD m_mergeVersion; 72 | STRUCT_RKTIME m_releaseTime; 73 | ENUM_RKDEVICE_TYPE m_supportDevice; 74 | DWORD m_471Offset; 75 | UCHAR m_471Size; 76 | UCHAR m_471Count; 77 | DWORD m_472Offset; 78 | UCHAR m_472Size; 79 | UCHAR m_472Count; 80 | DWORD m_loaderOffset; 81 | UCHAR m_loaderSize; 82 | UCHAR m_loaderCount; 83 | BYTE m_crc[4]; 84 | PBYTE m_BootData; 85 | DWORD m_BootSize; 86 | USHORT m_BootHeadSize; 87 | void WCHAR_To_wchar(WCHAR *src, wchar_t *dst, int len); 88 | void WCHAR_To_char(WCHAR *src, char *dst, int len); 89 | }; 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /RKComm.cpp: -------------------------------------------------------------------------------- 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 "RKComm.h" 9 | #include "RKLog.h" 10 | #include "Endian.h" 11 | extern unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber); 12 | CRKComm::CRKComm(CRKLog *pLog) 13 | { 14 | memset(&m_deviceDesc,0,sizeof(STRUCT_RKDEVICE_DESC)); 15 | m_log = pLog; 16 | } 17 | CRKComm::~CRKComm() 18 | { 19 | } 20 | 21 | CRKUsbComm::CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet):CRKComm(pLog) 22 | { 23 | bRet = InitializeUsb(devDesc); 24 | } 25 | CRKUsbComm::~CRKUsbComm() 26 | { 27 | UninitializeUsb(); 28 | } 29 | 30 | bool CRKUsbComm::InitializeUsb(STRUCT_RKDEVICE_DESC devDesc) 31 | { 32 | m_pUsbHandle = NULL; 33 | m_pipeBulkIn = m_pipeBulkOut = 0; 34 | m_interfaceNum = -1; 35 | if (!devDesc.pUsbHandle) { 36 | return false; 37 | } 38 | memcpy(&m_deviceDesc, &devDesc, sizeof(STRUCT_RKDEVICE_DESC)); 39 | int iRet; 40 | iRet = libusb_open((libusb_device *)devDesc.pUsbHandle, (libusb_device_handle **)&m_pUsbHandle); 41 | if (iRet!=0) { 42 | if (m_log) { 43 | m_log->Record("Error:InitializeUsb-->open device failed,err=%d", iRet); 44 | } 45 | return false; 46 | } 47 | struct libusb_config_descriptor *pConfigDesc=NULL; 48 | iRet = libusb_get_active_config_descriptor((libusb_device *)devDesc.pUsbHandle, &pConfigDesc); 49 | if (iRet!=0) { 50 | if (m_log) { 51 | m_log->Record("Error:InitializeUsb-->get device config descriptor failed, err=%d", iRet); 52 | } 53 | return false; 54 | } 55 | int i, j, k; 56 | const struct libusb_interface *pInterface; 57 | const struct libusb_endpoint_descriptor *pEndpointDesc; 58 | const struct libusb_interface_descriptor *pInterfaceDesc; 59 | for(i = 0; i < pConfigDesc->bNumInterfaces; i++) { 60 | pInterface = pConfigDesc->interface + i; 61 | for(j = 0; j < pInterface->num_altsetting; j++) { 62 | pInterfaceDesc = pInterface->altsetting+j; 63 | if (m_deviceDesc.emUsbType == RKUSB_MSC) { 64 | if( (pInterfaceDesc->bInterfaceClass != 8) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 0x50)) 65 | continue; 66 | } 67 | else 68 | { 69 | if( (pInterfaceDesc->bInterfaceClass != 0xff) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 5)) 70 | continue; 71 | } 72 | for(k = 0; k < pInterfaceDesc->bNumEndpoints; k++) { 73 | pEndpointDesc = pInterfaceDesc->endpoint+k; 74 | if ((pEndpointDesc->bEndpointAddress & 0x80) == 0) { 75 | if (m_pipeBulkOut == 0) 76 | m_pipeBulkOut = pEndpointDesc->bEndpointAddress; 77 | } 78 | else { 79 | if (m_pipeBulkIn == 0) 80 | m_pipeBulkIn = pEndpointDesc->bEndpointAddress; 81 | } 82 | if ((m_pipeBulkIn != 0) && (m_pipeBulkOut != 0)) {//found it 83 | m_interfaceNum = i; 84 | libusb_free_config_descriptor(pConfigDesc); 85 | iRet = libusb_claim_interface((libusb_device_handle *)m_pUsbHandle, m_interfaceNum); 86 | if (iRet != 0) { 87 | if (m_log) { 88 | m_log->Record("Error:libusb_claim_interface failed,err=%d", iRet); 89 | } 90 | return false; 91 | } 92 | return true; 93 | } 94 | } 95 | } 96 | } 97 | libusb_free_config_descriptor(pConfigDesc); 98 | return false; 99 | } 100 | void CRKUsbComm::UninitializeUsb() 101 | { 102 | if (m_pUsbHandle) { 103 | libusb_close((libusb_device_handle *)m_pUsbHandle); 104 | m_pUsbHandle = NULL; 105 | } 106 | memset(&m_deviceDesc, 0, sizeof(STRUCT_RKDEVICE_DESC)); 107 | m_pipeBulkIn = m_pipeBulkOut = 0; 108 | return ; 109 | } 110 | bool CRKUsbComm::Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc) 111 | { 112 | bool bRet; 113 | UninitializeUsb(); 114 | bRet = InitializeUsb(devDesc); 115 | return bRet; 116 | } 117 | bool CRKUsbComm::Reset_Usb_Device() 118 | { 119 | int iRet = -1; 120 | if (m_pUsbHandle) { 121 | iRet=libusb_reset_device((libusb_device_handle *)m_pUsbHandle); 122 | } 123 | return (iRet == 0) ? true : false; 124 | } 125 | 126 | bool CRKUsbComm::RKU_Read(BYTE* lpBuffer, DWORD dwSize) 127 | { 128 | int iRet; 129 | int nRead; 130 | iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, CMD_TIMEOUT); 131 | if (iRet!=0) { 132 | if (m_log) { 133 | m_log->Record("Error:RKU_Read failed,err=%d", iRet); 134 | } 135 | return false; 136 | } 137 | if (nRead != (int)dwSize) { 138 | if (m_log) { 139 | m_log->Record("Error:RKU_Read failed, size=%d, read=%d", dwSize, nRead); 140 | } 141 | return false; 142 | } 143 | return true; 144 | } 145 | 146 | bool CRKUsbComm::RKU_Write(BYTE* lpBuffer, DWORD dwSize) 147 | { 148 | int iRet; 149 | int nWrite; 150 | iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkOut, lpBuffer, dwSize, &nWrite, CMD_TIMEOUT); 151 | if (iRet != 0) { 152 | if (m_log) { 153 | m_log->Record("Error:RKU_Write failed, err=%d", iRet); 154 | } 155 | return false; 156 | } 157 | if (nWrite != (int)dwSize) { 158 | if (m_log) { 159 | m_log->Record("Error:RKU_Write failed, size=%d, read=%d", dwSize, nWrite); 160 | } 161 | return false; 162 | } 163 | return true; 164 | } 165 | int CRKUsbComm::RandomInteger(int low, int high) 166 | { 167 | int k; 168 | double d; 169 | 170 | d = (double)rand() / ((double)RAND_MAX + 1); 171 | k = (int)(d * (high - low + 1)); 172 | return (low + k); 173 | } 174 | DWORD CRKUsbComm::MakeCBWTag() 175 | { 176 | DWORD tag = 0; 177 | int i = 0; 178 | 179 | for(i=0; i<4; i++){ 180 | tag <<= 8; 181 | tag += RandomInteger(0, 0xFF); 182 | } 183 | return tag; 184 | } 185 | void CRKUsbComm::InitializeCBW(PCBW pCBW, USB_OPERATION_CODE code) 186 | { 187 | memset(pCBW,0, sizeof(CBW)); 188 | 189 | pCBW->dwCBWSignature = CBW_SIGN; 190 | pCBW->dwCBWTag = MakeCBWTag(); 191 | pCBW->cbwcb.ucOperCode = code; 192 | 193 | switch(code) { 194 | case TEST_UNIT_READY: /* Test Unit Ready : 0 */ 195 | case READ_FLASH_ID: /* Read Flash ID : 1 */ 196 | case READ_FLASH_INFO: 197 | case READ_CHIP_INFO: 198 | case READ_EFUSE: 199 | case READ_CAPABILITY: 200 | case READ_STORAGE: 201 | pCBW->ucCBWFlags= DIRECTION_IN; 202 | pCBW->ucCBWCBLength = 0x06; 203 | break; 204 | case DEVICE_RESET: /* Reset Device : 0xff */ 205 | case ERASE_SYSTEMDISK: 206 | case SET_RESET_FLAG: 207 | case CHANGE_STORAGE: 208 | pCBW->ucCBWFlags = DIRECTION_OUT; 209 | pCBW->ucCBWCBLength = 0x06; 210 | break; 211 | case TEST_BAD_BLOCK: /* Test Bad Block : 3 */ 212 | case READ_SECTOR: /* Read Pages : 4 */ 213 | case READ_LBA: /* Read Pages : 4 */ 214 | case READ_SDRAM: /* Write Pages : 15 */ 215 | case READ_SPI_FLASH: 216 | case READ_NEW_EFUSE: 217 | pCBW->ucCBWFlags = DIRECTION_IN; 218 | pCBW->ucCBWCBLength = 0x0a; 219 | break; 220 | case WRITE_SECTOR: /* Write Pages : 5 */ 221 | case WRITE_LBA: /* Write Pages : 15 */ 222 | case WRITE_SDRAM: /* Write Pages : 15 */ 223 | case EXECUTE_SDRAM: 224 | case ERASE_NORMAL: /* Erase Blocks : 6 */ 225 | case ERASE_FORCE: /* Read Spare : 11 */ 226 | case WRITE_EFUSE: 227 | case WRITE_SPI_FLASH: 228 | case WRITE_NEW_EFUSE: 229 | case ERASE_LBA: 230 | pCBW->ucCBWFlags = DIRECTION_OUT; 231 | pCBW->ucCBWCBLength = 0x0a; 232 | break; 233 | default: 234 | break; 235 | } 236 | } 237 | 238 | 239 | bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw) 240 | { 241 | DWORD dwReadBytes=0; 242 | DWORD dwTotalRead=0; 243 | int iTryCount; 244 | iTryCount = 3; 245 | do { 246 | dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) ); 247 | 248 | if (UFI_CHECK_SIGN(cbw,csw)) 249 | { 250 | return true; 251 | } 252 | if (dwReadBytes != sizeof(CSW)) 253 | { 254 | iTryCount--; 255 | sleep(3); 256 | } 257 | dwTotalRead += dwReadBytes; 258 | if (dwTotalRead >= MAX_CLEAR_LEN) 259 | { 260 | break; 261 | } 262 | }while ( iTryCount > 0 ); 263 | return false; 264 | } 265 | 266 | DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize) 267 | { 268 | int iRet; 269 | int nRead; 270 | iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000); 271 | if (iRet != 0) { 272 | if (m_log) { 273 | m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet); 274 | } 275 | return 0; 276 | } 277 | return nRead; 278 | } 279 | 280 | int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType) 281 | { 282 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 283 | if (m_log) { 284 | m_log->Record("Error:RKU_EraseBlock failed,device not support"); 285 | } 286 | return ERR_DEVICE_NOT_SUPPORT; 287 | } 288 | CBW cbw; 289 | CSW csw; 290 | USHORT usCount; 291 | usCount = dwCount; 292 | if(dwCount > MAX_ERASE_BLOCKS) 293 | return ERR_CROSS_BORDER; 294 | 295 | InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType); 296 | cbw.ucCBWLUN = ucFlashCS; 297 | cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 298 | cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 299 | 300 | if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 301 | { 302 | return ERR_DEVICE_WRITE_FAILED; 303 | } 304 | 305 | if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 306 | { 307 | return ERR_DEVICE_READ_FAILED; 308 | } 309 | 310 | if( !UFI_CHECK_SIGN(cbw, csw) ) 311 | return ERR_CMD_NOTMATCH; 312 | 313 | if(csw.ucCSWStatus == 1) 314 | return ERR_FOUND_BAD_BLOCK; 315 | 316 | return ERR_SUCCESS; 317 | } 318 | int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer) 319 | { 320 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 321 | if (m_log) { 322 | m_log->Record("Error:RKU_ReadChipInfo failed,device not support"); 323 | } 324 | return ERR_DEVICE_NOT_SUPPORT; 325 | } 326 | 327 | CBW cbw; 328 | CSW csw; 329 | 330 | InitializeCBW(&cbw, READ_CHIP_INFO); 331 | cbw.dwCBWTransferLength = 16; 332 | 333 | if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 334 | { 335 | return ERR_DEVICE_WRITE_FAILED; 336 | } 337 | 338 | if(!RKU_Read(lpBuffer, 16)) 339 | { 340 | return ERR_DEVICE_READ_FAILED; 341 | } 342 | 343 | if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) 344 | { 345 | return ERR_DEVICE_READ_FAILED; 346 | } 347 | 348 | if( !UFI_CHECK_SIGN(cbw, csw) ) 349 | return ERR_CMD_NOTMATCH; 350 | 351 | return ERR_SUCCESS; 352 | } 353 | int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer) 354 | { 355 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 356 | if (m_log) { 357 | m_log->Record("Error:RKU_ReadChipInfo failed,device not support"); 358 | } 359 | return ERR_DEVICE_NOT_SUPPORT; 360 | } 361 | 362 | CBW cbw; 363 | CSW csw; 364 | 365 | InitializeCBW(&cbw, READ_FLASH_ID); 366 | cbw.dwCBWTransferLength = 5; 367 | 368 | if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 369 | { 370 | return ERR_DEVICE_WRITE_FAILED; 371 | } 372 | 373 | if(!RKU_Read(lpBuffer, 5)) 374 | { 375 | return ERR_DEVICE_READ_FAILED; 376 | } 377 | 378 | if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) 379 | { 380 | return ERR_DEVICE_READ_FAILED; 381 | } 382 | 383 | if( !UFI_CHECK_SIGN(cbw, csw) ) 384 | return ERR_CMD_NOTMATCH; 385 | 386 | return ERR_SUCCESS; 387 | } 388 | int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead) 389 | { 390 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 391 | if (m_log) { 392 | m_log->Record("Error:RKU_ReadFlashInfo failed,device not support"); 393 | } 394 | return ERR_DEVICE_NOT_SUPPORT; 395 | } 396 | CBW cbw; 397 | CSW csw; 398 | 399 | InitializeCBW(&cbw, READ_FLASH_INFO); 400 | cbw.dwCBWTransferLength = 11; 401 | 402 | if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 403 | { 404 | return ERR_DEVICE_WRITE_FAILED; 405 | } 406 | 407 | DWORD dwRead; 408 | dwRead = RKU_Read_EX(lpBuffer, 512); 409 | if ((dwRead < 11) || (dwRead > 512)) 410 | { 411 | return ERR_DEVICE_READ_FAILED; 412 | } 413 | if (puiRead) 414 | { 415 | *puiRead = dwRead; 416 | } 417 | /* 418 | if(!RKU_Read(hDev, lpBuffer, 11)) 419 | { 420 | return ERR_DEVICE_READ_FAILED; 421 | } 422 | */ 423 | if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 424 | { 425 | return ERR_DEVICE_READ_FAILED; 426 | } 427 | 428 | if( !UFI_CHECK_SIGN(cbw, csw) ) 429 | return ERR_CMD_NOTMATCH; 430 | 431 | return ERR_SUCCESS; 432 | } 433 | int CRKUsbComm::RKU_ReadCapability(BYTE* lpBuffer) 434 | { 435 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 436 | if (m_log) { 437 | m_log->Record("Error:RKU_ReadCapability failed,device not support"); 438 | } 439 | return ERR_DEVICE_NOT_SUPPORT; 440 | } 441 | 442 | CBW cbw; 443 | CSW csw; 444 | DWORD dwRead; 445 | 446 | InitializeCBW(&cbw, READ_CAPABILITY); 447 | cbw.dwCBWTransferLength = 8; 448 | 449 | if(!RKU_Write((BYTE*)&cbw, sizeof(CBW))) 450 | { 451 | return ERR_DEVICE_WRITE_FAILED; 452 | } 453 | 454 | dwRead = RKU_Read_EX((BYTE*)&csw, sizeof(CSW)); 455 | 456 | if(dwRead != 8) 457 | { 458 | return ERR_DEVICE_READ_FAILED; 459 | } 460 | memcpy(lpBuffer, (BYTE*)&csw, 8); 461 | 462 | if(!RKU_Read((BYTE*)&csw, sizeof(CSW))) 463 | { 464 | return ERR_DEVICE_READ_FAILED; 465 | } 466 | 467 | if( !UFI_CHECK_SIGN(cbw, csw) ) 468 | return ERR_CMD_NOTMATCH; 469 | 470 | return ERR_SUCCESS; 471 | } 472 | 473 | int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode) 474 | { 475 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 476 | if (m_log) { 477 | m_log->Record("Error:RKU_ReadLBA failed,device not support"); 478 | } 479 | return ERR_DEVICE_NOT_SUPPORT; 480 | } 481 | CBW cbw; 482 | CSW csw; 483 | USHORT wSectorSize; 484 | USHORT usSectorLen; 485 | wSectorSize = 512; 486 | usSectorLen=dwCount; 487 | 488 | InitializeCBW(&cbw, READ_LBA); 489 | cbw.dwCBWTransferLength = dwCount * wSectorSize; 490 | cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 491 | cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen); 492 | cbw.cbwcb.ucReserved = bySubCode; 493 | 494 | if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 495 | { 496 | return ERR_DEVICE_WRITE_FAILED; 497 | } 498 | DWORD dwTotal; 499 | dwTotal = usSectorLen * wSectorSize; 500 | 501 | if(!RKU_Read(lpBuffer, dwTotal)) 502 | { 503 | return ERR_DEVICE_READ_FAILED; 504 | } 505 | 506 | if(!RKU_Read((BYTE*)&csw, sizeof(CSW))) 507 | { 508 | return ERR_DEVICE_READ_FAILED; 509 | } 510 | 511 | if( !UFI_CHECK_SIGN(cbw, csw) ) 512 | return ERR_CMD_NOTMATCH; 513 | 514 | if(csw.ucCSWStatus == 1) 515 | return ERR_FAILED; 516 | 517 | return ERR_SUCCESS; 518 | } 519 | 520 | int CRKUsbComm::RKU_ResetDevice(BYTE bySubCode) 521 | { 522 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 523 | if (m_log) { 524 | m_log->Record("Error:RKU_ResetDevice failed,device not support"); 525 | } 526 | return ERR_DEVICE_NOT_SUPPORT; 527 | } 528 | 529 | CBW cbw; 530 | CSW csw; 531 | 532 | InitializeCBW(&cbw, DEVICE_RESET); 533 | cbw.cbwcb.ucReserved = bySubCode; 534 | 535 | if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 536 | { 537 | return ERR_DEVICE_WRITE_FAILED; 538 | } 539 | 540 | if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 541 | { 542 | return ERR_DEVICE_READ_FAILED; 543 | } 544 | 545 | if( !UFI_CHECK_SIGN(cbw, csw) ) { 546 | bool bRet; 547 | bRet = RKU_ClearBuffer(cbw, csw); 548 | if (!bRet) { 549 | return ERR_CMD_NOTMATCH; 550 | } 551 | } 552 | 553 | if(csw.ucCSWStatus == 1) 554 | return ERR_FAILED; 555 | 556 | return ERR_SUCCESS; 557 | } 558 | 559 | int CRKUsbComm::RKU_ChangeStorage(BYTE storage) 560 | { 561 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 562 | if (m_log) { 563 | m_log->Record("Error:RKU_ChangeStorage failed,device not support"); 564 | } 565 | return ERR_DEVICE_NOT_SUPPORT; 566 | } 567 | 568 | CBW cbw; 569 | CSW csw; 570 | 571 | InitializeCBW(&cbw, CHANGE_STORAGE); 572 | cbw.cbwcb.ucReserved = storage; 573 | 574 | if(!RKU_Write((BYTE *)&cbw, sizeof(CBW))) 575 | { 576 | printf("AMO: ERR_DEVICE_WRITE_FAILED\n"); 577 | return ERR_DEVICE_WRITE_FAILED; 578 | } 579 | 580 | if(!RKU_Read((BYTE *)&csw, sizeof(CSW))) 581 | { 582 | return ERR_DEVICE_READ_FAILED; 583 | } 584 | 585 | if( !UFI_CHECK_SIGN(cbw, csw) ) { 586 | bool bRet; 587 | bRet = RKU_ClearBuffer(cbw, csw); 588 | if (!bRet) { 589 | return ERR_CMD_NOTMATCH; 590 | } 591 | } 592 | 593 | if(csw.ucCSWStatus == 1) 594 | return ERR_FAILED; 595 | 596 | return ERR_SUCCESS; 597 | } 598 | 599 | int CRKUsbComm::RKU_ReadStorage(BYTE* storage) 600 | { 601 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 602 | if (m_log) { 603 | m_log->Record("Error:RKU_ReadCapability failed,device not support"); 604 | } 605 | return ERR_DEVICE_NOT_SUPPORT; 606 | } 607 | 608 | CBW cbw; 609 | CSW csw; 610 | DWORD dwRead; 611 | 612 | InitializeCBW(&cbw, READ_STORAGE); 613 | cbw.dwCBWTransferLength = 4; 614 | 615 | if(!RKU_Write((BYTE*)&cbw, sizeof(CBW))) 616 | { 617 | return ERR_DEVICE_WRITE_FAILED; 618 | } 619 | 620 | DWORD storage_bits; 621 | dwRead = RKU_Read_EX((BYTE*)&storage_bits, sizeof(storage_bits)); 622 | 623 | if(dwRead != 4) 624 | { 625 | return ERR_DEVICE_READ_FAILED; 626 | } 627 | 628 | if(!RKU_Read((BYTE*)&csw, sizeof(CSW))) 629 | { 630 | return ERR_DEVICE_READ_FAILED; 631 | } 632 | 633 | if( !UFI_CHECK_SIGN(cbw, csw) ) 634 | return ERR_CMD_NOTMATCH; 635 | 636 | /* search the bit index */ 637 | *storage = 255; 638 | for (unsigned i=0; i < 32; i++) { 639 | if (storage_bits & (1<Record("Error:RKU_TestDeviceReady failed,device not support"); 653 | } 654 | return ERR_DEVICE_NOT_SUPPORT; 655 | } 656 | CBW cbw; 657 | CSW csw; 658 | 659 | InitializeCBW(&cbw, TEST_UNIT_READY); 660 | 661 | cbw.cbwcb.ucReserved = bySubCode; 662 | if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 663 | return ERR_DEVICE_WRITE_FAILED; 664 | } 665 | 666 | if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 667 | return ERR_DEVICE_READ_FAILED; 668 | } 669 | 670 | if( !UFI_CHECK_SIGN(cbw, csw) ) { 671 | bool bRet; 672 | bRet = RKU_ClearBuffer(cbw ,csw); 673 | if (!bRet) { 674 | return ERR_CMD_NOTMATCH; 675 | } 676 | } 677 | 678 | if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) { 679 | *dwCurrent = (csw.dwCBWDataResidue >>16); 680 | *dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF); 681 | 682 | *dwTotal = EndianU16_BtoL(*dwTotal); 683 | *dwCurrent = EndianU16_BtoL(*dwCurrent); 684 | } 685 | if(csw.ucCSWStatus == 1) { 686 | return ERR_DEVICE_UNREADY; 687 | } 688 | 689 | return ERR_DEVICE_READY; 690 | } 691 | int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode) 692 | { 693 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 694 | if (m_log) { 695 | m_log->Record("Error:RKU_WriteLBA failed,device not support"); 696 | } 697 | return ERR_DEVICE_NOT_SUPPORT; 698 | } 699 | CBW cbw; 700 | CSW csw; 701 | USHORT wSectorSize; 702 | USHORT usCount; 703 | wSectorSize = 512; 704 | usCount = dwCount; 705 | DWORD dwTotal = usCount * wSectorSize; 706 | 707 | InitializeCBW(&cbw, WRITE_LBA); 708 | cbw.dwCBWTransferLength = dwCount * wSectorSize; 709 | cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 710 | cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 711 | cbw.cbwcb.ucReserved = bySubCode; 712 | if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 713 | return ERR_DEVICE_WRITE_FAILED; 714 | } 715 | 716 | if(!RKU_Write( lpBuffer, dwTotal)) { 717 | return ERR_DEVICE_WRITE_FAILED; 718 | } 719 | 720 | if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 721 | return ERR_DEVICE_READ_FAILED; 722 | } 723 | 724 | if( !UFI_CHECK_SIGN(cbw, csw) ) 725 | return ERR_CMD_NOTMATCH; 726 | 727 | if(csw.ucCSWStatus == 1) 728 | return ERR_FAILED; 729 | 730 | return ERR_SUCCESS; 731 | } 732 | int CRKUsbComm::RKU_EraseLBA(DWORD dwPos, DWORD dwCount) 733 | { 734 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 735 | if (m_log) { 736 | m_log->Record("Error:RKU_WriteLBA failed,device not support"); 737 | } 738 | return ERR_DEVICE_NOT_SUPPORT; 739 | } 740 | CBW cbw; 741 | CSW csw; 742 | USHORT usCount; 743 | usCount = dwCount; 744 | 745 | 746 | InitializeCBW(&cbw, ERASE_LBA); 747 | cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 748 | cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 749 | 750 | if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 751 | return ERR_DEVICE_WRITE_FAILED; 752 | } 753 | 754 | if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 755 | return ERR_DEVICE_READ_FAILED; 756 | } 757 | 758 | if( !UFI_CHECK_SIGN(cbw, csw) ) 759 | return ERR_CMD_NOTMATCH; 760 | 761 | if(csw.ucCSWStatus == 1) 762 | return ERR_FAILED; 763 | 764 | return ERR_SUCCESS; 765 | } 766 | 767 | int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer) 768 | { 769 | if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { 770 | if (m_log) { 771 | m_log->Record("Error:RKU_WriteSector failed,device not support"); 772 | } 773 | return ERR_DEVICE_NOT_SUPPORT; 774 | } 775 | CBW cbw; 776 | CSW csw; 777 | USHORT wSectorSize; 778 | USHORT usCount; 779 | usCount=dwCount; 780 | if(usCount > 32) 781 | return ERR_CROSS_BORDER; 782 | 783 | wSectorSize = 528; 784 | InitializeCBW(&cbw, WRITE_SECTOR); 785 | cbw.dwCBWTransferLength = dwCount * wSectorSize; 786 | cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos); 787 | cbw.cbwcb.usLength = EndianU16_LtoB(usCount); 788 | 789 | if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) { 790 | return ERR_DEVICE_WRITE_FAILED; 791 | } 792 | 793 | if(!RKU_Write( lpBuffer, usCount * wSectorSize)) { 794 | return ERR_DEVICE_WRITE_FAILED; 795 | } 796 | 797 | if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) { 798 | return ERR_DEVICE_READ_FAILED; 799 | } 800 | 801 | if( !UFI_CHECK_SIGN(cbw, csw) ) 802 | return ERR_CMD_NOTMATCH; 803 | 804 | if(csw.ucCSWStatus == 1) 805 | return ERR_FAILED; 806 | 807 | return ERR_SUCCESS; 808 | } 809 | 810 | 811 | int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize) 812 | { 813 | if (m_deviceDesc.emUsbType != RKUSB_MASKROM) { 814 | if (m_log) { 815 | m_log->Record("Error:RKU_DeviceRequest failed,device not support"); 816 | } 817 | return ERR_DEVICE_NOT_SUPPORT; 818 | } 819 | if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) { 820 | if (m_log) { 821 | m_log->Record("Error:RKU_DeviceRequest failed,request not support"); 822 | } 823 | return ERR_REQUEST_NOT_SUPPORT; 824 | } 825 | 826 | bool bSendPendPacket = false; 827 | USHORT crcValue = 0xffff; 828 | BYTE *pData = NULL; 829 | pData = new BYTE[dwDataSize + 5]; 830 | memset(pData, 0, dwDataSize + 5); 831 | memcpy(pData, lpBuffer, dwDataSize); 832 | 833 | switch(dwDataSize % 4096) { 834 | case 4095: 835 | ++dwDataSize; 836 | break; 837 | case 4094: 838 | bSendPendPacket = true; 839 | break; 840 | case 0: 841 | default: 842 | break; 843 | } 844 | 845 | crcValue = CRC_CCITT(pData, dwDataSize); 846 | pData[dwDataSize] = (crcValue & 0xff00) >> 8; 847 | pData[dwDataSize+1] = crcValue & 0x00ff; 848 | dwDataSize += 2; 849 | 850 | UINT nSendBytes = 0; 851 | DWORD dwTotalSended = 0; 852 | int iRet; 853 | 854 | while(dwTotalSended < dwDataSize) { 855 | nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended); 856 | iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT); 857 | if (iRet != (int)nSendBytes) { 858 | if (m_log) { 859 | m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet); 860 | } 861 | delete []pData; 862 | return ERR_REQUEST_FAIL; 863 | } 864 | dwTotalSended += nSendBytes; 865 | } 866 | 867 | if(bSendPendPacket) { 868 | BYTE ucFillByte = 0; 869 | iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT); 870 | if (iRet != 0) { 871 | if (m_log) { 872 | m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet); 873 | } 874 | delete []pData; 875 | return ERR_REQUEST_FAIL; 876 | } 877 | } 878 | 879 | delete []pData; 880 | 881 | return ERR_SUCCESS; 882 | } 883 | 884 | 885 | -------------------------------------------------------------------------------- /RKComm.h: -------------------------------------------------------------------------------- 1 | #ifndef RKCOMM_HEADER 2 | #define RKCOMM_HEADER 3 | #include "DefineHeader.h" 4 | typedef enum { 5 | USB_BULK_READ = 0, 6 | USB_BULK_WRITE, 7 | USB_CONTROL, 8 | } USB_ACCESS_TYPE; 9 | typedef enum { 10 | TU_NONE_SUBCODE = 0, 11 | TU_ERASESYSTEM_SUBCODE = 0xFE, 12 | TU_LOWERFORMAT_SUBCODE = 0xFD, 13 | TU_ERASEUSERDATA_SUBCODE = 0xFB, 14 | TU_GETUSERSECTOR_SUBCODE = 0xF9 15 | } TESTUNIT_SUBCODE; 16 | typedef enum{ 17 | RST_NONE_SUBCODE = 0, 18 | RST_RESETMSC_SUBCODE, 19 | RST_POWEROFF_SUBCODE, 20 | RST_RESETMASKROM_SUBCODE, 21 | RST_DISCONNECTRESET_SUBCODE 22 | } RESET_SUBCODE; 23 | typedef enum{ 24 | RWMETHOD_IMAGE = 0, 25 | RWMETHOD_LBA 26 | } RW_SUBCODE; 27 | 28 | typedef enum { 29 | TEST_UNIT_READY = 0, 30 | READ_FLASH_ID = 0x01, 31 | TEST_BAD_BLOCK = 0x03, 32 | READ_SECTOR = 0x04, 33 | WRITE_SECTOR = 0x05, 34 | ERASE_NORMAL = 0x06, 35 | ERASE_FORCE = 0x0B, 36 | READ_LBA = 0x14, 37 | WRITE_LBA = 0x15, 38 | ERASE_SYSTEMDISK = 0x16, 39 | READ_SDRAM = 0x17, 40 | WRITE_SDRAM = 0x18, 41 | EXECUTE_SDRAM = 0x19, 42 | READ_FLASH_INFO = 0x1A, 43 | READ_CHIP_INFO = 0x1B, 44 | SET_RESET_FLAG = 0x1E, 45 | WRITE_EFUSE = 0x1F, 46 | READ_EFUSE = 0x20, 47 | READ_SPI_FLASH = 0x21, 48 | WRITE_SPI_FLASH = 0x22, 49 | WRITE_NEW_EFUSE = 0x23, 50 | READ_NEW_EFUSE = 0x24, 51 | ERASE_LBA=0x25, 52 | CHANGE_STORAGE = 0x2A, 53 | READ_STORAGE = 0x2B, 54 | READ_CAPABILITY=0xAA, 55 | DEVICE_RESET = 0xFF 56 | } USB_OPERATION_CODE; 57 | 58 | #pragma pack(1) 59 | 60 | typedef struct { 61 | BYTE ucOperCode; 62 | BYTE ucReserved; 63 | DWORD dwAddress; 64 | BYTE ucReserved2; 65 | USHORT usLength; 66 | BYTE ucReserved3[7]; 67 | } CBWCB, *PCBWCB; 68 | 69 | typedef struct { 70 | DWORD dwCBWSignature; 71 | DWORD dwCBWTag; 72 | DWORD dwCBWTransferLength; 73 | BYTE ucCBWFlags; 74 | BYTE ucCBWLUN; 75 | BYTE ucCBWCBLength; 76 | CBWCB cbwcb; 77 | } CBW, *PCBW; 78 | 79 | typedef struct { 80 | DWORD dwCSWSignature; 81 | DWORD dwCSWTag; 82 | DWORD dwCBWDataResidue; 83 | BYTE ucCSWStatus; 84 | } CSW, *PCSW; 85 | 86 | #pragma pack() 87 | #define CMD_TIMEOUT 0 88 | #define CBW_SIGN 0x43425355 /* "USBC" */ 89 | #define CSW_SIGN 0x53425355 /* "USBS" */ 90 | 91 | #define DIRECTION_OUT 0x00 92 | #define DIRECTION_IN 0x80 93 | #define MAX_TEST_BLOCKS 512 94 | #define MAX_ERASE_BLOCKS 16 95 | #define MAX_CLEAR_LEN 16*1024 96 | 97 | #ifndef ERR_SUCCESS 98 | #define ERR_SUCCESS 0 99 | #endif 100 | #define ERR_DEVICE_READY 0 101 | #define ERR_DEVICE_OPEN_FAILED -1 102 | #define ERR_CSW_OPEN_FAILED -2 103 | #define ERR_DEVICE_WRITE_FAILED -3 104 | #define ERR_DEVICE_READ_FAILED -4 105 | #define ERR_CMD_NOTMATCH -5 106 | #define ERR_DEVICE_UNREADY -6 107 | #define ERR_FOUND_BAD_BLOCK -7 108 | #define ERR_FAILED -8 109 | #define ERR_CROSS_BORDER -9 110 | #define ERR_DEVICE_NOT_SUPPORT -10 111 | #define ERR_REQUEST_NOT_SUPPORT -11 112 | #define ERR_REQUEST_FAIL -12 113 | #define ERR_BUFFER_NOT_ENOUGH -13 114 | #define UFI_CHECK_SIGN(cbw, csw) ((CSW_SIGN == (csw).dwCSWSignature) && ((csw).dwCSWTag == (cbw).dwCBWTag)) 115 | 116 | class CRKLog; 117 | class CRKComm 118 | { 119 | public: 120 | virtual int RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType) = 0; 121 | virtual int RKU_ReadChipInfo(BYTE *lpBuffer) = 0; 122 | virtual int RKU_ReadFlashID(BYTE *lpBuffer) = 0; 123 | virtual int RKU_ReadCapability(BYTE *lpBuffer)=0; 124 | virtual int RKU_ReadFlashInfo(BYTE *lpBuffer, UINT *puiRead = NULL) = 0; 125 | virtual int RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer, BYTE bySubCode = RWMETHOD_IMAGE) = 0; 126 | virtual int RKU_ResetDevice(BYTE bySubCode = RST_NONE_SUBCODE) = 0; 127 | virtual int RKU_TestDeviceReady(DWORD *dwTotal = NULL, DWORD *dwCurrent = NULL, BYTE bySubCode = TU_NONE_SUBCODE) = 0; 128 | virtual int RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer, BYTE bySubCode = RWMETHOD_IMAGE) = 0; 129 | virtual int RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer) = 0; 130 | virtual int RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize) = 0; 131 | virtual bool Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc) = 0; 132 | virtual bool Reset_Usb_Device() = 0; 133 | virtual int RKU_EraseLBA(DWORD dwPos,DWORD dwCount)=0; 134 | CRKComm(CRKLog *pLog); 135 | virtual ~CRKComm(); 136 | protected: 137 | STRUCT_RKDEVICE_DESC m_deviceDesc; 138 | CRKLog *m_log; 139 | private: 140 | virtual bool RKU_Write(BYTE *lpBuffer, DWORD dwSize) = 0; 141 | virtual bool RKU_Read(BYTE *lpBuffer, DWORD dwSize) = 0; 142 | }; 143 | class CRKUsbComm:public CRKComm 144 | { 145 | public: 146 | virtual int RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType); 147 | virtual int RKU_ChangeStorage(BYTE storage); 148 | virtual int RKU_ReadStorage(BYTE *storage); 149 | virtual int RKU_ReadChipInfo(BYTE *lpBuffer); 150 | virtual int RKU_ReadFlashID(BYTE *lpBuffer); 151 | virtual int RKU_ReadCapability(BYTE *lpBuffer); 152 | virtual int RKU_ReadFlashInfo(BYTE *lpBuffer, UINT *puiRead = NULL); 153 | virtual int RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer, BYTE bySubCode = RWMETHOD_IMAGE); 154 | virtual int RKU_ResetDevice(BYTE bySubCode = RST_NONE_SUBCODE); 155 | virtual int RKU_TestDeviceReady(DWORD *dwTotal = NULL, DWORD *dwCurrent = NULL, BYTE bySubCode = TU_NONE_SUBCODE); 156 | virtual int RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer, BYTE bySubCode = RWMETHOD_IMAGE); 157 | virtual int RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer); 158 | virtual int RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize); 159 | CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet); 160 | virtual ~CRKUsbComm(); 161 | virtual bool Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc); 162 | virtual bool Reset_Usb_Device(); 163 | virtual int RKU_EraseLBA(DWORD dwPos,DWORD dwCount); 164 | private: 165 | void *m_pUsbHandle; 166 | unsigned char m_pipeBulkIn; 167 | unsigned char m_pipeBulkOut; 168 | int m_interfaceNum; 169 | virtual bool RKU_Write(BYTE *lpBuffer, DWORD dwSize); 170 | virtual bool RKU_Read(BYTE *lpBuffer, DWORD dwSize); 171 | bool InitializeUsb(STRUCT_RKDEVICE_DESC devDesc); 172 | void UninitializeUsb(); 173 | bool RKU_ClearBuffer(CBW &cbw, CSW &csw); 174 | DWORD RKU_Read_EX(BYTE *lpBuffer, DWORD dwSize); 175 | void InitializeCBW(PCBW pCBW, USB_OPERATION_CODE code); 176 | int RandomInteger(int low, int high); 177 | DWORD MakeCBWTag(); 178 | }; 179 | 180 | #endif -------------------------------------------------------------------------------- /RKDevice.cpp: -------------------------------------------------------------------------------- 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 "RKDevice.h" 9 | 10 | const char* szManufName[] = 11 | { 12 | "SAMSUNG", 13 | "TOSHIBA", 14 | "HYNIX", 15 | "INFINEON", 16 | "MICRON", 17 | "RENESAS", 18 | "ST", 19 | "INTEL" 20 | }; 21 | 22 | void CRKDevice::SetVendorID(USHORT value) 23 | { 24 | m_vid = value; 25 | } 26 | void CRKDevice::SetProductID(USHORT value) 27 | { 28 | m_pid = value; 29 | } 30 | void CRKDevice::SetDeviceType(ENUM_RKDEVICE_TYPE value) 31 | { 32 | m_device = value; 33 | } 34 | void CRKDevice::SetOsType(ENUM_OS_TYPE value) 35 | { 36 | m_os = value; 37 | } 38 | 39 | void CRKDevice::SetUsbType(ENUM_RKUSB_TYPE value) 40 | { 41 | m_usb = value; 42 | } 43 | void CRKDevice::SetBcdUsb(USHORT value) 44 | { 45 | m_bcdUsb = value; 46 | } 47 | void CRKDevice::SetLayerName(char *value) 48 | { 49 | strcpy(m_layerName,value); 50 | } 51 | void CRKDevice::SetLocationID(DWORD value) 52 | { 53 | m_locationID = value; 54 | } 55 | 56 | void CRKDevice::SetCallBackPointer(ProgressPromptCB value) 57 | { 58 | if (value) 59 | { 60 | m_callBackProc = value; 61 | } 62 | } 63 | CRKLog* CRKDevice::GetLogObjectPointer() 64 | { 65 | return m_pLog; 66 | } 67 | 68 | CRKComm* CRKDevice::GetCommObjectPointer() 69 | { 70 | return m_pComm; 71 | } 72 | 73 | USHORT CRKDevice::GetVendorID() 74 | { 75 | return m_vid; 76 | } 77 | USHORT CRKDevice::GetProductID() 78 | { 79 | return m_pid; 80 | } 81 | ENUM_RKDEVICE_TYPE CRKDevice::GetDeviceType() 82 | { 83 | return m_device; 84 | } 85 | ENUM_OS_TYPE CRKDevice::GetOsType() 86 | { 87 | return m_os; 88 | } 89 | 90 | ENUM_RKUSB_TYPE CRKDevice::GetUsbType() 91 | { 92 | return m_usb; 93 | } 94 | 95 | USHORT CRKDevice::GetBcdUsb() 96 | { 97 | return m_bcdUsb; 98 | } 99 | DWORD CRKDevice::GetLocationID() 100 | { 101 | return m_locationID; 102 | } 103 | char* CRKDevice::GetLayerName() 104 | { 105 | return m_layerName; 106 | } 107 | 108 | string CRKDevice::GetLayerString(UINT dwLocationID) 109 | { 110 | char szLocation[32] = "\0"; 111 | snprintf(szLocation, sizeof(szLocation), "%d-%d", dwLocationID >> 8, dwLocationID & 0xff); 112 | return szLocation; 113 | } 114 | 115 | CRKDevice::CRKDevice(STRUCT_RKDEVICE_DESC &device) 116 | { 117 | VendorID.setContainer(this); 118 | VendorID.getter(&CRKDevice::GetVendorID); 119 | VendorID.setter(&CRKDevice::SetVendorID); 120 | 121 | ProductID.setContainer(this); 122 | ProductID.getter(&CRKDevice::GetProductID); 123 | ProductID.setter(&CRKDevice::SetProductID); 124 | 125 | DeviceType.setContainer(this); 126 | DeviceType.getter(&CRKDevice::GetDeviceType); 127 | DeviceType.setter(&CRKDevice::SetDeviceType); 128 | 129 | UsbType.setContainer(this); 130 | UsbType.getter(&CRKDevice::GetUsbType); 131 | UsbType.setter(&CRKDevice::SetUsbType); 132 | 133 | LayerName.setContainer(this); 134 | LayerName.getter(&CRKDevice::GetLayerName); 135 | LayerName.setter(&CRKDevice::SetLayerName); 136 | 137 | BcdUsb.setContainer(this); 138 | BcdUsb.getter(&CRKDevice::GetBcdUsb); 139 | BcdUsb.setter(&CRKDevice::SetBcdUsb); 140 | 141 | LocationID.setContainer(this); 142 | LocationID.getter(&CRKDevice::GetLocationID); 143 | LocationID.setter(&CRKDevice::SetLocationID); 144 | 145 | OsType.setContainer(this); 146 | OsType.getter(&CRKDevice::GetOsType); 147 | OsType.setter(&CRKDevice::SetOsType); 148 | 149 | LogObjectPointer.setContainer(this); 150 | LogObjectPointer.getter(&CRKDevice::GetLogObjectPointer); 151 | 152 | CommObjectPointer.setContainer(this); 153 | CommObjectPointer.getter(&CRKDevice::GetCommObjectPointer); 154 | 155 | CallBackPointer.setContainer(this); 156 | CallBackPointer.setter(&CRKDevice::SetCallBackPointer); 157 | 158 | m_vid = device.usVid; 159 | m_pid = device.usPid; 160 | m_usb = device.emUsbType; 161 | m_device = device.emDeviceType; 162 | m_bcdUsb = device.usbcdUsb; 163 | m_locationID = device.uiLocationID; 164 | strcpy(m_layerName, GetLayerString(m_locationID).c_str()); 165 | 166 | memset(m_flashInfo.blockState, 0, IDBLOCK_TOP); 167 | m_flashInfo.usPhyBlokcPerIDB = 1; 168 | m_flashInfo.uiSecNumPerIDB = 0; 169 | m_callBackProc = NULL; 170 | m_chipData = NULL; 171 | m_pImage = NULL; 172 | m_pLog = NULL; 173 | m_pComm = NULL; 174 | m_pFlashInfoData = NULL; 175 | m_usFlashInfoDataLen = 0; 176 | m_usFlashInfoDataOffset = 0; 177 | m_bEmmc = false; 178 | m_bDirectLba = false; 179 | m_bFirst4mAccess = false; 180 | } 181 | CRKDevice::~CRKDevice() 182 | { 183 | if (m_pComm) { 184 | delete m_pComm; 185 | m_pComm = NULL; 186 | } 187 | if (m_chipData) { 188 | delete []m_chipData; 189 | m_chipData = NULL; 190 | } 191 | 192 | if (m_pFlashInfoData) { 193 | delete []m_pFlashInfoData; 194 | m_pFlashInfoData = NULL; 195 | } 196 | } 197 | bool CRKDevice::SetObject(CRKImage *pImage, CRKComm *pComm, CRKLog *pLog) 198 | { 199 | if (!pComm) { 200 | return false; 201 | } 202 | m_pImage = pImage; 203 | m_pComm = pComm; 204 | m_pLog = pLog; 205 | if (m_pImage) { 206 | m_os = m_pImage->OsType; 207 | } else 208 | m_os = RK_OS; 209 | return true; 210 | } 211 | int CRKDevice::EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount) 212 | { 213 | int sectorOffset,nWrittenBlcok,iRet; 214 | BYTE emptyData[4 * (SECTOR_SIZE+SPARE_SIZE)]; 215 | memset(emptyData, 0xff, 4 * (SECTOR_SIZE + SPARE_SIZE)); 216 | nWrittenBlcok = 0; 217 | while (dwCount > 0) { 218 | sectorOffset = (ucFlashCS * m_flashInfo.uiBlockNum + dwPos + nWrittenBlcok) * m_flashInfo.uiSectorPerBlock; 219 | iRet = m_pComm->RKU_WriteSector(sectorOffset, 4, emptyData); 220 | if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) { 221 | if (m_pLog) { 222 | m_pLog->Record(" ERROR:EraseEmmcBlock-->RKU_WriteSector failed, RetCode(%d)", m_layerName, iRet); 223 | } 224 | return iRet; 225 | } 226 | dwCount--; 227 | nWrittenBlcok++; 228 | } 229 | return ERR_SUCCESS; 230 | } 231 | int CRKDevice::EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount) 232 | { 233 | int nWritten,iRet; 234 | BYTE emptyData[32 * SECTOR_SIZE]; 235 | memset(emptyData, 0xff, 32 * SECTOR_SIZE); 236 | 237 | while (dwCount > 0) { 238 | nWritten = (dwCount < 32) ? dwCount : 32; 239 | iRet = m_pComm->RKU_WriteLBA(dwSectorPos, nWritten, emptyData); 240 | if (iRet != ERR_SUCCESS) { 241 | if (m_pLog) { 242 | m_pLog->Record(" ERROR:EraseEmmcByWriteLBA-->RKU_WriteLBA failed, RetCode(%d)", m_layerName, iRet); 243 | } 244 | return iRet; 245 | } 246 | dwCount -= nWritten; 247 | dwSectorPos += nWritten; 248 | } 249 | return ERR_SUCCESS; 250 | } 251 | bool CRKDevice::EraseEmmc() 252 | { 253 | UINT uiCount,uiEraseCount,uiSectorOffset,uiTotalCount; 254 | UINT uiErase=1024*32; 255 | int iRet=ERR_SUCCESS,iLoopTimes=0; 256 | uiTotalCount = uiCount = m_flashInfo.uiFlashSize*2*1024; 257 | uiSectorOffset = 0; 258 | DWORD dwLayerID; 259 | dwLayerID = m_locationID; 260 | ENUM_CALL_STEP emCallStep = CALL_FIRST; 261 | 262 | while (uiCount) 263 | { 264 | if (uiCount >= uiErase) 265 | { 266 | uiEraseCount = uiErase; 267 | } 268 | else 269 | uiEraseCount = uiCount; 270 | iRet = m_pComm->RKU_EraseLBA(uiSectorOffset, uiEraseCount); 271 | 272 | if (iRet != ERR_SUCCESS) { 273 | if (m_pLog) { 274 | m_pLog->Record("ERROR:EraseEmmc-->RKU_EraseLBA failed,RetCode(%d),offset=0x%x,count=0x%x",iRet, uiSectorOffset, uiEraseCount); 275 | } 276 | return false; 277 | } 278 | uiCount -= uiEraseCount; 279 | uiSectorOffset += uiEraseCount; 280 | iLoopTimes++; 281 | if (iLoopTimes % 8 == 0) { 282 | if (m_callBackProc) { 283 | m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiSectorOffset, emCallStep); 284 | emCallStep = CALL_MIDDLE; 285 | } 286 | } 287 | } 288 | if (m_callBackProc) { 289 | emCallStep = CALL_LAST; 290 | m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiTotalCount, emCallStep); 291 | } 292 | return true; 293 | } 294 | bool CRKDevice::GetFlashInfo() 295 | { 296 | STRUCT_FLASHINFO_CMD info; 297 | BYTE flashID[5]; 298 | int iRet; 299 | UINT uiRead; 300 | iRet = m_pComm->RKU_ReadFlashInfo((PBYTE)&info, &uiRead); 301 | if( ERR_SUCCESS == iRet ) { 302 | if ((info.usBlockSize == 0) || (info.bPageSize == 0)) { 303 | if (m_pLog) { 304 | m_pLog->Record(" ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed,pagesize or blocksize is zero", m_layerName); 305 | } 306 | return false; 307 | } 308 | if (info.bManufCode <= 7) { 309 | strcpy(m_flashInfo.szManufacturerName, szManufName[info.bManufCode]); 310 | } else { 311 | strcpy(m_flashInfo.szManufacturerName, "UNKNOWN"); 312 | } 313 | m_flashInfo.uiFlashSize = info.uiFlashSize / 2 / 1024; 314 | m_flashInfo.uiPageSize = info.bPageSize / 2; 315 | m_flashInfo.usBlockSize = info.usBlockSize / 2; 316 | m_flashInfo.bECCBits = info.bECCBits; 317 | m_flashInfo.bAccessTime = info.bAccessTime; 318 | m_flashInfo.uiBlockNum = m_flashInfo.uiFlashSize * 1024 / m_flashInfo.usBlockSize; 319 | m_flashInfo.uiSectorPerBlock = info.usBlockSize; 320 | m_flashInfo.bFlashCS = info.bFlashCS; 321 | m_flashInfo.usValidSecPerBlock = (info.usBlockSize / info.bPageSize) * 4; 322 | if (m_pFlashInfoData) { 323 | delete []m_pFlashInfoData; 324 | m_pFlashInfoData = NULL; 325 | } 326 | m_usFlashInfoDataLen = BYTE2SECTOR(uiRead); 327 | m_pFlashInfoData = new BYTE[SECTOR_SIZE * m_usFlashInfoDataLen]; 328 | memset(m_pFlashInfoData, 0, SECTOR_SIZE * m_usFlashInfoDataLen); 329 | memcpy(m_pFlashInfoData, (PBYTE)&info, uiRead); 330 | if (m_pLog) { 331 | string strFlashInfo; 332 | m_pLog->PrintBuffer(strFlashInfo, m_pFlashInfoData, 11); 333 | m_pLog->Record(" INFO:FlashInfo:%s", m_layerName, strFlashInfo.c_str()); 334 | } 335 | } else { 336 | if (m_pLog) { 337 | m_pLog->Record(" ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed, RetCode(%d)", m_layerName, iRet); 338 | } 339 | return false; 340 | } 341 | iRet = m_pComm->RKU_ReadFlashID(flashID); 342 | if( ERR_SUCCESS == iRet ) { 343 | DWORD *pID = (DWORD *)flashID; 344 | if (*pID==0x434d4d45)/*emmc*/ { 345 | m_bEmmc = true; 346 | } else 347 | m_bEmmc = false; 348 | } else { 349 | if (m_pLog) { 350 | m_pLog->Record(" ERROR:GetFlashInfo-->RKU_ReadFlashID failed, RetCode(%d)", m_layerName, iRet); 351 | } 352 | return false; 353 | } 354 | return true; 355 | } 356 | bool CRKDevice::TestDevice() 357 | { 358 | int iResult, iTryCount; 359 | DWORD dwTotal, dwCurrent, dwLayerID; 360 | dwLayerID = m_locationID; 361 | ENUM_CALL_STEP emCallStep = CALL_FIRST; 362 | do { 363 | iTryCount = 3; 364 | while (iTryCount > 0) { 365 | iResult = m_pComm->RKU_TestDeviceReady(&dwTotal, &dwCurrent); 366 | if ((iResult == ERR_SUCCESS) || (iResult == ERR_DEVICE_UNREADY)) { 367 | break; 368 | } 369 | if (m_pLog) { 370 | m_pLog->Record(" ERROR:TestDevice-->RKU_TestDeviceReady failed, RetCode(%d)", m_layerName, iResult); 371 | } 372 | iTryCount--; 373 | sleep(1); 374 | } 375 | if (iTryCount <= 0) { 376 | return false; 377 | } 378 | 379 | if (iResult == ERR_SUCCESS) { 380 | if (emCallStep == CALL_MIDDLE) { 381 | if (m_callBackProc) { 382 | dwCurrent = dwTotal; 383 | emCallStep = CALL_LAST; 384 | m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep); 385 | } 386 | } 387 | break; 388 | } 389 | if (dwCurrent>dwTotal) { 390 | if (m_pLog) { 391 | m_pLog->Record(" ERROR:TestDevice-->RKU_TestDeviceReady failed,Total=%d, Current=%d", m_layerName, dwTotal, dwCurrent); 392 | } 393 | return false; 394 | } 395 | if (UsbType == RKUSB_LOADER) { 396 | if (dwTotal == 0) { 397 | if (m_pLog) 398 | { 399 | m_pLog->Record(" ERROR:TestDevice-->RKU_TestDeviceReady failed, Total is zero", m_layerName); 400 | } 401 | return false; 402 | } 403 | } 404 | if (m_callBackProc) 405 | { 406 | m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep); 407 | emCallStep = CALL_MIDDLE; 408 | } 409 | sleep(1); 410 | }while(iResult == ERR_DEVICE_UNREADY); 411 | return true; 412 | } 413 | bool CRKDevice::ResetDevice() 414 | { 415 | int iRet; 416 | iRet = m_pComm->RKU_ResetDevice(); 417 | if (iRet == ERR_SUCCESS) { 418 | return true; 419 | } else { 420 | bool bRet = false; 421 | if ((iRet == -2) || (iRet == -4)) { 422 | bRet = true; 423 | } 424 | if (m_pLog) { 425 | m_pLog->Record(" ERROR:ResetDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet); 426 | } 427 | return bRet; 428 | } 429 | } 430 | 431 | bool CRKDevice::PowerOffDevice() 432 | { 433 | int iRet; 434 | iRet = m_pComm->RKU_ResetDevice(RST_POWEROFF_SUBCODE); 435 | if (iRet == ERR_SUCCESS) { 436 | return true; 437 | } else { 438 | if (m_pLog) { 439 | m_pLog->Record(" ERROR:PowerOffDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet); 440 | } 441 | return false; 442 | } 443 | } 444 | bool CRKDevice::CheckChip() 445 | { 446 | int iRet; 447 | BYTE bChipInfo[CHIPINFO_LEN]; 448 | ENUM_RKDEVICE_TYPE curDeviceType = RKNONE_DEVICE; 449 | memset(bChipInfo, 0, CHIPINFO_LEN); 450 | iRet = m_pComm->RKU_ReadChipInfo(bChipInfo); 451 | if (iRet == ERR_SUCCESS) { 452 | if (!m_chipData) { 453 | m_chipData = new BYTE[CHIPINFO_LEN]; 454 | } 455 | memset(m_chipData, 0, CHIPINFO_LEN); 456 | memcpy(m_chipData, bChipInfo, CHIPINFO_LEN); 457 | DWORD *pValue; 458 | pValue = (DWORD *)(&bChipInfo[0]); 459 | 460 | if ((ENUM_RKDEVICE_TYPE)(*pValue) == m_device) { 461 | return true; 462 | } 463 | if (*pValue == 0x524B3237) { 464 | curDeviceType = RK27_DEVICE; 465 | } else if (*pValue == 0x32373341) { 466 | curDeviceType = RKCAYMAN_DEVICE; 467 | } else if (*pValue == 0x524B3238) { 468 | curDeviceType = RK28_DEVICE; 469 | } else if (*pValue == 0x32383158) { 470 | curDeviceType = RK281X_DEVICE; 471 | } else if (*pValue == 0x32383242) { 472 | curDeviceType = RKPANDA_DEVICE; 473 | } else if (*pValue == 0x32393058) { 474 | curDeviceType = RK29_DEVICE; 475 | } else if (*pValue == 0x32393258) { 476 | curDeviceType = RK292X_DEVICE; 477 | } else if (*pValue == 0x33303041) { 478 | curDeviceType = RK30_DEVICE; 479 | } else if (*pValue == 0x33313041) { 480 | curDeviceType = RK30B_DEVICE; 481 | } else if (*pValue == 0x33313042) { 482 | curDeviceType = RK31_DEVICE; 483 | } else if (*pValue == 0x33323041) { 484 | curDeviceType = RK32_DEVICE; 485 | } else if (*pValue == 0x32363243) { 486 | curDeviceType = RKSMART_DEVICE; 487 | } else if (*pValue == 0x6E616E6F) { 488 | curDeviceType = RKNANO_DEVICE; 489 | } else if (*pValue == 0x4E4F5243) { 490 | curDeviceType = RKCROWN_DEVICE; 491 | } 492 | 493 | if (curDeviceType == m_device){ 494 | return true; 495 | } else { 496 | if (m_pLog) { 497 | m_pLog->Record(" ERROR:CheckChip-->Chip is not match, firmware(0x%x), device(0x%x)", m_layerName, m_device, *pValue); 498 | } 499 | return false; 500 | } 501 | } 502 | else { 503 | if (m_pLog) { 504 | m_pLog->Record(" ERROR:CheckChip-->RKU_ReadChipInfo failed,RetCode(%d)", m_layerName, iRet); 505 | } 506 | return false; 507 | } 508 | } 509 | 510 | int CRKDevice::DownloadBoot() 511 | { 512 | UCHAR i; 513 | DWORD dwSize, dwDelay; 514 | PBYTE pBuffer = NULL; 515 | for ( i = 0; i < m_pImage->m_bootObject->Entry471Count; i++ ) { 516 | if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY471, i, dwSize, dwDelay) ) { 517 | if (m_pLog) { 518 | m_pLog->Record(" ERROR:DownloadBoot-->GetEntry471Property failed,index(%d)", m_layerName, i); 519 | } 520 | return -2; 521 | } 522 | if (dwSize>0) { 523 | pBuffer = new BYTE[dwSize]; 524 | if ( !m_pImage->m_bootObject->GetEntryData(ENTRY471, i, pBuffer) ) { 525 | if (m_pLog) { 526 | m_pLog->Record(" ERROR:DownloadBoot-->GetEntry471Data failed,index(%d)", m_layerName, i); 527 | } 528 | delete []pBuffer; 529 | return -3; 530 | } 531 | if ( !Boot_VendorRequest(0x0471,pBuffer,dwSize) ) { 532 | if (m_pLog) { 533 | m_pLog->Record(" ERROR:DownloadBoot-->Boot_VendorRequest471 failed,index(%d)", m_layerName, i); 534 | } 535 | delete []pBuffer; 536 | return -4; 537 | } 538 | delete []pBuffer; 539 | pBuffer = NULL; 540 | if (dwDelay>0) { 541 | usleep(dwDelay * 1000); 542 | } 543 | 544 | } 545 | } 546 | 547 | for ( i=0; i < m_pImage->m_bootObject->Entry472Count; i++ ) { 548 | if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY472, i, dwSize, dwDelay) ) { 549 | if (m_pLog) { 550 | m_pLog->Record(" ERROR:DownloadBoot-->GetEntry472Property failed,index(%d)", m_layerName, i); 551 | } 552 | return -2; 553 | } 554 | if (dwSize > 0) { 555 | pBuffer = new BYTE[dwSize]; 556 | if ( !m_pImage->m_bootObject->GetEntryData(ENTRY472, i, pBuffer) ) { 557 | if (m_pLog) { 558 | m_pLog->Record(" ERROR:DownloadBoot-->GetEntry472Data failed,index(%d)", m_layerName, i); 559 | } 560 | delete []pBuffer; 561 | return -3; 562 | } 563 | if ( !Boot_VendorRequest(0x0472, pBuffer, dwSize) ) { 564 | if (m_pLog) { 565 | m_pLog->Record(" ERROR:DownloadBoot-->Boot_VendorRequest472 failed,index(%d)", m_layerName, i); 566 | } 567 | delete []pBuffer; 568 | return -4; 569 | } 570 | delete []pBuffer; 571 | pBuffer = NULL; 572 | if (dwDelay > 0) { 573 | usleep(dwDelay * 1000); 574 | } 575 | } 576 | } 577 | sleep(1); 578 | return 0; 579 | 580 | } 581 | bool CRKDevice::Boot_VendorRequest( DWORD requestCode, PBYTE pBuffer, DWORD dwDataSize) 582 | { 583 | int iRet; 584 | iRet = m_pComm->RKU_DeviceRequest(requestCode, pBuffer, dwDataSize); 585 | return (iRet == ERR_SUCCESS) ? true : false; 586 | } 587 | int CRKDevice::EraseAllBlocks(bool force_block_erase) 588 | { 589 | int i; 590 | UINT uiBlockCount; 591 | int iRet = ERR_SUCCESS, iErasePos = 0, iEraseBlockNum = 0, iEraseTimes = 0, iCSIndex = 0; 592 | BYTE bCSCount = 0; 593 | for (i = 0; i < 8; i++) { 594 | if ( m_flashInfo.bFlashCS & (1 << i) ) { 595 | bCSCount++; 596 | } 597 | } 598 | ReadCapability(); 599 | DWORD dwLayerID; 600 | dwLayerID = LocationID; 601 | ENUM_CALL_STEP emCallStep = CALL_FIRST; 602 | if (!force_block_erase) { 603 | if ((m_bEmmc)||(m_bDirectLba)) { 604 | if (!EraseEmmc()) { 605 | if (m_pLog) { 606 | m_pLog->Record(" ERROR:EraseAllBlocks-->EraseEmmc failed", m_layerName); 607 | } 608 | return -1; 609 | } 610 | return 0; 611 | } 612 | } 613 | for (i = 0; i < 8; i++) { 614 | if ( m_flashInfo.bFlashCS & (1 << i) ) { 615 | uiBlockCount = m_flashInfo.uiBlockNum; 616 | iErasePos = 0; 617 | iEraseTimes = 0; 618 | while (uiBlockCount > 0) { 619 | iEraseBlockNum = (uiBlockCount < MAX_ERASE_BLOCKS) ? uiBlockCount : MAX_ERASE_BLOCKS; 620 | iRet = m_pComm->RKU_EraseBlock(i, iErasePos, iEraseBlockNum, ERASE_FORCE); 621 | if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) { 622 | if (m_pLog) { 623 | m_pLog->Record(" ERROR:EraseAllBlocks-->RKU_EraseBlock failed,RetCode(%d)", m_layerName, iRet); 624 | } 625 | return -1; 626 | } 627 | iErasePos += iEraseBlockNum; 628 | uiBlockCount -= iEraseBlockNum; 629 | iEraseTimes++; 630 | if (iEraseTimes % 8 == 0) { 631 | if (m_callBackProc) { 632 | m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum + iErasePos, emCallStep); 633 | emCallStep = CALL_MIDDLE; 634 | } 635 | } 636 | } 637 | iCSIndex++; 638 | } 639 | } 640 | 641 | if (m_callBackProc) { 642 | emCallStep = CALL_LAST; 643 | m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum, emCallStep); 644 | } 645 | return 0; 646 | } 647 | bool CRKDevice::ReadCapability() 648 | { 649 | int ret; 650 | BYTE data[8]; 651 | ret = m_pComm->RKU_ReadCapability(data); 652 | if (ret != ERR_SUCCESS) 653 | { 654 | if (m_pLog) 655 | { 656 | m_pLog->Record("ERROR:ReadCapability-->RKU_ReadCapability failed,err(%d)", ret); 657 | } 658 | return false; 659 | } 660 | if (data[0] & 0x1) 661 | { 662 | m_bDirectLba = true; 663 | } 664 | else 665 | m_bDirectLba = false; 666 | if (data[0] & 0x4) 667 | { 668 | m_bFirst4mAccess = true; 669 | } 670 | else 671 | m_bFirst4mAccess = false; 672 | return true; 673 | } 674 | 675 | 676 | -------------------------------------------------------------------------------- /RKDevice.h: -------------------------------------------------------------------------------- 1 | #ifndef RKDEVICE_HEADER 2 | #define RKDEVICE_HEADER 3 | #include "RKImage.h" 4 | #include "RKComm.h" 5 | #include "RKLog.h" 6 | #include "DefineHeader.h" 7 | 8 | #define SECTOR_SIZE 512 9 | #define PAGE_SIZE 2048 10 | #define SPARE_SIZE 16 11 | #define CHIPINFO_LEN 16 12 | #define IDBLOCK_TOP 50 13 | 14 | #define CALC_UNIT(a, b) ((a > 0) ? ((a - 1) / b + 1) : (a)) 15 | #define BYTE2SECTOR(x) (CALC_UNIT(x, SECTOR_SIZE)) 16 | #define PAGEALIGN(x) (CALC_UNIT(x, 4)) 17 | 18 | #pragma pack(1) 19 | typedef struct _STRUCT_FLASH_INFO { 20 | char szManufacturerName[16]; 21 | UINT uiFlashSize; 22 | USHORT usBlockSize; 23 | UINT uiPageSize; 24 | UINT uiSectorPerBlock; 25 | BYTE blockState[IDBLOCK_TOP]; 26 | UINT uiBlockNum; 27 | BYTE bECCBits; 28 | BYTE bAccessTime; 29 | BYTE bFlashCS; 30 | USHORT usValidSecPerBlock; 31 | USHORT usPhyBlokcPerIDB; 32 | UINT uiSecNumPerIDB; 33 | } STRUCT_FLASH_INFO, *PSTRUCT_FLASH_INFO; 34 | typedef struct _STRUCT_FLASHINFO_CMD { 35 | UINT uiFlashSize; 36 | USHORT usBlockSize; 37 | BYTE bPageSize; 38 | BYTE bECCBits; 39 | BYTE bAccessTime; 40 | BYTE bManufCode; 41 | BYTE bFlashCS; 42 | BYTE reserved[501]; 43 | } STRUCT_FLASHINFO_CMD, *PSTRUCT_FLASHINFO_CMD; 44 | #pragma pack() 45 | 46 | class CRKDevice 47 | { 48 | public: 49 | USHORT GetVendorID(); 50 | void SetVendorID(USHORT value); 51 | property VendorID; 52 | 53 | USHORT GetProductID(); 54 | void SetProductID(USHORT value); 55 | property ProductID; 56 | 57 | ENUM_RKDEVICE_TYPE GetDeviceType(); 58 | void SetDeviceType(ENUM_RKDEVICE_TYPE value); 59 | property DeviceType; 60 | 61 | ENUM_RKUSB_TYPE GetUsbType(); 62 | void SetUsbType(ENUM_RKUSB_TYPE value); 63 | property UsbType; 64 | 65 | char *GetLayerName(); 66 | void SetLayerName(char *value); 67 | property LayerName; 68 | 69 | DWORD GetLocationID(); 70 | void SetLocationID(DWORD value); 71 | property LocationID; 72 | 73 | USHORT GetBcdUsb(); 74 | void SetBcdUsb(USHORT value); 75 | property BcdUsb; 76 | 77 | ENUM_OS_TYPE GetOsType(); 78 | void SetOsType(ENUM_OS_TYPE value); 79 | property OsType; 80 | 81 | CRKLog *GetLogObjectPointer(); 82 | property LogObjectPointer; 83 | 84 | CRKComm *GetCommObjectPointer(); 85 | property CommObjectPointer; 86 | 87 | void SetCallBackPointer(ProgressPromptCB value); 88 | property CallBackPointer; 89 | 90 | int DownloadBoot(); 91 | bool TestDevice(); 92 | bool ResetDevice(); 93 | bool PowerOffDevice(); 94 | bool CheckChip(); 95 | bool GetFlashInfo(); 96 | int EraseAllBlocks(bool force_block_erase=false); 97 | bool SetObject(CRKImage *pImage, CRKComm *pComm, CRKLog *pLog); 98 | string GetLayerString(UINT dwLocationID); 99 | CRKDevice(STRUCT_RKDEVICE_DESC &device); 100 | ~CRKDevice(); 101 | protected: 102 | STRUCT_FLASH_INFO m_flashInfo; 103 | PBYTE m_pFlashInfoData; 104 | USHORT m_usFlashInfoDataOffset; 105 | USHORT m_usFlashInfoDataLen; 106 | PBYTE m_chipData; 107 | CRKImage *m_pImage; 108 | CRKComm *m_pComm; 109 | CRKLog *m_pLog; 110 | ProgressPromptCB m_callBackProc; 111 | bool m_bEmmc; 112 | bool m_bDirectLba; 113 | bool m_bFirst4mAccess; 114 | int EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount); 115 | int EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount); 116 | bool EraseEmmc(); 117 | bool Boot_VendorRequest(DWORD requestCode, PBYTE pBuffer, DWORD dwDataSize); 118 | bool ReadCapability(); 119 | private: 120 | USHORT m_vid; 121 | USHORT m_pid; 122 | ENUM_RKDEVICE_TYPE m_device; 123 | ENUM_OS_TYPE m_os; 124 | ENUM_RKUSB_TYPE m_usb; 125 | UINT m_locationID; 126 | USHORT m_bcdUsb; 127 | protected: 128 | char m_layerName[32]; 129 | }; 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /RKImage.cpp: -------------------------------------------------------------------------------- 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 | #include "RKImage.h" 8 | 9 | UINT CRKImage::GetVersion() 10 | { 11 | return m_version; 12 | } 13 | UINT CRKImage::GetMergeVersion() 14 | { 15 | return m_mergeVersion; 16 | } 17 | STRUCT_RKTIME CRKImage::GetReleaseTime() 18 | { 19 | return m_releaseTime; 20 | } 21 | ENUM_RKDEVICE_TYPE CRKImage::GetSupportDevice() 22 | { 23 | return m_supportDevice; 24 | } 25 | ENUM_OS_TYPE CRKImage::GetOsType() 26 | { 27 | UINT *pOsType; 28 | pOsType = (UINT *)&m_reserved[4]; 29 | return (ENUM_OS_TYPE)*pOsType; 30 | } 31 | 32 | USHORT CRKImage::GetBackupSize() 33 | { 34 | USHORT *pBackupSize; 35 | pBackupSize = (USHORT *)&m_reserved[12]; 36 | return *pBackupSize; 37 | } 38 | UINT CRKImage::GetBootOffset() 39 | { 40 | return m_bootOffset; 41 | } 42 | UINT CRKImage::GetBootSize() 43 | { 44 | return m_bootSize; 45 | } 46 | UINT CRKImage::GetFWOffset() 47 | { 48 | return m_fwOffset; 49 | } 50 | long long CRKImage::GetFWSize() 51 | { 52 | return m_fwSize; 53 | } 54 | bool CRKImage::SaveBootFile(string filename) 55 | { 56 | FILE *file = NULL; 57 | int iRead; 58 | file = fopen(filename.c_str(), "wb+"); 59 | if (!file) { 60 | return false; 61 | } 62 | BYTE buffer[1024]; 63 | DWORD dwBufferSize = 1024; 64 | DWORD dwBootSize = m_bootSize; 65 | DWORD dwReadSize; 66 | fseek(m_pFile, m_bootOffset, SEEK_SET); 67 | do { 68 | dwReadSize = (dwBootSize >= 1024) ? dwBufferSize : dwBootSize; 69 | iRead = fread(buffer, 1, dwReadSize, m_pFile); 70 | if (iRead != (int)dwReadSize) { 71 | fclose(file); 72 | return false; 73 | } 74 | fwrite(buffer, 1, dwReadSize, file); 75 | dwBootSize -= dwReadSize; 76 | } while(dwBootSize > 0); 77 | fclose(file); 78 | return true; 79 | } 80 | bool CRKImage::SaveFWFile(string filename) 81 | { 82 | FILE *file = NULL; 83 | int iRead; 84 | file = fopen(filename.c_str(), "wb+"); 85 | if (!file) { 86 | return false; 87 | } 88 | BYTE buffer[1024]; 89 | DWORD dwBufferSize = 1024; 90 | long long dwFWSize = m_fwSize; 91 | DWORD dwReadSize; 92 | fseeko(m_pFile, m_fwOffset, SEEK_SET); 93 | do { 94 | dwReadSize = (dwFWSize >= 1024) ? dwBufferSize : dwFWSize; 95 | iRead = fread(buffer, 1, dwReadSize, m_pFile); 96 | if (iRead != (int)dwReadSize) { 97 | fclose(file); 98 | return false; 99 | } 100 | fwrite(buffer, 1, dwReadSize, file); 101 | dwFWSize -= dwReadSize; 102 | } while (dwFWSize > 0); 103 | fclose(file); 104 | return true; 105 | } 106 | bool CRKImage::GetData(long long dwOffset, DWORD dwSize, PBYTE lpBuffer) 107 | { 108 | if ( (dwOffset < 0) || (dwSize == 0) ) { 109 | return false; 110 | } 111 | if ( dwOffset+dwSize > m_fileSize) { 112 | return false; 113 | } 114 | fseeko(m_pFile, dwOffset, SEEK_SET); 115 | UINT uiActualRead; 116 | uiActualRead = fread(lpBuffer,1, dwSize, m_pFile); 117 | if (dwSize != uiActualRead){ 118 | return false; 119 | } 120 | return true; 121 | } 122 | void CRKImage::GetReservedData(PBYTE &lpData, USHORT &usSize) 123 | { 124 | lpData = m_reserved; 125 | usSize = IMAGE_RESERVED_SIZE; 126 | } 127 | 128 | CRKImage::CRKImage(string filename, bool &bCheck) 129 | { 130 | Version.setContainer(this); 131 | Version.getter(&CRKImage::GetVersion); 132 | MergeVersion.setContainer(this); 133 | MergeVersion.getter(&CRKImage::GetMergeVersion); 134 | ReleaseTime.setContainer(this); 135 | ReleaseTime.getter(&CRKImage::GetReleaseTime); 136 | SupportDevice.setContainer(this); 137 | SupportDevice.getter(&CRKImage::GetSupportDevice); 138 | OsType.setContainer(this); 139 | OsType.getter(&CRKImage::GetOsType); 140 | BackupSize.setContainer(this); 141 | BackupSize.getter(&CRKImage::GetBackupSize); 142 | BootOffset.setContainer(this); 143 | BootOffset.getter(&CRKImage::GetBootOffset); 144 | BootSize.setContainer(this); 145 | BootSize.getter(&CRKImage::GetBootSize); 146 | FWOffset.setContainer(this); 147 | FWOffset.getter(&CRKImage::GetFWOffset); 148 | FWSize.setContainer(this); 149 | FWSize.getter(&CRKImage::GetFWSize); 150 | SignFlag.setContainer(this); 151 | SignFlag.getter(&CRKImage::GetSignFlag); 152 | struct stat statBuf; 153 | m_bootObject = NULL; 154 | m_pFile = NULL; 155 | m_bSignFlag = false; 156 | 157 | m_signMd5Size = 0; 158 | memset(m_md5, 0, 32); 159 | memset(m_signMd5, 0, 256); 160 | 161 | char szName[256]; 162 | strcpy(szName, filename.c_str()); 163 | if(stat(szName, &statBuf) < 0) { 164 | bCheck = false; 165 | return; 166 | } 167 | if (S_ISDIR(statBuf.st_mode)) { 168 | bCheck = false; 169 | return; 170 | } 171 | m_fileSize = statBuf.st_size; 172 | 173 | bool bOnlyBootFile=false; 174 | transform(filename.begin(), filename.end(), filename.begin(), (int(*)(int))tolower); 175 | if (filename.find(".bin") != string::npos) { 176 | bOnlyBootFile = true; 177 | } 178 | 179 | m_pFile = fopen(szName, "rb"); 180 | if (!m_pFile) { 181 | bCheck = false; 182 | return; 183 | } 184 | 185 | int nMd5DataSize, iRead; 186 | long long ulFwSize; 187 | STRUCT_RKIMAGE_HEAD imageHead; 188 | if (!bOnlyBootFile) { 189 | fseeko(m_pFile, 0, SEEK_SET); 190 | iRead = fread((PBYTE)(&imageHead), 1, sizeof(STRUCT_RKIMAGE_HEAD), m_pFile); 191 | if (iRead != sizeof(STRUCT_RKIMAGE_HEAD)) { 192 | bCheck = false; 193 | return; 194 | } 195 | if ( imageHead.uiTag != 0x57464B52 ) { 196 | bCheck = false; 197 | return; 198 | } 199 | if ((imageHead.reserved[14] == 'H') && (imageHead.reserved[15] == 'I')) { 200 | ulFwSize = *((DWORD *)(&imageHead.reserved[16])); 201 | ulFwSize <<= 32; 202 | ulFwSize += imageHead.dwFWOffset; 203 | ulFwSize += imageHead.dwFWSize; 204 | } else 205 | ulFwSize = imageHead.dwFWOffset + imageHead.dwFWSize; 206 | nMd5DataSize = GetImageSize() - ulFwSize; 207 | if (nMd5DataSize >= 160) { 208 | m_bSignFlag = true; 209 | m_signMd5Size = nMd5DataSize - 32; 210 | fseeko(m_pFile, ulFwSize, SEEK_SET); 211 | iRead = fread(m_md5, 1, 32, m_pFile); 212 | if (iRead != 32) { 213 | bCheck = false; 214 | return; 215 | } 216 | iRead = fread(m_signMd5, 1, nMd5DataSize - 32, m_pFile); 217 | if (iRead != (nMd5DataSize - 32)) { 218 | bCheck = false; 219 | return; 220 | } 221 | } else { 222 | fseeko(m_pFile, -32, SEEK_END); 223 | iRead = fread(m_md5, 1, 32, m_pFile); 224 | if (iRead != 32) { 225 | bCheck = false; 226 | return; 227 | } 228 | } 229 | 230 | m_version = imageHead.dwVersion; 231 | m_mergeVersion = imageHead.dwMergeVersion; 232 | m_releaseTime.usYear = imageHead.stReleaseTime.usYear; 233 | m_releaseTime.ucMonth = imageHead.stReleaseTime.ucMonth; 234 | m_releaseTime.ucDay = imageHead.stReleaseTime.ucDay; 235 | m_releaseTime.ucHour = imageHead.stReleaseTime.ucHour; 236 | m_releaseTime.ucMinute = imageHead.stReleaseTime.ucMinute; 237 | m_releaseTime.ucSecond = imageHead.stReleaseTime.ucSecond; 238 | m_supportDevice = imageHead.emSupportChip; 239 | m_bootOffset = imageHead.dwBootOffset; 240 | m_bootSize = imageHead.dwBootSize; 241 | m_fwOffset = imageHead.dwFWOffset; 242 | m_fwSize = ulFwSize - m_fwOffset; 243 | memcpy(m_reserved, imageHead.reserved, IMAGE_RESERVED_SIZE); 244 | } else { 245 | m_bootOffset = 0; 246 | m_bootSize = m_fileSize; 247 | } 248 | 249 | PBYTE lpBoot; 250 | lpBoot = new BYTE[m_bootSize]; 251 | fseeko(m_pFile, m_bootOffset, SEEK_SET); 252 | iRead = fread(lpBoot, 1, m_bootSize, m_pFile); 253 | if (iRead != (int)m_bootSize) { 254 | bCheck = false; 255 | return; 256 | } 257 | bool bRet; 258 | m_bootObject = new CRKBoot(lpBoot, m_bootSize, bRet); 259 | if (!bRet) { 260 | bCheck = false; 261 | return; 262 | } 263 | if (bOnlyBootFile) { 264 | m_supportDevice = m_bootObject->SupportDevice; 265 | UINT *pOsType; 266 | pOsType = (UINT *)&m_reserved[4]; 267 | *pOsType = (UINT)RK_OS; 268 | fclose(m_pFile); 269 | m_pFile = NULL; 270 | } 271 | bCheck = true; 272 | } 273 | CRKImage::~CRKImage() 274 | { 275 | if (m_pFile) { 276 | fclose(m_pFile); 277 | m_pFile = NULL; 278 | } 279 | if (m_bootObject) { 280 | delete m_bootObject; 281 | m_bootObject = NULL; 282 | } 283 | } 284 | 285 | long long CRKImage::GetImageSize() 286 | { 287 | return m_fileSize; 288 | } 289 | int CRKImage::GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5) 290 | { 291 | lpMd5 = m_md5; 292 | lpSignMd5 = m_signMd5; 293 | return m_signMd5Size; 294 | } 295 | bool CRKImage::GetSignFlag() 296 | { 297 | return m_bSignFlag; 298 | } 299 | -------------------------------------------------------------------------------- /RKImage.h: -------------------------------------------------------------------------------- 1 | #ifndef RKIMAGE_HEADER 2 | #define RKIMAGE_HEADER 3 | #include "DefineHeader.h" 4 | #include "RKBoot.h" 5 | #define IMAGE_RESERVED_SIZE 61 6 | #pragma pack(1) 7 | typedef struct { 8 | UINT uiTag; 9 | USHORT usSize; 10 | DWORD dwVersion; 11 | DWORD dwMergeVersion; 12 | STRUCT_RKTIME stReleaseTime; 13 | ENUM_RKDEVICE_TYPE emSupportChip; 14 | DWORD dwBootOffset; 15 | DWORD dwBootSize; 16 | DWORD dwFWOffset; 17 | DWORD dwFWSize; 18 | BYTE reserved[IMAGE_RESERVED_SIZE]; 19 | } STRUCT_RKIMAGE_HEAD, *PSTRUCT_RKIMAGE_HEAD; 20 | #pragma pack() 21 | class CRKImage 22 | { 23 | public: 24 | UINT GetVersion(); 25 | property Version; 26 | UINT GetMergeVersion(); 27 | property MergeVersion; 28 | STRUCT_RKTIME GetReleaseTime(); 29 | property ReleaseTime; 30 | ENUM_RKDEVICE_TYPE GetSupportDevice(); 31 | property SupportDevice; 32 | ENUM_OS_TYPE GetOsType(); 33 | property OsType; 34 | 35 | unsigned short GetBackupSize(); 36 | property BackupSize; 37 | UINT GetBootOffset(); 38 | property BootOffset; 39 | UINT GetBootSize(); 40 | property BootSize; 41 | UINT GetFWOffset(); 42 | property FWOffset; 43 | long long GetFWSize(); 44 | property FWSize; 45 | bool GetSignFlag(); 46 | property SignFlag; 47 | 48 | CRKBoot *m_bootObject; 49 | bool SaveBootFile(string filename); 50 | bool SaveFWFile(string filename); 51 | bool GetData(long long dwOffset, DWORD dwSize, PBYTE lpBuffer); 52 | void GetReservedData(PBYTE &lpData, USHORT &usSize); 53 | int GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5); 54 | long long GetImageSize(); 55 | CRKImage(string filename, bool &bCheck); 56 | ~CRKImage(); 57 | protected: 58 | 59 | private: 60 | DWORD m_version; 61 | DWORD m_mergeVersion; 62 | STRUCT_RKTIME m_releaseTime; 63 | ENUM_RKDEVICE_TYPE m_supportDevice; 64 | DWORD m_bootOffset; 65 | DWORD m_bootSize; 66 | DWORD m_fwOffset; 67 | long long m_fwSize; 68 | 69 | BYTE m_md5[32]; 70 | BYTE m_signMd5[256]; 71 | BYTE m_reserved[IMAGE_RESERVED_SIZE]; 72 | bool m_bSignFlag; 73 | int m_signMd5Size; 74 | FILE *m_pFile; 75 | long long m_fileSize; 76 | }; 77 | #endif -------------------------------------------------------------------------------- /RKLog.cpp: -------------------------------------------------------------------------------- 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 | #ifdef __MINGW32__ 9 | #define _POSIX_THREAD_SAFE_FUNCTIONS 10 | #endif 11 | 12 | #include "RKLog.h" 13 | 14 | int file_stat(string strPath) 15 | { 16 | struct stat statBuf; 17 | int ret; 18 | ret = stat(strPath.c_str(), &statBuf); 19 | if (ret != 0) { 20 | return STAT_NOT_EXIST; 21 | } 22 | if (S_ISDIR(statBuf.st_mode)) 23 | return STAT_DIR; 24 | return STAT_FILE; 25 | } 26 | string CRKLog::GetLogSavePath() 27 | { 28 | return m_path; 29 | } 30 | bool CRKLog::GetEnableLog() 31 | { 32 | return m_enable; 33 | } 34 | void CRKLog::SetEnableLog(bool bEnable) 35 | { 36 | m_enable = bEnable; 37 | } 38 | 39 | CRKLog::CRKLog(string logFilePath, string logFileName, bool enable) 40 | { 41 | LogSavePath.setContainer(this); 42 | LogSavePath.getter(&CRKLog::GetLogSavePath); 43 | 44 | EnableLog.setContainer(this); 45 | EnableLog.getter(&CRKLog::GetEnableLog); 46 | EnableLog.setter(&CRKLog::SetEnableLog); 47 | 48 | if (!opendir(logFilePath.c_str())) { 49 | m_path = ""; 50 | } else { 51 | if (logFilePath[logFilePath.size() - 1] != '/') { 52 | logFilePath += '/'; 53 | } 54 | m_path = logFilePath; 55 | } 56 | if (logFileName.size() <= 0) { 57 | m_name = "Log"; 58 | } else 59 | m_name = logFileName; 60 | m_enable = enable; 61 | 62 | } 63 | CRKLog::~CRKLog() 64 | { 65 | } 66 | void CRKLog::Record(const char *lpFmt,...) 67 | { 68 | /************************* �������־ ***********************/ 69 | char szBuf[1024] = ""; 70 | GET_FMT_STRING(lpFmt, szBuf); 71 | if ((m_enable) && (m_path.size() > 0)) 72 | { 73 | Write( szBuf); 74 | } 75 | } 76 | bool CRKLog::Write(string text) 77 | { 78 | time_t now; 79 | struct tm timeNow; 80 | char szDateTime[100]; 81 | string strName; 82 | FILE *file=NULL; 83 | time(&now); 84 | localtime_r(&now, &timeNow); 85 | snprintf(szDateTime, sizeof(szDateTime), "%04d-%02d-%02d.txt", timeNow.tm_year + 1900, timeNow.tm_mon + 1, timeNow.tm_mday); 86 | strName = m_path + m_name+szDateTime; 87 | 88 | try { 89 | file = fopen(strName.c_str(), "ab+"); 90 | if (!file) { 91 | return false; 92 | } 93 | snprintf(szDateTime, sizeof(szDateTime), "%02d:%02d:%02d \t", timeNow.tm_hour, timeNow.tm_min, timeNow.tm_sec); 94 | text = szDateTime + text + "\r\n"; 95 | fwrite(text.c_str(), 1, text.size() * sizeof(char), file); 96 | fclose(file); 97 | } catch (...) { 98 | fclose(file); 99 | return false; 100 | } 101 | return true; 102 | } 103 | bool CRKLog::SaveBuffer(string fileName, PBYTE lpBuffer, DWORD dwSize) 104 | { 105 | FILE *file; 106 | file = fopen(fileName.c_str(), "wb+"); 107 | if (!file) { 108 | return false; 109 | } 110 | fwrite(lpBuffer, 1, dwSize, file); 111 | fclose(file); 112 | return true; 113 | } 114 | void CRKLog::PrintBuffer(string &strOutput, PBYTE lpBuffer, DWORD dwSize, UINT uiLineCount) 115 | { 116 | UINT i,count; 117 | char strHex[32]; 118 | strOutput = ""; 119 | for (i = 0, count = 0; i < dwSize; i++, count++) { 120 | snprintf(strHex, sizeof(strHex), "%X", lpBuffer[i]); 121 | strOutput = strOutput + " " + strHex; 122 | if (count >= uiLineCount) { 123 | strOutput += "\r\n"; 124 | count = 0; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /RKLog.h: -------------------------------------------------------------------------------- 1 | #ifndef RKLOG_HEADER 2 | #define RKLOG_HEADER 3 | #include "DefineHeader.h" 4 | 5 | #define GET_FMT_STRING(fmt, buf) \ 6 | { \ 7 | va_list args; \ 8 | va_start(args, fmt); \ 9 | vsnprintf(buf, sizeof(buf)-1, fmt, args); \ 10 | va_end(args); \ 11 | buf[sizeof(buf)-1] = 0x00; \ 12 | }; 13 | 14 | class CRKLog 15 | { 16 | public: 17 | string GetLogSavePath(); 18 | bool GetEnableLog(); 19 | void SetEnableLog(bool bEnable); 20 | property LogSavePath; 21 | property EnableLog; 22 | CRKLog(string logFilePath, string logFileName, bool enable = false); 23 | ~CRKLog(); 24 | bool SaveBuffer(string fileName, PBYTE lpBuffer, DWORD dwSize); 25 | void PrintBuffer(string &strOutput, PBYTE lpBuffer, DWORD dwSize, UINT uiLineCount = 16); 26 | void Record(const char *lpFmt, ...); 27 | 28 | protected: 29 | private: 30 | string m_path; 31 | string m_name; 32 | bool m_enable; 33 | bool Write(string text); 34 | }; 35 | typedef enum { 36 | STAT_NOT_EXIST = 0, 37 | STAT_FILE, 38 | STAT_DIR 39 | } ENUM_FILE_STAT; 40 | int file_stat(string strPath); 41 | #endif 42 | -------------------------------------------------------------------------------- /RKScan.cpp: -------------------------------------------------------------------------------- 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 "RKScan.h" 9 | #define BUSID(id) ((id & 0x0000FF00) >> 8) 10 | int CRKScan::GetDEVICE_COUNTS() 11 | { 12 | return m_list.size(); 13 | } 14 | 15 | UINT CRKScan::GetMSC_TIMEOUT() 16 | { 17 | return m_waitMscSecond; 18 | } 19 | 20 | UINT CRKScan::GetRKUSB_TIMEOUT() 21 | { 22 | return m_waitRKusbSecond; 23 | } 24 | 25 | void CRKScan::SetMSC_TIMEOUT(UINT value) 26 | { 27 | m_waitMscSecond = value; 28 | } 29 | 30 | void CRKScan::SetRKUSB_TIMEOUT(UINT value) 31 | { 32 | m_waitRKusbSecond = value; 33 | } 34 | 35 | CRKScan::CRKScan(UINT uiMscTimeout, UINT uiRKusbTimeout) 36 | { 37 | DEVICE_COUNTS.setContainer(this); 38 | DEVICE_COUNTS.getter(&CRKScan::GetDEVICE_COUNTS); 39 | 40 | MSC_TIMEOUT.setContainer(this); 41 | MSC_TIMEOUT.getter(&CRKScan::GetMSC_TIMEOUT); 42 | MSC_TIMEOUT.setter(&CRKScan::SetMSC_TIMEOUT); 43 | 44 | RKUSB_TIMEOUT.setContainer(this); 45 | RKUSB_TIMEOUT.getter(&CRKScan::GetRKUSB_TIMEOUT); 46 | RKUSB_TIMEOUT.setter(&CRKScan::SetRKUSB_TIMEOUT); 47 | 48 | m_waitMscSecond = uiMscTimeout; 49 | m_waitRKusbSecond = uiRKusbTimeout; 50 | m_log = NULL; 51 | m_list.clear(); 52 | m_deviceConfigSet.clear(); 53 | m_deviceMscConfigSet.clear(); 54 | } 55 | bool CRKScan::FindRockusbVidPid(ENUM_RKDEVICE_TYPE type, USHORT &usVid, USHORT &usPid) 56 | { 57 | UINT i; 58 | bool bRet = false; 59 | for (i = 0; i < m_deviceConfigSet.size(); i++) { 60 | if (m_deviceConfigSet[i].emDeviceType == type) { 61 | usVid = m_deviceConfigSet[i].usVid; 62 | usPid = m_deviceConfigSet[i].usPid; 63 | bRet = true; 64 | break; 65 | } 66 | } 67 | return bRet; 68 | } 69 | void CRKScan::AddRockusbVidPid(USHORT newVid, USHORT newPid, USHORT oldVid, USHORT oldPid) 70 | { 71 | if ((newVid == 0) || (newPid == 0) || (oldVid == 0) || (oldPid == 0)) { 72 | return; 73 | } 74 | STRUCT_DEVICE_CONFIG config; 75 | unsigned int i; 76 | for (i = 0; i < m_deviceConfigSet.size(); i++) { 77 | if ((m_deviceConfigSet[i].usVid == oldVid) && (m_deviceConfigSet[i].usPid == oldPid)) { 78 | config.usVid = newVid; 79 | config.usPid = newPid; 80 | config.emDeviceType = m_deviceConfigSet[i].emDeviceType; 81 | break; 82 | } 83 | } 84 | if (i < m_deviceConfigSet.size()) 85 | m_deviceConfigSet.push_back(config); 86 | } 87 | 88 | void CRKScan::SetVidPid(USHORT mscVid, USHORT mscPid) 89 | { 90 | STRUCT_DEVICE_CONFIG config; 91 | m_deviceConfigSet.clear(); 92 | 93 | config.emDeviceType = RK27_DEVICE; 94 | config.usPid = 0x3201; 95 | config.usVid = 0x071B; 96 | m_deviceConfigSet.push_back(config); 97 | 98 | config.emDeviceType = RK28_DEVICE; 99 | config.usPid = 0x3228; 100 | config.usVid = 0x071B; 101 | m_deviceConfigSet.push_back(config); 102 | 103 | config.emDeviceType = RKNANO_DEVICE; 104 | config.usPid = 0x3226; 105 | config.usVid = 0x071B; 106 | m_deviceConfigSet.push_back(config); 107 | 108 | config.emDeviceType = RKCROWN_DEVICE; 109 | config.usPid = 0x261A; 110 | config.usVid = 0x2207; 111 | m_deviceConfigSet.push_back(config); 112 | 113 | config.emDeviceType = RK281X_DEVICE; 114 | config.usPid = 0x281A; 115 | config.usVid = 0x2207; 116 | m_deviceConfigSet.push_back(config); 117 | 118 | config.emDeviceType = RKCAYMAN_DEVICE; 119 | config.usPid = 0x273A; 120 | config.usVid = 0x2207; 121 | m_deviceConfigSet.push_back(config); 122 | 123 | config.emDeviceType = RK29_DEVICE; 124 | config.usPid = 0x290A; 125 | config.usVid = 0x2207; 126 | m_deviceConfigSet.push_back(config); 127 | 128 | config.emDeviceType = RKPANDA_DEVICE; 129 | config.usPid = 0x282B; 130 | config.usVid = 0x2207; 131 | m_deviceConfigSet.push_back(config); 132 | 133 | config.emDeviceType = RKSMART_DEVICE; 134 | config.usPid = 0x262C; 135 | config.usVid = 0x2207; 136 | m_deviceConfigSet.push_back(config); 137 | 138 | config.emDeviceType = RK292X_DEVICE; 139 | config.usPid = 0x292A; 140 | config.usVid = 0x2207; 141 | m_deviceConfigSet.push_back(config); 142 | 143 | config.emDeviceType = RK30_DEVICE; 144 | config.usPid = 0x300A; 145 | config.usVid = 0x2207; 146 | m_deviceConfigSet.push_back(config); 147 | 148 | config.emDeviceType = RK30B_DEVICE; 149 | config.usPid = 0x300B; 150 | config.usVid = 0x2207; 151 | m_deviceConfigSet.push_back(config); 152 | 153 | config.emDeviceType = RK31_DEVICE; 154 | config.usPid = 0x310B; 155 | config.usVid = 0x2207; 156 | m_deviceConfigSet.push_back(config); 157 | 158 | config.emDeviceType = RK31_DEVICE; 159 | config.usPid = 0x310C; 160 | config.usVid = 0x2207; 161 | m_deviceConfigSet.push_back(config); 162 | 163 | config.emDeviceType = RK32_DEVICE; 164 | config.usPid = 0x320A; 165 | config.usVid = 0x2207; 166 | m_deviceConfigSet.push_back(config); 167 | 168 | m_deviceMscConfigSet.clear(); 169 | 170 | config.emDeviceType = RKNONE_DEVICE; 171 | config.usPid = 0x3203; 172 | config.usVid = 0x071B; 173 | m_deviceMscConfigSet.push_back(config); 174 | 175 | config.emDeviceType = RKNONE_DEVICE; 176 | config.usPid = 0x3205; 177 | config.usVid = 0x071B; 178 | m_deviceMscConfigSet.push_back(config); 179 | 180 | config.emDeviceType = RKNONE_DEVICE; 181 | config.usPid = 0x2910; 182 | config.usVid = 0x0BB4; 183 | m_deviceMscConfigSet.push_back(config); 184 | 185 | config.emDeviceType = RKNONE_DEVICE; 186 | config.usPid = 0x0000; 187 | config.usVid = 0x2207; 188 | m_deviceMscConfigSet.push_back(config); 189 | 190 | config.emDeviceType = RKNONE_DEVICE; 191 | config.usPid = 0x0010; 192 | config.usVid = 0x2207; 193 | m_deviceMscConfigSet.push_back(config); 194 | 195 | if ((mscVid != 0) || (mscPid != 0)) { 196 | if (FindConfigSetPos(m_deviceMscConfigSet, mscVid, mscPid) == -1) { 197 | config.emDeviceType = RKNONE_DEVICE; 198 | config.usPid = mscPid; 199 | config.usVid = mscVid; 200 | m_deviceMscConfigSet.push_back(config); 201 | } 202 | } 203 | } 204 | int CRKScan::FindWaitSetPos(const RKDEVICE_CONFIG_SET &waitDeviceSet, USHORT vid, USHORT pid) 205 | { 206 | int pos=-1; 207 | UINT i; 208 | for ( i = 0; i < waitDeviceSet.size(); i++ ) { 209 | if ( (vid == waitDeviceSet[i].usVid) && (pid == waitDeviceSet[i].usPid) ) { 210 | pos = i; 211 | break; 212 | } 213 | } 214 | return pos; 215 | } 216 | int CRKScan::FindConfigSetPos(RKDEVICE_CONFIG_SET &devConfigSet, USHORT vid, USHORT pid) 217 | { 218 | int pos = -1; 219 | UINT i; 220 | for ( i = 0; i < devConfigSet.size(); i++ ) { 221 | if ( (vid == devConfigSet[i].usVid) && (pid == devConfigSet[i].usPid) ) { 222 | pos = i; 223 | break; 224 | } 225 | } 226 | return pos; 227 | } 228 | void CRKScan::EnumerateUsbDevice(RKDEVICE_DESC_SET &list, UINT &uiTotalMatchDevices) 229 | { 230 | STRUCT_RKDEVICE_DESC desc; 231 | struct libusb_device_descriptor descriptor; 232 | int ret,i,cnt; 233 | 234 | uiTotalMatchDevices = 0; 235 | libusb_device **pDevs = NULL; 236 | libusb_device *dev; 237 | ret = libusb_get_device_list(NULL, &pDevs); 238 | if (ret < 0) { 239 | if (m_log) 240 | m_log->Record("Error:EnumerateUsbDevice-->get_device_list failed,err=%d!", ret); 241 | return; 242 | } 243 | cnt = ret; 244 | for (i = 0; i < cnt; i++) { 245 | dev = pDevs[i]; 246 | if (dev) { 247 | ret = libusb_get_device_descriptor (dev, &descriptor); 248 | if (ret < 0) { 249 | libusb_free_device_list(pDevs, 1); 250 | if (m_log) 251 | m_log->Record("Error:EnumerateUsbDevice-->get_device_descriptor failed,err=%d!", ret); 252 | return; 253 | } 254 | desc.emDeviceType = RKNONE_DEVICE; 255 | desc.emUsbType = RKUSB_NONE; 256 | desc.pUsbHandle = (void *)dev; 257 | desc.usbcdUsb = descriptor.bcdUSB; 258 | desc.usVid = descriptor.idVendor; 259 | desc.usPid = descriptor.idProduct; 260 | desc.uiLocationID = libusb_get_bus_number(dev); 261 | desc.uiLocationID <<= 8; 262 | desc.uiLocationID += libusb_get_port_number(dev); 263 | libusb_ref_device(dev); 264 | uiTotalMatchDevices++; 265 | list.push_back(desc); 266 | } 267 | 268 | } 269 | libusb_free_device_list(pDevs, 1); 270 | 271 | } 272 | 273 | void CRKScan::FreeDeviceList(RKDEVICE_DESC_SET &list) 274 | { 275 | device_list_iter iter; 276 | for (iter = list.begin(); iter != list.end(); iter++) { 277 | if ((*iter).pUsbHandle) { 278 | libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 279 | (*iter).pUsbHandle = NULL; 280 | } 281 | } 282 | list.clear(); 283 | } 284 | bool CRKScan::IsRockusbDevice(ENUM_RKDEVICE_TYPE &type, USHORT vid, USHORT pid) 285 | { 286 | int iPos; 287 | iPos = FindConfigSetPos(m_deviceConfigSet, vid, pid); 288 | if (iPos != -1) { 289 | type = m_deviceConfigSet[iPos].emDeviceType; 290 | return true; 291 | } 292 | if (vid == 0x2207) { 293 | if ((pid >> 8) > 0) { 294 | type = RKNONE_DEVICE; 295 | return true; 296 | } 297 | } 298 | return false; 299 | } 300 | int CRKScan::Search(UINT type) 301 | { 302 | device_list_iter iter,new_iter; 303 | ENUM_RKDEVICE_TYPE devType; 304 | UINT uiTotalDevice; 305 | int iPos; 306 | 307 | FreeDeviceList(m_list); 308 | EnumerateUsbDevice( m_list, uiTotalDevice ); 309 | 310 | for ( iter = m_list.begin(); iter != m_list.end(); ) { 311 | if( (iPos = FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid)) != -1 ) { 312 | (*iter).emDeviceType = RKNONE_DEVICE; 313 | iter++; 314 | continue; 315 | } else if (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid) ) { 316 | (*iter).emDeviceType = devType; 317 | iter++; 318 | continue; 319 | } else { 320 | if ((*iter).pUsbHandle) { 321 | libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 322 | (*iter).pUsbHandle = NULL; 323 | } 324 | iter = m_list.erase(iter); 325 | uiTotalDevice--; 326 | } 327 | } 328 | 329 | if (m_list.size() <= 0) { 330 | return 0; 331 | } 332 | 333 | if ( (type & RKUSB_MASKROM) == 0 ) { 334 | for ( iter = m_list.begin(); iter != m_list.end(); ) { 335 | if( (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) && (((*iter).usbcdUsb & 0x1) == 0) ) { 336 | if ((*iter).pUsbHandle) { 337 | libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 338 | (*iter).pUsbHandle = NULL; 339 | } 340 | iter = m_list.erase(iter); 341 | uiTotalDevice--; 342 | } else { 343 | iter++; 344 | continue; 345 | } 346 | } 347 | } 348 | if (m_list.size() <= 0) { 349 | return 0; 350 | } 351 | 352 | if ( (type & RKUSB_LOADER) == 0 ) { 353 | for ( iter = m_list.begin(); iter != m_list.end(); ) { 354 | if( (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) && (((*iter).usbcdUsb & 0x1) == 1) ) { 355 | if ((*iter).pUsbHandle) { 356 | libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 357 | (*iter).pUsbHandle = NULL; 358 | } 359 | iter = m_list.erase(iter); 360 | uiTotalDevice--; 361 | } else { 362 | iter++; 363 | continue; 364 | } 365 | } 366 | } 367 | if (m_list.size() <= 0) { 368 | return 0; 369 | } 370 | 371 | if ( (type & RKUSB_MSC) == 0 ) { 372 | for ( iter = m_list.begin(); iter != m_list.end(); ) { 373 | if(FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1) { 374 | if ((*iter).pUsbHandle) { 375 | libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 376 | (*iter).pUsbHandle = NULL; 377 | } 378 | iter = m_list.erase(iter); 379 | uiTotalDevice--; 380 | } else { 381 | iter++; 382 | continue; 383 | } 384 | } 385 | } 386 | if (m_list.size() <= 0) { 387 | return 0; 388 | } 389 | 390 | for ( iter = m_list.begin(); iter != m_list.end(); iter++ ) { 391 | if (FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1) { 392 | (*iter).emUsbType = RKUSB_MSC; 393 | } else { 394 | USHORT usTemp; 395 | usTemp = (*iter).usbcdUsb; 396 | usTemp= usTemp & 0x1; 397 | if ( usTemp == 0 ) 398 | (*iter).emUsbType = RKUSB_MASKROM; 399 | else 400 | (*iter).emUsbType = RKUSB_LOADER; 401 | } 402 | } 403 | return m_list.size(); 404 | } 405 | bool CRKScan::MutexWait(UINT_VECTOR &vecExistedDevice, STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid, USHORT usPid) 406 | { 407 | device_list_iter iter; 408 | int uiWaitSecond; 409 | int iFoundCount = 0; 410 | UINT iRet,i; 411 | bool bFound = false; 412 | if (usbType == RKUSB_MSC) 413 | uiWaitSecond = m_waitMscSecond; 414 | else 415 | uiWaitSecond = m_waitRKusbSecond; 416 | time_t tmInit, tmNow; 417 | time(&tmInit); 418 | device.uiLocationID = 0; 419 | while( difftime(time(&tmNow), tmInit) <= uiWaitSecond ) { 420 | iRet = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC); 421 | if ( iRet == vecExistedDevice.size() + 1 ) { 422 | for (i = 0; i < vecExistedDevice.size(); i++) { 423 | for (iter = m_list.begin(); iter != m_list.end(); ) { 424 | if ((*iter).uiLocationID == vecExistedDevice[i]) { 425 | iter = m_list.erase(iter); 426 | } else 427 | iter++; 428 | } 429 | } 430 | if (m_list.size() != 1) { 431 | device.uiLocationID = 0; 432 | iFoundCount = 0; 433 | } else { 434 | iter = m_list.begin(); 435 | if (device.uiLocationID == 0) { 436 | iFoundCount++; 437 | device.uiLocationID = (*iter).uiLocationID; 438 | } else { 439 | if (device.uiLocationID == (*iter).uiLocationID) { 440 | iFoundCount++; 441 | } else { 442 | device.uiLocationID = 0; 443 | iFoundCount = 0; 444 | } 445 | } 446 | } 447 | } else { 448 | device.uiLocationID = 0; 449 | iFoundCount = 0; 450 | } 451 | if (iFoundCount >= 10) { 452 | bFound = true; 453 | break; 454 | } 455 | } 456 | if (!bFound) { 457 | return false; 458 | } 459 | bFound = Wait(device, usbType, usVid, usPid); 460 | return bFound; 461 | } 462 | 463 | bool CRKScan::MutexWaitPrepare(UINT_VECTOR &vecExistedDevice, DWORD uiOfflineDevice) 464 | { 465 | int iRet, iRet2; 466 | device_list_iter iter; 467 | time_t timeInit, timeNow; 468 | time(&timeInit); 469 | iRet = iRet2 =0; 470 | while ((time(&timeNow) - timeInit) <= 3) { 471 | iRet = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC); 472 | usleep(20000); 473 | iRet2 = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC); 474 | if (iRet2 == iRet) { 475 | break; 476 | } 477 | } 478 | if ((iRet <= 0) || (iRet2 != iRet)) { 479 | return false; 480 | } 481 | vecExistedDevice.clear(); 482 | bool bFound = false; 483 | for ( iter = m_list.begin(); iter != m_list.end(); iter++ ) { 484 | if ((*iter).uiLocationID != uiOfflineDevice) { 485 | vecExistedDevice.push_back((*iter).uiLocationID); 486 | } else 487 | bFound = true; 488 | } 489 | if (!bFound) { 490 | return false; 491 | } 492 | return true; 493 | 494 | } 495 | 496 | bool CRKScan::Wait(STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid, USHORT usPid) 497 | { 498 | RKDEVICE_DESC_SET deviceList; 499 | ENUM_RKUSB_TYPE curDeviceType; 500 | ENUM_RKDEVICE_TYPE devType; 501 | device_list_iter iter; 502 | UINT totalDevice; 503 | int uiWaitSecond; 504 | int iFoundCount = 0; 505 | bool bRet = false; 506 | if (usbType == RKUSB_MSC) 507 | uiWaitSecond = m_waitMscSecond; 508 | else 509 | uiWaitSecond = m_waitRKusbSecond; 510 | time_t tmInit, tmNow; 511 | time(&tmInit); 512 | while( difftime(time(&tmNow), tmInit) <= uiWaitSecond ) { 513 | FreeDeviceList(deviceList); 514 | EnumerateUsbDevice(deviceList, totalDevice); 515 | for ( iter = deviceList.begin(); iter != deviceList.end(); iter++ ) { 516 | if ((BUSID((*iter).uiLocationID) != BUSID(device.uiLocationID)) || 517 | ((BUSID((*iter).uiLocationID) == BUSID(device.uiLocationID)) && ((*iter).uiLocationID >= device.uiLocationID))) { 518 | if ((usVid != 0) || (usPid != 0)) { 519 | if ( ((*iter).usVid != usVid) || ((*iter).usPid != usPid) ) 520 | continue; 521 | } 522 | if (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) { 523 | if ( ((*iter).usbcdUsb & 0x0001) == 0 ) 524 | curDeviceType = RKUSB_MASKROM; 525 | else 526 | curDeviceType = RKUSB_LOADER; 527 | } else if ( FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1 ) { 528 | curDeviceType = RKUSB_MSC; 529 | } else 530 | curDeviceType = RKUSB_NONE; 531 | 532 | if ( curDeviceType == usbType ) { 533 | iFoundCount++; 534 | break; 535 | } 536 | } 537 | } 538 | if ( iter == deviceList.end() ) { 539 | iFoundCount = 0; 540 | } 541 | if ( iFoundCount >= 8 ) { 542 | device.usVid = (*iter).usVid; 543 | device.usPid = (*iter).usPid; 544 | device.uiLocationID = (*iter).uiLocationID; 545 | device.pUsbHandle= (*iter).pUsbHandle; 546 | device.emUsbType = usbType; 547 | device.usbcdUsb = (*iter).usbcdUsb; 548 | libusb_ref_device((libusb_device *)device.pUsbHandle); 549 | 550 | if (usbType == RKUSB_MSC) { 551 | device.emDeviceType = RKNONE_DEVICE; 552 | } else { 553 | if (IsRockusbDevice(devType, device.usVid, device.usPid)) 554 | device.emDeviceType = devType; 555 | } 556 | bRet = true; 557 | break; 558 | } 559 | usleep(50000); 560 | } 561 | 562 | FreeDeviceList(deviceList); 563 | return bRet; 564 | } 565 | int CRKScan::GetPos(UINT locationID) 566 | { 567 | device_list_iter iter; 568 | int pos = 0; 569 | bool bFound = false; 570 | for (iter = m_list.begin(); iter != m_list.end(); iter++) { 571 | if (locationID == (*iter).uiLocationID) { 572 | bFound=true; 573 | break; 574 | } 575 | pos++; 576 | } 577 | return (bFound ? pos : -1); 578 | } 579 | bool CRKScan::GetDevice(STRUCT_RKDEVICE_DESC &device, int pos) 580 | { 581 | if ( (pos < 0) || (pos >= (int)m_list.size()) ) { 582 | return false; 583 | } 584 | device_list_iter iter; 585 | for (iter = m_list.begin(); iter != m_list.end(); iter++) { 586 | if (pos == 0) { 587 | break; 588 | } 589 | pos--; 590 | } 591 | device.usVid = (*iter).usVid; 592 | device.usPid = (*iter).usPid; 593 | device.emDeviceType = (*iter).emDeviceType; 594 | device.emUsbType = (*iter).emUsbType; 595 | device.uiLocationID = (*iter).uiLocationID; 596 | device.pUsbHandle= (*iter).pUsbHandle; 597 | device.usbcdUsb = (*iter).usbcdUsb; 598 | return true; 599 | } 600 | 601 | bool CRKScan::SetLogObject(CRKLog *pLog) 602 | { 603 | if (pLog) { 604 | if (m_log) { 605 | delete m_log; 606 | } 607 | m_log = pLog; 608 | } else 609 | return false; 610 | return true; 611 | } 612 | CRKScan::~CRKScan() 613 | { 614 | FreeDeviceList(m_list); 615 | if (m_log) { 616 | delete m_log; 617 | m_log = NULL; 618 | } 619 | } 620 | -------------------------------------------------------------------------------- /RKScan.h: -------------------------------------------------------------------------------- 1 | #ifndef RKSCAN_HEADER 2 | #define RKSCAN_HEADER 3 | #include "DefineHeader.h" 4 | #include "RKLog.h" 5 | 6 | typedef struct { 7 | USHORT usVid; 8 | USHORT usPid; 9 | ENUM_RKDEVICE_TYPE emDeviceType; 10 | } STRUCT_DEVICE_CONFIG, *PSTRUCT_DEVICE_CONFIG; 11 | 12 | typedef vector RKDEVICE_CONFIG_SET; 13 | class CRKScan 14 | { 15 | public: 16 | UINT GetMSC_TIMEOUT(); 17 | void SetMSC_TIMEOUT(UINT value); 18 | property MSC_TIMEOUT; 19 | 20 | UINT GetRKUSB_TIMEOUT(); 21 | void SetRKUSB_TIMEOUT(UINT value); 22 | property RKUSB_TIMEOUT; 23 | 24 | int GetDEVICE_COUNTS(); 25 | property DEVICE_COUNTS; 26 | 27 | CRKScan(UINT uiMscTimeout = 30, UINT uiRKusbTimeout = 20); 28 | void SetVidPid(USHORT mscVid = 0, USHORT mscPid = 0); 29 | void AddRockusbVidPid(USHORT newVid, USHORT newPid, USHORT oldVid, USHORT oldPid); 30 | bool FindRockusbVidPid(ENUM_RKDEVICE_TYPE type, USHORT &usVid, USHORT &usPid); 31 | int Search(UINT type); 32 | bool Wait(STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid = 0, USHORT usPid = 0); 33 | bool MutexWaitPrepare(UINT_VECTOR &vecExistedDevice, DWORD uiOfflineDevice); 34 | bool MutexWait(UINT_VECTOR &vecExistedDevice, STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid = 0, USHORT usPid = 0); 35 | int GetPos(UINT locationID); 36 | bool GetDevice(STRUCT_RKDEVICE_DESC &device, int pos); 37 | bool SetLogObject(CRKLog *pLog); 38 | ~CRKScan(); 39 | private: 40 | UINT m_waitRKusbSecond; 41 | UINT m_waitMscSecond; 42 | CRKLog *m_log; 43 | RKDEVICE_DESC_SET m_list; 44 | RKDEVICE_CONFIG_SET m_deviceConfigSet; 45 | RKDEVICE_CONFIG_SET m_deviceMscConfigSet; 46 | int FindConfigSetPos(RKDEVICE_CONFIG_SET &devConfigSet, USHORT vid, USHORT pid); 47 | int FindWaitSetPos(const RKDEVICE_CONFIG_SET &waitDeviceSet, USHORT vid, USHORT pid); 48 | void EnumerateUsbDevice(RKDEVICE_DESC_SET &list, UINT &uiTotalMatchDevices); 49 | void FreeDeviceList(RKDEVICE_DESC_SET &list); 50 | bool IsRockusbDevice(ENUM_RKDEVICE_TYPE &type, USHORT vid, USHORT pid); 51 | }; 52 | #endif -------------------------------------------------------------------------------- /Readme.txt: -------------------------------------------------------------------------------- 1 | rkdeveloptool gives you a simple way to read/write rockusb device.let's start. 2 | 3 | compile and install 4 | 1. install libusb and libudev 5 | sudo apt-get install libudev-dev libusb-1.0-0-dev dh-autoreconf 6 | 2. go into root of rkdeveloptool 7 | 3. ./autogen.sh 8 | 4. ./configure 9 | 5. make 10 | 11 | rkdeveloptool usage,input "rkdeveloptool -h" to see 12 | 13 | example: 14 | 1.download kernel.img 15 | sudo ./rkdeveloptool db RKXXLoader.bin //download usbplug to device 16 | sudo ./rkdeveloptool wl 0x8000 kernel.img //0x8000 is base of kernel partition,unit is sector. 17 | sudo ./rkdeveloptool rd //reset device 18 | 19 | compile error help 20 | if you encounter the error like below: 21 | ./configure: line 4269: syntax error near unexpected token `LIBUSB1,libusb-1.0' 22 | ./configure: line 4269: `PKG_CHECK_MODULES(LIBUSB1,libusb-1.0)' 23 | 24 | You should install pkg-config libusb-1.0: 25 | sudo apt-get install pkg-config libusb-1.0 26 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | autoreconf --force --install 3 | -------------------------------------------------------------------------------- /boot_merger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd 3 | * 4 | * SPDX-License-Identifier: GPL-2.0+ 5 | */ 6 | #ifndef BOOT_MERGER_H 7 | #define BOOT_MERGER_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | 17 | #define SCANF_EAT(in) fscanf(in, "%*[ \r\n\t/]")//, gEat) 18 | #define MAX_LINE_LEN 256 19 | 20 | typedef char line_t[MAX_LINE_LEN]; 21 | 22 | 23 | 24 | #define DEF_CONFIG_FILE "config.ini" 25 | 26 | #define DEF_MAJOR 2 27 | #define DEF_MINOR 30 28 | #define DEF_CHIP "RK320A" 29 | #define DEF_CODE471_NUM 1 30 | #define DEF_CODE472_NUM 1 31 | #define DEF_CODE471_SLEEP 0 32 | #define DEF_CODE472_SLEEP 0 33 | #define DEF_CODE471_PATH "rk3288_ddr_400MHZ_v1.01.bin" 34 | #define DEF_CODE472_PATH "rk3288_usbplug_v2.32.bin" 35 | #define DEF_LOADER_NUM 2 36 | #define DEF_LOADER0 "FlashData" 37 | #define DEF_LOADER0_PATH "rk3288_ddr_400MHZ_v1.01.bin" 38 | #define DEF_LOADER1 "FlashBoot" 39 | #define DEF_LOADER1_PATH "u-boot.bin" 40 | #define DEF_OUT_PATH "rk3288_bootloader_test.bin" 41 | 42 | #define OUT_SUBFIX ".bin" 43 | 44 | #define SEC_CHIP "[CHIP_NAME]" 45 | #define SEC_VERSION "[VERSION]" 46 | #define SEC_471 "[CODE471_OPTION]" 47 | #define SEC_472 "[CODE472_OPTION]" 48 | #define SEC_LOADER "[LOADER_OPTION]" 49 | #define SEC_OUT "[OUTPUT]" 50 | 51 | #define OPT_NAME "NAME" 52 | #define OPT_MAJOR "MAJOR" 53 | #define OPT_MINOR "MINOR" 54 | #define OPT_NUM "NUM" 55 | #define OPT_LOADER_NUM "LOADERCOUNT" 56 | #define OPT_PATH "Path" 57 | #define OPT_SLEEP "Sleep" 58 | #define OPT_LOADER_NAME "LOADER" 59 | #define OPT_OUT_PATH "PATH" 60 | 61 | typedef struct { 62 | char name[MAX_LINE_LEN]; 63 | char path[MAX_LINE_LEN]; 64 | } name_entry; 65 | 66 | typedef struct { 67 | int major; 68 | int minor; 69 | char chip[MAX_LINE_LEN]; 70 | int code471Sleep; 71 | int code472Sleep; 72 | int code471Num; 73 | int code472Num; 74 | line_t* code471Path; 75 | line_t* code472Path; 76 | int loaderNum; 77 | name_entry* loader; 78 | char outPath[MAX_LINE_LEN]; 79 | } options; 80 | 81 | 82 | #define TAG 0x544F4F42 83 | #define MERGER_VERSION 0x01030000 84 | #define SMALL_PACKET 512 85 | 86 | #define MAX_NAME_LEN 20 87 | #define MAX_MERGE_SIZE (1024 << 10) 88 | 89 | #define SEC_CHIP_TYPES "[CHIP_TYPES]" 90 | 91 | #define CHIP_RK28 "RK28" 92 | #define CHIP_RK281X "RK281X" 93 | #define CHIP_RKPANDA "RKPANDA" 94 | #define CHIP_RK27 "RK27" 95 | #define CHIP_RKNANO "RKNANO" 96 | #define CHIP_RKSMART "RKSMART" 97 | #define CHIP_RKCROWN "RKCROWN" 98 | #define CHIP_RKCAYMAN "RKCAYMAN" 99 | #define CHIP_RK29 "RK29" 100 | #define CHIP_RK292X "RK292X" 101 | #define CHIP_RK30 "RK30" 102 | #define CHIP_RK30B "RK30B" 103 | #define CHIP_RK31 "RK31" 104 | #define CHIP_RK32 "RK32" 105 | 106 | typedef enum { 107 | ENTRY_471 =1, 108 | ENTRY_472 =2, 109 | ENTRY_LOADER =4, 110 | } rk_entry_type; 111 | 112 | #pragma pack(1) 113 | typedef struct { 114 | uint16_t year; 115 | uint8_t month; 116 | uint8_t day; 117 | uint8_t hour; 118 | uint8_t minute; 119 | uint8_t second; 120 | } rk_time; 121 | 122 | #define BOOT_RESERVED_SIZE 57 123 | typedef struct { 124 | uint32_t tag; 125 | uint16_t size; 126 | uint32_t version; 127 | uint32_t mergerVersion; 128 | rk_time releaseTime; 129 | uint32_t chipType; 130 | uint8_t code471Num; 131 | uint32_t code471Offset; 132 | uint8_t code471Size; 133 | uint8_t code472Num; 134 | uint32_t code472Offset; 135 | uint8_t code472Size; 136 | uint8_t loaderNum; 137 | uint32_t loaderOffset; 138 | uint8_t loaderSize; 139 | uint8_t signFlag; 140 | uint8_t rc4Flag; 141 | uint8_t reserved[BOOT_RESERVED_SIZE]; 142 | } rk_boot_header; 143 | 144 | typedef struct { 145 | uint8_t size; 146 | rk_entry_type type; 147 | uint16_t name[MAX_NAME_LEN]; 148 | uint32_t dataOffset; 149 | uint32_t dataSize; 150 | uint32_t dataDelay; 151 | } rk_boot_entry; 152 | #pragma pack() 153 | 154 | #endif// BOOT_MERGER_H 155 | -------------------------------------------------------------------------------- /cfg/.gitignore: -------------------------------------------------------------------------------- 1 | compile 2 | config* 3 | depcomp 4 | install* 5 | missing 6 | stamp* 7 | -------------------------------------------------------------------------------- /cfg/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2017 Trevor Woerner 2 | 3 | ######################## 4 | # cfg/Makefile.am 5 | ######################## 6 | SUBDIRS = 7 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | // the configured options and settings for RKDevelopTool_Mac 2 | #define PACKAGE_VERSION "@RKDevelopTool_Mac_PACKAGE_VERSION@" 3 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockchip-linux/rkdeveloptool/304f073752fd25c854e1bcf05d8e7f925b1f4e14/config.ini -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | dnl Copyright (C) 2017 Trevor Woerner 2 | 3 | AC_INIT([Rockchip rkdeveloptool], 1.32, [Eddie Cai ], rkdeveloptool) 4 | AC_PREREQ([2.68]) 5 | AC_CONFIG_SRCDIR(main.cpp) 6 | AC_CONFIG_AUX_DIR(cfg) 7 | AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-bzip2 1.9]) 8 | AM_CONFIG_HEADER(cfg/config.h) 9 | 10 | SUBDIRS="" 11 | 12 | AC_PROG_CPP 13 | AC_PROG_CXX 14 | AC_PROG_CXXCPP 15 | AC_PROG_MAKE_SET 16 | AC_PROG_INSTALL 17 | AC_PROG_LN_S 18 | 19 | AC_CANONICAL_HOST 20 | case "$host_os" in 21 | freebsd*) 22 | CPPFLAGS="$CFLAGS -I/usr/local/include" 23 | LDFLAGS="$LDFLAGS -L/usr/local/lib" 24 | ;; 25 | openbsd*) 26 | CPPFLAGS="$CFLAGS -I/usr/local/include" 27 | LDFLAGS="$LDFLAGS -L/usr/local/lib" 28 | ;; 29 | *) 30 | ;; 31 | esac 32 | 33 | 34 | PKG_CHECK_MODULES(LIBUSB1,libusb-1.0) 35 | 36 | AC_CONFIG_FILES([Makefile]) 37 | 38 | AC_OUTPUT 39 | -------------------------------------------------------------------------------- /crc.cpp: -------------------------------------------------------------------------------- 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 | #include "DefineHeader.h" 8 | UINT gTable_Crc32[256] = 9 | {//crc32 factor 0x04C10DB7 10 | 0x00000000, 0x04c10db7, 0x09821b6e, 0x0d4316d9, 11 | 0x130436dc, 0x17c53b6b, 0x1a862db2, 0x1e472005, 12 | 0x26086db8, 0x22c9600f, 0x2f8a76d6, 0x2b4b7b61, 13 | 0x350c5b64, 0x31cd56d3, 0x3c8e400a, 0x384f4dbd, 14 | 0x4c10db70, 0x48d1d6c7, 0x4592c01e, 0x4153cda9, 15 | 0x5f14edac, 0x5bd5e01b, 0x5696f6c2, 0x5257fb75, 16 | 0x6a18b6c8, 0x6ed9bb7f, 0x639aada6, 0x675ba011, 17 | 0x791c8014, 0x7ddd8da3, 0x709e9b7a, 0x745f96cd, 18 | 0x9821b6e0, 0x9ce0bb57, 0x91a3ad8e, 0x9562a039, 19 | 0x8b25803c, 0x8fe48d8b, 0x82a79b52, 0x866696e5, 20 | 0xbe29db58, 0xbae8d6ef, 0xb7abc036, 0xb36acd81, 21 | 0xad2ded84, 0xa9ece033, 0xa4aff6ea, 0xa06efb5d, 22 | 0xd4316d90, 0xd0f06027, 0xddb376fe, 0xd9727b49, 23 | 0xc7355b4c, 0xc3f456fb, 0xceb74022, 0xca764d95, 24 | 0xf2390028, 0xf6f80d9f, 0xfbbb1b46, 0xff7a16f1, 25 | 0xe13d36f4, 0xe5fc3b43, 0xe8bf2d9a, 0xec7e202d, 26 | 0x34826077, 0x30436dc0, 0x3d007b19, 0x39c176ae, 27 | 0x278656ab, 0x23475b1c, 0x2e044dc5, 0x2ac54072, 28 | 0x128a0dcf, 0x164b0078, 0x1b0816a1, 0x1fc91b16, 29 | 0x018e3b13, 0x054f36a4, 0x080c207d, 0x0ccd2dca, 30 | 0x7892bb07, 0x7c53b6b0, 0x7110a069, 0x75d1adde, 31 | 0x6b968ddb, 0x6f57806c, 0x621496b5, 0x66d59b02, 32 | 0x5e9ad6bf, 0x5a5bdb08, 0x5718cdd1, 0x53d9c066, 33 | 0x4d9ee063, 0x495fedd4, 0x441cfb0d, 0x40ddf6ba, 34 | 0xaca3d697, 0xa862db20, 0xa521cdf9, 0xa1e0c04e, 35 | 0xbfa7e04b, 0xbb66edfc, 0xb625fb25, 0xb2e4f692, 36 | 0x8aabbb2f, 0x8e6ab698, 0x8329a041, 0x87e8adf6, 37 | 0x99af8df3, 0x9d6e8044, 0x902d969d, 0x94ec9b2a, 38 | 0xe0b30de7, 0xe4720050, 0xe9311689, 0xedf01b3e, 39 | 0xf3b73b3b, 0xf776368c, 0xfa352055, 0xfef42de2, 40 | 0xc6bb605f, 0xc27a6de8, 0xcf397b31, 0xcbf87686, 41 | 0xd5bf5683, 0xd17e5b34, 0xdc3d4ded, 0xd8fc405a, 42 | 0x6904c0ee, 0x6dc5cd59, 0x6086db80, 0x6447d637, 43 | 0x7a00f632, 0x7ec1fb85, 0x7382ed5c, 0x7743e0eb, 44 | 0x4f0cad56, 0x4bcda0e1, 0x468eb638, 0x424fbb8f, 45 | 0x5c089b8a, 0x58c9963d, 0x558a80e4, 0x514b8d53, 46 | 0x25141b9e, 0x21d51629, 0x2c9600f0, 0x28570d47, 47 | 0x36102d42, 0x32d120f5, 0x3f92362c, 0x3b533b9b, 48 | 0x031c7626, 0x07dd7b91, 0x0a9e6d48, 0x0e5f60ff, 49 | 0x101840fa, 0x14d94d4d, 0x199a5b94, 0x1d5b5623, 50 | 0xf125760e, 0xf5e47bb9, 0xf8a76d60, 0xfc6660d7, 51 | 0xe22140d2, 0xe6e04d65, 0xeba35bbc, 0xef62560b, 52 | 0xd72d1bb6, 0xd3ec1601, 0xdeaf00d8, 0xda6e0d6f, 53 | 0xc4292d6a, 0xc0e820dd, 0xcdab3604, 0xc96a3bb3, 54 | 0xbd35ad7e, 0xb9f4a0c9, 0xb4b7b610, 0xb076bba7, 55 | 0xae319ba2, 0xaaf09615, 0xa7b380cc, 0xa3728d7b, 56 | 0x9b3dc0c6, 0x9ffccd71, 0x92bfdba8, 0x967ed61f, 57 | 0x8839f61a, 0x8cf8fbad, 0x81bbed74, 0x857ae0c3, 58 | 0x5d86a099, 0x5947ad2e, 0x5404bbf7, 0x50c5b640, 59 | 0x4e829645, 0x4a439bf2, 0x47008d2b, 0x43c1809c, 60 | 0x7b8ecd21, 0x7f4fc096, 0x720cd64f, 0x76cddbf8, 61 | 0x688afbfd, 0x6c4bf64a, 0x6108e093, 0x65c9ed24, 62 | 0x11967be9, 0x1557765e, 0x18146087, 0x1cd56d30, 63 | 0x02924d35, 0x06534082, 0x0b10565b, 0x0fd15bec, 64 | 0x379e1651, 0x335f1be6, 0x3e1c0d3f, 0x3add0088, 65 | 0x249a208d, 0x205b2d3a, 0x2d183be3, 0x29d93654, 66 | 0xc5a71679, 0xc1661bce, 0xcc250d17, 0xc8e400a0, 67 | 0xd6a320a5, 0xd2622d12, 0xdf213bcb, 0xdbe0367c, 68 | 0xe3af7bc1, 0xe76e7676, 0xea2d60af, 0xeeec6d18, 69 | 0xf0ab4d1d, 0xf46a40aa, 0xf9295673, 0xfde85bc4, 70 | 0x89b7cd09, 0x8d76c0be, 0x8035d667, 0x84f4dbd0, 71 | 0x9ab3fbd5, 0x9e72f662, 0x9331e0bb, 0x97f0ed0c, 72 | 0xafbfa0b1, 0xab7ead06, 0xa63dbbdf, 0xa2fcb668, 73 | 0xbcbb966d, 0xb87a9bda, 0xb5398d03, 0xb1f880b4, 74 | }; 75 | #define tole(x) (x) 76 | /*factor is 0xedb88320*/ 77 | unsigned int crc32table_le[] = { 78 | tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL), 79 | tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L), 80 | tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L), 81 | tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L), 82 | tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL), 83 | tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L), 84 | tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL), 85 | tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L), 86 | tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L), 87 | tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL), 88 | tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L), 89 | tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L), 90 | tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L), 91 | tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL), 92 | tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L), 93 | tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL), 94 | tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL), 95 | tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L), 96 | tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L), 97 | tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L), 98 | tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL), 99 | tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L), 100 | tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL), 101 | tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L), 102 | tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L), 103 | tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL), 104 | tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L), 105 | tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L), 106 | tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L), 107 | tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL), 108 | tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L), 109 | tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL), 110 | tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL), 111 | tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L), 112 | tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L), 113 | tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L), 114 | tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL), 115 | tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L), 116 | tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL), 117 | tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L), 118 | tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L), 119 | tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL), 120 | tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L), 121 | tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L), 122 | tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L), 123 | tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL), 124 | tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L), 125 | tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL), 126 | tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL), 127 | tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L), 128 | tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L), 129 | tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L), 130 | tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL), 131 | tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L), 132 | tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL), 133 | tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L), 134 | tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L), 135 | tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL), 136 | tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L), 137 | tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L), 138 | tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L), 139 | tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL), 140 | tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L), 141 | tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL) 142 | }; 143 | 144 | 145 | #define rr_max 104 /* Number of parity checks, rr = deg[g(x)] */ 146 | #define parallel 8 //bit count 147 | #define mm 13//limit count 148 | #define nn 8191//code size 149 | #define kk 4120//info length 150 | #define tt 8//correct count 151 | 152 | #define tt2 2*tt 153 | UINT s[tt2+1]; // Syndrome values 154 | 155 | UINT rr;//redundant length // BCH code parameters 156 | 157 | 158 | UINT p[mm + 1]; 159 | UINT alpha_to[nn+1], index_of[nn+1] ; // Galois field 160 | UINT gg[rr_max+1] ; // Generator polynomial 161 | 162 | UINT ggx1=0; 163 | UINT ggx2=0; 164 | UINT ggx3=0; 165 | UINT ggx4=0; 166 | 167 | // get crc32 value 168 | UINT CRC_32(unsigned char* pData, UINT ulSize) 169 | { 170 | UINT i; 171 | UINT nAccum = 0; 172 | 173 | for ( i = 0; i < ulSize; i++) 174 | nAccum = (nAccum << 8) ^ gTable_Crc32[(nAccum >> 24) ^ (*pData++)]; 175 | return nAccum; 176 | } 177 | #define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8) 178 | 179 | unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len) 180 | { 181 | /* 182 | UINT i; 183 | UINT nAccum = crc; 184 | 185 | for ( i = 0; i < len; i++) { 186 | nAccum = (nAccum >> 8) ^ crc32table_le[(nAccum ^ (*p)) & 0xFF]; 187 | p++; 188 | } 189 | return nAccum; 190 | */ 191 | unsigned int *b =(unsigned int *)p; 192 | unsigned int *tab = crc32table_le; 193 | crc = crc ^ 0xFFFFFFFF; 194 | if((((uintptr_t)b)&3 && len)){ 195 | do { 196 | unsigned char *p = (unsigned char *)b; 197 | DO_CRC(*p++); 198 | b = (unsigned int *)p; 199 | } while ((--len) && ((uintptr_t)b)&3 ); 200 | } 201 | if((len >= 4)){ 202 | unsigned int save_len = len & 3; 203 | len = len >> 2; 204 | --b; 205 | do { 206 | crc ^= *++b; 207 | DO_CRC(0); 208 | DO_CRC(0); 209 | DO_CRC(0); 210 | DO_CRC(0); 211 | } while (--len); 212 | b++; 213 | len = save_len; 214 | } 215 | if(len){ 216 | do { 217 | unsigned char *p = (unsigned char *)b; 218 | DO_CRC(*p++); 219 | b = (unsigned int *)p; 220 | } while (--len); 221 | } 222 | crc = crc ^ 0xFFFFFFFF; 223 | return crc; 224 | 225 | } 226 | 227 | #define CRC16_CCITT 0x1021 //CRC operator 228 | void CRCBuildTable16(unsigned short aPoly , unsigned short *crcTable) 229 | { 230 | unsigned short i, j; 231 | unsigned short nData; 232 | unsigned short nAccum; 233 | 234 | for (i = 0; i < 256; i++) 235 | { 236 | nData = (unsigned short)(i << 8); 237 | nAccum = 0; 238 | for (j = 0; j < 8; j++) 239 | { 240 | if ((nData ^ nAccum) & 0x8000) 241 | nAccum = (nAccum << 1) ^ aPoly; 242 | else 243 | nAccum <<= 1; 244 | nData <<= 1; 245 | } 246 | crcTable[i] = nAccum; 247 | } 248 | } 249 | 250 | unsigned short CRC_16(unsigned char* aData, UINT aSize) 251 | { 252 | UINT i; 253 | unsigned short nAccum = 0; 254 | unsigned short crcTable[256]; 255 | 256 | CRCBuildTable16(CRC16_CCITT , crcTable); 257 | for (i = 0; i < aSize; i++) 258 | nAccum = (nAccum << 8) ^ crcTable[(nAccum >> 8) ^ *aData++]; 259 | 260 | return nAccum; 261 | } 262 | 263 | void P_RC4(unsigned char* buf, unsigned short len) 264 | { 265 | unsigned char S[256],K[256],temp; 266 | unsigned short i,j,t,x; 267 | unsigned char key[16]={124,78,3,4,85,5,9,7,45,44,123,56,23,13,23,17}; 268 | 269 | j = 0; 270 | for(i=0; i<256; i++){ 271 | S[i] = (unsigned char)i; 272 | j&=0x0f; 273 | K[i] = key[j]; 274 | j++; 275 | } 276 | 277 | j = 0; 278 | for(i=0; i<256; i++){ 279 | j = (j + S[i] + K[i]) % 256; 280 | temp = S[i]; 281 | S[i] = S[j]; 282 | S[j] = temp; 283 | } 284 | 285 | i = j = 0; 286 | for(x=0; x>j) & 1); 311 | bch1=((bch1>>1)|((bch2&1)*0x80000000))^(ggx1*feed_back); 312 | bch2=((bch2>>1)|((bch3&1)*0x80000000))^(ggx2*feed_back); 313 | bch3=((bch3>>1)|((bch4&1)*0x80000000))^(ggx3*feed_back); 314 | bch4=(((bch4>>1)^(ggx4*feed_back))) | (feed_back*0x80); 315 | } 316 | } 317 | 318 | //********Handle FF*********************** 319 | bch1 = ~(bch1 ^ 0xad6273b1); 320 | bch2 = ~(bch2 ^ 0x348393d2); 321 | bch3 = ~(bch3 ^ 0xe6ebed3c); 322 | bch4 = ~(bch4 ^ 0xc8); 323 | //********************************************* 324 | 325 | for (i=0;i<515;i++) 326 | encode_out[i] = encode_in[i]; 327 | encode_out[515] = bch1&0x000000ff; 328 | encode_out[516] = (bch1&0x0000ff00)>>8; 329 | encode_out[517] = (bch1&0x00ff0000)>>16; 330 | encode_out[518] = (bch1&0xff000000)>>24; 331 | encode_out[519] = bch2&0x000000ff; 332 | encode_out[520] = (bch2&0x0000ff00)>>8; 333 | encode_out[521] = (bch2&0x00ff0000)>>16; 334 | encode_out[522] = (bch2&0xff000000)>>24; 335 | encode_out[523] = bch3&0x000000ff; 336 | encode_out[524] = (bch3&0x0000ff00)>>8; 337 | encode_out[525] = (bch3&0x00ff0000)>>16; 338 | encode_out[526] = (bch3&0xff000000)>>24; 339 | encode_out[527] = bch4&0x000000ff; 340 | } 341 | 342 | #define poly16_CCITT 0x1021 /* crc-ccitt mask */ 343 | 344 | unsigned short CRC_Calculate(unsigned short crc, unsigned char ch) 345 | { 346 | UINT i; 347 | for(i=0x80; i!=0; i>>=1) 348 | { 349 | if((crc & 0x8000) != 0) 350 | { 351 | crc <<= 1; 352 | crc ^= poly16_CCITT; 353 | } 354 | else 355 | crc <<= 1; 356 | if((ch & i)!=0) 357 | crc ^= poly16_CCITT; 358 | } 359 | return crc; 360 | } 361 | unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber) 362 | { 363 | unsigned short crc = 0xffff; 364 | while(CalculateNumber--) 365 | { 366 | crc = CRC_Calculate(crc, *p); 367 | p++; 368 | } 369 | return crc; 370 | } 371 | void gen_poly() 372 | { 373 | UINT gen_roots[nn + 1], gen_roots_true[nn + 1] ; // Roots of generator polynomial 374 | UINT i, j, Temp ; 375 | 376 | // Initialization of gen_roots 377 | for (i = 0; i <= nn; i++) 378 | { gen_roots_true[i] = 0; 379 | gen_roots[i] = 0; 380 | } 381 | 382 | // Cyclotomic cosets of gen_roots 383 | for (i = 1; i <= 2*tt ; i++) 384 | { 385 | for (j = 0; j < mm; j++) 386 | { 387 | Temp = ((1< 0; j--) 407 | if (gg[j] != 0) 408 | gg[j] = gg[j-1]^ alpha_to[(index_of[gg[j]] + index_of[alpha_to[gen_roots[i]]]) % nn] ; 409 | else 410 | gg[j] = gg[j-1] ; 411 | gg[0] = alpha_to[(index_of[gg[0]] + index_of[alpha_to[gen_roots[i]]]) % nn] ; 412 | } 413 | 414 | ggx1 = gg[103] | (gg[102]<<1) | (gg[101]<<2) | (gg[100]<<3) | (gg[99]<<4) |(gg[98]<<5)| (gg[97]<<6)|(gg[96]<<7) 415 | | (gg[95]<<8) | (gg[94]<<9) | (gg[93]<<10) | (gg[92]<<11) |(gg[91]<<12)| (gg[90]<<13)|(gg[89]<<14) |(gg[88]<<15) 416 | | (gg[87]<<16) | (gg[86]<<17) | (gg[85]<<18) | (gg[84]<<19) | (gg[83]<<20) |(gg[82]<<21)| (gg[81]<<22)|(gg[80]<<23) 417 | | (gg[79]<<24) | (gg[78]<<25) | (gg[77]<<26) | (gg[76]<<27) |(gg[75]<<28)| (gg[74]<<29)|(gg[73]<<30) |(gg[72]<<31); 418 | ggx2 = gg[71] | (gg[70]<<1) | (gg[69]<<2) | (gg[68]<<3) | (gg[67]<<4) |(gg[66]<<5)| (gg[65]<<6)|(gg[64]<<7) 419 | | (gg[63]<<8) | (gg[62]<<9) | (gg[61]<<10) | (gg[60]<<11) |(gg[59]<<12)| (gg[58]<<13)|(gg[57]<<14) |(gg[56]<<15) 420 | | (gg[55]<<16) | (gg[54]<<17) | (gg[53]<<18) | (gg[52]<<19) | (gg[51]<<20) |(gg[50]<<21)| (gg[49]<<22)|(gg[48]<<23) 421 | | (gg[47]<<24) | (gg[46]<<25) | (gg[45]<<26) | (gg[44]<<27) |(gg[43]<<28)| (gg[42]<<29)|(gg[41]<<30) |(gg[40]<<31); 422 | ggx3 = gg[39] | (gg[38]<<1) | (gg[37]<<2) | (gg[36]<<3) | (gg[35]<<4) |(gg[34]<<5)| (gg[33]<<6)|(gg[32]<<7) 423 | | (gg[31]<<8) | (gg[30]<<9) | (gg[29]<<10) | (gg[28]<<11) |(gg[27]<<12)| (gg[26]<<13)|(gg[25]<<14) |(gg[24]<<15) 424 | | (gg[23]<<16) | (gg[22]<<17) | (gg[21]<<18) | (gg[20]<<19) | (gg[19]<<20) |(gg[18]<<21)| (gg[17]<<22)|(gg[16]<<23) 425 | | (gg[15]<<24) | (gg[14]<<25) | (gg[13]<<26) | (gg[12]<<27) |(gg[11]<<28)| (gg[10]<<29)|(gg[9]<<30) |(gg[8]<<31); 426 | ggx4 = gg[7] | (gg[6]<<1) | (gg[5]<<2) | (gg[4]<<3) | (gg[3]<<4) |(gg[2]<<5)| (gg[1]<<6); 427 | 428 | } 429 | 430 | void generate_gf() 431 | { 432 | UINT i; 433 | UINT mask ; // Register states 434 | 435 | // Primitive polynomials 436 | for (i = 1; i < mm; i++) 437 | p[i] = 0; 438 | p[0] = p[mm] = 1; 439 | if (mm == 2) p[1] = 1; 440 | else if (mm == 3) p[1] = 1; 441 | else if (mm == 4) p[1] = 1; 442 | else if (mm == 5) p[2] = 1; 443 | else if (mm == 6) p[1] = 1; 444 | else if (mm == 7) p[1] = 1; 445 | else if (mm == 8) p[4] = p[5] = p[6] = 1; 446 | else if (mm == 9) p[4] = 1; 447 | else if (mm == 10) p[3] = 1; 448 | else if (mm == 11) p[2] = 1; 449 | else if (mm == 12) p[3] = p[4] = p[7] = 1; 450 | else if (mm == 13) p[1] = p[2] = p[3] = p[5] = p[7] = p[8] = p[10] = 1; // 25AF 451 | else if (mm == 14) p[2] = p[4] = p[6] = p[7] = p[8] = 1; // 41D5 452 | else if (mm == 15) p[1] = 1; 453 | else if (mm == 16) p[2] = p[3] = p[5] = 1; 454 | else if (mm == 17) p[3] = 1; 455 | else if (mm == 18) p[7] = 1; 456 | else if (mm == 19) p[1] = p[5] = p[6] = 1; 457 | else if (mm == 20) p[3] = 1; 458 | // Galois field implementation with shift registers 459 | // Ref: L&C, Chapter 6.7, pp. 217 460 | mask = 1 ; 461 | alpha_to[mm] = 0 ; 462 | for (i = 0; i < mm; i++) 463 | { 464 | alpha_to[i] = mask ; 465 | index_of[alpha_to[i]] = i ; 466 | if (p[i] != 0) 467 | alpha_to[mm] ^= mask ; 468 | mask <<= 1 ; 469 | } 470 | 471 | index_of[alpha_to[mm]] = mm ; 472 | mask >>= 1 ; 473 | for (i = mm + 1; i < nn; i++) 474 | { 475 | if (alpha_to[i-1] >= mask) 476 | alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1] ^ mask) << 1) ; 477 | else 478 | alpha_to[i] = alpha_to[i-1] << 1 ; 479 | 480 | index_of[alpha_to[i]] = i ; 481 | } 482 | index_of[0] = -1 ; 483 | } 484 | -------------------------------------------------------------------------------- /gpt.h: -------------------------------------------------------------------------------- 1 | #ifndef _GPT_H 2 | #define _GPT_H 3 | 4 | #define MSDOS_MBR_SIGNATURE 0xAA55 5 | #define EFI_PMBR_OSTYPE_EFI 0xEF 6 | #define EFI_PMBR_OSTYPE_EFI_GPT 0xEE 7 | 8 | #define GPT_HEADER_SIGNATURE 0x5452415020494645ULL 9 | #define GPT_HEADER_REVISION_V1 0x00010000 10 | #define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL 11 | #define GPT_ENTRY_NAME "gpt" 12 | #define GPT_ENTRY_NUMBERS 128 13 | #define GPT_ENTRY_SIZE 128 14 | #define PART_PROPERTY_BOOTABLE (1 << 2) 15 | 16 | #define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \ 17 | ((efi_guid_t) \ 18 | {{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ 19 | (b) & 0xff, ((b) >> 8) & 0xff, \ 20 | (c) & 0xff, ((c) >> 8) & 0xff, \ 21 | (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) 22 | 23 | #define PARTITION_IDBLOCK_GUID \ 24 | EFI_GUID(0xDA2BB095, 0x390E, 0x48ca, \ 25 | 0x90, 0x47, 0x05, 0xE8, 0x18, 0xB2, 0x97, 0xCE) 26 | 27 | typedef unsigned char u8; 28 | typedef unsigned short u16; 29 | typedef unsigned int u32; 30 | typedef unsigned long long u64; 31 | 32 | #define uswap_16(x) \ 33 | ((((x) & 0xff00) >> 8) | \ 34 | (((x) & 0x00ff) << 8)) 35 | #define uswap_32(x) \ 36 | ((((x) & 0xff000000) >> 24) | \ 37 | (((x) & 0x00ff0000) >> 8) | \ 38 | (((x) & 0x0000ff00) << 8) | \ 39 | (((x) & 0x000000ff) << 24)) 40 | #define _uswap_64(x, sfx) \ 41 | ((((x) & 0xff00000000000000##sfx) >> 56) | \ 42 | (((x) & 0x00ff000000000000##sfx) >> 40) | \ 43 | (((x) & 0x0000ff0000000000##sfx) >> 24) | \ 44 | (((x) & 0x000000ff00000000##sfx) >> 8) | \ 45 | (((x) & 0x00000000ff000000##sfx) << 8) | \ 46 | (((x) & 0x0000000000ff0000##sfx) << 24) | \ 47 | (((x) & 0x000000000000ff00##sfx) << 40) | \ 48 | (((x) & 0x00000000000000ff##sfx) << 56)) 49 | #if defined(__GNUC__) 50 | # define uswap_64(x) _uswap_64(x, ull) 51 | #else 52 | # define uswap_64(x) _uswap_64(x, ) 53 | #endif 54 | #define __LITTLE_ENDIAN__ 1 55 | #ifdef __LITTLE_ENDIAN__ 56 | # define cpu_to_le16(x) (x) 57 | # define cpu_to_le32(x) (x) 58 | # define cpu_to_le64(x) (x) 59 | # define le16_to_cpu(x) (x) 60 | # define le32_to_cpu(x) (x) 61 | # define le64_to_cpu(x) (x) 62 | # define cpu_to_be16(x) uswap_16(x) 63 | # define cpu_to_be32(x) uswap_32(x) 64 | # define cpu_to_be64(x) uswap_64(x) 65 | # define be16_to_cpu(x) uswap_16(x) 66 | # define be32_to_cpu(x) uswap_32(x) 67 | # define be64_to_cpu(x) uswap_64(x) 68 | #else 69 | # define cpu_to_le16(x) uswap_16(x) 70 | # define cpu_to_le32(x) uswap_32(x) 71 | # define cpu_to_le64(x) uswap_64(x) 72 | # define le16_to_cpu(x) uswap_16(x) 73 | # define le32_to_cpu(x) uswap_32(x) 74 | # define le64_to_cpu(x) uswap_64(x) 75 | # define cpu_to_be16(x) (x) 76 | # define cpu_to_be32(x) (x) 77 | # define cpu_to_be64(x) (x) 78 | # define be16_to_cpu(x) (x) 79 | # define be32_to_cpu(x) (x) 80 | # define be64_to_cpu(x) (x) 81 | #endif 82 | 83 | 84 | typedef union { 85 | struct { 86 | unsigned int time_low; 87 | unsigned short time_mid; 88 | unsigned short time_hi_and_version; 89 | unsigned char clock_seq_hi_and_reserved; 90 | unsigned char clock_seq_low; 91 | unsigned char node[6]; 92 | } uuid; 93 | u8 raw[16]; 94 | } efi_guid_t; 95 | #pragma pack(1) 96 | typedef struct { 97 | u16 usTag;/*0xEEEE*/ 98 | u16 usBackupGpt;/*0:no backup,1:has backup*/ 99 | u16 usEntryCount; 100 | u64 entryDataSize[32]; 101 | } gpt_compact_info; 102 | /* based on linux/include/genhd.h */ 103 | typedef struct { 104 | u8 boot_ind; /* 0x80 - active */ 105 | u8 head; /* starting head */ 106 | u8 sector; /* starting sector */ 107 | u8 cyl; /* starting cylinder */ 108 | u8 sys_ind; /* What partition type */ 109 | u8 end_head; /* end head */ 110 | u8 end_sector; /* end sector */ 111 | u8 end_cyl; /* end cylinder */ 112 | u32 start_sect; /* starting sector counting from 0 */ 113 | u32 nr_sects; /* nr of sectors in partition */ 114 | } mbr_partition ; 115 | 116 | /* based on linux/fs/partitions/efi.h */ 117 | typedef struct _gpt_header { 118 | u64 signature; 119 | u32 revision; 120 | u32 header_size; 121 | u32 header_crc32; 122 | u32 reserved1; 123 | u64 my_lba; 124 | u64 alternate_lba; 125 | u64 first_usable_lba; 126 | u64 last_usable_lba; 127 | efi_guid_t disk_guid; 128 | u64 partition_entry_lba; 129 | u32 num_partition_entries; 130 | u32 sizeof_partition_entry; 131 | u32 partition_entry_array_crc32; 132 | } gpt_header; 133 | 134 | typedef union _gpt_entry_attributes { 135 | struct { 136 | u64 required_to_function:1; 137 | u64 no_block_io_protocol:1; 138 | u64 legacy_bios_bootable:1; 139 | u64 reserved:45; 140 | u64 type_guid_specific:16; 141 | } fields; 142 | unsigned long long raw; 143 | } gpt_entry_attributes; 144 | 145 | #define PARTNAME_SZ 72 146 | typedef struct _gpt_entry { 147 | efi_guid_t partition_type_guid; 148 | efi_guid_t unique_partition_guid; 149 | u64 starting_lba; 150 | u64 ending_lba; 151 | gpt_entry_attributes attributes; 152 | u16 partition_name[PARTNAME_SZ / sizeof(u16)]; 153 | } gpt_entry; 154 | 155 | typedef struct _legacy_mbr { 156 | u8 boot_code[440]; 157 | u32 unique_mbr_signature; 158 | u16 unknown; 159 | mbr_partition partition_record[4]; 160 | u16 signature; 161 | } legacy_mbr; 162 | #pragma pack() 163 | #endif /* _GPT_H */ 164 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. -------------------------------------------------------------------------------- /parameter_gpt.txt: -------------------------------------------------------------------------------- 1 | FIRMWARE_VER: 6.0.0 2 | MACHINE_MODEL: RK3399 3 | MACHINE_ID: 007 4 | MANUFACTURER: RK3399 5 | MAGIC: 0x5041524B 6 | ATAG: 0x00200800 7 | MACHINE: 3399 8 | CHECK_MASK: 0x80 9 | PWR_HLD: 0,0,A,0,1 10 | #uuid:rootfs=00000000-0000-0000-0000-00000000 11 | #KERNEL_IMG: 0x00280000 12 | #FDT_NAME: rk-kernel.dtb 13 | #RECOVER_KEY: 1,1,0,20,0 14 | #in section; per section 512(0x200) bytes 15 | CMDLINE: mtdparts=rk29xxnand:0x00001f40@0x00000040(loader1),0x00000080@0x00001f80(reserved1),0x00002000@0x00002000(reserved2),0x00002000@0x00004000(loader2),0x00002000@0x00006000(atf),0x00038000@0x00008000(boot:bootable),-@0x0040000(rootfs:grow) 16 | --------------------------------------------------------------------------------