1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Licensed under the Apache License, Version 2.0 (the "License");
5*4882a593Smuzhiyun * you may not use this file except in compliance with the License.
6*4882a593Smuzhiyun * You may obtain a copy of the License at
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * http://www.apache.org/licenses/LICENSE-2.0
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Unless required by applicable law or agreed to in writing, software
11*4882a593Smuzhiyun * distributed under the License is distributed on an "AS IS" BASIS,
12*4882a593Smuzhiyun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4882a593Smuzhiyun * See the License for the specific language governing permissions and
14*4882a593Smuzhiyun * limitations under the License.
15*4882a593Smuzhiyun */
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #include <string.h>
18*4882a593Smuzhiyun #include <stdlib.h>
19*4882a593Smuzhiyun #include <sys/types.h>
20*4882a593Smuzhiyun #include <sys/stat.h>
21*4882a593Smuzhiyun #include <fcntl.h>
22*4882a593Smuzhiyun #include <unistd.h>
23*4882a593Smuzhiyun #include <errno.h>
24*4882a593Smuzhiyun #include <stdbool.h>
25*4882a593Smuzhiyun #include "rkimage.h"
26*4882a593Smuzhiyun #include "log.h"
27*4882a593Smuzhiyun #include "rktools.h"
28*4882a593Smuzhiyun #include "crc.h"
29*4882a593Smuzhiyun #include "../mtdutils/mtdutils.h"
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun USHORT m_usFlashDataSec;
33*4882a593Smuzhiyun USHORT m_usFlashBootSec;
34*4882a593Smuzhiyun DWORD m_dwLoaderSize;
35*4882a593Smuzhiyun DWORD m_dwLoaderDataSize;
36*4882a593Smuzhiyun DWORD uiSecNumPerIDB;
37*4882a593Smuzhiyun size_t uiFlashPageSize;
38*4882a593Smuzhiyun size_t uiFlashBlockSize;
39*4882a593Smuzhiyun USHORT usPhyBlokcPerIDB;
40*4882a593Smuzhiyun bool m_bRc4Disable;
41*4882a593Smuzhiyun DWORD m_idBlockOffset[IDB_BLOCKS];
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun long long m_FlashSize;
44*4882a593Smuzhiyun long long m_FlasBlockNum;
45*4882a593Smuzhiyun PSTRUCT_RKBOOT_HEAD pBootHead;
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun
CheckUid(BYTE uidSize,BYTE * pUid)48*4882a593Smuzhiyun static bool CheckUid(BYTE uidSize, BYTE *pUid)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun if (uidSize != RKDEVICE_UID_LEN) {
51*4882a593Smuzhiyun return false;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun USHORT oldCrc, newCrc;
54*4882a593Smuzhiyun oldCrc = *(USHORT *)(pUid + RKDEVICE_UID_LEN - 2);
55*4882a593Smuzhiyun newCrc = CRC_CCITT(pUid, RKDEVICE_UID_LEN - 2);
56*4882a593Smuzhiyun if (oldCrc != newCrc) {
57*4882a593Smuzhiyun return false;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun return true;
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun
UshortToBCD(USHORT num)62*4882a593Smuzhiyun static USHORT UshortToBCD(USHORT num)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun USHORT bcd = 0;
65*4882a593Smuzhiyun bcd = (num % 10) | ( ((num / 10 ) % 10) << 4 ) | ( ((num / 100) % 10) << 8) | ( ((num / 1000) % 10) << 12);
66*4882a593Smuzhiyun return bcd;
67*4882a593Smuzhiyun }
ByteToBCD(BYTE num)68*4882a593Smuzhiyun static BYTE ByteToBCD(BYTE num)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun BYTE bcd = 0;
71*4882a593Smuzhiyun bcd = (num % 10) | ( ((num / 10 ) % 10) << 4 );
72*4882a593Smuzhiyun return bcd;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
WCHAR_To_char(WCHAR * src,char * dst,int len)75*4882a593Smuzhiyun static void WCHAR_To_char(WCHAR *src, char *dst, int len)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun memset(dst, 0, len * sizeof(char));
78*4882a593Smuzhiyun for (int i = 0; i < len; i++) {
79*4882a593Smuzhiyun memcpy(dst, src, 1);
80*4882a593Smuzhiyun src++;
81*4882a593Smuzhiyun dst++;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun
getLoaderSizeAndData(char * loaderName,const unsigned char * data_buf,unsigned char ** loaderBuffer)85*4882a593Smuzhiyun static DWORD getLoaderSizeAndData(char * loaderName, const unsigned char * data_buf, unsigned char **loaderBuffer)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun DWORD dwOffset;
89*4882a593Smuzhiyun UCHAR ucCount, ucSize;
90*4882a593Smuzhiyun DWORD dwSize = 0;
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun dwOffset = pBootHead->dwLoaderEntryOffset;
93*4882a593Smuzhiyun ucCount = pBootHead->ucLoaderEntryCount;
94*4882a593Smuzhiyun ucSize = pBootHead->ucLoaderEntrySize;
95*4882a593Smuzhiyun for (UCHAR i = 0; i < ucCount; i++) {
96*4882a593Smuzhiyun PSTRUCT_RKBOOT_ENTRY pEntry;
97*4882a593Smuzhiyun pEntry = (PSTRUCT_RKBOOT_ENTRY)(data_buf + dwOffset + (ucSize * i));
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun char szName[20];
100*4882a593Smuzhiyun WCHAR_To_char(pEntry->szName, szName, 20);
101*4882a593Smuzhiyun if (strcmp(loaderName, szName) == 0) {
102*4882a593Smuzhiyun LOGI("pEntry->szName = %s.\n", szName);
103*4882a593Smuzhiyun dwSize = pEntry->dwDataSize;
104*4882a593Smuzhiyun *loaderBuffer = (unsigned char *)malloc(dwSize);
105*4882a593Smuzhiyun if (*loaderBuffer == NULL) {
106*4882a593Smuzhiyun LOGE("malloc error.\n");
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun memset(*loaderBuffer, 0, dwSize);
109*4882a593Smuzhiyun memcpy(*loaderBuffer, data_buf + pEntry->dwDataOffset, pEntry->dwDataSize);
110*4882a593Smuzhiyun LOGI("pEntry->dwDataOffset = %d, pEntry->dwDataSize = %d.\n", pEntry->dwDataOffset, pEntry->dwDataSize);
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun return dwSize;
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
FindValidBlocks(char bBegin,char bLen,PBYTE pblockState)117*4882a593Smuzhiyun static CHAR FindValidBlocks(char bBegin, char bLen, PBYTE pblockState)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun char bCount = 0;
120*4882a593Smuzhiyun char bIndex = bBegin;
121*4882a593Smuzhiyun while (bBegin < IDBLOCK_TOP) {
122*4882a593Smuzhiyun //if(0 == m_flashInfo.blockState[bBegin++])
123*4882a593Smuzhiyun if (0 == pblockState[bBegin++])
124*4882a593Smuzhiyun ++bCount;
125*4882a593Smuzhiyun else {
126*4882a593Smuzhiyun bCount = 0;
127*4882a593Smuzhiyun bIndex = bBegin;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun if (bCount >= bLen)
130*4882a593Smuzhiyun break;
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun if (bBegin >= IDBLOCK_TOP)
133*4882a593Smuzhiyun bIndex = -1;
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun return bIndex;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
MakeSector0(PBYTE pSector)138*4882a593Smuzhiyun static bool MakeSector0(PBYTE pSector)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun PRKANDROID_IDB_SEC0 pSec0;
141*4882a593Smuzhiyun memset(pSector, 0, SECTOR_SIZE);
142*4882a593Smuzhiyun pSec0 = (PRKANDROID_IDB_SEC0)pSector;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun pSec0->dwTag = 0x0FF0AA55;
145*4882a593Smuzhiyun if (m_bRc4Disable) {
146*4882a593Smuzhiyun pSec0->uiRc4Flag = 1;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun pSec0->usBootCode1Offset = 0x4;
149*4882a593Smuzhiyun pSec0->usBootCode2Offset = 0x4;
150*4882a593Smuzhiyun pSec0->usBootDataSize = m_usFlashDataSec;
151*4882a593Smuzhiyun pSec0->usBootCodeSize = m_usFlashDataSec + m_usFlashBootSec;
152*4882a593Smuzhiyun return true;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun
MakeSector1(PBYTE pSector)155*4882a593Smuzhiyun static void MakeSector1(PBYTE pSector)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun PRKANDROID_IDB_SEC1 pSec1;
158*4882a593Smuzhiyun memset(pSector, 0, SECTOR_SIZE);
159*4882a593Smuzhiyun pSec1 = (PRKANDROID_IDB_SEC1)pSector;
160*4882a593Smuzhiyun USHORT usSysReserved;
161*4882a593Smuzhiyun if ((m_idBlockOffset[4] + 1) % 12 == 0) {
162*4882a593Smuzhiyun usSysReserved = m_idBlockOffset[4] + 13;
163*4882a593Smuzhiyun } else {
164*4882a593Smuzhiyun usSysReserved = ((m_idBlockOffset[4] + 1) / 12 + 1) * 12;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun if (usSysReserved > IDBLOCK_TOP) {
167*4882a593Smuzhiyun usSysReserved = IDBLOCK_TOP;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun pSec1->usSysReservedBlock = usSysReserved;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun pSec1->usDisk0Size = 0;
173*4882a593Smuzhiyun pSec1->usDisk1Size = 0;
174*4882a593Smuzhiyun pSec1->usDisk2Size = 0;
175*4882a593Smuzhiyun pSec1->usDisk3Size = 0;
176*4882a593Smuzhiyun pSec1->uiChipTag = 0x38324B52;
177*4882a593Smuzhiyun pSec1->uiMachineId = 0;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun pSec1->usLoaderYear = UshortToBCD(pBootHead->stReleaseTime.usYear);
180*4882a593Smuzhiyun pSec1->usLoaderDate = ByteToBCD(pBootHead->stReleaseTime.ucMonth);
181*4882a593Smuzhiyun pSec1->usLoaderDate = (pSec1->usLoaderDate << 8) | ByteToBCD(pBootHead->stReleaseTime.ucDay);
182*4882a593Smuzhiyun pSec1->usLoaderVer = pBootHead->dwVersion;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun pSec1->usLastLoaderVer = 0;
185*4882a593Smuzhiyun pSec1->usReadWriteTimes = 1;
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun pSec1->uiFlashSize = m_FlashSize * 1024;
188*4882a593Smuzhiyun LOGI("m_FlashSize * 1024 = %lld.\n", m_FlashSize * 1024);
189*4882a593Smuzhiyun //pSec1->usBlockSize = m_flashInfo.usBlockSize*2;
190*4882a593Smuzhiyun //pSec1->bPageSize = m_flashInfo.uiPageSize*2;
191*4882a593Smuzhiyun //pSec1->bECCBits = m_flashInfo.bECCBits;
192*4882a593Smuzhiyun //pSec1->bAccessTime = m_flashInfo.bAccessTime;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun pSec1->usFlashInfoLen = 0;
195*4882a593Smuzhiyun pSec1->usFlashInfoOffset = 0;
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun pSec1->usIdBlock0 = m_idBlockOffset[0];
199*4882a593Smuzhiyun pSec1->usIdBlock1 = m_idBlockOffset[1];
200*4882a593Smuzhiyun pSec1->usIdBlock2 = m_idBlockOffset[2];
201*4882a593Smuzhiyun pSec1->usIdBlock3 = m_idBlockOffset[3];
202*4882a593Smuzhiyun pSec1->usIdBlock4 = m_idBlockOffset[4];
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
MakeSector2(PBYTE pSector)205*4882a593Smuzhiyun static bool MakeSector2(PBYTE pSector)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun PRKANDROID_IDB_SEC2 pSec2;
208*4882a593Smuzhiyun pSec2 = (PRKANDROID_IDB_SEC2)pSector;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun pSec2->usInfoSize = 0;
211*4882a593Smuzhiyun memset(pSec2->bChipInfo, 0, CHIPINFO_LEN);
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun memset(pSec2->reserved, 0, RKANDROID_SEC2_RESERVED_LEN);
214*4882a593Smuzhiyun pSec2->usSec3CustomDataOffset = 0;//debug
215*4882a593Smuzhiyun pSec2->usSec3CustomDataSize = 0;//debug
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun strcpy(pSec2->szVcTag, "VC");
218*4882a593Smuzhiyun strcpy(pSec2->szCrcTag, "CRC");
219*4882a593Smuzhiyun return true;
220*4882a593Smuzhiyun }
MakeSector3(PBYTE pSector)221*4882a593Smuzhiyun static bool MakeSector3(PBYTE pSector)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun PRKANDROID_IDB_SEC3 pSec3;
224*4882a593Smuzhiyun memset(pSector, 0, SECTOR_SIZE);
225*4882a593Smuzhiyun pSec3 = (PRKANDROID_IDB_SEC3)pSector;
226*4882a593Smuzhiyun return true;
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun
MakeIDBlockData(PBYTE lpIDBlock,PBYTE loaderCodeBuffer,PBYTE loaderDataBuffer)229*4882a593Smuzhiyun static int MakeIDBlockData(PBYTE lpIDBlock, PBYTE loaderCodeBuffer, PBYTE loaderDataBuffer)
230*4882a593Smuzhiyun {
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun RKANDROID_IDB_SEC0 sector0Info;
233*4882a593Smuzhiyun RKANDROID_IDB_SEC1 sector1Info;
234*4882a593Smuzhiyun RKANDROID_IDB_SEC2 sector2Info;
235*4882a593Smuzhiyun RKANDROID_IDB_SEC3 sector3Info;
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun MakeSector0((PBYTE)§or0Info);
238*4882a593Smuzhiyun MakeSector1((PBYTE)§or1Info);
239*4882a593Smuzhiyun if (!MakeSector2((PBYTE)§or2Info)) {
240*4882a593Smuzhiyun return -6;
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun if (!MakeSector3((PBYTE)§or3Info)) {
244*4882a593Smuzhiyun return -7;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE);
248*4882a593Smuzhiyun sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE);
249*4882a593Smuzhiyun sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE);
250*4882a593Smuzhiyun memcpy(lpIDBlock, §or0Info, SECTOR_SIZE);
251*4882a593Smuzhiyun memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE);
252*4882a593Smuzhiyun memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE);
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun //close rc4 encryption
255*4882a593Smuzhiyun if (sector0Info.uiRc4Flag) {
256*4882a593Smuzhiyun for (int i = 0; i < m_dwLoaderDataSize / SECTOR_SIZE; i++) {
257*4882a593Smuzhiyun P_RC4(loaderDataBuffer + SECTOR_SIZE * i, SECTOR_SIZE);
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun for (int i = 0; i < m_dwLoaderSize / SECTOR_SIZE; i++) {
260*4882a593Smuzhiyun P_RC4(loaderCodeBuffer + SECTOR_SIZE * i, SECTOR_SIZE);
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun memcpy(lpIDBlock + SECTOR_SIZE * 4, loaderDataBuffer, m_dwLoaderDataSize);
264*4882a593Smuzhiyun memcpy(lpIDBlock + SECTOR_SIZE * (4 + m_usFlashDataSec), loaderCodeBuffer, m_dwLoaderSize);
265*4882a593Smuzhiyun sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE, 0);
266*4882a593Smuzhiyun memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE);
267*4882a593Smuzhiyun for (int i = 0; i < 4; i++) {
268*4882a593Smuzhiyun if (i == 1) {
269*4882a593Smuzhiyun continue;
270*4882a593Smuzhiyun } else {
271*4882a593Smuzhiyun P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun return 0;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun
calcIDBCount()277*4882a593Smuzhiyun static void calcIDBCount()
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun uiSecNumPerIDB = 4 + m_usFlashDataSec + m_usFlashBootSec;
280*4882a593Smuzhiyun usPhyBlokcPerIDB = ((uiSecNumPerIDB > 0) ? ((uiSecNumPerIDB - 1) / 8 + 1) : (uiSecNumPerIDB));
281*4882a593Smuzhiyun LOGI("usPhyBlokcPerIDB = %d.\n", usPhyBlokcPerIDB);
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
reserveIDBlock()284*4882a593Smuzhiyun static int reserveIDBlock()
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun // 3. ReserveIDBlock
287*4882a593Smuzhiyun CHAR iRet;
288*4882a593Smuzhiyun char iBlockIndex = 0;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun BYTE blockState[IDBLOCK_TOP];
291*4882a593Smuzhiyun memset(m_idBlockOffset, 0, sizeof(DWORD)*IDB_BLOCKS);
292*4882a593Smuzhiyun memset(blockState, 0, IDBLOCK_TOP);
293*4882a593Smuzhiyun for (char i = 0; i < IDB_BLOCKS; i++) {
294*4882a593Smuzhiyun iRet = iBlockIndex = FindValidBlocks(iBlockIndex, usPhyBlokcPerIDB, blockState);
295*4882a593Smuzhiyun if (iRet < 0 ) {
296*4882a593Smuzhiyun return -1;
297*4882a593Smuzhiyun LOGE("FindValidBlocks Error.\n");
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun m_idBlockOffset[i] = iBlockIndex;
300*4882a593Smuzhiyun iBlockIndex += usPhyBlokcPerIDB;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun return 0;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun
WriteIDBlock(PBYTE lpIDBlock,DWORD dwSectorNum,char * dest_path)306*4882a593Smuzhiyun static int WriteIDBlock(PBYTE lpIDBlock, DWORD dwSectorNum, char *dest_path)
307*4882a593Smuzhiyun {
308*4882a593Smuzhiyun LOGE("WriteIDBlock start %s \n", dest_path);
309*4882a593Smuzhiyun // int fd_dest = open("/tmp/loader2.txt", O_RDWR|O_SYNC, 0);
310*4882a593Smuzhiyun int fd_dest = open(dest_path, O_CREAT | O_RDWR | O_SYNC | O_TRUNC, 0);
311*4882a593Smuzhiyun if (fd_dest < 0) {
312*4882a593Smuzhiyun LOGE("WriteIDBlock open %s failed. %s\n", dest_path, strerror(errno));
313*4882a593Smuzhiyun return -2;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun for (int i = 0; i <= 4; i++) {
317*4882a593Smuzhiyun //debug for 3308
318*4882a593Smuzhiyun //256 为128k 的起始位置
319*4882a593Smuzhiyun //每256k 备份一份
320*4882a593Smuzhiyun lseek64(fd_dest, (i * 512)*SECTOR_SIZE, SEEK_SET);
321*4882a593Smuzhiyun if (write(fd_dest, lpIDBlock, dwSectorNum * SECTOR_SIZE) != dwSectorNum * SECTOR_SIZE) {
322*4882a593Smuzhiyun close(fd_dest);
323*4882a593Smuzhiyun LOGE("[%s:%d] error (%s).\n", __func__, __LINE__, strerror(errno));
324*4882a593Smuzhiyun return -1;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun sync();
328*4882a593Smuzhiyun close(fd_dest);
329*4882a593Smuzhiyun return 0;
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun
download_loader(PBYTE data_buf,int size,char * dest_path)332*4882a593Smuzhiyun bool download_loader(PBYTE data_buf, int size, char *dest_path)
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun generate_gf();
335*4882a593Smuzhiyun gen_poly();
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun if (getFlashInfo(NULL, &uiFlashBlockSize, &uiFlashPageSize) != 0) {
338*4882a593Smuzhiyun LOGE("%s-%d: get mtd info error\n", __func__, __LINE__);
339*4882a593Smuzhiyun return false;
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun // 1. 获取头部信息,和文件内容
342*4882a593Smuzhiyun pBootHead = (PSTRUCT_RKBOOT_HEAD)(data_buf);
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun if (pBootHead->uiTag != 0x544F4F42 && pBootHead->uiTag != 0x2052444C) {
345*4882a593Smuzhiyun LOGE("pBootHead->uiTag!=0x544F4F42 && pBootHead->uiTag!=0x2052444C, cur is 0x%08x\n", pBootHead->uiTag );
346*4882a593Smuzhiyun return false;
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun if (pBootHead->ucRc4Flag) {
350*4882a593Smuzhiyun m_bRc4Disable = true;
351*4882a593Smuzhiyun } else {
352*4882a593Smuzhiyun m_bRc4Disable = false;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun char loaderDataName[] = "FlashData";
356*4882a593Smuzhiyun unsigned char *loaderDataBuffer = NULL;
357*4882a593Smuzhiyun m_dwLoaderDataSize = getLoaderSizeAndData(loaderDataName, data_buf, &loaderDataBuffer);
358*4882a593Smuzhiyun m_usFlashDataSec = PAGEALIGN(BYTE2SECTOR(m_dwLoaderDataSize)) * 4;
359*4882a593Smuzhiyun LOGI("m_usFlashDataSec = %d, m_dwLoaderDataSize = %d.\n", m_usFlashDataSec, m_dwLoaderDataSize);
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun char loaderName[] = "FlashBoot";
362*4882a593Smuzhiyun unsigned char *loaderCodeBuffer = NULL;
363*4882a593Smuzhiyun m_dwLoaderSize = getLoaderSizeAndData(loaderName, data_buf, &loaderCodeBuffer);
364*4882a593Smuzhiyun m_usFlashBootSec = PAGEALIGN(BYTE2SECTOR(m_dwLoaderSize)) * 4;
365*4882a593Smuzhiyun LOGI("m_usFlashBootSec = %d, m_dwLoaderSize = %d.\n", m_usFlashBootSec, m_dwLoaderSize);
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun calcIDBCount();
368*4882a593Smuzhiyun reserveIDBlock();
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun // 4. MakeIDBlockData
371*4882a593Smuzhiyun if (getFlashSize(dest_path, &m_FlashSize, &m_FlasBlockNum) != 0) {
372*4882a593Smuzhiyun LOGE("getFlashSize error.\n");
373*4882a593Smuzhiyun return false;
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun LOGI("[%s:%d] m_FlashSize [%lld]\n", __func__, __LINE__, m_FlashSize);
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun // 5. download IDBlock
378*4882a593Smuzhiyun PBYTE pIDBData = NULL;
379*4882a593Smuzhiyun pIDBData = (PBYTE)malloc(uiSecNumPerIDB * SECTOR_SIZE);
380*4882a593Smuzhiyun if ( !pIDBData )
381*4882a593Smuzhiyun return false;
382*4882a593Smuzhiyun memset(pIDBData, 0, uiSecNumPerIDB * SECTOR_SIZE);
383*4882a593Smuzhiyun if (MakeIDBlockData(pIDBData, loaderCodeBuffer, loaderDataBuffer) != 0 ) {
384*4882a593Smuzhiyun LOGE("[%s:%d] MakeIDBlockData failed.\n", __func__, __LINE__);
385*4882a593Smuzhiyun return false;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun if (WriteIDBlock(pIDBData, uiSecNumPerIDB, dest_path) != 0) {
389*4882a593Smuzhiyun LOGE("[%s:%d] WriteIDBlock failed.\n", __func__, __LINE__);
390*4882a593Smuzhiyun return false;
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun free(pIDBData);
393*4882a593Smuzhiyun free(loaderCodeBuffer);
394*4882a593Smuzhiyun free(loaderDataBuffer);
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun return true;
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun
399