static int flash_write_image(int mtdnum, struct img_type *img) { struct flash_description *flash = get_flash_info(); if (!isNand(flash, mtdnum)) return flash_write_nor(mtdnum, img); return flash_write_nand(mtdnum, img); }
static int flash_write_image(int mtdnum, struct img_type *img, bool hamming1) { struct flash_description *flash = get_flash_info(); if (!isNand(flash, mtdnum)) return flash_write_nor(mtdnum, img); if (hamming1) return flash_write_nand_hamming1(mtdnum, img); else return flash_write_nand(mtdnum, img); }
static int flash_write_nand_hamming1(int mtdnum, struct img_type *img) { struct flash_description *flash = get_flash_info(); struct mtd_dev_info *mtd = &flash->mtd_info[mtdnum].mtd; int fd = img->fdin; int ofd; unsigned char *page; unsigned char code[3]; unsigned char ecc[12]; int cnt; int i, j; int len; long long imglen = 0; int page_idx = 0; int ret = EXIT_FAILURE; char mtd_device[LINESIZE]; bool rawNand = isNand(flash, mtdnum); snprintf(mtd_device, sizeof(mtd_device), "/dev/mtd%d", mtdnum); /* * Get page size */ len = mtd->min_io_size; if (!rawNand) len *= 2; imglen = img->size; page = (unsigned char *) malloc(len); if (page == NULL) { ERROR("Error opening input file"); goto out; } ofd = open(mtd_device, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG); if (ofd < 0) { ERROR("Error opening output file"); goto out_input; } if (rawNand) /* The device has to be accessed in RAW mode to fill oob area */ if (ioctl(ofd, MTDFILEMODE, (void *) MTD_FILE_MODE_RAW)) { ERROR("RAW mode access"); goto out_input; } while (imglen > 0) { cnt = read(fd, page, min(mtd->min_io_size, imglen)); if (cnt < 0) break; /* Writes has to be page aligned */ if (cnt < mtd->min_io_size) memset(page + cnt, 0xff, mtd->min_io_size - cnt); if (rawNand) for (i = 0; i < mtd->min_io_size / mtd->subpage_size; i++) { /* Obtain ECC code for sector */ ecc_sector(page + i * mtd->subpage_size, code, mtd->subpage_size); for (j = 0; j < 3; j++) ecc[i * 3 + j] = code[j]; } else /* The OneNAND has a 2-plane memory but the ROM boot * can only access one of them, so we have to double * copy each 2K page. */ memcpy(page + mtd->min_io_size, page, mtd->min_io_size); if (write(ofd, page, len) != len) { perror("Error writing to output file"); goto out_output; } if (rawNand) if (write_ecc(ofd, ecc, page_idx * mtd->min_io_size)) { perror("Error writing ECC in OOB area"); goto out_output; } page_idx++; imglen -= cnt; } if (cnt < 0) { ERROR("File I/O error on input file"); goto out_output; } TRACE("Successfully written %s to mtd %d", img->fname, mtdnum); ret = EXIT_SUCCESS; out_output: close(ofd); out_input: free(page); out: return ret; }