X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fcmd_nand.c;h=37198d21e8c6e1638f112a63205884317fba5af4;hb=f0d5a6f060d00358b85c62a921a423ea8df71184;hp=c72612d0d6f3c828271d48ab5b4a053cb121576f;hpb=375c2c9e57ea5b8d678475379378f4774aa9cb88;p=oweals%2Fu-boot.git diff --git a/common/cmd_nand.c b/common/cmd_nand.c index c72612d0d6..37198d21e8 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -37,8 +37,6 @@ 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) { return 0; @@ -93,7 +91,7 @@ static inline int str2long(char *p, ulong *num) } static int -arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size) +arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, size_t *size) { int idx = nand_curr_device; #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) @@ -110,7 +108,7 @@ arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size) } *off = part->offset; if (argc >= 2) { - if (!(str2long(argv[1], size))) { + if (!(str2long(argv[1], (ulong *)size))) { printf("'%s' is not a number\n", argv[1]); return -1; } @@ -136,7 +134,7 @@ arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size) } if (argc >= 2) { - if (!(str2long(argv[1], size))) { + if (!(str2long(argv[1], (ulong *)size))) { printf("'%s' is not a number\n", argv[1]); return -1; } @@ -158,10 +156,15 @@ out: int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int i, dev, ret; - ulong addr, off, size; + ulong addr, off; + size_t size; char *cmd, *s; nand_info_t *nand; +#ifdef CFG_NAND_QUIET + int quiet = CFG_NAND_QUIET; +#else int quiet = 0; +#endif const char *quiet_str = getenv("quiet"); /* at least two arguments please */ @@ -343,6 +346,14 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) opts.quiet = quiet; ret = nand_write_opts(nand, &opts); } + } else if (s != NULL && !strcmp(s, ".oob")) { + /* read out-of-band data */ + if (read) + ret = nand->read_oob(nand, off, size, &size, + (u_char *) addr); + else + ret = nand->write_oob(nand, off, size, &size, + (u_char *) addr); } else { if (read) ret = nand_read(nand, off, &size, (u_char *)addr); @@ -452,7 +463,7 @@ U_BOOT_CMD(nand, 5, 1, do_nand, "info - show available NAND devices\n" "nand device [dev] - show or set current device\n" "nand read[.jffs2] - addr off|partition size\n" - "nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n" + "nand write[.jffs2] - addr off|partition 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" @@ -468,14 +479,34 @@ 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; + char *ep, *s; + size_t cnt; image_header_t *hdr; + int jffs2 = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif + + s = strchr(cmd, '.'); + if (s != NULL && + (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) + jffs2 = 1; printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset); cnt = nand->oobblock; - r = nand_read(nand, offset, &cnt, (u_char *) addr); + if (jffs2) { + nand_read_options_t opts; + memset(&opts, 0, sizeof(opts)); + opts.buffer = (u_char*) addr; + opts.length = cnt; + opts.offset = offset; + opts.quiet = 1; + r = nand_read_opts(nand, &opts); + } else { + r = nand_read(nand, offset, &cnt, (u_char *) addr); + } + if (r) { puts("** Read error\n"); show_boot_progress (-56); @@ -483,20 +514,47 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } show_boot_progress (56); - hdr = (image_header_t *) addr; + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; + + show_boot_progress (57); + image_print_contents (hdr); - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + show_boot_progress (-150); + puts ("** Bad FIT image format\n"); + return 1; + } + show_boot_progress (151); + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; +#endif + default: show_boot_progress (-57); + puts ("** Unknown image type\n"); return 1; } - show_boot_progress (57); - print_image_hdr(hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); + if (jffs2) { + nand_read_options_t opts; + memset(&opts, 0, sizeof(opts)); + opts.buffer = (u_char*) addr; + opts.length = cnt; + opts.offset = offset; + opts.quiet = 1; + r = nand_read_opts(nand, &opts); + } else { + r = nand_read(nand, offset, &cnt, (u_char *) addr); + } - r = nand_read(nand, offset, &cnt, (u_char *) addr); if (r) { puts("** Read error\n"); show_boot_progress (-58); @@ -504,6 +562,12 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } show_boot_progress (58); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; @@ -545,7 +609,7 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (argc > 3) goto usage; if (argc == 3) - addr = simple_strtoul(argv[2], NULL, 16); + addr = simple_strtoul(argv[1], NULL, 16); else addr = CFG_LOAD_ADDR; return nand_load_image(cmdtp, &nand_info[dev->id->num], @@ -604,7 +668,7 @@ usage: U_BOOT_CMD(nboot, 4, 1, do_nandboot, "nboot - boot from NAND device\n", - "[partition] | [[[loadAddr] dev] offset]\n"); + "[.jffs2] [partition] | [[[loadAddr] dev] offset]\n"); #endif @@ -774,23 +838,24 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (strncmp (argv[1], "read", 4) == 0 || strncmp (argv[1], "write", 5) == 0) { - ulong addr = simple_strtoul (argv[2], NULL, 16); - ulong off = simple_strtoul (argv[3], NULL, 16); - ulong size = simple_strtoul (argv[4], NULL, 16); - int cmd = (strncmp (argv[1], "read", 4) == 0) ? - NANDRW_READ : NANDRW_WRITE; - int ret, total; + ulong addr = simple_strtoul (argv[2], NULL, 16); + off_t off = simple_strtoul (argv[3], NULL, 16); + size_t size = simple_strtoul (argv[4], NULL, 16); + int cmd = (strncmp (argv[1], "read", 4) == 0) ? + NANDRW_READ : NANDRW_WRITE; + size_t total; + int ret; char *cmdtail = strchr (argv[1], '.'); if (cmdtail && !strncmp (cmdtail, ".oob", 2)) { /* read out-of-band data */ if (cmd & NANDRW_READ) { ret = nand_read_oob (nand_dev_desc + curr_device, - off, size, (size_t *) & total, + off, size, &total, (u_char *) addr); } else { ret = nand_write_oob (nand_dev_desc + curr_device, - off, size, (size_t *) & total, + off, size, &total, (u_char *) addr); } return ret; @@ -826,7 +891,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) ret = nand_legacy_rw (nand_dev_desc + curr_device, cmd, off, size, - (size_t *) & total, + &total, (u_char *) addr); printf (" %d bytes %s: %s\n", total, @@ -886,6 +951,10 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong offset = 0; image_header_t *hdr; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif + show_boot_progress (52); switch (argc) { case 1: @@ -941,17 +1010,31 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (56); - hdr = (image_header_t *)addr; - - if (ntohl(hdr->ih_magic) == IH_MAGIC) { - - print_image_hdr (hdr); + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; + image_print_contents (hdr); - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); + cnt = image_get_image_size (hdr); cnt -= SECTORSIZE; - } else { - printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic)); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + show_boot_progress (-150); + puts ("** Bad FIT image format\n"); + return 1; + } + show_boot_progress (151); + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; +#endif + default: show_boot_progress (-57); + puts ("** Unknown image type\n"); return 1; } show_boot_progress (57); @@ -965,6 +1048,12 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (58); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr;