Merge pull request #57 from bbrezillon/nand-image-builder
Nand image builder improvements
This commit is contained in:
commit
89dac0f7ea
@ -14,55 +14,22 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* For the BCH implementation:
|
||||
*
|
||||
* Copyright © 2011 Parrot S.A.
|
||||
*
|
||||
* Author: Ivan Djelic <ivan.djelic@parrot.com>
|
||||
*
|
||||
* Description:
|
||||
* See also:
|
||||
* http://lxr.free-electrons.com/source/lib/bch.c
|
||||
*
|
||||
* This library provides runtime configurable encoding/decoding of binary
|
||||
* Bose-Chaudhuri-Hocquenghem (BCH) codes.
|
||||
* For the randomizer and image builder implementation:
|
||||
*
|
||||
* Call init_bch to get a pointer to a newly allocated bch_control structure for
|
||||
* the given m (Galois field order), t (error correction capability) and
|
||||
* (optional) primitive polynomial parameters.
|
||||
* Copyright © 2016 NextThing Co.
|
||||
* Copyright © 2016 Free Electrons
|
||||
*
|
||||
* Call encode_bch to compute and store ecc parity bytes to a given buffer.
|
||||
* Call decode_bch to detect and locate errors in received data.
|
||||
* Author: Boris Brezillon <boris.brezillon@free-electrons.com>
|
||||
*
|
||||
* On systems supporting hw BCH features, intermediate results may be provided
|
||||
* to decode_bch in order to skip certain steps. See decode_bch() documentation
|
||||
* for details.
|
||||
*
|
||||
* Option CONFIG_BCH_CONST_PARAMS can be used to force fixed values of
|
||||
* parameters m and t; thus allowing extra compiler optimizations and providing
|
||||
* better (up to 2x) encoding performance. Using this option makes sense when
|
||||
* (m,t) are fixed and known in advance, e.g. when using BCH error correction
|
||||
* on a particular NAND flash device.
|
||||
*
|
||||
* Algorithmic details:
|
||||
*
|
||||
* Encoding is performed by processing 32 input bits in parallel, using 4
|
||||
* remainder lookup tables.
|
||||
*
|
||||
* The final stage of decoding involves the following internal steps:
|
||||
* a. Syndrome computation
|
||||
* b. Error locator polynomial computation using Berlekamp-Massey algorithm
|
||||
* c. Error locator root finding (by far the most expensive step)
|
||||
*
|
||||
* In this implementation, step c is not performed using the usual Chien search.
|
||||
* Instead, an alternative approach described in [1] is used. It consists in
|
||||
* factoring the error locator polynomial using the Berlekamp Trace algorithm
|
||||
* (BTA) down to a certain degree (4), after which ad hoc low-degree polynomial
|
||||
* solving techniques [2] are used. The resulting algorithm, called BTZ, yields
|
||||
* much better performance than Chien search for usual (m,t) values (typically
|
||||
* m >= 13, t < 32, see [1]).
|
||||
*
|
||||
* [1] B. Biswas, V. Herbert. Efficient root finding of polynomials over fields
|
||||
* of characteristic 2, in: Western European Workshop on Research in Cryptology
|
||||
* - WEWoRC 2009, Graz, Austria, LNCS, Springer, July 2009, to appear.
|
||||
* [2] [Zin96] V.A. Zinoviev. On the solution of equations of degree 10 over
|
||||
* finite fields GF(2^q). In Rapport de recherche INRIA no 2829, 1996.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
@ -950,21 +917,51 @@ static void display_help(int status)
|
||||
{
|
||||
fprintf(status == EXIT_SUCCESS ? stdout : stderr,
|
||||
"Usage: sunxi-nand-image-builder [OPTIONS] source-image output-image\n"
|
||||
"\n"
|
||||
"Creates a raw NAND image that can be read by the sunxi NAND controller.\n"
|
||||
"\n"
|
||||
"-h --help Display this help and exit\n"
|
||||
"-c <strength>/<step> --ecc=<strength>/<step> ECC config\n"
|
||||
" Valid strengths: 16, 24, 28, 32, 40, 48, 56, 60 and 64\n"
|
||||
" Valid steps: 512 and 1024\n"
|
||||
"-p <size> --page-size=<size> Page size\n"
|
||||
"-o <size> --oob-size=<size> OOB size\n"
|
||||
"-u <size> --usable-page-size=<size> Usable page size. Only needed for boot0 mode\n"
|
||||
"-e <size> --eraseblock-size=<size> Erase block size\n"
|
||||
"-b --boot0 Build a boot0 image.\n"
|
||||
"-s --scramble Scramble data\n"
|
||||
"-a <offset> --address Where the image will be programmed.\n"
|
||||
" This option is only required for non boot0 images that are meant to be programmed at a non eraseblock aligned offset.\n"
|
||||
"\n");
|
||||
"-h --help Display this help and exit\n"
|
||||
"-c <str>/<step> --ecc=<str>/<step> ECC config (strength/step-size)\n"
|
||||
"-p <size> --page=<size> Page size\n"
|
||||
"-o <size> --oob=<size> OOB size\n"
|
||||
"-u <size> --usable=<size> Usable page size\n"
|
||||
"-e <size> --eraseblock=<size> Erase block size\n"
|
||||
"-b --boot0 Build a boot0 image.\n"
|
||||
"-s --scramble Scramble data\n"
|
||||
"-a <offset> --address=<offset> Where the image will be programmed.\n"
|
||||
"\n"
|
||||
"Notes:\n"
|
||||
"All the information you need to pass to this tool should be part of\n"
|
||||
"the NAND datasheet.\n"
|
||||
"\n"
|
||||
"The NAND controller only supports the following ECC configs\n"
|
||||
" Valid ECC strengths: 16, 24, 28, 32, 40, 48, 56, 60 and 64\n"
|
||||
" Valid ECC step size: 512 and 1024\n"
|
||||
"\n"
|
||||
"If you are building a boot0 image, you'll have specify extra options.\n"
|
||||
"These options should be chosen based on the layouts described here:\n"
|
||||
" http://linux-sunxi.org/NAND#More_information_on_BROM_NAND\n"
|
||||
"\n"
|
||||
" --usable should be assigned the 'Hardware page' value\n"
|
||||
" --ecc should be assigned the 'ECC capacity'/'ECC page' values\n"
|
||||
" --usable should be smaller than --page\n"
|
||||
"\n"
|
||||
"The --address option is only required for non-boot0 images that are \n"
|
||||
"meant to be programmed at a non eraseblock aligned offset.\n"
|
||||
"\n"
|
||||
"Examples:\n"
|
||||
" The H27UCG8T2BTR-BC NAND exposes\n"
|
||||
" * 16k pages\n"
|
||||
" * 1280 OOB bytes per page\n"
|
||||
" * 4M eraseblocks\n"
|
||||
" * requires data scrambling\n"
|
||||
" * expects a minimum ECC of 40bits/1024bytes\n"
|
||||
"\n"
|
||||
" A normal image can be generated with\n"
|
||||
" sunxi-nand-image-builder -p 16384 -o 1280 -e 0x400000 -s -c 40/1024\n"
|
||||
" A boot0 image can be generated with\n"
|
||||
" sunxi-nand-image-builder -p 16384 -o 1280 -e 0x400000 -s -b -u 4096 -c 64/1024\n"
|
||||
);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
@ -974,20 +971,37 @@ static int check_image_info(struct image_info *info)
|
||||
int eccbytes, eccsteps;
|
||||
unsigned i;
|
||||
|
||||
if (!info->page_size || !info->oob_size || !info->eraseblock_size ||
|
||||
!info->usable_page_size)
|
||||
if (!info->page_size) {
|
||||
fprintf(stderr, "--page is missing\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->ecc_step_size != 512 && info->ecc_step_size != 1024)
|
||||
if (!info->page_size) {
|
||||
fprintf(stderr, "--oob is missing\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!info->eraseblock_size) {
|
||||
fprintf(stderr, "--eraseblock is missing\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->ecc_step_size != 512 && info->ecc_step_size != 1024) {
|
||||
fprintf(stderr, "Invalid ECC step argument: %d\n",
|
||||
info->ecc_step_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(valid_ecc_strengths); i++) {
|
||||
if (valid_ecc_strengths[i] == info->ecc_strength)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(valid_ecc_strengths))
|
||||
if (i == ARRAY_SIZE(valid_ecc_strengths)) {
|
||||
fprintf(stderr, "Invalid ECC strength argument: %d\n",
|
||||
info->ecc_strength);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
eccbytes = DIV_ROUND_UP(info->ecc_strength * 14, 8);
|
||||
if (eccbytes % 2)
|
||||
@ -997,8 +1011,11 @@ static int check_image_info(struct image_info *info)
|
||||
eccsteps = info->usable_page_size / info->ecc_step_size;
|
||||
|
||||
if (info->page_size + info->oob_size <
|
||||
info->usable_page_size + (eccsteps * (eccbytes)))
|
||||
info->usable_page_size + (eccsteps * eccbytes)) {
|
||||
fprintf(stderr,
|
||||
"ECC bytes do not fit in the NAND page, choose a weaker ECC\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1015,19 +1032,19 @@ int main(int argc, char **argv)
|
||||
int option_index = 0;
|
||||
char *endptr = NULL;
|
||||
static const struct option long_options[] = {
|
||||
{"help", no_argument, 0, 0},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"ecc", required_argument, 0, 'c'},
|
||||
{"page-size", required_argument, 0, 'p'},
|
||||
{"oob-size", required_argument, 0, 'o'},
|
||||
{"usable-page-size", required_argument, 0, 'u'},
|
||||
{"eraseblock-size", required_argument, 0, 'e'},
|
||||
{"page", required_argument, 0, 'p'},
|
||||
{"oob", required_argument, 0, 'o'},
|
||||
{"usable", required_argument, 0, 'u'},
|
||||
{"eraseblock", required_argument, 0, 'e'},
|
||||
{"boot0", no_argument, 0, 'b'},
|
||||
{"scramble", no_argument, 0, 's'},
|
||||
{"address", required_argument, 0, 'a'},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
int c = getopt_long(argc, argv, "c:p:o:u:e:ba:s",
|
||||
int c = getopt_long(argc, argv, "c:p:o:u:e:ba:sh",
|
||||
long_options, &option_index);
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user