mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
[PATCH] NAND: Partition name support added to NAND subsystem
chpart, nboot and NAND subsystem related commands now accept also partition name to specify offset. Signed-off-by: Ladislav Michl <ladis@linux-mips.org> Signed-off-by: Stefan Roese <sr@denx.de>
This commit is contained in:
parent
07a69a18c2
commit
856f054410
4 changed files with 234 additions and 182 deletions
|
@ -1300,7 +1300,7 @@ static void list_partitions(void)
|
|||
* Given partition identifier in form of <dev_type><dev_num>,<part_num> find
|
||||
* corresponding device and verify partition number.
|
||||
*
|
||||
* @param id string describing device and partition
|
||||
* @param id string describing device and partition or partition name
|
||||
* @param dev pointer to the requested device (output)
|
||||
* @param part_num verified partition number (output)
|
||||
* @param part pointer to requested partition (output)
|
||||
|
@ -1309,11 +1309,23 @@ static void list_partitions(void)
|
|||
int find_dev_and_part(const char *id, struct mtd_device **dev,
|
||||
u8 *part_num, struct part_info **part)
|
||||
{
|
||||
struct list_head *dentry, *pentry;
|
||||
u8 type, dnum, pnum;
|
||||
const char *p;
|
||||
|
||||
DEBUGF("--- find_dev_and_part ---\nid = %s\n", id);
|
||||
|
||||
list_for_each(dentry, &devices) {
|
||||
*part_num = 0;
|
||||
*dev = list_entry(dentry, struct mtd_device, link);
|
||||
list_for_each(pentry, &(*dev)->parts) {
|
||||
*part = list_entry(pentry, struct part_info, link);
|
||||
if (strcmp((*part)->name, id) == 0)
|
||||
return 0;
|
||||
(*part_num)++;
|
||||
}
|
||||
}
|
||||
|
||||
p = id;
|
||||
*dev = NULL;
|
||||
*part = NULL;
|
||||
|
|
|
@ -36,6 +36,15 @@
|
|||
#include <jffs2/jffs2.h>
|
||||
#include <nand.h>
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
|
||||
|
||||
/* parition handling routines */
|
||||
int mtdparts_init(void);
|
||||
int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
|
||||
int find_dev_and_part(const char *id, struct mtd_device **dev,
|
||||
u8 *part_num, struct part_info **part);
|
||||
#endif
|
||||
|
||||
extern nand_info_t nand_info[]; /* info for NAND chips */
|
||||
|
||||
static int nand_dump_oob(nand_info_t *nand, ulong off)
|
||||
|
@ -83,50 +92,75 @@ static int nand_dump(nand_info_t *nand, ulong off)
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize)
|
||||
static inline int str2long(char *p, ulong *num)
|
||||
{
|
||||
*off = 0;
|
||||
*size = 0;
|
||||
char *endptr;
|
||||
|
||||
#if defined(CONFIG_JFFS2_NAND) && defined(CFG_JFFS_CUSTOM_PART)
|
||||
if (argc >= 1 && strcmp(argv[0], "partition") == 0) {
|
||||
int part_num;
|
||||
struct part_info *part;
|
||||
const char *partstr;
|
||||
*num = simple_strtoul(p, &endptr, 16);
|
||||
return (*p != '\0' && *endptr == '\0') ? 1 : 0;
|
||||
}
|
||||
|
||||
if (argc >= 2)
|
||||
partstr = argv[1];
|
||||
else
|
||||
partstr = getenv("partition");
|
||||
static int
|
||||
arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size)
|
||||
{
|
||||
int idx = nand_curr_device;
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
|
||||
struct mtd_device *dev;
|
||||
struct part_info *part;
|
||||
u8 pnum;
|
||||
|
||||
if (partstr)
|
||||
part_num = (int)simple_strtoul(partstr, NULL, 10);
|
||||
else
|
||||
part_num = 0;
|
||||
|
||||
part = jffs2_part_info(part_num);
|
||||
if (part == NULL) {
|
||||
printf("\nInvalid partition %d\n", part_num);
|
||||
return;
|
||||
if (argc >= 1 && !(str2long(argv[0], off))) {
|
||||
if ((mtdparts_init() == 0) &&
|
||||
(find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) {
|
||||
if (dev->id->type != MTD_DEV_TYPE_NAND) {
|
||||
puts("not a NAND device\n");
|
||||
return -1;
|
||||
}
|
||||
*off = part->offset;
|
||||
if (argc >= 2) {
|
||||
if (!(str2long(argv[1], size))) {
|
||||
printf("'%s' is not a number\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
if (*size > part->size)
|
||||
*size = part->size;
|
||||
} else {
|
||||
*size = part->size;
|
||||
}
|
||||
idx = dev->id->num;
|
||||
*nand = nand_info[idx];
|
||||
goto out;
|
||||
}
|
||||
*size = part->size;
|
||||
*off = (ulong)part->offset;
|
||||
} else
|
||||
}
|
||||
#endif
|
||||
{
|
||||
if (argc >= 1)
|
||||
*off = (ulong)simple_strtoul(argv[0], NULL, 16);
|
||||
else
|
||||
*off = 0;
|
||||
|
||||
if (argc >= 2)
|
||||
*size = (ulong)simple_strtoul(argv[1], NULL, 16);
|
||||
else
|
||||
*size = totsize - *off;
|
||||
|
||||
if (argc >= 1) {
|
||||
if (!(str2long(argv[0], off))) {
|
||||
printf("'%s' is not a number\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
*off = 0;
|
||||
}
|
||||
|
||||
if (argc >= 2) {
|
||||
if (!(str2long(argv[1], size))) {
|
||||
printf("'%s' is not a number\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
*size = nand->size - *off;
|
||||
}
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
|
||||
out:
|
||||
#endif
|
||||
printf("device %d ", idx);
|
||||
if (*size == nand->size)
|
||||
puts("whole chip\n");
|
||||
else
|
||||
printf("offset 0x%x, size 0x%x\n", *off, *size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
|
@ -213,35 +247,22 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Syntax is:
|
||||
* 0 1 2 3 4
|
||||
* nand erase [clean] [off size]
|
||||
*/
|
||||
if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) {
|
||||
nand_erase_options_t opts;
|
||||
int clean = argc >= 3 && !strcmp("clean", argv[2]);
|
||||
int rest_argc = argc - 2;
|
||||
char **rest_argv = argv + 2;
|
||||
/* "clean" at index 2 means request to write cleanmarker */
|
||||
int clean = argc > 2 && !strcmp("clean", argv[2]);
|
||||
int o = clean ? 3 : 2;
|
||||
int scrub = !strcmp(cmd, "scrub");
|
||||
|
||||
if (clean) {
|
||||
rest_argc--;
|
||||
rest_argv++;
|
||||
}
|
||||
|
||||
if (rest_argc == 0) {
|
||||
|
||||
printf("\nNAND %s: device %d whole chip\n",
|
||||
cmd,
|
||||
nand_curr_device);
|
||||
|
||||
off = size = 0;
|
||||
} else {
|
||||
arg_off_size(rest_argc, rest_argv, &off, &size,
|
||||
nand->size);
|
||||
|
||||
if (off == 0 && size == 0)
|
||||
return 1;
|
||||
|
||||
printf("\nNAND %s: device %d offset 0x%x, size 0x%x\n",
|
||||
cmd, nand_curr_device, off, size);
|
||||
}
|
||||
printf("\nNAND %s: ", scrub ? "scrub" : "erase");
|
||||
/* skip first two or three arguments, look for offset and size */
|
||||
if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0)
|
||||
return 1;
|
||||
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
opts.offset = off;
|
||||
|
@ -250,23 +271,22 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||
opts.quiet = quiet;
|
||||
|
||||
if (scrub) {
|
||||
printf("Warning: "
|
||||
"scrub option will erase all factory set "
|
||||
"bad blocks!\n"
|
||||
" "
|
||||
"There is no reliable way to recover them.\n"
|
||||
" "
|
||||
"Use this command only for testing purposes "
|
||||
"if you\n"
|
||||
" "
|
||||
"are sure of what you are doing!\n"
|
||||
"\nReally scrub this NAND flash? <y/N>\n"
|
||||
);
|
||||
puts("Warning: "
|
||||
"scrub option will erase all factory set "
|
||||
"bad blocks!\n"
|
||||
" "
|
||||
"There is no reliable way to recover them.\n"
|
||||
" "
|
||||
"Use this command only for testing purposes "
|
||||
"if you\n"
|
||||
" "
|
||||
"are sure of what you are doing!\n"
|
||||
"\nReally scrub this NAND flash? <y/N>\n");
|
||||
|
||||
if (getc() == 'y' && getc() == '\r') {
|
||||
opts.scrub = 1;
|
||||
} else {
|
||||
printf("scrub aborted\n");
|
||||
puts("scrub aborted\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -301,13 +321,10 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||
|
||||
addr = (ulong)simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
arg_off_size(argc - 3, argv + 3, &off, &size, nand->size);
|
||||
if (off == 0 && size == 0)
|
||||
return 1;
|
||||
|
||||
read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
|
||||
printf("\nNAND %s: device %d offset %u, size %u ... ",
|
||||
read ? "read" : "write", nand_curr_device, off, size);
|
||||
printf("\nNAND %s: ", read ? "read" : "write");
|
||||
if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
|
||||
return 1;
|
||||
|
||||
s = strchr(cmd, '.');
|
||||
if (s != NULL &&
|
||||
|
@ -334,15 +351,13 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||
opts.quiet = quiet;
|
||||
ret = nand_write_opts(nand, &opts);
|
||||
}
|
||||
printf("%s\n", ret ? "ERROR" : "OK");
|
||||
return ret == 0 ? 0 : 1;
|
||||
} else {
|
||||
if (read)
|
||||
ret = nand_read(nand, off, &size, (u_char *)addr);
|
||||
else
|
||||
ret = nand_write(nand, off, &size, (u_char *)addr);
|
||||
}
|
||||
|
||||
if (read)
|
||||
ret = nand_read(nand, off, &size, (u_char *)addr);
|
||||
else
|
||||
ret = nand_write(nand, off, &size, (u_char *)addr);
|
||||
|
||||
printf(" %d bytes %s: %s\n", size,
|
||||
read ? "read" : "written", ret ? "ERROR" : "OK");
|
||||
|
||||
|
@ -412,9 +427,9 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||
}
|
||||
} else {
|
||||
if (!nand_lock(nand, tight)) {
|
||||
printf ("NAND flash successfully locked\n");
|
||||
puts("NAND flash successfully locked\n");
|
||||
} else {
|
||||
printf ("Error locking NAND flash. \n");
|
||||
puts("Error locking NAND flash\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -422,19 +437,14 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (strcmp(cmd, "unlock") == 0) {
|
||||
if (argc == 2) {
|
||||
off = 0;
|
||||
size = nand->size;
|
||||
} else {
|
||||
arg_off_size(argc - 2, argv + 2, &off, &size,
|
||||
nand->size);
|
||||
}
|
||||
if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
|
||||
return 1;
|
||||
|
||||
if (!nand_unlock(nand, off, size)) {
|
||||
printf("NAND flash successfully unlocked\n");
|
||||
puts("NAND flash successfully unlocked\n");
|
||||
} else {
|
||||
printf("Error unlocking NAND flash. "
|
||||
"Write and erase will probably fail\n");
|
||||
puts("Error unlocking NAND flash, "
|
||||
"write and erase will probably fail\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -449,8 +459,8 @@ U_BOOT_CMD(nand, 5, 1, do_nand,
|
|||
"nand - NAND sub-system\n",
|
||||
"info - show available NAND devices\n"
|
||||
"nand device [dev] - show or set current device\n"
|
||||
"nand read[.jffs2] - addr off size\n"
|
||||
"nand write[.jffs2] - addr off size - read/write `size' bytes starting\n"
|
||||
"nand read[.jffs2] - addr off|partition size\n"
|
||||
"nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n"
|
||||
" at offset `off' to/from memory address `addr'\n"
|
||||
"nand erase [clean] [off size] - erase `size' bytes from\n"
|
||||
" offset `off' (entire device if not specified)\n"
|
||||
|
@ -462,15 +472,92 @@ U_BOOT_CMD(nand, 5, 1, do_nand,
|
|||
"nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
|
||||
"nand unlock [offset] [size] - unlock section\n");
|
||||
|
||||
static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
|
||||
ulong offset, ulong addr, char *cmd)
|
||||
{
|
||||
int r;
|
||||
char *ep;
|
||||
ulong cnt;
|
||||
image_header_t *hdr;
|
||||
|
||||
printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
|
||||
|
||||
cnt = nand->oobblock;
|
||||
r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
||||
if (r) {
|
||||
puts("** Read error\n");
|
||||
SHOW_BOOT_PROGRESS(-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
hdr = (image_header_t *) addr;
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
|
||||
SHOW_BOOT_PROGRESS(-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_image_hdr(hdr);
|
||||
|
||||
cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t));
|
||||
|
||||
r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
||||
if (r) {
|
||||
puts("** Read error\n");
|
||||
SHOW_BOOT_PROGRESS(-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Loading ok, update default load address */
|
||||
|
||||
load_addr = addr;
|
||||
|
||||
/* Check if we should attempt an auto-start */
|
||||
if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
|
||||
char *local_args[2];
|
||||
extern int do_bootm(cmd_tbl_t *, int, int, char *[]);
|
||||
|
||||
local_args[0] = cmd;
|
||||
local_args[1] = NULL;
|
||||
|
||||
printf("Automatic boot of image at addr 0x%08lx ...\n", addr);
|
||||
|
||||
do_bootm(cmdtp, 0, 1, local_args);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
char *boot_device = NULL;
|
||||
char *ep;
|
||||
int dev;
|
||||
int r;
|
||||
ulong addr, cnt, offset = 0;
|
||||
image_header_t *hdr;
|
||||
nand_info_t *nand;
|
||||
int idx;
|
||||
ulong addr, offset = 0;
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
|
||||
struct mtd_device *dev;
|
||||
struct part_info *part;
|
||||
u8 pnum;
|
||||
|
||||
if (argc >= 2) {
|
||||
char *p = (argc == 2) ? argv[1] : argv[2];
|
||||
if (!(str2long(p, &addr)) && (mtdparts_init() == 0) &&
|
||||
(find_dev_and_part(p, &dev, &pnum, &part) == 0)) {
|
||||
if (dev->id->type != MTD_DEV_TYPE_NAND) {
|
||||
puts("Not a NAND device\n");
|
||||
return 1;
|
||||
}
|
||||
if (argc > 3)
|
||||
goto usage;
|
||||
if (argc == 3)
|
||||
addr = simple_strtoul(argv[2], NULL, 16);
|
||||
else
|
||||
addr = CFG_LOAD_ADDR;
|
||||
return nand_load_image(cmdtp, &nand_info[dev->id->num],
|
||||
part->offset, addr, argv[0]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (argc) {
|
||||
case 1:
|
||||
|
@ -491,6 +578,9 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||
offset = simple_strtoul(argv[3], NULL, 16);
|
||||
break;
|
||||
default:
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
|
||||
usage:
|
||||
#endif
|
||||
printf("Usage:\n%s\n", cmdtp->usage);
|
||||
SHOW_BOOT_PROGRESS(-1);
|
||||
return 1;
|
||||
|
@ -502,68 +592,20 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
dev = simple_strtoul(boot_device, &ep, 16);
|
||||
idx = simple_strtoul(boot_device, NULL, 16);
|
||||
|
||||
if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) {
|
||||
printf("\n** Device %d not available\n", dev);
|
||||
if (idx < 0 || idx >= CFG_MAX_NAND_DEVICE || !nand_info[idx].name) {
|
||||
printf("\n** Device %d not available\n", idx);
|
||||
SHOW_BOOT_PROGRESS(-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nand = &nand_info[dev];
|
||||
printf("\nLoading from device %d: %s (offset 0x%lx)\n",
|
||||
dev, nand->name, offset);
|
||||
|
||||
cnt = nand->oobblock;
|
||||
r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
||||
if (r) {
|
||||
printf("** Read error on %d\n", dev);
|
||||
SHOW_BOOT_PROGRESS(-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
hdr = (image_header_t *) addr;
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
|
||||
SHOW_BOOT_PROGRESS(-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_image_hdr(hdr);
|
||||
|
||||
cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t));
|
||||
|
||||
r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
||||
if (r) {
|
||||
printf("** Read error on %d\n", dev);
|
||||
SHOW_BOOT_PROGRESS(-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Loading ok, update default load address */
|
||||
|
||||
load_addr = addr;
|
||||
|
||||
/* Check if we should attempt an auto-start */
|
||||
if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
|
||||
char *local_args[2];
|
||||
extern int do_bootm(cmd_tbl_t *, int, int, char *[]);
|
||||
|
||||
local_args[0] = argv[0];
|
||||
local_args[1] = NULL;
|
||||
|
||||
printf("Automatic boot of image at addr 0x%08lx ...\n", addr);
|
||||
|
||||
do_bootm(cmdtp, 0, 1, local_args);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(nboot, 4, 1, do_nandboot,
|
||||
"nboot - boot from NAND device\n", "loadAddr dev\n");
|
||||
|
||||
"nboot - boot from NAND device\n",
|
||||
"[partition] | [[[loadAddr] dev] offset]\n");
|
||||
|
||||
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
|
||||
|
||||
|
|
|
@ -34,14 +34,19 @@ Commands:
|
|||
nand device num
|
||||
Make device `num' the current device and print information about it.
|
||||
|
||||
nand erase off size
|
||||
nand erase clean [off size]
|
||||
Erase `size' bytes starting at offset `off'. Only complete erase
|
||||
blocks can be erased.
|
||||
nand erase off|partition size
|
||||
nand erase clean [off|partition size]
|
||||
Erase `size' bytes starting at offset `off'. Alternatively partition
|
||||
name can be specified, in this case size will be eventually limited
|
||||
to not exceed partition size (this behaviour applies also to read
|
||||
and write commands). Only complete erase blocks can be erased.
|
||||
|
||||
If `erase' is specified without an offset or size, the entire flash
|
||||
is erased. If `erase' is specified with partition but without an
|
||||
size, the entire partition is erased.
|
||||
|
||||
If `clean' is specified, a JFFS2-style clean marker is written to
|
||||
each block after it is erased. If `clean' is specified without an
|
||||
offset or size, the entire flash is erased.
|
||||
each block after it is erased.
|
||||
|
||||
This command will not erase blocks that are marked bad. There is
|
||||
a debug option in cmd_nand.c to allow bad blocks to be erased.
|
||||
|
@ -51,28 +56,28 @@ Commands:
|
|||
nand info
|
||||
Print information about all of the NAND devices found.
|
||||
|
||||
nand read addr ofs size
|
||||
nand read addr ofs|partition size
|
||||
Read `size' bytes from `ofs' in NAND flash to `addr'. If a page
|
||||
cannot be read because it is marked bad or an uncorrectable data
|
||||
error is found the command stops with an error.
|
||||
|
||||
nand read.jffs2 addr ofs size
|
||||
nand read.jffs2 addr ofs|partition size
|
||||
Like `read', but the data for blocks that are marked bad is read as
|
||||
0xff. This gives a readable JFFS2 image that can be processed by
|
||||
the JFFS2 commands such as ls and fsload.
|
||||
|
||||
nand read.oob addr ofs size
|
||||
nand read.oob addr ofs|partition size
|
||||
Read `size' bytes from the out-of-band data area corresponding to
|
||||
`ofs' in NAND flash to `addr'. This is limited to the 16 bytes of
|
||||
data for one 512-byte page or 2 256-byte pages. There is no check
|
||||
for bad blocks or ECC errors.
|
||||
|
||||
nand write addr ofs size
|
||||
nand write addr ofs|partition size
|
||||
Write `size' bytes from `addr' to `ofs' in NAND flash. If a page
|
||||
cannot be written because it is marked bad or the write fails the
|
||||
command stops with an error.
|
||||
|
||||
nand write.jffs2 addr ofs size
|
||||
nand write.jffs2 addr ofs|partition size
|
||||
Like `write', but blocks that are marked bad are skipped and the
|
||||
is written to the next block instead. This allows writing writing
|
||||
a JFFS2 image, as long as the image is short enough to fit even
|
||||
|
@ -80,7 +85,7 @@ Commands:
|
|||
produced by mkfs.jffs2 should work well, but loading an image copied
|
||||
from another flash is going to be trouble if there are any bad blocks.
|
||||
|
||||
nand write.oob addr ofs size
|
||||
nand write.oob addr ofs|partition size
|
||||
Write `size' bytes from `addr' to the out-of-band data area
|
||||
corresponding to `ofs' in NAND flash. This is limited to the 16 bytes
|
||||
of data for one 512-byte page or 2 256-byte pages. There is no check
|
||||
|
|
|
@ -83,15 +83,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
|
|||
|
||||
erase.mtd = meminfo;
|
||||
erase.len = meminfo->erasesize;
|
||||
if (opts->offset == 0 && opts->length == 0) {
|
||||
/* erase complete chip */
|
||||
erase.addr = 0;
|
||||
erase_length = meminfo->size;
|
||||
} else {
|
||||
/* erase specified region */
|
||||
erase.addr = opts->offset;
|
||||
erase_length = opts->length;
|
||||
}
|
||||
erase.addr = opts->offset;
|
||||
erase_length = opts->length;
|
||||
|
||||
isNAND = meminfo->type == MTD_NANDFLASH ? 1 : 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue