[embeded] Port u-boot to mini2440 (3)

2017-4-26 写技术

After embedded board run to kernel, it will called a file system. It is NAND flash in mini2440 system board, so take a yaffs file system to the flash. This part is for porting yaffs file system function in u-boot.


1.Edit /common/cmd_nand.c:

diff -uNr u-boot-2009.08_nand/common/cmd_nand.c u-boot-2009.08_yaffs/common/cmd_nand.c
--- u-boot-2009.08_nand/common/cmd_nand.c	2017-03-19 15:24:58.000000000 +0800
+++ u-boot-2009.08_yaffs/common/cmd_nand.c	2017-04-25 16:26:18.501859985 +0800
@@ -389,6 +389,26 @@
 			else
 				ret = nand_write_skip_bad(nand, off, &size,
 							  (u_char *)addr);
+
+#if defined(ENABLE_CMD_NAND_YAFFS)
+		}else if(s != NULL &&
+		          (!strcmp(s,".yaffs")|| !strcmp(s, ".yaffs1"))){
+			if(read){
+				printf("nand read.yaffs[1] is not provide by nicholas!");
+			}else{
+				nand->rw_oob = 1;
+#if defined(ENABLE_CMD_NAND_YAFFS_SKIPFB)
+				nand->skipfirstblk = 1;
+#else
+				nand->skipfirstblk = 0;
+#endif
+				ret = nand_write_skip_bad(nand, off, &size, (u_char *)addr);
+#if defined(ENABLE_CMD_NAND_YAFFS_SKIPFB)
+				nand->skipfirstblk = 0;
+#endif
+				nand->rw_oob = 0;
+			}	
+#endif
 		} else if (!strcmp(s, ".oob")) {
 			/* out-of-band data */
 			mtd_oob_ops_t ops = {

2.Edit /drivers/mtd/nand/nand_base.c:

diff -uNr u-boot-2009.08_nand/drivers/mtd/nand/nand_base.c u-boot-2009.08_yaffs/drivers/mtd/nand/nand_base.c
--- u-boot-2009.08_nand/drivers/mtd/nand/nand_base.c	2017-03-19 15:24:54.000000000 +0800
+++ u-boot-2009.08_yaffs/drivers/mtd/nand/nand_base.c	2017-04-25 16:52:28.501848090 +0800
@@ -1959,6 +1959,29 @@
 	struct nand_chip *chip = mtd->priv;
 	int ret;
 
+#if defined(ENABLE_CMD_NAND_YAFFS)
+	int oldopsmode = 0;
+	if(mtd->rw_oob == 1){
+		size_t oobsize = mtd->oobsize;
+		size_t datasize = mtd->writesize;
+		int i = 0;
+		uint8_t oobtemp[oobsize];
+		int datapages = 0;
+		datapages = len/(datasize);
+		for(i=0;i<(datapages);i++){
+			memcpy((void *)oobtemp,
+				(void *)(buf + datasize*(i+1)),
+				oobsize);
+			memmove((void *)(buf + datasize*(i+1)),
+				(void *)(buf + datasize*(i+1) + oobsize),
+				(datapages - (i+1))*(datasize)+(datapages - 1)*oobsize);
+			memcpy((void *)(buf + (datapages)*(datasize + oobsize)- oobsize),
+				(void *)(oobtemp),
+				oobsize);
+		}
+	}
+#endif
+
 	/* Do not allow reads past end of device */
 	if ((to + len) > mtd->size)
 		return -EINVAL;
@@ -1969,7 +1992,18 @@
 
 	chip->ops.len = len;
 	chip->ops.datbuf = (uint8_t *)buf;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+	if(mtd->rw_oob != 1){
+		chip->ops.oobbuf = NULL;
+	}else{
+		chip->ops.oobbuf = (uint8_t *)(buf + len);
+		chip->ops.ooblen = mtd->oobsize;
+		oldopsmode = chip->ops.mode;
+		chip->ops.mode = MTD_OOB_RAW;
+	}
+#else
 	chip->ops.oobbuf = NULL;
+#endif
 
 	ret = nand_do_write_ops(mtd, to, &chip->ops);
 
@@ -1977,6 +2011,10 @@
 
 	nand_release_device(mtd);
 
+#if defined(ENABLE_CMD_NAND_YAFFS)
+	chip->ops.mode = oldopsmode;
+#endif
+
 	return ret;
 }

3.Edit /drivers/mtd/nand/nand_util.c:

diff -uNr u-boot-2009.08_nand/drivers/mtd/nand/nand_util.c u-boot-2009.08_yaffs/drivers/mtd/nand/nand_util.c
--- u-boot-2009.08_nand/drivers/mtd/nand/nand_util.c	2017-03-19 15:24:54.000000000 +0800
+++ u-boot-2009.08_yaffs/drivers/mtd/nand/nand_util.c	2017-04-25 16:53:16.317847727 +0800
@@ -481,6 +481,22 @@
 	size_t len_incl_bad;
 	u_char *p_buffer = buffer;
 
+#if defined(ENABLE_CMD_NAND_YAFFS)
+	if(nand->rw_oob == 1){
+		size_t oobsize = nand->oobsize;
+		size_t datasize = nand->writesize;
+		int datapages = 0;
+		
+		if(((*length)%(nand->oobsize + nand->writesize))!= 0){
+			printf("Attempt to write error length data!\n");
+			return -EINVAL;
+		}
+		datapages = *length/(datasize + oobsize);
+		*length = datapages * datasize;
+		left_to_write = *length;
+	}
+#endif
+
 	/* Reject writes, which are not page aligned */
 	if ((offset & (nand->writesize - 1)) != 0 ||
 	    (*length & (nand->writesize - 1)) != 0) {
@@ -495,6 +511,7 @@
 		return -EINVAL;
 	}
 
+#if !defined(ENABLE_CMD_NAND_YAFFS)
 	if (len_incl_bad == *length) {
 		rval = nand_write (nand, offset, length, buffer);
 		if (rval != 0)
@@ -503,6 +520,7 @@
 
 		return rval;
 	}
+#endif
 
 	while (left_to_write > 0) {
 		size_t block_offset = offset & (nand->erasesize - 1);
@@ -516,6 +534,14 @@
 			offset += nand->erasesize - block_offset;
 			continue;
 		}
+#if defined(ENABLE_CMD_NAND_YAFFS)
+		if(nand->skipfirstblk == 1){
+			nand->skipfirstblk = 0;
+			printf("Skip the first good block %llx\n", offset & ~(nand->erasesize - 1));
+			offset += nand->erasesize - block_offset;
+			continue;
+		}
+#endif
 
 		if (left_to_write < (nand->erasesize - block_offset))
 			write_size = left_to_write;
@@ -531,8 +557,17 @@
 		}
 
 		left_to_write -= write_size;
+		printf("%d%% is complete.\r", 100 - (left_to_write/(*length/100)));
 		offset        += write_size;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+		if(nand->rw_oob == 1){
+			p_buffer += write_size + (write_size/nand->writesize * nand->oobsize);
+		}else{
+			p_buffer += write_size;
+		}
+#else
 		p_buffer      += write_size;
+#endif
 	}
 
 	return 0;

4. Edit /include/linux/mtd/mtd.h:

diff -uNr u-boot-2009.08_nand/include/linux/mtd/mtd.h u-boot-2009.08_yaffs/include/linux/mtd/mtd.h
--- u-boot-2009.08_nand/include/linux/mtd/mtd.h	2017-03-19 15:24:58.000000000 +0800
+++ u-boot-2009.08_yaffs/include/linux/mtd/mtd.h	2017-04-25 16:51:27.333848553 +0800
@@ -129,6 +129,11 @@
 	 */
 	u_int32_t writesize;
 
+#if defined(ENABLE_CMD_NAND_YAFFS)
+	u_char rw_oob;
+	u_char skipfirstblk;
+#endif
+
 	u_int32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */
 	u_int32_t oobavail;  /* Available OOB bytes per block */

标签: embedded

发表评论:

Powered by anycle 湘ICP备15001973号-1