summaryrefslogtreecommitdiff
path: root/ubi-utils/src
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-01-18 14:01:04 +0200
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-01-18 14:04:15 +0200
commitc842430437cbf2e584994c8eba71bf29bab6cdfc (patch)
tree74db9d2fd6d711ccffe104386ddab9055fc38f14 /ubi-utils/src
parent5d048c343fa24e33741ee4e921650f77ab510f81 (diff)
ubi-utils: move various stuff to sort-me-out
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'ubi-utils/src')
-rw-r--r--ubi-utils/src/bin2nand.c366
-rw-r--r--ubi-utils/src/nand2bin.c493
-rw-r--r--ubi-utils/src/nandcorr.c95
-rw-r--r--ubi-utils/src/nandecc.c159
-rw-r--r--ubi-utils/src/nandecc.h29
5 files changed, 0 insertions, 1142 deletions
diff --git a/ubi-utils/src/bin2nand.c b/ubi-utils/src/bin2nand.c
deleted file mode 100644
index 83f50cc..0000000
--- a/ubi-utils/src/bin2nand.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Oliver Lohmann
- */
-
-/*
- * Create a flashable NAND image from a binary image
- *
- * History:
- * 1.0 Initial release (tglx)
- * 1.1 Understands hex and dec input parameters (tglx)
- * 1.2 Generates separated OOB data, if needed. (oloh)
- * 1.3 Padds data/oob to a given size. (oloh)
- * 1.4 Removed argp because we want to use uClibc.
- * 1.5 Minor cleanup
- * 1.6 Written variable not initialized (-j did not work) (haver)
- * 1.7 Made NAND ECC layout configurable (haver)
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#include "error.h"
-#include "config.h"
-#include "nandecc.h"
-#include "ecclayouts.h"
-
-#define PROGRAM_VERSION "1.7"
-
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
-#define CHECK_ENDP(option, endp) do { \
- if (*endp) { \
- fprintf(stderr, \
- "Parse error option \'%s\'. " \
- "No correct numeric value.\n" \
- , option); \
- exit(EXIT_FAILURE); \
- } \
-} while(0)
-
-typedef enum action_t {
- ACT_NORMAL = 0x00000001,
-} action_t;
-
-#define PAGESIZE 2048
-#define PADDING 0 /* 0 means, do not adjust anything */
-#define BUFSIZE 4096
-
-static char doc[] = "\nVersion: " PROGRAM_VERSION "\n"
- "bin2nand - a tool for adding OOB information to a "
- "binary input file.\n";
-
-static const char *optionsstr =
-" -c, --copyright Print copyright informatoin.\n"
-" -j, --padding=<num> Padding in Byte/Mi/ki. Default = no padding\n"
-" -l, --ecc-placement=<MTD,IBM> OOB placement scheme (default is IBM).\n"
-" -p, --pagesize=<num> Pagesize in Byte/Mi/ki. Default = 2048\n"
-" -o, --output=<fname> Output filename. Interleaved Data/OOB if\n"
-" output-oob not specified.\n"
-" -q, --output-oob=<fname> Write OOB data in separate file.\n"
-" -?, --help Give this help list\n"
-" --usage Give a short usage message\n"
-" -V, --version Print program version\n";
-
-static const char *usage =
-"Usage: bin2nand [-c?V] [-j <num>] [-p <num>] [-o <fname>] [-q <fname>]\n"
-" [--copyright] [--padding=<num>] [--pagesize=<num>]\n"
-" [--output=<fname>] [--output-oob=<fname>] [--help] [--usage]\n"
-" [--version]\n";
-
-struct option long_options[] = {
- { .name = "copyright", .has_arg = 0, .flag = NULL, .val = 'c' },
- { .name = "padding", .has_arg = 1, .flag = NULL, .val = 'j' },
- { .name = "pagesize", .has_arg = 1, .flag = NULL, .val = 'p' },
- { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' },
- { .name = "output-oob", .has_arg = 1, .flag = NULL, .val = 'q' },
- { .name = "ecc-layout", .has_arg = 1, .flag = NULL, .val = 'l' },
- { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' },
- { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 },
- { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' },
- { NULL, 0, NULL, 0}
-};
-
-#define __unused __attribute__((unused))
-static const char copyright [] __unused = "Copyright IBM Corp. 2007";
-
-struct args {
- action_t action;
-
- size_t pagesize;
- size_t oobsize;
- size_t padding;
-
- FILE* fp_in;
- const char *file_out_data; /* Either: Data and OOB interleaved
- or plain data */
- const char *file_out_oob; /* OOB Data only. */
- struct nand_ecclayout *nand_oob;
-
- /* special stuff needed to get additional arguments */
- char *arg1;
- char **options; /* [STRING...] */
-};
-
-
-static int ustrtoull(const char *cp, char **endp, unsigned int base)
-{
- unsigned long long res = strtoull(cp, endp, base);
-
- switch (**endp) {
- case 'G':
- res *= 1024;
- case 'M':
- res *= 1024;
- case 'k':
- case 'K':
- res *= 1024;
- /* "Ki", "ki", "Mi" or "Gi" are to be used. */
- if ((*endp)[1] == 'i')
- (*endp) += 2;
- }
- return res;
-}
-
-static int
-parse_opt(int argc, char **argv, struct args *args)
-{
- const char *ecc_layout = NULL;
- unsigned int i, oob_idx = 0;
- char* endp;
-
- while (1) {
- int key;
-
- key = getopt_long(argc, argv, "cj:l:p:o:q:?V", long_options, NULL);
- if (key == -1)
- break;
-
- switch (key) {
- case 'p': /* pagesize */
- args->pagesize = (size_t)
- ustrtoull(optarg, &endp, 0);
- CHECK_ENDP("p", endp);
- break;
- case 'j': /* padding */
- args->padding = (size_t)
- ustrtoull(optarg, &endp, 0);
- CHECK_ENDP("j", endp);
- break;
- case 'o': /* output */
- args->file_out_data = optarg;
- break;
- case 'q': /* output oob */
- args->file_out_oob = optarg;
- break;
- case 'l': /* --ecc-layout=<...> */
- ecc_layout = optarg;
- break;
- case '?': /* help */
- printf("%s%s", doc, optionsstr);
- exit(0);
- break;
- case 'V':
- printf("%s\n", PROGRAM_VERSION);
- exit(0);
- break;
- case 'c':
- printf("%s\n", copyright);
- exit(0);
- default:
- printf("%s", usage);
- exit(-1);
- }
- }
-
- if (optind < argc) {
- args->fp_in = fopen(argv[optind++], "rb");
- if ((args->fp_in) == NULL) {
- err_quit("Cannot open file %s for input\n",
- argv[optind++]);
- }
- }
-
- switch (args->pagesize) {
- case 512: args->oobsize = 16; oob_idx = 0; break;
- case 2048: args->oobsize = 64; oob_idx = 1; break;
- default:
- err_msg("Unsupported page size: %d\n", args->pagesize);
- return -EINVAL;
- }
-
- /* Figure out correct oob layout if it differs from default */
- if (ecc_layout) {
- for (i = 0; i < ARRAY_SIZE(oob_placement); i++)
- if (strcmp(ecc_layout, oob_placement[i].name) == 0)
- args->nand_oob =
- oob_placement[i].nand_oob[oob_idx];
- }
- return 0;
-}
-
-static int
-process_page(struct args *args, uint8_t *buf, FILE *fp_data, FILE *fp_oob,
- size_t *written)
-{
- int eccpoi;
- size_t i;
- uint8_t oobbuf[64];
- uint8_t ecc_code[3] = { 0, }; /* temp */
-
- /* Calculate ECC for each subpage of 256 bytes */
- memset(oobbuf, 0xff, sizeof(oobbuf));
- for (eccpoi = 0, i = 0; i < args->pagesize; i += 256, eccpoi += 3) {
- int j;
- nand_calculate_ecc(&buf[i], ecc_code);
- for (j = 0; j < 3; j++)
- oobbuf[args->nand_oob->eccpos[eccpoi + j]] = ecc_code[j];
- }
-
- /* write data */
- *written += fwrite(buf, 1, args->pagesize, fp_data);
-
- /* either separate oob or interleave with data */
- if (fp_oob) {
- i = fwrite(oobbuf, 1, args->oobsize, fp_oob);
- if (ferror(fp_oob)) {
- err_msg("IO error\n");
- return -EIO;
- }
- }
- else {
- i = fwrite(oobbuf, 1, args->oobsize, fp_data);
- if (ferror(fp_data)) {
- err_msg("IO error\n");
- return -EIO;
- }
- }
-
- return 0;
-}
-
-int main (int argc, char** argv)
-{
- int rc = -1;
- int res = 0;
- size_t written = 0, read;
- struct args args = {
- .action = ACT_NORMAL,
- .pagesize = PAGESIZE,
- .padding = PADDING,
- .fp_in = NULL,
- .file_out_data = NULL,
- .file_out_oob = NULL,
- .nand_oob = &ibm_nand_oob_64,
- };
-
- FILE* fp_out_data = stdout;
- FILE* fp_out_oob = NULL;
-
- parse_opt(argc, argv, &args);
-
- uint8_t* buf = calloc(1, BUFSIZE);
- if (!buf) {
- err_quit("Cannot allocate page buffer.\n");
- }
-
- if (!args.fp_in) {
- err_msg("No input image specified!\n");
- goto err;
- }
-
- if (args.file_out_data) {
- fp_out_data = fopen(args.file_out_data, "wb");
- if (fp_out_data == NULL) {
- err_sys("Cannot open file %s for output\n",
- args.file_out_data);
- goto err;
- }
- }
-
- if (args.file_out_oob) {
- fp_out_oob = fopen(args.file_out_oob, "wb");
- if (fp_out_oob == NULL) {
- err_sys("Cannot open file %s for output\n",
- args.file_out_oob);
- goto err;
- }
- }
-
-
- while(1) {
- read = fread(buf, 1, args.pagesize, args.fp_in);
- if (feof(args.fp_in) && read == 0)
- break;
-
- if (read < args.pagesize) {
- err_msg("Image not page aligned\n");
- goto err;
- }
-
- if (ferror(args.fp_in)) {
- err_msg("Read error\n");
- goto err;
- }
-
- res = process_page(&args, buf, fp_out_data, fp_out_oob,
- &written);
- if (res != 0)
- goto err;
- }
-
- while (written < args.padding) {
- memset(buf, 0xff, args.pagesize);
- res = process_page(&args, buf, fp_out_data, fp_out_oob,
- &written);
- if (res != 0)
- goto err;
- }
-
- rc = 0;
-err:
- free(buf);
-
- if (args.fp_in)
- fclose(args.fp_in);
-
- if (fp_out_oob)
- fclose(fp_out_oob);
-
- if (fp_out_data && fp_out_data != stdout)
- fclose(fp_out_data);
-
- if (rc != 0) {
- err_msg("Error during conversion. rc: %d\n", rc);
- if (args.file_out_data)
- remove(args.file_out_data);
- if (args.file_out_oob)
- remove(args.file_out_oob);
- }
- return rc;
-}
diff --git a/ubi-utils/src/nand2bin.c b/ubi-utils/src/nand2bin.c
deleted file mode 100644
index 8c95b27..0000000
--- a/ubi-utils/src/nand2bin.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2006, 2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Frank Haverkamp
- *
- * An utility to decompose NAND images and strip OOB off. Not yet finished ...
- *
- * 1.2 Removed argp because we want to use uClibc.
- * 1.3 Minor cleanup
- * 1.4 Fixed OOB output file
- * 1.5 Added verbose output and option to set blocksize.
- * Added split block mode for more convenient analysis.
- * 1.6 Fixed ECC error detection and correction.
- * 1.7 Made NAND ECC layout configurable, the holes which were previously
- * filled with 0x00 are untouched now and will be 0xff just like MTD
- * behaves when writing the oob (haver)
- */
-
-#include <config.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <getopt.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "config.h"
-#include "nandecc.h"
-#include "ecclayouts.h"
-
-#define PROGRAM_VERSION "1.7"
-
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-#define MAXPATH 1024
-#define MIN(x,y) ((x)<(y)?(x):(y))
-
-struct args {
- const char *oob_file;
- const char *output_file;
- size_t pagesize;
- size_t oobsize;
- int bad_marker_offs_in_oob;
- size_t blocksize;
- int split_blocks;
- size_t in_len; /* size of input file */
- int correct_ecc;
- struct nand_ecclayout *nand_oob;
-
- /* special stuff needed to get additional arguments */
- char *arg1;
- char **options; /* [STRING...] */
-};
-
-static struct args myargs = {
- .output_file = "data.bin",
- .oob_file = "oob.bin",
- .pagesize = 2048,
- .blocksize = 128 * 1024,
- .nand_oob = &ibm_nand_oob_64,
- .in_len = 0,
- .split_blocks = 0,
- .correct_ecc = 0,
- .arg1 = NULL,
- .options = NULL,
-};
-
-static char doc[] = "\nVersion: " PROGRAM_VERSION "\n"
- "nand2bin - split data and OOB.\n";
-
-static const char *optionsstr =
-" -l, --ecc-placement=<MTD,IBM> OOB placement scheme (default is IBM).\n"
-" -o, --output=<output> Data output file\n"
-" -O, --oob=<oob> OOB output file\n"
-" -p, --pagesize=<pagesize> NAND pagesize\n"
-" -b, --blocksize=<blocksize> NAND blocksize\n"
-" -s, --split-blocks generate binaries for each block\n"
-" -e, --correct-ecc Correct data according to ECC info\n"
-" -v, --verbose verbose output\n"
-" -?, --help Give this help list\n"
-" --usage Give a short usage message\n";
-
-static const char *usage =
-"Usage: nand2bin [-?] [-o <output>] [-O <oob>] [-p <pagesize>]\n"
-" [--output=<output>] [--oob=<oob>] [--pagesize=<pagesize>] [--help]\n"
-" [--usage] input.mif\n";
-
-static int verbose = 0;
-
-static struct option long_options[] = {
- { .name = "ecc-layout", .has_arg = 1, .flag = NULL, .val = 'l' },
- { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' },
- { .name = "oob", .has_arg = 1, .flag = NULL, .val = 'O' },
- { .name = "pagesize", .has_arg = 1, .flag = NULL, .val = 'p' },
- { .name = "blocksize", .has_arg = 1, .flag = NULL, .val = 'b' },
- { .name = "split-blocks", .has_arg = 0, .flag = NULL, .val = 's' },
- { .name = "correct-ecc", .has_arg = 0, .flag = NULL, .val = 'e' },
- { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' },
- { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' },
- { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 },
- { NULL, 0, NULL, 0}
-};
-
-/*
- * str_to_num - Convert string into number and cope with endings like
- * k, K, kib, KiB for kilobyte
- * m, M, mib, MiB for megabyte
- */
-static uint32_t str_to_num(char *str)
-{
- char *s = str;
- ulong num = strtoul(s, &s, 0);
-
- if (*s != '\0') {
- if (strcmp(s, "KiB") == 0)
- num *= 1024;
- else if (strcmp(s, "MiB") == 0)
- num *= 1024*1024;
- else {
- fprintf(stderr, "WARNING: Wrong number format "
- "\"%s\", check your paramters!\n", str);
- }
- }
- return num;
-}
-
-/*
- * @brief Parse the arguments passed into the test case.
- *
- * @param argc The number of arguments
- * @param argv The argument list
- * @param args Pointer to program args structure
- *
- * @return error
- *
- */
-static int parse_opt(int argc, char **argv, struct args *args)
-{
- unsigned int i, oob_idx = 0;
- const char *ecc_layout = NULL;
-
- while (1) {
- int key;
-
- key = getopt_long(argc, argv, "b:el:o:O:p:sv?", long_options, NULL);
- if (key == -1)
- break;
-
- switch (key) {
- case 'b': /* --blocksize<blocksize> */
- args->blocksize = str_to_num(optarg);
- break;
- case 'e': /* --correct-ecc */
- args->correct_ecc = 1;
- break;
- case 'l': /* --ecc-layout=<...> */
- ecc_layout = optarg;
- break;
- case 'o': /* --output=<output.bin> */
- args->output_file = optarg;
- break;
- case 'O': /* --oob=<oob.bin> */
- args->oob_file = optarg;
- break;
- case 'p': /* --pagesize<pagesize> */
- args->pagesize = str_to_num(optarg);
- break;
- case 's': /* --split-blocks */
- args->split_blocks = 1;
- break;
- case 'v': /* --verbose */
- verbose++;
- break;
- case 'V':
- printf("%s\n", PROGRAM_VERSION);
- exit(0);
- break;
- case '?': /* help */
- printf("Usage: nand2bin [OPTION...] input.mif\n");
- printf("%s%s", doc, optionsstr);
- printf("\nReport bugs to %s\n",
- PACKAGE_BUGREPORT);
- exit(0);
- break;
- default:
- printf("%s", usage);
- exit(-1);
- }
- }
-
- if (optind < argc)
- args->arg1 = argv[optind++];
-
- switch (args->pagesize) {
- case 512:
- args->oobsize = 16;
- args->bad_marker_offs_in_oob = 5;
- oob_idx = 0;
- break;
- case 2048:
- args->oobsize = 64;
- args->bad_marker_offs_in_oob = 0;
- oob_idx = 1;
- break;
- default:
- fprintf(stderr, "Unsupported page size: %d\n", args->pagesize);
- return -EINVAL;
- }
-
- /* Figure out correct oob layout if it differs from default */
- if (ecc_layout) {
- for (i = 0; i < ARRAY_SIZE(oob_placement); i++)
- if (strcmp(ecc_layout, oob_placement[i].name) == 0)
- args->nand_oob =
- oob_placement[i].nand_oob[oob_idx];
- }
- return 0;
-}
-
-/*
- * We must only compare the relevant bytes in the OOB area. All other
- * bytes can be ignored. The information we need to do this is in
- * nand_oob.
- */
-static int oob_cmp(struct nand_ecclayout *nand_oob, uint8_t *oob,
- uint8_t *calc_oob)
-{
- unsigned int i;
- for (i = 0; i < nand_oob->eccbytes; i++)
- if (oob[nand_oob->eccpos[i]] != calc_oob[nand_oob->eccpos[i]])
- return 1;
- return 0;
-}
-
-static inline void hexdump(FILE *fp, const uint8_t *buf, ssize_t size)
-{
- int k;
-
- for (k = 0; k < size; k++) {
- fprintf(fp, "%02x ", buf[k]);
- if ((k & 15) == 15)
- fprintf(fp, "\n");
- }
-}
-
-static int process_page(struct args *args, uint8_t *buf, uint8_t *oobbuf)
-{
- size_t i, j;
- int eccpoi;
- uint8_t ecc_code[3] = { 0, }; /* temp */
-
- /* Calculate ECC */
- memset(oobbuf, 0xff, args->oobsize);
- for (eccpoi = 0, i = 0; i < args->pagesize; i += 256, eccpoi += 3) {
- nand_calculate_ecc(&buf[i], ecc_code);
- for (j = 0; j < 3; j++)
- oobbuf[args->nand_oob->eccpos[eccpoi + j]] = ecc_code[j];
- }
- return 0;
-}
-
-static int decompose_image(struct args *args, FILE *in_fp,
- FILE *bin_fp, FILE *oob_fp)
-{
- unsigned int i, eccpoi;
- int read, rc, page = 0;
- uint8_t *buf = malloc(args->pagesize);
- uint8_t *oob = malloc(args->oobsize);
- uint8_t *calc_oob = malloc(args->oobsize);
- uint8_t *calc_buf = malloc(args->pagesize);
- uint8_t *page_buf;
- int pages_per_block = args->blocksize / args->pagesize;
- int badpos = args->bad_marker_offs_in_oob;
- uint8_t ecc_code[3] = { 0, }; /* temp */
- uint8_t calc_ecc_code[3] = { 0, }; /* temp */
-
- if (!buf || !oob || !calc_oob || !calc_buf)
- exit(EXIT_FAILURE);
-
- while (!feof(in_fp)) {
- /* read page by page */
- read = fread(buf, 1, args->pagesize, in_fp);
- if (ferror(in_fp)) {
- fprintf(stderr, "I/O Error.");
- exit(EXIT_FAILURE);
- }
- if (read != (ssize_t)args->pagesize)
- break;
-
- read = fread(oob, 1, args->oobsize, in_fp);
- if (ferror(in_fp)) {
- fprintf(stderr, "I/O Error.");
- exit(EXIT_FAILURE);
- }
-
- page_buf = buf; /* default is unmodified data */
-
- if ((page == 0 || page == 1) && (oob[badpos] != 0xff)) {
- if (verbose)
- printf("Block %d is bad\n",
- page / pages_per_block);
- goto write_data;
- }
- if (args->correct_ecc)
- page_buf = calc_buf;
-
- process_page(args, buf, calc_oob);
- memcpy(calc_buf, buf, args->pagesize);
-
- if (verbose && oob_cmp(args->nand_oob, oob, calc_oob) != 0) {
- printf("\nECC compare mismatch found at block %d page %d!\n",
- page / pages_per_block, page % pages_per_block);
-
- printf("Read out OOB Data:\n");
- hexdump(stdout, oob, args->oobsize);
-
- printf("Calculated OOB Data:\n");
- hexdump(stdout, calc_oob, args->oobsize);
- }
-
- /* Do correction on subpage base */
- for (i = 0, eccpoi = 0; i < args->pagesize; i += 256, eccpoi += 3) {
- int j;
-
- for (j = 0; j < 3; j++) {
- ecc_code[j] = oob[args->nand_oob->eccpos[eccpoi + j]];
- calc_ecc_code[j] =
- calc_oob[args->nand_oob->eccpos[eccpoi + j]];
- }
- rc = nand_correct_data(calc_buf + i, ecc_code,
- calc_ecc_code);
- if (rc == -1)
- fprintf(stdout, "Uncorrectable ECC error at "
- "block %d page %d/%d\n",
- page / pages_per_block,
- page % pages_per_block, i / 256);
- else if (rc > 0)
- fprintf(stdout, "Correctable ECC error at "
- "block %d page %d/%d\n",
- page / pages_per_block,
- page % pages_per_block, i / 256);
- }
-
- write_data:
- rc = fwrite(page_buf, 1, args->pagesize, bin_fp);
- if (ferror(bin_fp)) {
- fprintf(stderr, "I/O Error.");
- exit(EXIT_FAILURE);
- }
- rc = fwrite(oob, 1, args->oobsize, oob_fp);
- if (ferror(bin_fp)) {
- fprintf(stderr, "I/O Error.");
- exit(EXIT_FAILURE);
- }
-
- page++;
- }
- free(calc_buf);
- free(calc_oob);
- free(oob);
- free(buf);
- return 0;
-}
-
-static int split_blocks(struct args *args, FILE *in_fp)
-{
- uint8_t *buf;
- int pages_per_block = args->blocksize / args->pagesize;
- int block_len = pages_per_block * (args->pagesize + args->oobsize);
- int blocks = args->in_len / block_len;
- char bname[256] = { 0, };
- int badpos = args->bad_marker_offs_in_oob;
- int bad_blocks = 0, i, bad_block = 0;
- ssize_t rc;
- FILE *b;
-
- buf = malloc(block_len);
- if (!buf) {
- perror("Not enough memory");
- exit(EXIT_FAILURE);
- }
-
- for (i = 0; i < blocks; i++) {
- rc = fread(buf, 1, block_len, in_fp);
- if (rc != block_len) {
- fprintf(stderr, "cannot read enough data!\n");
- exit(EXIT_FAILURE);
- }
-
- /* do block analysis */
- bad_block = 0;
- if ((buf[args->pagesize + badpos] != 0xff) ||
- (buf[2 * args->pagesize + args->oobsize + badpos] != 0xff)) {
- bad_blocks++;
- bad_block = 1;
- }
- if ((verbose && bad_block) || (verbose > 1)) {
- printf("-- (block %d oob of page 0 and 1)\n", i);
- hexdump(stdout, buf + args->pagesize, args->oobsize);
- printf("--\n");
- hexdump(stdout, buf + 2 * args->pagesize +
- args->oobsize, args->oobsize);
- }
-
- /* write complete block out */
- snprintf(bname, sizeof(bname) - 1, "%s.%d", args->arg1, i);
- b = fopen(bname, "w+");
- if (!b) {
- perror("Cannot open file");
- exit(EXIT_FAILURE);
- }
- rc = fwrite(buf, 1, block_len, b);
- if (rc != block_len) {
- fprintf(stderr, "could not write all data!\n");
- exit(EXIT_FAILURE);
- }
- fclose(b);
- }
-
- free(buf);
- if (bad_blocks || verbose)
- fprintf(stderr, "%d blocks, %d bad blocks\n",
- blocks, bad_blocks);
- return 0;
-}
-
-int
-main(int argc, char *argv[])
-{
- FILE *in, *bin = NULL, *oob = NULL;
- struct stat file_info;
-
- parse_opt(argc, argv, &myargs);
-
- if (!myargs.arg1) {
- fprintf(stderr, "Please specify input file!\n");
- exit(EXIT_FAILURE);
- }
-
- if (lstat(myargs.arg1, &file_info) != 0) {
- perror("Cannot fetch file size from input file.\n");
- exit(EXIT_FAILURE);
- }
- myargs.in_len = file_info.st_size;
-
- in = fopen(myargs.arg1, "r");
- if (!in) {
- perror("Cannot open file");
- exit(EXIT_FAILURE);
- }
-
- if (myargs.split_blocks) {
- split_blocks(&myargs, in);
- goto out;
- }
-
- bin = fopen(myargs.output_file, "w+");
- if (!bin) {
- perror("Cannot open file");
- exit(EXIT_FAILURE);
- }
- oob = fopen(myargs.oob_file, "w+");
- if (!oob) {
- perror("Cannot open file");
- exit(EXIT_FAILURE);
- }
- decompose_image(&myargs, in, bin, oob);
-
- out:
- if (in) fclose(in);
- if (bin) fclose(bin);
- if (oob) fclose(oob);
- exit(EXIT_SUCCESS);
-}
diff --git a/ubi-utils/src/nandcorr.c b/ubi-utils/src/nandcorr.c
deleted file mode 100644
index caa07e2..0000000
--- a/ubi-utils/src/nandcorr.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * ECC algorithm for NAND FLASH. Detects and corrects 1 bit errors in
- * a 256 bytes of data.
- *
- * Reimplement by Thomas Gleixner after staring long enough at the
- * mess in drivers/mtd/nand/nandecc.c
- *
- */
-
-#include "nandecc.h"
-
-static int countbits(uint32_t byte)
-{
- int res = 0;
-
- for (;byte; byte >>= 1)
- res += byte & 0x01;
- return res;
-}
-
-/**
- * @dat: data which should be corrected
- * @read_ecc: ecc information read from flash
- * @calc_ecc: calculated ecc information from the data
- * @return: number of corrected bytes
- * or -1 when no correction is possible
- */
-int nand_correct_data(uint8_t *dat, const uint8_t *read_ecc,
- const uint8_t *calc_ecc)
-{
- uint8_t s0, s1, s2;
-
- /*
- * Do error detection
- *
- * Be careful, the index magic is due to a pointer to a
- * uint32_t.
- */
- s0 = calc_ecc[0] ^ read_ecc[0];
- s1 = calc_ecc[1] ^ read_ecc[1];
- s2 = calc_ecc[2] ^ read_ecc[2];
-
- if ((s0 | s1 | s2) == 0)
- return 0;
-
- /* Check for a single bit error */
- if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 &&
- ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 &&
- ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) {
-
- uint32_t byteoffs, bitnum;
-
- byteoffs = (s1 << 0) & 0x80;
- byteoffs |= (s1 << 1) & 0x40;
- byteoffs |= (s1 << 2) & 0x20;
- byteoffs |= (s1 << 3) & 0x10;
-
- byteoffs |= (s0 >> 4) & 0x08;
- byteoffs |= (s0 >> 3) & 0x04;
- byteoffs |= (s0 >> 2) & 0x02;
- byteoffs |= (s0 >> 1) & 0x01;
-
- bitnum = (s2 >> 5) & 0x04;
- bitnum |= (s2 >> 4) & 0x02;
- bitnum |= (s2 >> 3) & 0x01;
-
- dat[byteoffs] ^= (1 << bitnum);
-
- return 1;
- }
-
- if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
- return 1;
-
- return -1;
-}
-
diff --git a/ubi-utils/src/nandecc.c b/ubi-utils/src/nandecc.c
deleted file mode 100644
index 71660ef..0000000
--- a/ubi-utils/src/nandecc.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * This file contains an ECC algorithm from Toshiba that detects and
- * corrects 1 bit errors in a 256 byte block of data.
- *
- * drivers/mtd/nand/nand_ecc.c
- *
- * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
- * Toshiba America Electronics Components, Inc.
- *
- * This file is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 or (at your option) any
- * later version.
- *
- * This file is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this file; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * As a special exception, if other files instantiate templates or use
- * macros or inline functions from these files, or you compile these
- * files and link them with other works to produce a work based on these
- * files, these files do not by themselves cause the resulting work to be
- * covered by the GNU General Public License. However the source code for
- * these files must still be made available in accordance with section (3)
- * of the GNU General Public License.
- *
- * This exception does not invalidate any other reasons why a work based on
- * this file might be covered by the GNU General Public License.
- */
-
-#include "nandecc.h"
-
-/*
- * Pre-calculated 256-way 1 byte column parity
- */
-static const uint8_t nand_ecc_precalc_table[] = {
- 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
- 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
- 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
- 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
- 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
- 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
- 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
- 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
- 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
- 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
- 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
- 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
- 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
- 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
- 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
- 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
- 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
- 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
- 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
- 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
- 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
- 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
- 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
- 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
- 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
- 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
- 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
- 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
- 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
- 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
- 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
- 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
-};
-
-/**
- * nand_trans_result - [GENERIC] create non-inverted ECC
- * @reg2: line parity reg 2
- * @reg3: line parity reg 3
- * @ecc_code: ecc
- *
- * Creates non-inverted ECC code from line parity
- */
-static void nand_trans_result(uint8_t reg2, uint8_t reg3,
- uint8_t *ecc_code)
-{
- uint8_t a, b, i, tmp1, tmp2;
-
- /* Initialize variables */
- a = b = 0x80;
- tmp1 = tmp2 = 0;
-
- /* Calculate first ECC byte */
- for (i = 0; i < 4; i++) {
- if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
- tmp1 |= b;
- b >>= 1;
- if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
- tmp1 |= b;
- b >>= 1;
- a >>= 1;
- }
-
- /* Calculate second ECC byte */
- b = 0x80;
- for (i = 0; i < 4; i++) {
- if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
- tmp2 |= b;
- b >>= 1;
- if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
- tmp2 |= b;
- b >>= 1;
- a >>= 1;
- }
-
- /* Store two of the ECC bytes */
- ecc_code[1] = tmp1;
- ecc_code[0] = tmp2;
-}
-
-/**
- * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for
- * 256 byte block
- *
- * @dat: raw data
- * @ecc_code: buffer for ECC
- */
-int nand_calculate_ecc(const uint8_t *dat, uint8_t *ecc_code)
-{
- uint8_t idx, reg1, reg2, reg3;
- int j;
-
- /* Initialize variables */
- reg1 = reg2 = reg3 = 0;
- ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
-
- /* Build up column parity */
- for(j = 0; j < 256; j++) {
-
- /* Get CP0 - CP5 from table */
- idx = nand_ecc_precalc_table[dat[j]];
- reg1 ^= (idx & 0x3f);
-
- /* All bit XOR = 1 ? */
- if (idx & 0x40) {
- reg3 ^= (uint8_t) j;
- reg2 ^= ~((uint8_t) j);
- }
- }
-
- /* Create non-inverted ECC code from line parity */
- nand_trans_result(reg2, reg3, ecc_code);
-
- /* Calculate final ECC code */
- ecc_code[0] = ~ecc_code[0];
- ecc_code[1] = ~ecc_code[1];
- ecc_code[2] = ((~reg1) << 2) | 0x03;
- return 0;
-}
diff --git a/ubi-utils/src/nandecc.h b/ubi-utils/src/nandecc.h
deleted file mode 100644
index bcf1982..0000000
--- a/ubi-utils/src/nandecc.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _NAND_ECC_H
-#define _NAND_ECC_H
-/*
- * Copyright (c) International Business Machines Corp., 2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * NAND ecc functions
- */
-
-#include <stdint.h>
-
-int nand_calculate_ecc(const uint8_t *dat, uint8_t *ecc_code);
-int nand_correct_data(uint8_t *dat, const uint8_t *read_ecc,
- const uint8_t *calc_ecc);
-
-#endif