blob: 57543685706eb7610c6805836b353a91656a3613 [file] [log] [blame]
xf.li6c8fc1e2023-08-12 00:11:09 -07001#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <fcntl.h>
8
9#include <mtd/mtd-abi.h>
10#include <errno.h>
11
12#include <sys/ioctl.h>
13#include "mtd_api.h"
14
15#define MTD_PATH_LENGTH_MAX (256)
16
17static ssize_t readn(int fd, void *vptr, size_t n);
18static ssize_t writen(int fd, const void *vptr, size_t n);
19
20/*******************************************************************************
21 * 内部函数/mtd_private.h *
22 *******************************************************************************/
23/**
24 * @brief 从文件描述符读取数据
25 * @param fd 入参,文件描述符
26 * @param vptr 出参,数据缓冲区
27 * @param n 入参,内容字节数
28 * @return 成功返回成功读取的字节数,失败返回-1
29 * @retval
30 * @note 封装read接口,读取被打断时会重试直到全部读取成功
31 * @warning
32 */
33static ssize_t readn(int fd, void *vptr, size_t n)
34{
35 size_t nleft;
36 ssize_t nread;
37 char *ptr;
38
39 ptr = vptr;
40 nleft = n;
41 while (nleft > 0)
42 {
43 if ((nread = read(fd, ptr, nleft)) < 0)
44 {
45 if (errno == EINTR)
46 {
47 nread = 0; /* and call read() again */
48 }
49 else
50 {
51 return (-1);
52 }
53 }
54 else if (nread == 0)
55 {
56 break; /* EOF */
57 }
58
59 nleft -= nread;
60 ptr += nread;
61 }
62 return (n - nleft); /* return >= 0 */
63}
64
65/**
66 * @brief 向文件描述符写入数据
67 * @param fd 入参,文件描述符
68 * @param vptr 入参,数据缓冲区
69 * @param n 入参,内容字节数
70 * @return 成功返回成功写入的字节数,失败返回-1
71 * @retval
72 * @note 封装write接口,写入被打断时会重试直到全部写入成功
73 * @warning
74 */
75static ssize_t writen(int fd, const void *vptr, size_t n)
76{
77 size_t nleft;
78 ssize_t nwritten;
79 const char *ptr;
80
81 ptr = vptr;
82 nleft = n;
83 while (nleft > 0)
84 {
85 nwritten = write(fd, ptr, nleft);
86 if (nwritten < 0)
87 {
88 if (errno == EINTR)
89 {
90 nwritten = 0; /* call write() again */
91 }
92 else
93 {
94 return (-1); /* error */
95 }
96 }
97 else if (nwritten == 0)
98 {
99 break;
100 }
101
102 nleft -= nwritten;
103 ptr += nwritten;
104 }
105 return (n - nleft); /* return >= 0 */
106}
107
108/*******************************************************************************
109 * 外部函数定义 *
110 *******************************************************************************/
111int mtd_find(const char *i_parti_name, device_type_t device_type, char *o_mtd_path, unsigned int o_mtd_path_len)
112{
113 FILE *fp_mtd = 0;
114 char buf[128];
115 char *line_str;
116
117 if (!o_mtd_path_len)
118 {
119 return -1;
120 }
121
122 fp_mtd = fopen("/proc/mtd", "r+");
123 if (NULL == fp_mtd)
124 {
125 printf("[libmtd]: mtd_find, open file error:%s", strerror(errno));
126 return -1;
127 }
128 // printf("[libmtd]: partition name:%s\n", i_parti_name);
129
130 while (1)
131 {
132 int matches = 0;
133 char mtdname[64] = {0};
134 int mtdnum = 0;
135 unsigned int mtdsize, mtderasesize;
136 memset(buf, 0, sizeof(buf));
137 line_str = fgets(buf, sizeof(buf) - 1, fp_mtd);
138
139 if (NULL == line_str)
140 {
141 printf("[libmtd]: mtd_find, get info from mtd error:%s\n", strerror(errno));
142 fclose(fp_mtd);
143 return -1;
144 }
145 // mtd5: 00100000 00020000 "fotaflag"
146 matches = sscanf(buf, "mtd%d: %x %x \"%63[^\"]",
147 &mtdnum, &mtdsize, &mtderasesize, mtdname);
148 mtdname[63] = '\0';
149
150 if ((matches == 4) && (strcmp(mtdname, i_parti_name) == 0))
151 {
152 memset(o_mtd_path, 0, o_mtd_path_len);
153 if (device_type == DEVICE_MTD_BLOCK)
154 {
155 snprintf(o_mtd_path, o_mtd_path_len, "/dev/mtdblock%d", mtdnum);
156 }
157 else if (device_type == DEVICE_MTD)
158 {
159 snprintf(o_mtd_path, o_mtd_path_len, "/dev/mtd%d", mtdnum);
160 }
161 else if (device_type == DEVICE_ZFTL)
162 {
163 snprintf(o_mtd_path, o_mtd_path_len, "/dev/zftl%d", mtdnum);
164 }
165 else
166 {
167 printf("[libmtd]: mtd_find, unknown device type %d\n", device_type);
168 fclose(fp_mtd);
169 return -1;
170 }
171 // printf("[libmtd]: o_mtd_path=[%s]\n", o_mtd_path);
172 break;
173 }
174 }
175 fclose(fp_mtd);
176 return 0;
177}
178
179int mtd_get_info(int fd, struct mtd_info_user *info)
180{
181 if (0 != ioctl(fd, MEMGETINFO, info))
182 {
183 printf("[libmtd]: mtd_get_info, get fd(%d) info error, %s\n", fd, strerror(errno));
184 return -1;
185 }
186 return 0;
187}
188
189int mtd_block_isbad(int fd, off_t offset)
190{
191 int ret = 0;
192 ret = ioctl(fd, MEMGETBADBLOCK, &offset);
193 if (ret > 0)
194 {
195 printf("[libmtd]: mtd_block_isbad, bad block at 0x%lx, ret = %d\n", offset, ret);
196 ret = 1;
197 }
198 else if (ret < 0)
199 {
200 printf("[libmtd]: mtd_block_isbad, ioctl(MEMGETBADBLOCK) error at 0x%lx, %s, ret = %d\n", offset, strerror(errno), ret);
201 ret = -1;
202 }
203 return ret;
204}
205
206int mtd_erase_partition(const char *partition_name)
207{
208 int ret = 0;
209 char mtd_path[MTD_PATH_LENGTH_MAX] = {0};
210 int fd_mtd = -1;
211
212 struct mtd_info_user meminfo = {0};
213 struct erase_info_user64 erase_info = {0};
214
215 if (NULL == partition_name)
216 {
217 return -1;
218 }
219
220 ret = mtd_find(partition_name, DEVICE_MTD, mtd_path, MTD_PATH_LENGTH_MAX);
221 if (ret < 0)
222 {
223 printf("[libmtd]: mtd_erase_partition, mtd_find %s failed\n", partition_name);
224 ret = -1;
225 goto out;
226 }
227 fd_mtd = open(mtd_path, O_RDWR);
228 if (fd_mtd < 0)
229 {
230 printf("[libmtd]: mtd_erase_partition, open %s error, %s\n", partition_name, strerror(errno));
231 return -1;
232 }
233 ret = mtd_get_info(fd_mtd, &meminfo);
234 if (ret < 0)
235 {
236 printf("[libmtd]: mtd_erase_partition, get %s info error, %s\n", partition_name, strerror(errno));
237 ret = -1;
238 goto out;
239 }
240
241 erase_info.length = meminfo.erasesize;
242 for (erase_info.start = 0; erase_info.start < meminfo.size; erase_info.start += meminfo.erasesize)
243 {
244 ret = mtd_block_isbad(fd_mtd, erase_info.start);
245 if (1 == ret)
246 {
247 continue;
248 }
249 else if (-1 == ret)
250 {
251 printf("[libmtd]: mtd_erase_partition, mtd_block_isbad %s error\n", partition_name);
252 goto out;
253 }
254
255 if (0 != ioctl(fd_mtd, MEMERASE64, &erase_info))
256 {
257 printf("[libmtd]: mtd_erase_partition, erasing %s failure at 0x%llx\n", partition_name, erase_info.start);
258 if (ioctl(fd_mtd, MEMSETBADBLOCK, &(erase_info.start)) < 0)
259 {
260 printf("[libmtd]: mtd_erase_partition, mark %s bad block error, %s\n", partition_name, strerror(errno));
261 ret = -1;
262 goto out;
263 }
264 continue;
265 }
266 }
267 ret = 0;
268out:
269 if (fd_mtd >= 0)
270 {
271 close(fd_mtd);
272 }
273 return ret;
274}
275
276int mtd_write_partition(const char *partition_name, const char *image_file)
277{
278 int ret = 0;
279 ssize_t wr_len;
280 char mtd_path[MTD_PATH_LENGTH_MAX] = {0};
281 int fd_mtd = -1;
282 struct mtd_info_user meminfo = {0};
283
284 off_t data_size = 0;
285 off_t index = 0;
286 off_t fd_img_index = 0;
287 int fd_img = -1;
288 char *buf = NULL;
289 struct stat statbuff = {0};
290
291 if (NULL == partition_name || NULL == image_file)
292 {
293 return -1;
294 }
295
296 ret = mtd_find(partition_name, DEVICE_MTD, mtd_path, MTD_PATH_LENGTH_MAX);
297 if (ret < 0)
298 {
299 printf("[libmtd]: mtd_write_partition, mtd_find %s failed\n", partition_name);
300 ret = -1;
301 goto out;
302 }
303 fd_mtd = open(mtd_path, O_RDWR);
304 if (fd_mtd < 0)
305 {
306 printf("[libmtd]: mtd_write_partition, open %s error, %s\n", partition_name, strerror(errno));
307 return -1;
308 }
309 ret = mtd_get_info(fd_mtd, &meminfo);
310 if (ret < 0)
311 {
312 printf("[libmtd]: mtd_write_partition, get %s info error, %s\n", partition_name, strerror(errno));
313 ret = -1;
314 goto out;
315 }
316
317 if (stat(image_file, &statbuff) < 0)
318 {
319 printf("[libmtd]: mtd_write_partition, stat %s failed, %s\n", image_file, strerror(errno));
320 ret = -1;
321 goto out;
322 }
323
324 fd_img = open(image_file, O_RDONLY);
325 if (fd_img < 0)
326 {
327 printf("[libmtd]: mtd_write_partition, open %s failed, %s\n", image_file, strerror(errno));
328 ret = -1;
329 goto out;
330 }
331
332 buf = (char *)malloc(meminfo.erasesize);
333 if (!buf)
334 {
335 printf("[libmtd]: mtd_write_partition, malloc failed\n");
336 ret = -1;
337 goto out;
338 }
339
340 for (index = 0; index < meminfo.size && fd_img_index < statbuff.st_size; index += meminfo.erasesize)
341 {
342 ret = mtd_block_isbad(fd_mtd, index);
343 if (1 == ret)
344 {
345 continue;
346 }
347 else if (-1 == ret)
348 {
349 printf("[libmtd]: mtd_write_partition, mtd_block_isbad %s error,at 0x%llx\n", partition_name, index);
350 goto out;
351 }
352
353 if (lseek(fd_img, fd_img_index, SEEK_SET) < 0)
354 {
355 printf("[libmtd]: mtd_write_partition, lseek %s error = %s!\n", image_file, strerror(errno));
356 ret = -1;
357 goto out;
358 }
359 if (fd_img_index + meminfo.erasesize > statbuff.st_size)
360 {
361 data_size = statbuff.st_size - fd_img_index;
362 }
363 else
364 {
365 data_size = meminfo.erasesize;
366 }
367 wr_len = readn(fd_img, buf, (size_t)data_size);
368 if (wr_len < 0)
369 {
370 printf("[libmtd]: mtd_write_partition, read %s error, %s\n", image_file, strerror(errno));
371 ret = -1;
372 goto out;
373 }
374 fd_img_index += data_size;
375
376 if (lseek(fd_mtd, index, SEEK_SET) < 0)
377 {
378 printf("[libmtd]: mtd_write_partition, lseek %s error = %s!\n", partition_name, strerror(errno));
379 ret = -1;
380 goto out;
381 }
382 wr_len = writen(fd_mtd, buf, (size_t)data_size);
383 if (wr_len < 0)
384 {
385 printf("[libmtd]: mtd_write_partition, write %s error, %s\n", partition_name, strerror(errno));
386 ret = -1;
387 goto out;
388 }
389 memset(buf, 0xFF, meminfo.erasesize);
390 }
391 if (fd_img_index < statbuff.st_size)
392 {
393 printf("[libmtd]: mtd_write_partition, No space left, writelen=0x%lx, filesize=0x%lx\n", fd_img_index, statbuff.st_size);
394 ret = -1;
395 goto out;
396 }
397 ret = 0;
398out:
399 if (fd_mtd >= 0)
400 {
401 close(fd_mtd);
402 }
403
404 if (buf != NULL)
405 {
406 // memset(buf, 0xFF, meminfo.erasesize);
407 free(buf);
408 }
409
410 if (fd_img >= 0)
411 {
412 close(fd_img);
413 }
414
415 return ret;
416}
417
418int mtd_erase_offset(int fd, off_t offset)
419{
420 struct mtd_info_user meminfo = {0};
421 struct erase_info_user64 erase_info = {0};
422
423 if (fd < 0)
424 {
425 printf("[libmtd]: mtd_erase_offset, fd(%d) error\n", fd);
426 return -1;
427 }
428
429 if (0 != mtd_get_info(fd, &meminfo))
430 {
431 printf("[libmtd]: mtd_erase_offset, get fd(%d) info error, %s\n", fd, strerror(errno));
432 return -1;
433 }
434
435 if (0 != (offset % meminfo.erasesize))
436 {
437 printf("[libmtd]: mtd_erase_offset, not at the beginning of a block, erasesize is %d\n", meminfo.erasesize);
438 return -1;
439 }
440
441 erase_info.length = meminfo.erasesize;
442 erase_info.start = offset;
443
444 if (mtd_block_isbad(fd, erase_info.start))
445 {
446 return -1;
447 }
448 if (0 != ioctl(fd, MEMERASE64, &erase_info))
449 {
450 printf("[libmtd]: mtd_erase_offset, erasing failure at 0x%llx\n", erase_info.start);
451 if (ioctl(fd, MEMSETBADBLOCK, &(erase_info.start)) < 0)
452 {
453 printf("[libmtd]: mtd_erase_offset, mark bad block error, %s\n", strerror(errno));
454 }
455 return -1;
456 }
457
458 return 0;
459}
460
461ssize_t mtd_write_offset(int fd, off_t offset, const void *buf, size_t count)
462{
463 ssize_t writen_len;
464 struct mtd_info_user meminfo = {0};
465
466 if (fd < 0)
467 {
468 return -1;
469 }
470
471 if (0 != mtd_get_info(fd, &meminfo))
472 {
473 printf("[libmtd]: mtd_write_offset, get fd(%d) info error, %s\n", fd, strerror(errno));
474 return -1;
475 }
476 if (count <= 0 || count > meminfo.erasesize)
477 {
478 printf("[libmtd]: mtd_write_offset, count(0x%lx), less than 0, or larger than erasesize(0x%x)\n", count, meminfo.erasesize);
479 return -1;
480 }
481 if (0 != (offset % meminfo.erasesize))
482 {
483 printf("[libmtd]: mtd_write_offset, not at the beginning of a block, erasesize is 0x%x\n", meminfo.erasesize);
484 return -1;
485 }
486
487 if (mtd_block_isbad(fd, offset))
488 {
489 return -1;
490 }
491
492 if (lseek(fd, offset, SEEK_SET) < 0)
493 {
494 printf("[libmtd]: mtd_write_offset, lseek error = %s!\n", strerror(errno));
495 return -1;
496 }
497 writen_len = writen(fd, buf, count);
498 if (writen_len != count)
499 {
500 if (-1 == writen_len)
501 {
502 printf("[libmtd]: mtd_write_offset, write error, %s\n", strerror(errno));
503 }
504 return -1;
505 }
506
507 return writen_len;
508}
509
510ssize_t mtd_read_offset(int fd, off_t offset, void *buf, size_t count)
511{
512 ssize_t readn_len;
513 struct mtd_info_user meminfo = {0};
514
515 if (fd < 0)
516 {
517 return -1;
518 }
519
520 if (0 != mtd_get_info(fd, &meminfo))
521 {
522 printf("[libmtd]: mtd_read_offset, get fd(%d) info error, %s\n", fd, strerror(errno));
523 return -1;
524 }
525 if (count <= 0 || count > meminfo.erasesize)
526 {
527 printf("[libmtd]: mtd_read_offset, count(0x%lx), less than 0, or larger than erasesize(0x%x)\n", count, meminfo.erasesize);
528 return -1;
529 }
530 if (0 != (offset % meminfo.erasesize))
531 {
532 printf("[libmtd]: mtd_read_offset, not at the beginning of a block, erasesize is %x\n", meminfo.erasesize);
533 return -1;
534 }
535
536 if (mtd_block_isbad(fd, offset))
537 {
538 return -1;
539 }
540
541 if (lseek(fd, offset, SEEK_SET) < 0)
542 {
543 printf("[libmtd]: mtd_read_offset, lseek error = %s!\n", strerror(errno));
544 return -1;
545 }
546 readn_len = readn(fd, buf, count);
547 if (readn_len != count)
548 {
549 if (-1 == readn_len)
550 {
551 printf("[libmtd]: mtd_read_offset, read error, %s\n", strerror(errno));
552 }
553 return -1;
554 }
555
556 return readn_len;
557}
558
559static int zftl_verify_partition(const char *partition_name, const char *image_file)
560{
561 int ret = 0;
562 ssize_t rd_len;
563 size_t read_size = 4096;
564 char zftl_path[MTD_PATH_LENGTH_MAX] = {0};
565 int fd_zftl = -1;
566 struct mtd_info_user meminfo = {0};
567
568 off_t data_size = 0;
569 off_t index = 0;
570 off_t fd_img_index = 0;
571 int fd_img = -1;
572 char *buf = NULL;
573 char *buf2 = NULL;
574 struct stat statbuff = {0};
575
576 if (NULL == partition_name || NULL == image_file)
577 {
578 return -1;
579 }
580
581 ret = mtd_find(partition_name, DEVICE_ZFTL, zftl_path, MTD_PATH_LENGTH_MAX);
582 if (ret < 0)
583 {
584 printf("[libmtd]: zftl_verify_partition, mtd_find %s failed\n", partition_name);
585 return -1;
586 }
587 fd_zftl = open(zftl_path, O_RDONLY);
588 if (fd_zftl < 0)
589 {
590 printf("[libmtd]: zftl_verify_partition, open %s error, %s\n", partition_name, strerror(errno));
591 return -1;
592 }
593
594 if (stat(image_file, &statbuff) < 0)
595 {
596 printf("[libmtd]: zftl_verify_partition, stat %s failed, %s\n", image_file, strerror(errno));
597 ret = -1;
598 goto out;
599 }
600
601 fd_img = open(image_file, O_RDONLY);
602 if (fd_img < 0)
603 {
604 printf("[libmtd]: zftl_verify_partition, open %s failed, %s\n", image_file, strerror(errno));
605 ret = -1;
606 goto out;
607 }
608
609 buf = (char *)malloc(read_size);
610 if (!buf)
611 {
612 printf("[libmtd]: zftl_verify_partition, malloc failed\n");
613 ret = -1;
614 goto out;
615 }
616 buf2 = (char *)malloc(read_size);
617 if (!buf2)
618 {
619 printf("[libmtd]: zftl_verify_partition, malloc2 failed\n");
620 ret = -1;
621 goto out;
622 }
623
624 for (index = 0; fd_img_index < statbuff.st_size; index += read_size)
625 {
626 //memset(buf, 0xFF, read_size);
627
628 if (fd_img_index + read_size > statbuff.st_size)
629 {
630 data_size = statbuff.st_size - fd_img_index;
631 }
632 else
633 {
634 data_size = read_size;
635 }
636 // data_size = (fd_img_index + read_size > statbuff.st_size) ? (statbuff.st_size - fd_img_index) : (read_size);
637
638 rd_len = readn(fd_img, buf, (size_t)data_size);
639 if (rd_len < 0)
640 {
641 printf("[libmtd]: zftl_verify_partition, read image file %s error, %s\n", image_file, strerror(errno));
642 ret = -1;
643 goto out;
644 }
645 fd_img_index += data_size;
646
647 rd_len = readn(fd_zftl, buf2, (size_t)data_size);
648 if (rd_len < 0)
649 {
650 printf("[libmtd]: zftl_verify_partition, read zftl %s error, %s\n", partition_name, strerror(errno));
651 ret = -1;
652 goto out;
653 }
654
655 if (memcmp(buf, buf2, (size_t)data_size) != 0)
656 {
657 printf("[libmtd]: zftl_verify_partition, data memcmp %s error\n", partition_name);
658 ret = -1;
659 goto out;
660 }
661 }
662
663 ret = 0;
664out:
665 if (fd_zftl >= 0)
666 {
667 //fsync(fd_zftl);
668 close(fd_zftl);
669 }
670
671 if (buf != NULL)
672 {
673 // memset(buf, 0xFF, meminfo.erasesize);
674 free(buf);
675 }
676 if (buf2 != NULL)
677 {
678 // memset(buf, 0xFF, meminfo.erasesize);
679 free(buf2);
680 }
681
682 if (fd_img >= 0)
683 {
684 close(fd_img);
685 }
686 if (ret == 0)
687 {
688 printf("[libmtd]: zftl %s verify sucess\n", partition_name);
689 }
690 else
691 {
692 printf("[libmtd]: zftl %s verify fail\n", partition_name);
693 }
694
695 return ret;
696}
697
698int zftl_write_partition(const char *partition_name, const char *image_file)
699{
700 int ret = 0;
701 ssize_t wr_len;
702 size_t write_size = 4096;
703 char zftl_path[MTD_PATH_LENGTH_MAX] = {0};
704 int fd_zftl = -1;
705 struct mtd_info_user meminfo = {0};
706
707 off_t data_size = 0;
708 off_t index = 0;
709 off_t fd_img_index = 0;
710 int fd_img = -1;
711 char *buf = NULL;
712 struct stat statbuff = {0};
713
714 if (NULL == partition_name || NULL == image_file)
715 {
716 return -1;
717 }
718
719 ret = mtd_find(partition_name, DEVICE_ZFTL, zftl_path, MTD_PATH_LENGTH_MAX);
720 if (ret < 0)
721 {
722 printf("[libmtd]: zftl_write_partition, mtd_find %s failed\n", partition_name);
723 return -1;
724 }
725 fd_zftl = open(zftl_path, O_RDWR);
726 if (fd_zftl < 0)
727 {
728 printf("[libmtd]: zftl_write_partition, open %s error, %s\n", partition_name, strerror(errno));
729 return -1;
730 }
731
732 if (stat(image_file, &statbuff) < 0)
733 {
734 printf("[libmtd]: zftl_write_partition, stat %s failed, %s\n", image_file, strerror(errno));
735 ret = -1;
736 goto out;
737 }
738
739 fd_img = open(image_file, O_RDONLY);
740 if (fd_img < 0)
741 {
742 printf("[libmtd]: zftl_write_partition, open %s failed, %s\n", image_file, strerror(errno));
743 ret = -1;
744 goto out;
745 }
746
747 buf = (char *)malloc(write_size);
748 if (!buf)
749 {
750 printf("[libmtd]: zftl_write_partition, malloc failed\n");
751 ret = -1;
752 goto out;
753 }
754
755 for (index = 0; fd_img_index < statbuff.st_size; index += write_size)
756 {
757 memset(buf, 0xFF, write_size);
758
759 if (fd_img_index + write_size > statbuff.st_size)
760 {
761 data_size = statbuff.st_size - fd_img_index;
762 }
763 else
764 {
765 data_size = write_size;
766 }
767 // data_size = (fd_img_index + write_size > statbuff.st_size) ? (statbuff.st_size - fd_img_index) : (write_size);
768
769 wr_len = readn(fd_img, buf, (size_t)data_size);
770 if (wr_len < 0)
771 {
772 printf("[libmtd]: zftl_write_partition, read %s error, %s\n", image_file, strerror(errno));
773 ret = -1;
774 goto out;
775 }
776 fd_img_index += data_size;
777
778 wr_len = writen(fd_zftl, buf, (size_t)data_size);
779 if (wr_len < 0)
780 {
781 printf("[libmtd]: zftl_write_partition, write %s error, %s\n", partition_name, strerror(errno));
782 ret = -1;
783 goto out;
784 }
785
786 }
787 if (fd_img_index < statbuff.st_size)
788 {
789 printf("[libmtd]: zftl_write_partition, No space left, writelen=0x%lx, filesize=0x%lx\n", fd_img_index, statbuff.st_size);
790 ret = -1;
791 goto out;
792 }
793 ret = 0;
794out:
795 if (fd_zftl >= 0)
796 {
797 fsync(fd_zftl);
798 close(fd_zftl);
799 }
800
801 if (buf != NULL)
802 {
803 // memset(buf, 0xFF, meminfo.erasesize);
804 free(buf);
805 }
806
807 if (fd_img >= 0)
808 {
809 close(fd_img);
810 }
811
812 if (ret == 0)
813 {
814 //write sucess then do verify
815 ret = zftl_verify_partition(partition_name, image_file);
816 }
817
818 return ret;
819}