예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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;
}