xref: /OK3568_Linux_fs/external/recovery/update_engine/rkboot.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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)&sector0Info);
238*4882a593Smuzhiyun     MakeSector1((PBYTE)&sector1Info);
239*4882a593Smuzhiyun     if (!MakeSector2((PBYTE)&sector2Info)) {
240*4882a593Smuzhiyun         return -6;
241*4882a593Smuzhiyun     }
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun     if (!MakeSector3((PBYTE)&sector3Info)) {
244*4882a593Smuzhiyun         return -7;
245*4882a593Smuzhiyun     }
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun     sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
248*4882a593Smuzhiyun     sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
249*4882a593Smuzhiyun     sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
250*4882a593Smuzhiyun     memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
251*4882a593Smuzhiyun     memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
252*4882a593Smuzhiyun     memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, 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, &sector2Info, 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