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

📄 cmd_nand.c.l

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 L
📖 第 1 页 / 共 3 页
字号:
679  * bad. This can be very handy if you are _sure_ that the block680  * is OK, say because you marked a good block bad to test bad681  * block handling and you are done testing, or if you have682  * accidentally marked blocks bad.683  *684  * Erasing factory marked bad blocks is a _bad_ idea. If the685  * erase succeeds there is no reliable way to find them again,686  * and attempting to program or erase bad blocks can affect687  * the data in _other_ (good) blocks.688  */689 #define  ALLOW_ERASE_BAD_DEBUG 0690 691 #define CONFIG_MTD_NAND_ECC  /* enable ECC */692 #define CONFIG_MTD_NAND_ECC_JFFS2693 694 /* bits for nand_legacy_rw() `cmd'; or together as needed */695 #define NANDRW_READ 0x01696 #define NANDRW_WRITE    0x00697 #define NANDRW_JFFS2    0x02698 #define NANDRW_JFFS2_SKIP   0x04699 700 /*701  * Imports from nand_legacy.c702  */703 extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];704 extern int curr_device;705 extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs,706                 size_t len, int clean);707 extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start,708              size_t len, size_t *retlen, u_char *buf);709 extern void nand_print(struct nand_chip *nand);710 extern void nand_print_bad(struct nand_chip *nand);711 extern int nand_read_oob(struct nand_chip *nand, size_t ofs,712                    size_t len, size_t *retlen, u_char *buf);713 extern int nand_write_oob(struct nand_chip *nand, size_t ofs,714                 size_t len, size_t *retlen, const u_char *buf);715 716 717 int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])718 {719     int rcode = 0;720 721     switch (argc) {722     case 0:723     case 1:724     printf ("Usage:\n%s\n", cmdtp->usage);725     return 1;726     case 2:727     if (strcmp(argv[1],"info") == 0) {728         int i;729 730         putc ('\n');731 732         for (i=0; i<CFG_MAX_NAND_DEVICE; ++i) {733             if(nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN)734                 continue; /* list only known devices */735             printf ("Device %d: ", i);736             nand_print(&nand_dev_desc[i]);737         }738         return 0;739 740     } else if (strcmp(argv[1],"device") == 0) {741         if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {742             puts ("\nno devices available\n");743             return 1;744         }745         printf ("\nDevice %d: ", curr_device);746         nand_print(&nand_dev_desc[curr_device]);747         return 0;748 749     } else if (strcmp(argv[1],"bad") == 0) {750         if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {751             puts ("\nno devices available\n");752             return 1;753         }754         printf ("\nDevice %d bad blocks:\n", curr_device);755         nand_print_bad(&nand_dev_desc[curr_device]);756         return 0;757 758     }759     printf ("Usage:\n%s\n", cmdtp->usage);760     return 1;761     case 3:762     if (strcmp(argv[1],"device") == 0) {763         int dev = (int)simple_strtoul(argv[2], NULL, 10);764 765         printf ("\nDevice %d: ", dev);766         if (dev >= CFG_MAX_NAND_DEVICE) {767             puts ("unknown device\n");768             return 1;769         }770         nand_print(&nand_dev_desc[dev]);771         /*nand_print (dev);*/772 773         if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) {774             return 1;775         }776 777         curr_device = dev;778 779         puts ("... is now current device\n");780 781         return 0;782     }783     else if (strcmp(argv[1],"erase") == 0 && strcmp(argv[2], "clean") == 0) {784         struct nand_chip* nand = &nand_dev_desc[curr_device];785         ulong off = 0;786         ulong size = nand->totlen;787         int ret;788 789         printf ("\nNAND erase: device %d offset %ld, size %ld ... ",790             curr_device, off, size);791 792         ret = nand_legacy_erase (nand, off, size, 1);793 794         printf("%s\n", ret ? "ERROR" : "OK");795 796         return ret;797     }798 799     printf ("Usage:\n%s\n", cmdtp->usage);800     return 1;801     default:802     /* at least 4 args */803 804     if (strncmp(argv[1], "read", 4) == 0 ||805         strncmp(argv[1], "write", 5) == 0) {806         ulong addr = simple_strtoul(argv[2], NULL, 16);807         ulong off  = simple_strtoul(argv[3], NULL, 16);808         ulong size = simple_strtoul(argv[4], NULL, 16);809         int cmd    = (strncmp(argv[1], "read", 4) == 0) ?810                 NANDRW_READ : NANDRW_WRITE;811         int ret, total;812         char* cmdtail = strchr(argv[1], '.');813 814         if (cmdtail && !strncmp(cmdtail, ".oob", 2)) {815             /* read out-of-band data */816             if (cmd & NANDRW_READ) {817                 ret = nand_read_oob(nand_dev_desc + curr_device,818                             off, size, (size_t *)&total,819                             (u_char*)addr);820             }821             else {822                 ret = nand_write_oob(nand_dev_desc + curr_device,823                              off, size, (size_t *)&total,824                              (u_char*)addr);825             }826             return ret;827         }828         else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2))829             cmd |= NANDRW_JFFS2;    /* skip bad blocks */830         else if (cmdtail && !strncmp(cmdtail, ".jffs2s", 2)) {831             cmd |= NANDRW_JFFS2;    /* skip bad blocks (on read too) */832             if (cmd & NANDRW_READ)833                 cmd |= NANDRW_JFFS2_SKIP;   /* skip bad blocks (on read too) */834         }835 #ifdef SXNI855T836         /* need ".e" same as ".j" for compatibility with older units */837         else if (cmdtail && !strcmp(cmdtail, ".e"))838             cmd |= NANDRW_JFFS2;    /* skip bad blocks */839 #endif840 #ifdef CFG_NAND_SKIP_BAD_DOT_I841         /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */842         /* ".i" for image -> read skips bad block (no 0xff) */843         else if (cmdtail && !strcmp(cmdtail, ".i")) {844             cmd |= NANDRW_JFFS2;    /* skip bad blocks (on read too) */845             if (cmd & NANDRW_READ)846                 cmd |= NANDRW_JFFS2_SKIP;   /* skip bad blocks (on read too) */847         }848 #endif /* CFG_NAND_SKIP_BAD_DOT_I */849         else if (cmdtail) {850             printf ("Usage:\n%s\n", cmdtp->usage);851             return 1;852         }853 854         printf ("\nNAND %s: device %d offset %ld, size %ld ...\n",855             (cmd & NANDRW_READ) ? "read" : "write",856             curr_device, off, size);857 858         ret = nand_legacy_rw(nand_dev_desc + curr_device, cmd, off, size,859                  (size_t *)&total, (u_char*)addr);860 861         printf (" %d bytes %s: %s\n", total,862             (cmd & NANDRW_READ) ? "read" : "written",863             ret ? "ERROR" : "OK");864 865         return ret;866     } else if (strcmp(argv[1],"erase") == 0 &&867            (argc == 4 || strcmp("clean", argv[2]) == 0)) {868         int clean = argc == 5;869         ulong off = simple_strtoul(argv[2 + clean], NULL, 16);870         ulong size = simple_strtoul(argv[3 + clean], NULL, 16);871         int ret;872 873         printf ("\nNAND erase: device %d offset %ld, size %ld ...\n",874             curr_device, off, size);875 876         ret = nand_legacy_erase (nand_dev_desc + curr_device,877                     off, size, clean);878 879         printf("%s\n", ret ? "ERROR" : "OK");880 881         return ret;882     } else {883         printf ("Usage:\n%s\n", cmdtp->usage);884         rcode = 1;885     }886 887     return rcode;888     }889 }890 891 U_BOOT_CMD(892     nand,   5,  1,  do_nand,893     "nand    - legacy NAND sub-system\n",894     "info  - show available NAND devices\n"895     "nand device [dev] - show or set current device\n"896     "nand read[.jffs2[s]]  addr off size\n"897     "nand write[.jffs2] addr off size - read/write `size' bytes starting\n"898     "    at offset `off' to/from memory address `addr'\n"899     "nand erase [clean] [off size] - erase `size' bytes from\n"900     "    offset `off' (entire device if not specified)\n"901     "nand bad - show bad blocks\n"902     "nand read.oob addr off size - read out-of-band data\n"903     "nand write.oob addr off size - read out-of-band data\n"904 );905 906 int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])907 {908     char *boot_device = NULL;909     char *ep;910     int dev;911     ulong cnt;912     ulong addr;913     ulong offset = 0;914     image_header_t *hdr;915     int rcode = 0;916     switch (argc) {917     case 1:918         addr = CFG_LOAD_ADDR;919         boot_device = getenv ("bootdevice");920         break;921     case 2:922         addr = simple_strtoul(argv[1], NULL, 16);923         boot_device = getenv ("bootdevice");924         break;925     case 3:926         addr = simple_strtoul(argv[1], NULL, 16);927         boot_device = argv[2];928         break;929     case 4:930         addr = simple_strtoul(argv[1], NULL, 16);931         boot_device = argv[2];932         offset = simple_strtoul(argv[3], NULL, 16);933         break;934     default:935         printf ("Usage:\n%s\n", cmdtp->usage);936         SHOW_BOOT_PROGRESS (-1);937         return 1;938     }939 940     if (!boot_device) {941         puts ("\n** No boot device **\n");942         SHOW_BOOT_PROGRESS (-1);943         return 1;944     }945 946     dev = simple_strtoul(boot_device, &ep, 16);947 948     if ((dev >= CFG_MAX_NAND_DEVICE) ||949         (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) {950         printf ("\n** Device %d not available\n", dev);951         SHOW_BOOT_PROGRESS (-1);952         return 1;953     }954 955     printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",956         dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,957         offset);958 959     if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset,960             SECTORSIZE, NULL, (u_char *)addr)) {961         printf ("** Read error on %d\n", dev);962         SHOW_BOOT_PROGRESS (-1);963         return 1;964     }965 966     hdr = (image_header_t *)addr;967 968     if (ntohl(hdr->ih_magic) == IH_MAGIC) {969 970         print_image_hdr (hdr);971 972         cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));973         cnt -= SECTORSIZE;974     } else {975         printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic));976         SHOW_BOOT_PROGRESS (-1);977         return 1;978     }979 980     if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ,981             offset + SECTORSIZE, cnt, NULL,982             (u_char *)(addr+SECTORSIZE))) {983         printf ("** Read error on %d\n", dev);984         SHOW_BOOT_PROGRESS (-1);985         return 1;986     }987 988     /* Loading ok, update default load address */989 990     load_addr = addr;991 992     /* Check if we should attempt an auto-start */993     if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {994         char *local_args[2];995         extern int do_bootm (cmd_tbl_t *, int, int, char *[]);996 997         local_args[0] = argv[0];998         local_args[1] = NULL;999 1000         printf ("Automatic boot of image at addr 0x%08lx ...\n", addr);1001 1002         do_bootm (cmdtp, 0, 1, local_args);1003         rcode = 1;1004     }1005     return rcode;1006 }1007 1008 U_BOOT_CMD(1009     nboot,  4,  1,  do_nandboot,1010     "nboot   - boot from NAND device\n",1011     "loadAddr dev\n"1012 );1013 1014 #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */1015 1016 #endif /* CFG_NAND_LEGACY */

⌨️ 快捷键说明

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