[U-Boot] U-boot nand bug, read.part should fail
Harvey Chapman
hchapman-uboot at 3gfp.com
Fri Feb 8 16:48:16 CET 2013
On Feb 7, 2013, at 5:22 PM, Scott Wood <scottwood at freescale.com> wrote:
> It's fine until you get a bad block in the partition, and you end up accessing the first block of the next partition (or getting "Attempt to read/write outside the flash area" if it's the last partition).
>
> Of course, fixing partition/chip accesses to account for this when determining size would be even better. :-)
Something like this?
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -621,60 +621,78 @@ int do_nand(cmd_tbl_t * cmdtp, int flag,
nand = &nand_info[dev];
s = strchr(cmd, '.');
if (s && !strcmp(s, ".raw")) {
raw = 1;
if (arg_off(argv[3], &dev, &off, &size))
return 1;
if (argc > 4 && !str2long(argv[4], &pagecount)) {
printf("'%s' is not a number\n", argv[4]);
return 1;
}
if (pagecount * nand->writesize > size) {
puts("Size exceeds partition or device limit\n");
return -1;
}
rwsize = pagecount * (nand->writesize + nand->oobsize);
} else {
if (arg_off_size(argc - 3, argv + 3, &dev,
&off, &size) != 0)
return 1;
rwsize = size;
}
+ /* If no size was given, it has been calculated for us as
+ * the remainder of the chip or partition from offset. Adjust
+ * down for bad blocks, if necessary.
+ */
+ if (argc < 4) {
+ nand_info_t *nand = &nand_info[dev];
+ int maxsize = rwsize;
+ int offset = off;
+ for (; offset < maxsize; offset += nand->erasesize)
+ if (nand_block_isbad(nand, offset))
+ rwsize -= nand->erasesize;
+
+ if (rwsize != maxsize)
+ printf("\nsize adjusted to %d (%d bad blocks)\n",
+ rwsize,
+ (maxsize - rwsize) / nand->erasesize);
+ }
+
if (!s || !strcmp(s, ".jffs2") ||
!strcmp(s, ".e") || !strcmp(s, ".i") || !strcmp(s, ".part")) {
if (read)
ret = nand_read_skip_bad(nand, off, &rwsize,
(u_char *)addr);
else
ret = nand_write_skip_bad(nand, off, &rwsize,
(u_char *)addr, 0);
#ifdef CONFIG_CMD_NAND_TRIMFFS
} else if (!strcmp(s, ".trimffs")) {
if (read) {
printf("Unknown nand command suffix '%s'\n", s);
return 1;
}
ret = nand_write_skip_bad(nand, off, &rwsize,
(u_char *)addr,
WITH_DROP_FFS);
#endif
#ifdef CONFIG_CMD_NAND_YAFFS
} else if (!strcmp(s, ".yaffs")) {
if (read) {
printf("Unknown nand command suffix '%s'.\n", s);
return 1;
}
ret = nand_write_skip_bad(nand, off, &rwsize,
(u_char *)addr,
WITH_INLINE_OOB);
#endif
} else if (!strcmp(s, ".oob")) {
/* out-of-band data */
More information about the U-Boot
mailing list