⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yaffs.c

📁 斯道S3C2410普及版III型vivi-usb启动源码
💻 C
字号:
/* * vivi/drivers/mtd/nand/bon.c  * * Based on vivi/util/imagewrite * * $Id: bon.c,v 1.13 2003/06/12 11:14:01 nandy Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Description: Simple management routines for the bon file system. * */#include <config.h>#include <mtd/mtd.h>#include <mtd/nand_ecc.h>#include <printk.h>#include <errno.h>#include <heap.h>#include <string.h>#include <command.h>#include <ctype.h>#include <mtd/bonfs.h>#include <priv_data.h>#ifdef CONFIG_MTD_YAFFS// countBits is a quick way of counting the number of bits in a byte.// ie. countBits[n] holds the number of 1 bits in a byte with the value n.static const char countBits[256] ={	0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,	1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,	1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,	2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,	1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,	2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,	2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,	3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,	1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,	2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,	2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,	3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,	2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,	3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,	3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,	4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8};/* * OOB layout */struct nand_oobinfo yaffs_oobinfo = {	useecc: 1,	eccpos: {8, 9, 10, 13, 14, 15}};#if 1struct nand_oobinfo yaffs_noeccinfo = {	useecc: 0,};static voidmark_bad_yaffs(struct mtd_info *mtd, ulong offset){	char oobbuf[NAND_OOB_SIZE];	memset (oobbuf, 0xff, NAND_OOB_SIZE);	oobbuf[5] = 0;	mtd->write_oob(mtd, offset, NAND_OOB_SIZE, NULL, oobbuf);}static intis_bad_yaffs_block(struct mtd_info *mtd, ulong offset){	unsigned char oobbuf[NAND_OOB_SIZE];	char buf[NAND_SECTOR_SIZE];	struct erase_info erase;	size_t retlen;	erase.addr = offset;	erase.len = mtd->erasesize;	if (mtd->erase(mtd, &erase) < 0) {printk("erase error\n");return 1;}	if (mtd->read_oob(mtd, offset, NAND_OOB_SIZE, &retlen, oobbuf)) {		printk("read oob error\n");		return -1;	}	if (countBits[oobbuf[5]] < 7) {printk("countbit error\n");return -1;}	if (mtd->read(mtd, offset, NAND_SECTOR_SIZE, &retlen, buf)) {		printk("read error 1\n");		return -1;	}	if (retlen != NAND_SECTOR_SIZE) {		printk("read error\n");		mark_bad_yaffs(mtd, offset);		return -1;	}	return 0;}static intwrite_oob_yaffs(struct mtd_info *mtd, char *buf, ulong offset){	char oob_buf[NAND_OOB_SIZE];//	unsigned char ecc[3];	memset(oob_buf, 0xFF, NAND_OOB_SIZE);/*	calc_ecc(mtd,buf, ecc);	memcpy(oob_buf + 8, ecc, 3);	calc_ecc(mtd,buf + 256, ecc);	memcpy(oob_buf + 11, ecc, 3);*/	memcpy(oob_buf, buf+NAND_SECTOR_SIZE, 8);	if (mtd->write_oob(mtd, offset, NAND_OOB_SIZE, NULL, oob_buf))		return 1;	else		return 0;}/**	Use NAND write ECC*/static int nand_write_ecc_yaffs (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, char * buf){#if 0/*	int i=0,cnt=len;	int col;	col=(mtd->oobblock-1) & len;	if(col){		cnt=len+mtd->oobblock-col;	}	for(i=len;i<cnt;i++)		buf[i]=0xff;*/	char tmp[NAND_SECTOR_SIZE];	int i;	size_t retlen;	mtd->read(mtd, to, NAND_SECTOR_SIZE, &retlen, tmp);	printk("read 0x%s\n", to);	return 0;#else	printk("1write to 0x%x buf=0x%x\n", buf, to);	mtd->write_ecc(mtd, to, len, retlen, (u_char *)buf, NULL, &yaffs_oobinfo);	if(len == (int)(*retlen)){		*retlen=len;		return 0;	}else{ 		printk("here nand write error\n");		return (*retlen);	}#endif}	static intwrite_block_yaffs(struct mtd_info *mtd, ulong offset, char *buf){	int i;	size_t retlen = 0;	//printk("offset=0x%x buf=0x%x\n", offset, buf);	if (is_bad_yaffs_block(mtd, offset)) {printk("bad block\n"); return 1;}	for (i = 0; i < (mtd->erasesize/NAND_SECTOR_SIZE); i++) {//		printk("buf=0x%x\n", buf);		mtd->write(mtd, offset, NAND_SECTOR_SIZE, &retlen, buf);//		mtd->write_ecc(mtd, offset, NAND_SECTOR_SIZE, &retlen, buf, NULL, &yaffs_oobinfo);//		if (nand_write_ecc_yaffs(mtd, offset, NAND_SECTOR_SIZE, &retlen, buf))//			{printk("write_ecc error\n"); return 1;}		if (retlen != NAND_SECTOR_SIZE)			{printk("size error\n");return 1;}	//	if (write_oob_yaffs(mtd, buf, offset))  return 1;		offset += NAND_SECTOR_SIZE;		buf += NAND_SECTOR_SIZE+NAND_OOB_SIZE;	}}char yaffs_bon_block[(NAND_SECTOR_SIZE+NAND_OOB_SIZE)*32];#endifint yaffs_led_flag=0;extern mtd_partition_t *mtd_parts;extern int *nb_mtd_parts;write_bon_yaffs(struct mtd_info *mtd, ulong offset, char *src, long size){	char *buf=src;//	unsigned short *bad;	ulong addr, mtdsize, mtdstart;	int i;	mtd_partition_t *parts = mtd_parts;	int num = *nb_mtd_parts;	unsigned long sum=0;		size -= size%528 ;	//printk("write_bon_yaffs,offset =  0x%x \n",offset);	//printk("write_bon_yaffs,size =  0x%x \n",size);		if (offset % mtd->erasesize) {		printk("bad alignment\n");		return -1;	}	if (!(mtd->oobsize==NAND_OOB_SIZE)&&mtd->oobblock==NAND_SECTOR_SIZE){		printk("Unknow flash (not normal NAND flash)\n");		return -1;	}	for (i = 0; i < num; i++) {		if (parts[i].offset == offset) break;	}	if (i == num) i = num - 1;		//printk ("i = %d \n",i);	//printk ("part name is 0x%s\n",parts[i].name);	//printk ("part offset is 0x%x\n",parts[i].offset);	//printk ("part size is 0x%x\n",parts[i].size);	//printk ("part flag is 0x%x\n",parts[i].flag);					if (offset + size > parts[i].offset + parts[i].size) {		printk("image is too big for this partition\n");		return -1;	}	if ((size/(mtd->oobblock+mtd->oobsize)+32)*mtd->oobblock> parts[i].size)	{		printk("image is too big for this partition for yaffs\n");		return -1;	}//	block = (offset - parts[i].offset) / mtd->erasesize;//	bad = parts[i].bad_blocks;//	if (bad) {//		while (*bad++ <= block) block++;//	}//	offset = parts[i].offset + block * mtd->erasesize;	mtdsize = parts[i].size;	mtdstart = parts[i].offset;	//printk ("addr is 0x%x ,mtdsize is 0x%x\n",mtdstart,mtdsize);	/*	for (i = 0; i < 32; i ++)		printk("buf[%d] = 0x%x ",i,buf[i] );	printk("\n");	while(1);	*/	for (addr=mtdstart; addr<mtdsize+mtdstart; addr+=mtd->erasesize)	{		char oob_buf[NAND_OOB_SIZE];		struct erase_info erase;		erase.addr = addr;		erase.len = mtd->erasesize;		//printk("Erase block at 0x%x\n", addr);		if (mtd->erase(mtd, &erase) < 0)		{			printk("addr 0x%x erase error\n",erase.addr);			//mark_bad_yaffs(mtd,addr);			//return 1;			continue;		}				//if (yaffs_led_flag%50==0)Led_Display(0x6);		//if (yaffs_led_flag%50==25)Led_Display(0x9);		//yaffs_led_flag++;		mtd->read_oob(mtd, addr, NAND_OOB_SIZE, NULL, oob_buf);		if (countBits[oob_buf[5]]<7)		{			printk("block at 0x%lx is damaged\n", addr);			//mark_bad_yaffs(mtd,addr);					}		else		{			if (addr>mtdstart)			{				ulong tmp=addr;				for (tmp=0; tmp<mtd->erasesize; tmp+=NAND_SECTOR_SIZE)				{					if (size > 0){						char oobbuf[NAND_OOB_SIZE];						memcpy(oobbuf, buf+NAND_SECTOR_SIZE, 16);						oobbuf[8]=0xff;						oobbuf[9]=0xff;						oobbuf[10]=0xff;						oobbuf[13]=0xff;						oobbuf[14]=0xff;						oobbuf[15]=0xff;						mtd->write_oob(mtd, tmp+addr, NAND_OOB_SIZE, NULL, oobbuf);						mtd->write_ecc(mtd, tmp+addr, NAND_SECTOR_SIZE, NULL, buf, NULL, &yaffs_oobinfo);						buf+=NAND_SECTOR_SIZE+NAND_OOB_SIZE;						size -= NAND_SECTOR_SIZE+NAND_OOB_SIZE;						sum+= 528;						if (size <= 0)						{							printk("yaffs wiriter has write %d  byte\n",sum);						return;							}					}				}			}		}	}	return 0;}#endif /* CONFIG_CMD_BONFS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -