项目进行到最后阶段,需要把程序拿到工厂去烧写测试。
结果发现工厂的软件没有针对ST-Uboot自带stm_nand_calculate_ecc校验,所以只能够将uboot.bin做成跟
根文件系统一样的自带ecc校验的来进行烧写,即2048 64字节的bin文件。
拿回来之后启动正常,但是出现了
nand_read_bbt: Bad block at 0x00000000
第一个块居然坏了!!!
但是芯片出厂的时候是保证第一个块是好的。
经过仔细分析,终于发现了问题
当uboot从nandflash上启动时,自身也有ecc校验并且和linux默认的ecc校验很不一样,如果改成其自带的linux默认ecc校验 会导致uboot根本无法启动:
-
/*
-
* Do we want to read/write NAND Flash compatible with the ST40's
-
* NAND Controller H/W IP block for "boot-mode"? If we want
-
* to read/write NAND flash that is meant to support booting
-
* from NAND, then we need to use 3 bytes of ECC per 128 byte
-
* record. If so, then define the "CFG_NAND_ECC_HW3_128" macro.
-
*/
-
# define CFG_NAND_ECC_HW3_128 /* define for "boot-from-NAND" compatibility */
-
-
/*
-
* If using CFG_NAND_ECC_HW3_128, then we must also define
-
* where the (high watermark) boundary is. That is, the
-
* NAND offset, below which we are in "boot-mode", and
-
* must use 3 bytes of ECC for each 128 byte record.
-
* For this offset (and above) we can use any supported
-
* ECC configuration (e.g 3/256 S/W, or 3/512 H/W).
-
*/
-
# define CFG_NAND_STM_BOOT_MODE_BOUNDARY (1ul << 17) /* 128 Kb */
从注释可以得知 要使用 boot from nand 就必须要用到3 bytes of ECC for each 128 byte record.
即每128字节做3字节的ecc校验
我们用到的nandflash是K9F1G08U0B这块:存储单元为(128M 4M)*8位,数据寄存器为(2K 64)字节,
所以在uboot上他的oob区域被定义为
-
/* for LARGE-page devices */
-
static struct nand_oobinfo stm_nand_oobinfo_64 = {
-
.useecc = MTD_NANDECC_AUTOPLACE,
-
.eccbytes = 48,
-
.eccpos = {
-
0, 1, 2, /* ECC for 1st 128-byte record */
-
4, 5, 6, /* ECC for 2nd 128-byte record */
-
8, 9, 10, /* ECC for 3rd 128-byte record */
-
12, 13, 14, /* ECC for 4th 128-byte record */
-
16, 17, 18, /* ECC for 5th 128-byte record */
-
20, 21, 22, /* ECC for 6th 128-byte record */
-
24, 25, 26, /* ECC for 7th 128-byte record */
-
28, 29, 30, /* ECC for 8th 128-byte record */
-
32, 33, 34, /* ECC for 9th 128-byte record */
-
36, 37, 38, /* ECC for 10th 128-byte record */
-
40, 41, 42, /* ECC for 11th 128-byte record */
-
44, 45, 46, /* ECC for 12th 128-byte record */
-
48, 49, 50, /* ECC for 13th 128-byte record */
-
52, 53, 54, /* ECC for 14th 128-byte record */
-
56, 57, 58, /* ECC for 15th 128-byte record */
-
60, 61, 62}, /* ECC for 16th 128-byte record */
-
.oobfree = {
-
{ 3, 1}, { 7, 1}, {11, 1}, {15, 1},
-
{19, 1}, {23, 1}, {27, 1}, {31, 1},
-
{35, 1}, {39, 1}, {43, 1}, {47, 1},
-
{51, 1}, {55, 1}, {59, 1}, {63, 1} },
-
};
以第一块第一页(2048 byte)为例:
OOB:
cf 00 fc ff 0f 00 3c ff
00 00 00 ff 95 25 64 ff
65 26 a8 ff 3c 00 cc ff
95 2a 68 ff 30 33 0c ff
cc 30 c0 ff 59 16 54 ff
aa 16 64 ff 3f 0f 30 ff
6a 2a 58 ff f0 0f f0 ff
55 25 a4 ff 59 15 54 ff
和默认的linux ecc校验区域做对比 以第二快第二页为例:
OOB:
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff 3f 3f 5a 6a 9b 99 a6
9b a6 5a 9b 59 6a 6b 00
0f 33 9a 65 57 0f f3 0f
很明显的可以看出差别。
然后uboot启动时会首先去寻找bbt,即坏块表,如果找不到的话会在某个指定的位置建立一个bbt,而我们的bbt放在了nandflash最后3个块上面。
将bbt dump出来后发现
Page 07fc0000 dump:
fc ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff