Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Sunxi Tools
Commits
89dac0f7
Commit
89dac0f7
authored
Jun 06, 2016
by
NiteHawk
Browse files
Merge pull request #57 from bbrezillon/nand-image-builder
Nand image builder improvements
parents
a4557874
fe299a32
Changes
1
Hide whitespace changes
Inline
Side-by-side
nand-image-builder.c
View file @
89dac0f7
...
...
@@ -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:
*
* This library provides runtime configurable encoding/decoding of binary
* Bose-Chaudhuri-Hocquenghem (BCH) codes.
*
* 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.
*
* 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.
*
* 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:
* See also:
* http://lxr.free-electrons.com/source/lib/bch.c
*
* Encoding is performed by processing 32 input bits in parallel, using 4
* remainder lookup tables.
* For the randomizer and image builder implementation:
*
* 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)
* Copyright © 2016 NextThing Co.
* Copyright © 2016 Free Electrons
*
* 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]).
* Author: Boris Brezillon <boris.brezillon@free-electrons.com>
*
* [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
->
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
)
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:s
h
"
,
long_options
,
&
option_index
);
if
(
c
==
EOF
)
break
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment