xref: /OK3568_Linux_fs/external/recovery/update_engine/flash_image.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 <stdio.h>
18*4882a593Smuzhiyun #include <sys/types.h>
19*4882a593Smuzhiyun #include <unistd.h>
20*4882a593Smuzhiyun #include <sys/stat.h>
21*4882a593Smuzhiyun #include <fcntl.h>
22*4882a593Smuzhiyun #include <stdlib.h>
23*4882a593Smuzhiyun #include <string.h>
24*4882a593Smuzhiyun #include <errno.h>
25*4882a593Smuzhiyun #include <libgen.h>
26*4882a593Smuzhiyun #include <limits.h>
27*4882a593Smuzhiyun #include <stdbool.h>
28*4882a593Smuzhiyun #include "flash_image.h"
29*4882a593Smuzhiyun #include "update.h"
30*4882a593Smuzhiyun #include "log.h"
31*4882a593Smuzhiyun #include "rktools.h"
32*4882a593Smuzhiyun #include "gpt.h"
33*4882a593Smuzhiyun #include "rkimage.h"
34*4882a593Smuzhiyun #include "defineHeader.h"
35*4882a593Smuzhiyun #include "rkboot.h"
36*4882a593Smuzhiyun #include "../mtdutils/mtdutils.h"
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define UBI_HEAD_MAGIC "UBI#"
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun static PSTRUCT_PARAM_ITEM gp_param_item = NULL;
42*4882a593Smuzhiyun static long long *gp_backup_gpt_offset = NULL;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun // get greastest common divisor (gcd)
get_gcd(long long x,long long y)45*4882a593Smuzhiyun static int get_gcd ( long long x, long long y )
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun     while (x != y) { //用大数减去小数并将结果保存起来
48*4882a593Smuzhiyun         if (x > y) {
49*4882a593Smuzhiyun             x -= y;
50*4882a593Smuzhiyun         } else if (x < y) {
51*4882a593Smuzhiyun             y -= x;
52*4882a593Smuzhiyun         }
53*4882a593Smuzhiyun     }
54*4882a593Smuzhiyun     return x;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
is_ubi(char * src_path,long long offset)57*4882a593Smuzhiyun static bool is_ubi(char *src_path, long long offset)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun     char magic[5] = {0};
60*4882a593Smuzhiyun     bool ret;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun     int fd_src = open(src_path, O_RDONLY);
63*4882a593Smuzhiyun     if (fd_src < 0) {
64*4882a593Smuzhiyun         LOGE("error opening %s.\n", src_path);
65*4882a593Smuzhiyun         return 0;
66*4882a593Smuzhiyun     }
67*4882a593Smuzhiyun     if ( lseek64(fd_src, offset, SEEK_SET) == -1) {
68*4882a593Smuzhiyun         close(fd_src);
69*4882a593Smuzhiyun         LOGE("lseek64 failed (%s:%d).\n", __func__, __LINE__);
70*4882a593Smuzhiyun         return 0;
71*4882a593Smuzhiyun     }
72*4882a593Smuzhiyun     read(fd_src, magic, 4);
73*4882a593Smuzhiyun     LOGI("image magic is %s\n", magic);
74*4882a593Smuzhiyun     if (strcmp(magic, UBI_HEAD_MAGIC) == 0)
75*4882a593Smuzhiyun         ret = 1;
76*4882a593Smuzhiyun     else
77*4882a593Smuzhiyun         ret = 0;
78*4882a593Smuzhiyun     close(fd_src);
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun     return ret;
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun 
mtd_read()83*4882a593Smuzhiyun static void mtd_read()
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun 
mtd_write(char * src_path,long long offset,long long size,long long flash_offset,char * dest_path)88*4882a593Smuzhiyun static int mtd_write(char *src_path, long long offset, long long size, long long flash_offset, char *dest_path)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun     LOGI("mtd_write %s, offset = %#llx size = %#llx flash_offset = %lld.\n", dest_path, offset, size, flash_offset);
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun     struct stat sb;
93*4882a593Smuzhiyun     char mtd_write_erase_cmd[256] = {0};
94*4882a593Smuzhiyun     int system_ret;
95*4882a593Smuzhiyun     stat(dest_path, &sb);
96*4882a593Smuzhiyun     long long dd_bs = 1;
97*4882a593Smuzhiyun     long long dd_skip = offset;
98*4882a593Smuzhiyun     long long dd_count = size;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun     if ((sb.st_mode & S_IFMT) == S_IFCHR) {
101*4882a593Smuzhiyun         memset(mtd_write_erase_cmd, 0, sizeof(mtd_write_erase_cmd) / sizeof(mtd_write_erase_cmd[0]));
102*4882a593Smuzhiyun         sprintf(mtd_write_erase_cmd, "flash_erase %s 0 0", dest_path);
103*4882a593Smuzhiyun         system_ret = system(mtd_write_erase_cmd);
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun         dd_bs = get_gcd(offset, size);
106*4882a593Smuzhiyun         dd_skip = offset / dd_bs;
107*4882a593Smuzhiyun         dd_count = size / dd_bs;
108*4882a593Smuzhiyun         // dd if=/mnt/sdcard/sdupdate.img bs=4 skip=2727533 count=3646464 | nandwrite -p /dev/block/by-name/recovery
109*4882a593Smuzhiyun         memset(mtd_write_erase_cmd, 0, sizeof(mtd_write_erase_cmd) / sizeof(mtd_write_erase_cmd[0]));
110*4882a593Smuzhiyun         sprintf(mtd_write_erase_cmd, "dd if=%s bs=%lld skip=%lld count=%lld | nandwrite -p %s",
111*4882a593Smuzhiyun                 src_path, dd_bs, dd_skip, dd_count, dest_path );
112*4882a593Smuzhiyun         system_ret = system(mtd_write_erase_cmd);
113*4882a593Smuzhiyun     } else {
114*4882a593Smuzhiyun         LOGE("flash_erase: can't erase MTD \"%s\"\n", dest_path);
115*4882a593Smuzhiyun         return -1;
116*4882a593Smuzhiyun     }
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun     return 0;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun 
block_read()121*4882a593Smuzhiyun static void block_read()
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun 
block_write(char * src_path,long long offset,long long size,long long flash_offset,char * dest_path)126*4882a593Smuzhiyun static int block_write(char *src_path, long long offset, long long size, long long flash_offset, char *dest_path)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun     LOGI("block_write src %s dest %s.\n", src_path, dest_path);
129*4882a593Smuzhiyun     int fd_dest = 0, fd_src = 0;
130*4882a593Smuzhiyun     long long src_offset = 0, dest_offset = 0;
131*4882a593Smuzhiyun     long long src_remain, dest_remain;
132*4882a593Smuzhiyun     int src_step, dest_step;
133*4882a593Smuzhiyun     long long src_file_offset = 0;
134*4882a593Smuzhiyun     long long read_count, write_count;
135*4882a593Smuzhiyun     char data_buf[BLOCK_WRITE_LEN] = {0};
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun     fd_src = open(src_path, O_RDONLY);
138*4882a593Smuzhiyun     if (fd_src < 0) {
139*4882a593Smuzhiyun         LOGE("Can't open %s\n", src_path);
140*4882a593Smuzhiyun         return -2;
141*4882a593Smuzhiyun     }
142*4882a593Smuzhiyun     src_offset = offset;
143*4882a593Smuzhiyun     dest_remain = src_remain = size;
144*4882a593Smuzhiyun     dest_step = src_step = BLOCK_WRITE_LEN;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun     if (lseek64(fd_src, src_offset, SEEK_SET) == -1) {
147*4882a593Smuzhiyun         close(fd_src);
148*4882a593Smuzhiyun         LOGE("lseek64 failed (%s:%d).\n", __func__, __LINE__);
149*4882a593Smuzhiyun         return -2;
150*4882a593Smuzhiyun     }
151*4882a593Smuzhiyun     src_file_offset = src_offset;
152*4882a593Smuzhiyun     // dest_offset = flash_offset;
153*4882a593Smuzhiyun     // This step is going to write (src_path: sdupdate.img) to the file which is partition data (e.g. uboot)
154*4882a593Smuzhiyun     // So dest_offset is 0.
155*4882a593Smuzhiyun     dest_offset = 0;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun     fd_dest = open(dest_path, O_RDWR | O_CREAT | O_TRUNC, 0644);
158*4882a593Smuzhiyun     if (fd_dest < 0) {
159*4882a593Smuzhiyun         close(fd_src);
160*4882a593Smuzhiyun         LOGE("Can't open %s\n", dest_path);
161*4882a593Smuzhiyun         return -2;
162*4882a593Smuzhiyun     }
163*4882a593Smuzhiyun     if ( lseek64(fd_dest, dest_offset, SEEK_SET) == -1 ) {
164*4882a593Smuzhiyun         LOGE("(%s:%d) lseek64 failed(%s).\n", __func__, __LINE__, strerror(errno));
165*4882a593Smuzhiyun         close(fd_src);
166*4882a593Smuzhiyun         close(fd_dest);
167*4882a593Smuzhiyun         return -2;
168*4882a593Smuzhiyun     }
169*4882a593Smuzhiyun     while (src_remain > 0 && dest_remain > 0) {
170*4882a593Smuzhiyun         memset(data_buf, 0, BLOCK_WRITE_LEN);
171*4882a593Smuzhiyun         read_count = src_remain > src_step ? src_step : src_remain;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun         if (read(fd_src, data_buf, read_count) != read_count) {
174*4882a593Smuzhiyun             close(fd_dest);
175*4882a593Smuzhiyun             close(fd_src);
176*4882a593Smuzhiyun             LOGE("Read failed(%s):(%s:%d)\n", strerror(errno), __func__, __LINE__);
177*4882a593Smuzhiyun             return -2;
178*4882a593Smuzhiyun         }
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun         src_remain -= read_count;
181*4882a593Smuzhiyun         src_file_offset += read_count;
182*4882a593Smuzhiyun         write_count = dest_remain > dest_step ? dest_step : dest_remain;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun         if (write(fd_dest, data_buf, write_count) != write_count) {
185*4882a593Smuzhiyun             close(fd_dest);
186*4882a593Smuzhiyun             close(fd_src);
187*4882a593Smuzhiyun             LOGE("(%s:%d) write failed(%s).\n", __func__, __LINE__, strerror(errno));
188*4882a593Smuzhiyun             return -2;
189*4882a593Smuzhiyun         }
190*4882a593Smuzhiyun         dest_remain -= write_count;
191*4882a593Smuzhiyun     }
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun     fsync(fd_dest);
194*4882a593Smuzhiyun     close(fd_dest);
195*4882a593Smuzhiyun     close(fd_src);
196*4882a593Smuzhiyun     return 0;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun extern int do_patch_rkimg(const char *img, ssize_t offset, ssize_t size,
200*4882a593Smuzhiyun                           const char *blk_dev, const char *dst_file);
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun extern bool is_sdboot;
flash_normal(char * src_path,void * pupdate_cmd)203*4882a593Smuzhiyun int flash_normal(char *src_path, void *pupdate_cmd)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun     LOGI("%s:%d start.\n", __func__, __LINE__);
206*4882a593Smuzhiyun     PUPDATE_CMD pcmd = (PUPDATE_CMD)pupdate_cmd;
207*4882a593Smuzhiyun     int ret = 0;
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun     if (is_sdboot || !isMtdDevice()) {
210*4882a593Smuzhiyun         //block
211*4882a593Smuzhiyun         char dst_file[256];
212*4882a593Smuzhiyun         /* record the already upgraded img name,
213*4882a593Smuzhiyun          * so it can continue on upgrading after unexpected shutdown/reboot
214*4882a593Smuzhiyun          */
215*4882a593Smuzhiyun         char done_file[256];
216*4882a593Smuzhiyun         /* The pattern writes to done_file, e.g.
217*4882a593Smuzhiyun          *  >uboot<
218*4882a593Smuzhiyun          *  >boot<
219*4882a593Smuzhiyun          *  >rootfs<
220*4882a593Smuzhiyun          */
221*4882a593Smuzhiyun         char pattern[64];
222*4882a593Smuzhiyun         int fd;
223*4882a593Smuzhiyun         off_t size, len;
224*4882a593Smuzhiyun         char buf[512];
225*4882a593Smuzhiyun         struct stat dst_stat;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun         LOGI("%s:%d, diff check for %s\n", __func__, __LINE__, pcmd->name);
228*4882a593Smuzhiyun         snprintf(dst_file, 256, "%s.%s", src_path, pcmd->name);
229*4882a593Smuzhiyun         snprintf(done_file, 256, "%s.done", src_path);
230*4882a593Smuzhiyun         if ((fd = open(done_file, O_RDWR | O_CREAT | O_DSYNC, 0)) < 0 ||
231*4882a593Smuzhiyun             (size = lseek(fd, 0, SEEK_END) < 0) ||
232*4882a593Smuzhiyun             (lseek(fd, 0, SEEK_SET) < 0)) {
233*4882a593Smuzhiyun             LOGE("open %s failed, upgrading abort!\n", done_file);
234*4882a593Smuzhiyun             return -1;
235*4882a593Smuzhiyun         }
236*4882a593Smuzhiyun         memset(buf, 0, 512);
237*4882a593Smuzhiyun         len = 0;
238*4882a593Smuzhiyun         while (size > 0 && len != size) {
239*4882a593Smuzhiyun             ssize_t val;
240*4882a593Smuzhiyun             if ((val = read(fd, buf + len, size - len)) < 0) {
241*4882a593Smuzhiyun                 close(fd);
242*4882a593Smuzhiyun                 LOGE("read %s failed: %s\n", done_file, strerror(errno));
243*4882a593Smuzhiyun                 return val;
244*4882a593Smuzhiyun             }
245*4882a593Smuzhiyun             len += val;
246*4882a593Smuzhiyun         }
247*4882a593Smuzhiyun         snprintf(pattern, 64, ">%s<", pcmd->name);
248*4882a593Smuzhiyun         /* If this partition already upgraded,
249*4882a593Smuzhiyun          * the old image (in flash) could be broken,
250*4882a593Smuzhiyun          * it's fine to skip it.
251*4882a593Smuzhiyun          */
252*4882a593Smuzhiyun         if (strstr(buf, pattern) != NULL) {
253*4882a593Smuzhiyun             close(fd);
254*4882a593Smuzhiyun             return 0;
255*4882a593Smuzhiyun         }
256*4882a593Smuzhiyun         /* Otherwise, we shall look inside to make sure:
257*4882a593Smuzhiyun          * do_patch_rkimg() can generate a corrent new image even if
258*4882a593Smuzhiyun          * machine could lost-power/crash during upgrading
259*4882a593Smuzhiyun          * By doing this, do_patch_rkimg() will checking:
260*4882a593Smuzhiyun          *   - if dst_file already exist
261*4882a593Smuzhiyun          *     - md5sum is correct, then we may reboot during writing-to-flash
262*4882a593Smuzhiyun          *       >>  do not do patch again.
263*4882a593Smuzhiyun          *     - md5sum is wrong, then we may reboot during do_patch_rkimg()
264*4882a593Smuzhiyun          *       >>  the old image (in flash) good enough as is, do patch again.
265*4882a593Smuzhiyun          *   - if dst_file is not exist
266*4882a593Smuzhiyun          *     - this is normal case, we're safe to continue
267*4882a593Smuzhiyun          */
268*4882a593Smuzhiyun         if (stat(dst_file, &dst_stat) == 0)
269*4882a593Smuzhiyun             LOGI("file %s exist for <%s>, unexpected detected, trying to continue\n",
270*4882a593Smuzhiyun                  dst_file, pcmd->name);
271*4882a593Smuzhiyun         ret = do_patch_rkimg(src_path, pcmd->offset, pcmd->size,
272*4882a593Smuzhiyun                              pcmd->dest_path, dst_file);
273*4882a593Smuzhiyun         if (ret == 0) {
274*4882a593Smuzhiyun             ret = block_write(src_path, pcmd->offset, pcmd->size,
275*4882a593Smuzhiyun                               pcmd->flash_offset, pcmd->dest_path);
276*4882a593Smuzhiyun         } else if (ret > 0) {
277*4882a593Smuzhiyun             ret = block_write(dst_file, 0, ret,
278*4882a593Smuzhiyun                               pcmd->flash_offset, pcmd->dest_path);
279*4882a593Smuzhiyun             //TODO: do not skip diff image verify
280*4882a593Smuzhiyun             pcmd->skip_verify = true;
281*4882a593Smuzhiyun         } else {
282*4882a593Smuzhiyun             return ret;
283*4882a593Smuzhiyun         }
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun         lseek(fd, 0, SEEK_END);
286*4882a593Smuzhiyun         if (write(fd, pattern, strlen(pattern)) != strlen(pattern)) {
287*4882a593Smuzhiyun             LOGW("write len error");
288*4882a593Smuzhiyun         }
289*4882a593Smuzhiyun         close(fd);
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun         sync();
292*4882a593Smuzhiyun         /* Make sure that dst file written to flash before unlink it */
293*4882a593Smuzhiyun         unlink(dst_file);
294*4882a593Smuzhiyun         sync();
295*4882a593Smuzhiyun     } else {
296*4882a593Smuzhiyun         //mtd
297*4882a593Smuzhiyun         LOGI("pcmd->flash_offset = %lld.\n", pcmd->flash_offset);
298*4882a593Smuzhiyun         ret = mtd_write(src_path, pcmd->offset, pcmd->size, pcmd->flash_offset, pcmd->dest_path);
299*4882a593Smuzhiyun     }
300*4882a593Smuzhiyun     return ret;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun 
string_to_uuid(char * strUUid,char * uuid)303*4882a593Smuzhiyun static void string_to_uuid(char* strUUid, char *uuid)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun     unsigned int i;
306*4882a593Smuzhiyun     char value;
307*4882a593Smuzhiyun     memset(uuid, 0, 16);
308*4882a593Smuzhiyun     for (i = 0; i < 256; i++) {
309*4882a593Smuzhiyun         if (strUUid[i] == '\0') {
310*4882a593Smuzhiyun             break;
311*4882a593Smuzhiyun         }
312*4882a593Smuzhiyun         value = 0;
313*4882a593Smuzhiyun         if ((strUUid[i] >= '0') && (strUUid[i] <= '9'))
314*4882a593Smuzhiyun             value = strUUid[i] - '0';
315*4882a593Smuzhiyun         if ((strUUid[i] >= 'a') && (strUUid[i] <= 'f'))
316*4882a593Smuzhiyun             value = strUUid[i] - 'a' + 10;
317*4882a593Smuzhiyun         if ((strUUid[i] >= 'A') && (strUUid[i] <= 'F'))
318*4882a593Smuzhiyun             value = strUUid[i] - 'A' + 10;
319*4882a593Smuzhiyun         if ((i % 2) == 0)
320*4882a593Smuzhiyun             uuid[i / 2] += (value << 4);
321*4882a593Smuzhiyun         else
322*4882a593Smuzhiyun             uuid[i / 2] += value;
323*4882a593Smuzhiyun     }
324*4882a593Smuzhiyun     unsigned int *p32;
325*4882a593Smuzhiyun     unsigned short *p16;
326*4882a593Smuzhiyun     p32 = (unsigned int*)uuid;
327*4882a593Smuzhiyun     *p32 = cpu_to_be32(*p32);
328*4882a593Smuzhiyun     p16 = (unsigned short *)(uuid + 4);
329*4882a593Smuzhiyun     *p16 = cpu_to_be16(*p16);
330*4882a593Smuzhiyun     p16 = (unsigned short *)(uuid + 6);
331*4882a593Smuzhiyun     *p16 = cpu_to_be16(*p16);
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun 
getUuidFromString(char * str,PSTRUCT_CONFIG_ITEM p_config)334*4882a593Smuzhiyun static void getUuidFromString(char *str, PSTRUCT_CONFIG_ITEM  p_config)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun     char data_buf[strlen(str)];
337*4882a593Smuzhiyun     memcpy(data_buf, str, strlen(str));
338*4882a593Smuzhiyun     char *line = strtok(data_buf, "\n");
339*4882a593Smuzhiyun     while (line != NULL) {
340*4882a593Smuzhiyun         if (line[0] == '#') {
341*4882a593Smuzhiyun             continue;
342*4882a593Smuzhiyun         }
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun         char *pline = strstr(line, "uuid");
345*4882a593Smuzhiyun         if (pline != NULL && (pline = strstr(pline, ":")) != NULL) {
346*4882a593Smuzhiyun             pline++; //过滤掉冒号
347*4882a593Smuzhiyun             //过滤掉空格
348*4882a593Smuzhiyun             while (*pline == ' ') {
349*4882a593Smuzhiyun                 pline++;
350*4882a593Smuzhiyun             }
351*4882a593Smuzhiyun             char tmp;
352*4882a593Smuzhiyun             char value[256] = {0};
353*4882a593Smuzhiyun             sscanf(pline, "%[^=]%c%s", p_config->name, &tmp, value);
354*4882a593Smuzhiyun             string_to_uuid(value, p_config->value);
355*4882a593Smuzhiyun             p_config++;
356*4882a593Smuzhiyun         }
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun         line = strtok(NULL, "\n");
359*4882a593Smuzhiyun     }
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun 
getParamFromString(char * str,PSTRUCT_PARAM_ITEM p_param)362*4882a593Smuzhiyun static void getParamFromString(char *str, PSTRUCT_PARAM_ITEM p_param)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun     char data_buf[strlen(str)];
365*4882a593Smuzhiyun     memcpy(data_buf, str, strlen(str));
366*4882a593Smuzhiyun     char *line = strtok(data_buf, "\n");
367*4882a593Smuzhiyun     while (line != NULL) {
368*4882a593Smuzhiyun         if (line[0] == '#') {
369*4882a593Smuzhiyun             continue;
370*4882a593Smuzhiyun         }
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun         char *pline = strstr(line, "mtdparts");
373*4882a593Smuzhiyun         if (pline != NULL && (pline = strstr(pline, ":")) != NULL) {
374*4882a593Smuzhiyun             pline++; //过滤掉冒号
375*4882a593Smuzhiyun             //过滤掉空格
376*4882a593Smuzhiyun             while (*pline == ' ') {
377*4882a593Smuzhiyun                 pline++;
378*4882a593Smuzhiyun             }
379*4882a593Smuzhiyun             int pline_len = strlen(pline);
380*4882a593Smuzhiyun             char mtdparts_line[pline_len];
381*4882a593Smuzhiyun             memset(mtdparts_line, 0, pline_len);
382*4882a593Smuzhiyun             memcpy(mtdparts_line, pline, pline_len);
383*4882a593Smuzhiyun             //开始解析文件
384*4882a593Smuzhiyun             char *token = strtok(mtdparts_line, ",");
385*4882a593Smuzhiyun             while (token != NULL) {
386*4882a593Smuzhiyun                 char size[20], offset[20];
387*4882a593Smuzhiyun                 char tmp;
388*4882a593Smuzhiyun                 if (*token == '-') {
389*4882a593Smuzhiyun                     sscanf(token, "-@0x%x(%[^)]", &p_param->offset, p_param->name);
390*4882a593Smuzhiyun                     p_param->size = 0xFFFFFFFF;
391*4882a593Smuzhiyun                     p_param++;
392*4882a593Smuzhiyun                 } else {
393*4882a593Smuzhiyun                     sscanf(token, "0x%x@0x%x(%[^)]", &p_param->size, &p_param->offset, p_param->name);
394*4882a593Smuzhiyun                     p_param++;
395*4882a593Smuzhiyun                 }
396*4882a593Smuzhiyun                 token = strtok(NULL, ",");
397*4882a593Smuzhiyun             }
398*4882a593Smuzhiyun         }
399*4882a593Smuzhiyun         line = strtok(NULL, "\n");
400*4882a593Smuzhiyun     }
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun 
gen_rand_uuid(unsigned char * uuid_bin)403*4882a593Smuzhiyun static void gen_rand_uuid(unsigned char *uuid_bin)
404*4882a593Smuzhiyun {
405*4882a593Smuzhiyun     efi_guid_t id;
406*4882a593Smuzhiyun     unsigned int *ptr = (unsigned int *)&id;
407*4882a593Smuzhiyun     unsigned int i;
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun     /* Set all fields randomly */
410*4882a593Smuzhiyun     for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
411*4882a593Smuzhiyun         *(ptr + i) = cpu_to_be32(rand());
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun     id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
414*4882a593Smuzhiyun     id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun     memcpy(uuid_bin, id.raw, sizeof(id));
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun #define tole(x)        (x)
420*4882a593Smuzhiyun unsigned int crc32table_le[] = {
421*4882a593Smuzhiyun     tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL),
422*4882a593Smuzhiyun     tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L),
423*4882a593Smuzhiyun     tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L),
424*4882a593Smuzhiyun     tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L),
425*4882a593Smuzhiyun     tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL),
426*4882a593Smuzhiyun     tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L),
427*4882a593Smuzhiyun     tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL),
428*4882a593Smuzhiyun     tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L),
429*4882a593Smuzhiyun     tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L),
430*4882a593Smuzhiyun     tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL),
431*4882a593Smuzhiyun     tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L),
432*4882a593Smuzhiyun     tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L),
433*4882a593Smuzhiyun     tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L),
434*4882a593Smuzhiyun     tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL),
435*4882a593Smuzhiyun     tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L),
436*4882a593Smuzhiyun     tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL),
437*4882a593Smuzhiyun     tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL),
438*4882a593Smuzhiyun     tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L),
439*4882a593Smuzhiyun     tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L),
440*4882a593Smuzhiyun     tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L),
441*4882a593Smuzhiyun     tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL),
442*4882a593Smuzhiyun     tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L),
443*4882a593Smuzhiyun     tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL),
444*4882a593Smuzhiyun     tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L),
445*4882a593Smuzhiyun     tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L),
446*4882a593Smuzhiyun     tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL),
447*4882a593Smuzhiyun     tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L),
448*4882a593Smuzhiyun     tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L),
449*4882a593Smuzhiyun     tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L),
450*4882a593Smuzhiyun     tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL),
451*4882a593Smuzhiyun     tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L),
452*4882a593Smuzhiyun     tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL),
453*4882a593Smuzhiyun     tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL),
454*4882a593Smuzhiyun     tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L),
455*4882a593Smuzhiyun     tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L),
456*4882a593Smuzhiyun     tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L),
457*4882a593Smuzhiyun     tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL),
458*4882a593Smuzhiyun     tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L),
459*4882a593Smuzhiyun     tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL),
460*4882a593Smuzhiyun     tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L),
461*4882a593Smuzhiyun     tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L),
462*4882a593Smuzhiyun     tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL),
463*4882a593Smuzhiyun     tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L),
464*4882a593Smuzhiyun     tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L),
465*4882a593Smuzhiyun     tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L),
466*4882a593Smuzhiyun     tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL),
467*4882a593Smuzhiyun     tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L),
468*4882a593Smuzhiyun     tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL),
469*4882a593Smuzhiyun     tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL),
470*4882a593Smuzhiyun     tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L),
471*4882a593Smuzhiyun     tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L),
472*4882a593Smuzhiyun     tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L),
473*4882a593Smuzhiyun     tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL),
474*4882a593Smuzhiyun     tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L),
475*4882a593Smuzhiyun     tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL),
476*4882a593Smuzhiyun     tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L),
477*4882a593Smuzhiyun     tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L),
478*4882a593Smuzhiyun     tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL),
479*4882a593Smuzhiyun     tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L),
480*4882a593Smuzhiyun     tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L),
481*4882a593Smuzhiyun     tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L),
482*4882a593Smuzhiyun     tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL),
483*4882a593Smuzhiyun     tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L),
484*4882a593Smuzhiyun     tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL)
485*4882a593Smuzhiyun };
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun #define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
crc32_le(unsigned int crc,unsigned char * p,unsigned int len)488*4882a593Smuzhiyun static unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun     unsigned int      *b = (unsigned int *)p;
491*4882a593Smuzhiyun     unsigned int      *tab = crc32table_le;
492*4882a593Smuzhiyun     crc = crc ^ 0xFFFFFFFF;
493*4882a593Smuzhiyun     if ((((long)b) & 3 && len)) {
494*4882a593Smuzhiyun         do {
495*4882a593Smuzhiyun             unsigned char *p = (unsigned char *)b;
496*4882a593Smuzhiyun             DO_CRC(*p++);
497*4882a593Smuzhiyun             b = (unsigned int *)p;
498*4882a593Smuzhiyun         } while ((--len) && ((long)b) & 3 );
499*4882a593Smuzhiyun     }
500*4882a593Smuzhiyun     if ((len >= 4)) {
501*4882a593Smuzhiyun         unsigned int save_len = len & 3;
502*4882a593Smuzhiyun         len = len >> 2;
503*4882a593Smuzhiyun         --b;
504*4882a593Smuzhiyun         do {
505*4882a593Smuzhiyun             crc ^= *++b;
506*4882a593Smuzhiyun             DO_CRC(0);
507*4882a593Smuzhiyun             DO_CRC(0);
508*4882a593Smuzhiyun             DO_CRC(0);
509*4882a593Smuzhiyun             DO_CRC(0);
510*4882a593Smuzhiyun         } while (--len);
511*4882a593Smuzhiyun         b++;
512*4882a593Smuzhiyun         len = save_len;
513*4882a593Smuzhiyun     }
514*4882a593Smuzhiyun     if (len) {
515*4882a593Smuzhiyun         do {
516*4882a593Smuzhiyun             unsigned char *p = (unsigned char *)b;
517*4882a593Smuzhiyun             DO_CRC(*p++);
518*4882a593Smuzhiyun             b = (unsigned int *)p;
519*4882a593Smuzhiyun         } while (--len);
520*4882a593Smuzhiyun     }
521*4882a593Smuzhiyun     crc = crc ^ 0xFFFFFFFF;
522*4882a593Smuzhiyun     return crc;
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun 
create_gpt_buffer(u8 * gpt,PSTRUCT_PARAM_ITEM p_param,int param_len,PSTRUCT_CONFIG_ITEM p_config,int config_len,u64 diskSectors)526*4882a593Smuzhiyun static void create_gpt_buffer(u8 *gpt, PSTRUCT_PARAM_ITEM p_param, int param_len, PSTRUCT_CONFIG_ITEM p_config, int config_len, u64 diskSectors)
527*4882a593Smuzhiyun {
528*4882a593Smuzhiyun     legacy_mbr *mbr = (legacy_mbr *)gpt;
529*4882a593Smuzhiyun     gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
530*4882a593Smuzhiyun     gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun     /*1.protective mbr*/
533*4882a593Smuzhiyun     memset(gpt, 0, SECTOR_SIZE);
534*4882a593Smuzhiyun     mbr->signature = MSDOS_MBR_SIGNATURE;
535*4882a593Smuzhiyun     mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
536*4882a593Smuzhiyun     mbr->partition_record[0].start_sect = 1;
537*4882a593Smuzhiyun     mbr->partition_record[0].nr_sects = (u32) - 1;
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun     /*2.gpt header*/
540*4882a593Smuzhiyun     memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
541*4882a593Smuzhiyun     gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
542*4882a593Smuzhiyun     gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
543*4882a593Smuzhiyun     gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
544*4882a593Smuzhiyun     gptHead->my_lba = cpu_to_le64(1);
545*4882a593Smuzhiyun     gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
546*4882a593Smuzhiyun     gptHead->first_usable_lba = cpu_to_le64(34);
547*4882a593Smuzhiyun     gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
548*4882a593Smuzhiyun     gptHead->partition_entry_lba = cpu_to_le64(2);
549*4882a593Smuzhiyun     gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
550*4882a593Smuzhiyun     gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
551*4882a593Smuzhiyun     gptHead->header_crc32 = 0;
552*4882a593Smuzhiyun     gptHead->partition_entry_array_crc32 = 0;
553*4882a593Smuzhiyun     gen_rand_uuid(gptHead->disk_guid.raw);
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun     /*3.gpt partition entry*/
556*4882a593Smuzhiyun     memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
557*4882a593Smuzhiyun     for (int i = 0; i < param_len; i++) {
558*4882a593Smuzhiyun         if (strcmp(p_param[i].name, "") == 0) {
559*4882a593Smuzhiyun             continue;
560*4882a593Smuzhiyun         }
561*4882a593Smuzhiyun         gen_rand_uuid(gptEntry->partition_type_guid.raw);
562*4882a593Smuzhiyun         gen_rand_uuid(gptEntry->unique_partition_guid.raw);
563*4882a593Smuzhiyun         gptEntry->starting_lba = cpu_to_le64(p_param[i].offset);
564*4882a593Smuzhiyun         gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + p_param[i].size - 1);
565*4882a593Smuzhiyun         gptEntry->attributes.raw = 0;
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun         char partition_name[20] = {0};
568*4882a593Smuzhiyun         strcpy(partition_name, p_param[i].name);
569*4882a593Smuzhiyun         char *p;
570*4882a593Smuzhiyun         if ( (p = strstr(partition_name, ":")) != NULL) {
571*4882a593Smuzhiyun             if (strstr(partition_name, "bootable") != NULL) {
572*4882a593Smuzhiyun                 gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
573*4882a593Smuzhiyun             }
574*4882a593Smuzhiyun             if (strstr(partition_name, "grow") != NULL) {
575*4882a593Smuzhiyun                 gptEntry->ending_lba = cpu_to_le64(diskSectors - 34);
576*4882a593Smuzhiyun             }
577*4882a593Smuzhiyun             *p = '\0';
578*4882a593Smuzhiyun             strcpy(p_param[i].name, partition_name);
579*4882a593Smuzhiyun         }
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun         for (int j = 0; j < strlen(p_param[i].name); j++)
582*4882a593Smuzhiyun             gptEntry->partition_name[j] = p_param[i].name[j];
583*4882a593Smuzhiyun         for (int j = 0; j < config_len; j++) {
584*4882a593Smuzhiyun             if (strcmp(p_config[j].name, p_param[i].name) == 0) {
585*4882a593Smuzhiyun                 memcpy(gptEntry->unique_partition_guid.raw, p_config[j].value, 16);
586*4882a593Smuzhiyun                 break ;
587*4882a593Smuzhiyun             }
588*4882a593Smuzhiyun         }
589*4882a593Smuzhiyun         gptEntry++;
590*4882a593Smuzhiyun     }
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun     gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
593*4882a593Smuzhiyun     gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun }
596*4882a593Smuzhiyun 
prepare_gpt_backup(u8 * master,u8 * backup)597*4882a593Smuzhiyun static void prepare_gpt_backup(u8 *master, u8 *backup)
598*4882a593Smuzhiyun {
599*4882a593Smuzhiyun     gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
600*4882a593Smuzhiyun     gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE);
601*4882a593Smuzhiyun     u32 calc_crc32;
602*4882a593Smuzhiyun     u64 val;
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun     /* recalculate the values for the Backup GPT Header */
605*4882a593Smuzhiyun     val = le64_to_cpu(gptMasterHead->my_lba);
606*4882a593Smuzhiyun     gptBackupHead->my_lba = gptMasterHead->alternate_lba;
607*4882a593Smuzhiyun     gptBackupHead->alternate_lba = cpu_to_le64(val);
608*4882a593Smuzhiyun     gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1);
609*4882a593Smuzhiyun     gptBackupHead->header_crc32 = 0;
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun     calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size));
612*4882a593Smuzhiyun     gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32);
613*4882a593Smuzhiyun }
614*4882a593Smuzhiyun 
flash_register_partition_data(PSTRUCT_PARAM_ITEM p_param_item,long long * p_gpt_backup_offset)615*4882a593Smuzhiyun int flash_register_partition_data(PSTRUCT_PARAM_ITEM p_param_item, long long *p_gpt_backup_offset)
616*4882a593Smuzhiyun {
617*4882a593Smuzhiyun     if (p_param_item) {
618*4882a593Smuzhiyun         gp_param_item = p_param_item;
619*4882a593Smuzhiyun     }
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun     if (p_gpt_backup_offset) {
622*4882a593Smuzhiyun         gp_backup_gpt_offset = p_gpt_backup_offset;
623*4882a593Smuzhiyun     }
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun     return 0;
626*4882a593Smuzhiyun }
627*4882a593Smuzhiyun 
flash_parameter(char * src_path,void * pupdate_cmd)628*4882a593Smuzhiyun int flash_parameter(char *src_path, void *pupdate_cmd)
629*4882a593Smuzhiyun {
630*4882a593Smuzhiyun     LOGI("flash_parameter start src_path [%s].\n", src_path);
631*4882a593Smuzhiyun     PUPDATE_CMD pcmd = (PUPDATE_CMD)pupdate_cmd;
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun     unsigned int m_uiParamFileSize = pcmd->size;
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun     if (m_uiParamFileSize % SECTOR_SIZE != 0) {
636*4882a593Smuzhiyun         m_uiParamFileSize = (m_uiParamFileSize / SECTOR_SIZE + 1) * SECTOR_SIZE;
637*4882a593Smuzhiyun     }
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun     // 1. 读取parameter 数据
640*4882a593Smuzhiyun     unsigned char data_buf[m_uiParamFileSize];
641*4882a593Smuzhiyun     memset(data_buf, 0, m_uiParamFileSize);
642*4882a593Smuzhiyun     int fd_src = open(src_path, O_RDONLY);
643*4882a593Smuzhiyun     if (fd_src < 0) {
644*4882a593Smuzhiyun         LOGE("Can't open %s, %s\n", src_path, strerror(errno));
645*4882a593Smuzhiyun         return -2;
646*4882a593Smuzhiyun     }
647*4882a593Smuzhiyun     if (lseek64(fd_src, pcmd->offset, SEEK_SET) == -1) {
648*4882a593Smuzhiyun         LOGE("lseek64 failed (%s:%d), %s.\n", __func__, __LINE__, strerror(errno));
649*4882a593Smuzhiyun         close(fd_src);
650*4882a593Smuzhiyun         return -2;
651*4882a593Smuzhiyun     }
652*4882a593Smuzhiyun     if (read(fd_src, data_buf, pcmd->size) != pcmd->size) {
653*4882a593Smuzhiyun         close(fd_src);
654*4882a593Smuzhiyun         return -2;
655*4882a593Smuzhiyun     }
656*4882a593Smuzhiyun     close(fd_src);
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun     // 2. 获取分区大小和uuid
659*4882a593Smuzhiyun     STRUCT_PARAM_ITEM param_item[20] = {0};
660*4882a593Smuzhiyun     STRUCT_CONFIG_ITEM config_item[10] = {0};
661*4882a593Smuzhiyun     getParamFromString((char *)data_buf + 8, param_item);
662*4882a593Smuzhiyun     getUuidFromString((char *)data_buf + 8, config_item);
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun     if (gp_param_item) {
665*4882a593Smuzhiyun         memcpy(gp_param_item, param_item, sizeof(param_item) );
666*4882a593Smuzhiyun     }
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun     LOGI("%s-%d: List partitions:\n", __func__, __LINE__);
669*4882a593Smuzhiyun     for (int j = 0; j < sizeof(param_item) / sizeof(param_item[0]); j++) {
670*4882a593Smuzhiyun         LOGI("    param_item[%d].name [%s]\n", j, param_item[j].name);
671*4882a593Smuzhiyun     }
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun     // 3. 获得flash 的大小,和块数
674*4882a593Smuzhiyun     long long block_num;
675*4882a593Smuzhiyun     if (getFlashSize(NULL, NULL, &block_num) != 0) {
676*4882a593Smuzhiyun         LOGE("getFlashSize error.\n");
677*4882a593Smuzhiyun         return -2;
678*4882a593Smuzhiyun     }
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun     LOGI("%s, block_num = %lld.\n", __func__, block_num);
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun     // 4. 创建gpt 表
683*4882a593Smuzhiyun     unsigned char write_buf[SECTOR_SIZE * 67];
684*4882a593Smuzhiyun     unsigned char *backup_gpt;
685*4882a593Smuzhiyun     backup_gpt = write_buf + 34 * SECTOR_SIZE;
686*4882a593Smuzhiyun     memset(write_buf, 0, SECTOR_SIZE * 67);
687*4882a593Smuzhiyun     create_gpt_buffer(write_buf, param_item, 20, config_item, 10, block_num);
688*4882a593Smuzhiyun     memcpy(backup_gpt, write_buf + 2 * SECTOR_SIZE, 32 * SECTOR_SIZE);
689*4882a593Smuzhiyun     memcpy(backup_gpt + 32 * SECTOR_SIZE, write_buf + SECTOR_SIZE, SECTOR_SIZE);
690*4882a593Smuzhiyun     prepare_gpt_backup(write_buf, backup_gpt);
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun     if (gp_backup_gpt_offset) {
693*4882a593Smuzhiyun         *gp_backup_gpt_offset = (block_num - 33) * SECTOR_SIZE;
694*4882a593Smuzhiyun     }
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun     //5. 写入主GPT表
697*4882a593Smuzhiyun     int fd_dest = open(pcmd->dest_path, O_CREAT | O_RDWR | O_TRUNC, 0644);
698*4882a593Smuzhiyun     if (fd_dest < 0) {
699*4882a593Smuzhiyun         LOGE("Can't open %s, %s\n", pcmd->dest_path, strerror(errno));
700*4882a593Smuzhiyun         return -2;
701*4882a593Smuzhiyun     }
702*4882a593Smuzhiyun     lseek64(fd_dest, 0, SEEK_SET);
703*4882a593Smuzhiyun     if (write(fd_dest, write_buf, 34 * SECTOR_SIZE) != 34 * SECTOR_SIZE) {
704*4882a593Smuzhiyun         LOGE("write error %s: (%s:%d).\n", strerror(errno), __func__, __LINE__);
705*4882a593Smuzhiyun         close(fd_dest);
706*4882a593Smuzhiyun         return -2;
707*4882a593Smuzhiyun     }
708*4882a593Smuzhiyun     //6. 尾部写入GPT表到文件
709*4882a593Smuzhiyun     /*
710*4882a593Smuzhiyun      * char gpt_backup_dest_path[100] = {0};
711*4882a593Smuzhiyun      * memset(gpt_backup_dest_path, 0, sizeof(gpt_backup_dest_path)/sizeof(gpt_backup_dest_path[0]));
712*4882a593Smuzhiyun      * memcpy(gpt_backup_dest_path, pcmd->dest_path, strlen(pcmd->dest_path));
713*4882a593Smuzhiyun      * dirname(gpt_backup_dest_path);
714*4882a593Smuzhiyun      * sprintf(gpt_backup_dest_path, "%s/%s", gpt_backup_dest_path, GPT_BACKUP_FILE_NAME);
715*4882a593Smuzhiyun      */
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun #if 0
718*4882a593Smuzhiyun     int fd_backup = open(gpt_backup_dest_path, O_CREAT | O_RDWR | O_TRUNC, 0644);
719*4882a593Smuzhiyun     if (fd_backup < 0) {
720*4882a593Smuzhiyun         LOGE("Can't open %s, %s\n", gpt_backup_dest_path, strerror(errno));
721*4882a593Smuzhiyun         return -2;
722*4882a593Smuzhiyun     }
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun     if (write(fd_backup, backup_gpt, 33 * SECTOR_SIZE) != 33 * SECTOR_SIZE) {
725*4882a593Smuzhiyun         LOGE("write error %s: (%s:%d).\n", strerror(errno), __func__, __LINE__);
726*4882a593Smuzhiyun         close(fd_backup);
727*4882a593Smuzhiyun         return -2;
728*4882a593Smuzhiyun     }
729*4882a593Smuzhiyun     close(fd_backup);
730*4882a593Smuzhiyun #endif
731*4882a593Smuzhiyun     close(fd_dest);
732*4882a593Smuzhiyun     sync();
733*4882a593Smuzhiyun     return 0;
734*4882a593Smuzhiyun }
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun 
flash_bootloader(char * src_path,void * pupdate_cmd)737*4882a593Smuzhiyun int flash_bootloader(char *src_path, void *pupdate_cmd)
738*4882a593Smuzhiyun {
739*4882a593Smuzhiyun     PUPDATE_CMD pcmd = (PUPDATE_CMD)pupdate_cmd;
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun     if (isMtdDevice()) {
742*4882a593Smuzhiyun         // bootrom read IDBlock from the offset which is equal to block size for Nand Flash
743*4882a593Smuzhiyun         size_t block_size = 0;
744*4882a593Smuzhiyun         if (getFlashInfo(NULL, &block_size, NULL) != 0) {
745*4882a593Smuzhiyun             LOGE("%s-%d: get mtd info error\n", __func__, __LINE__);
746*4882a593Smuzhiyun             return false;
747*4882a593Smuzhiyun         }
748*4882a593Smuzhiyun         pcmd->flash_offset = block_size;
749*4882a593Smuzhiyun     } else {
750*4882a593Smuzhiyun         // bootrom read IDBlock from the offset (32KB + 512KB * n <n=0,1,2,3...>) for eMMC
751*4882a593Smuzhiyun         pcmd->flash_offset = 32 * 1024;
752*4882a593Smuzhiyun     }
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun     // 1. 读取bootloader
755*4882a593Smuzhiyun     unsigned char data_buf[pcmd->size];
756*4882a593Smuzhiyun     memset(data_buf, 0, pcmd->size);
757*4882a593Smuzhiyun     int fd_src = open(src_path, O_RDONLY);
758*4882a593Smuzhiyun     if (fd_src < 0) {
759*4882a593Smuzhiyun         LOGE("Can't open %s, %s\n", src_path, strerror(errno));
760*4882a593Smuzhiyun         return -2;
761*4882a593Smuzhiyun     }
762*4882a593Smuzhiyun     if (lseek64(fd_src, pcmd->offset, SEEK_SET) == -1) {
763*4882a593Smuzhiyun         LOGE("(%s:%d) lseek64 failed: %s.\n", __func__, __LINE__, strerror(errno));
764*4882a593Smuzhiyun         close(fd_src);
765*4882a593Smuzhiyun         return -2;
766*4882a593Smuzhiyun     }
767*4882a593Smuzhiyun     if (read(fd_src, data_buf, pcmd->size) != pcmd->size) {
768*4882a593Smuzhiyun         close(fd_src);
769*4882a593Smuzhiyun         LOGE("read error(%s:%d) : %s.\n", __func__, __LINE__, strerror(errno));
770*4882a593Smuzhiyun         return -2;
771*4882a593Smuzhiyun     }
772*4882a593Smuzhiyun     close(fd_src);
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun     if (!download_loader(data_buf, pcmd->size, pcmd->dest_path)) {
775*4882a593Smuzhiyun         LOGE("download_loader error.\n");
776*4882a593Smuzhiyun         return -1;
777*4882a593Smuzhiyun     }
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun     return 0;
780*4882a593Smuzhiyun }
781*4882a593Smuzhiyun 
782