最近按照客户需求扩大nand容量,之前自己做的AM335X板子使用镁光的4g容量MT29F4G08ABADA,这次更换为8g容量MT29F8G08ABACA。
4g容量的pagesize为2048b,obb大小64b,8g容量的pagesize为4096b,obb大小224b,请问修改uboot中nand配置需要注意些什么,我修改完使用sd卡烧写uboot
后断电重启,串口打CC,写操作每次都显示OK,但事实上没写成功,不知道什么原因
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
最近按照客户需求扩大nand容量,之前自己做的AM335X板子使用镁光的4g容量MT29F4G08ABADA,这次更换为8g容量MT29F8G08ABACA。
4g容量的pagesize为2048b,obb大小64b,8g容量的pagesize为4096b,obb大小224b,请问修改uboot中nand配置需要注意些什么,我修改完使用sd卡烧写uboot
后断电重启,串口打CC,写操作每次都显示OK,但事实上没写成功,不知道什么原因
你的写操作是什么?怎么知道它没写成功?
在文件中 Am335x_evm.h (include\configs) 修改相关参数:
#ifdef CONFIG_NAND
/* NAND: device related configs */
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \
CONFIG_SYS_NAND_PAGE_SIZE)
#define CONFIG_SYS_NAND_PAGE_SIZE 2048
#define CONFIG_SYS_NAND_OOBSIZE 64
#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)
感谢您的回复! 我使用SD卡启动到uboot下,使用nand write 写MLO,再使用nand read 读
U-Boot# nand write 0x81000000 0x0 0x20000
NAND write: device 0 offset 0x0, size 0x20000
131072 bytes written: OK
U-Boot# nand read 0x81000000 0x0 0x20000
NAND read: device 0 offset 0x0, size 0x20000
...
ECC: uncorrectable.
ECC: uncorrectable.
NAND read from offset 0 failed -74
0 bytes read: ERROR
您说的地方也都改了,看起来是ECC错误,那么ECC部分如何修改
#define CONFIG_SYS_NAND_PAGE_SIZE 4*1024 //2048
#define CONFIG_SYS_NAND_OOBSIZE 224 //64
#define CONFIG_SYS_NAND_BLOCK_SIZE (256*1024)//(128*1024)
#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS
#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \
10, 11, 12, 13, 14, 15, 16, 17, \
18, 19, 20, 21, 22, 23, 24, 25, \
26, 27, 28, 29, 30, 31, 32, 33, \
34, 35, 36, 37, 38, 39, 40, 41, \
42, 43, 44, 45, 46, 47, 48, 49, \
50, 51, 52, 53, 54, 55, 56, 57, }
#define CONFIG_SYS_NAND_ECCSIZE 512
#define CONFIG_SYS_NAND_ECCBYTES 14
8g容量的nand手册上看到
Minimum required ECC 8-bit ECC per 540 bytes of data
标红的部分应该怎么改
配置如下:
#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH16_CODE_HW #define CONFIG_SYS_NAND_ECCBYTES 26 #define CONFIG_SPL_NAND_AM33XX_BCH #define CONFIG_SYS_NAND_ECCSIZE 512 #define CONFIG_SYS_NAND_ECCPOS \ { 2, 3, 4, 5, 6, 7, 8, 9, \ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, \ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, \ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, \ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, \ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, \ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, \ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, \ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, \ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, \ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, \ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, \ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, \ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, \ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, \ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, \ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, \ 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, \ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, \ 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, \ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, }
在DT Bindings 配置
ti,nand-ecc-opts="bch16"
ti,elm-id="<&elm>
在KConfigs 配置
CONFIG_MTD_NAND_OMAP_BCH=y
我的UBOOT使用的是psp6.0中的u-boot-2013.01.01-psp06.00.00.00,没有使用设备树配置,对于我使用的uboot版本,如何添加BCH16的支持
先修改下面这些,uboot能正常驱动uboot了吗?
#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH16_CODE_HW #define CONFIG_SYS_NAND_ECCBYTES 26 #define CONFIG_SPL_NAND_AM33XX_BCH #define CONFIG_SYS_NAND_ECCSIZE 512 #define CONFIG_SYS_NAND_ECCPOS \ { 2, 3, 4, 5, 6, 7, 8, 9, \ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, \ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, \ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, \ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, \ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, \ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, \ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, \ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, \ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, \ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, \ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, \ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, \ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, \ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, \ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, \ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, \ 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, \ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, \ 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, \ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, }
U-Boot 2013.01.01 (May 05 2017 - 11:00:08)
I2C: ready
DRAM: 512 MiB
WARNING: Caches not enabled
NAND: nand option: 0xd
maf_id:0x2c
dev_id:0xd3
ret:0 busw: 0
byte2:0x90
byte3:0xa6
byte4:0x64
byte5:0x0
byte6:0x0
byte7:0x0
else busw:0
NAND device: Manufacturer ID: 0x2c, Chip ID: 0xd3 (Micron NAND 1GiB 3,3V 8-bit)
NAND 1GiB 3,3V 8-bit, sector size 256 KiB
Page size 4096 b
OOB size 224 b
Erase size 262144 b
nand scan : ret 0
1024 MiB
MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1
按照您给的配置修改完,uboot卡在这了,而且看了下
#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH16_CODE_HW
这个定义uboot中没有用到
是这个CONFIG_NAND_OMAP_ECCSCHEME 没定义
还是这个CONFIG_NAND_OMAP_ECCSCHEME 没定义 ?
CONFIG_NAND_OMAP_ECCSCHEME
是这个,整个uboot中没有用到这个定义
check了一下,发现你用的这个版本的uboot和kernel都不支持BCH16,较新的PDK是可以支持的
To select ECC algorithm for NAND:
U-Boot# nandecc [sw | hw <hw_type>]
Usage:
sw - Set software ECC for NAND hw <hw_type> - Set hardware ECC for NAND <hw_type> - 0 for Hamming code 1 for bch4 2 for bch8 3 for bch16 Currently we support only Software, Hamming Code and BCH8. We do not support BCH4 and BCH16
Component | Default ECC scheme used by the component | ECC scheme to be used to flash the component | ECC schemes supported by the component |
---|---|---|---|
SPL | BCH8 | BCH8 | BCH8 |
U-boot | Hamming | BCH8 | Hamming/BCH8 |
Linux | BCH8 | BCH8 | BCH8 |
File System | NA | BCH8 | NA |
Environment variables | NA | Hamming | NA |
现在有点疑惑,am335x的ROM CODE是否支持镁光的MT29F8G08ABACA
1 page = (4K + 224 bytes)
1 block = (4K + 224) bytes x 64 pages = (256K + 14K) bytes
1 plane = (256K + 14K) bytes x 2048 blocks= 4320Mb
1 LUN = 4320Mb x 2 planes= 8640Mb
manufacturer ID: 0x2c
device ID : 0xd3
我可以帮你check 一下ROM code是否可以
下面是这块NAND的指标参数对吧
嗯,是的,那个oob 224b 很诡异,不知道uboot下如何配置
可以尝试用新的PDK来驱动看看行不行,如果可以驱动成功,把MLO Uboot 写进去,看看能不能从Nand启动,也顺便证明了ROM core能不能驱动它
我在am335x technical reference manul 手册26章中发现有这一句,Support for large page size (2048 bytes + 64 spare bytes) or very large page size 4096 bytes + 128 /218 spare bytes), 能否作为不支持该nand的依据
这个NAND flash是可以支持的。
首先为你解释一下什么是OOB。OOB Area (spare region) 的作用是为了实现ECC的功能,所保留在nand flash 每一page的空间大小:
当往某一款NAND Flash的page中写入数据的时候,假设这款NAND flash是每写256字节时候,我们生成一个ECC校验和,称之为原ECC校验和,需要保存到PAGE的OOB(out-of-band)数据区中。
当从NAND Flash中读取数据的时候,每256字节我们生成一个ECC校验和,称之为新ECC校验和。
校验的时候,根据上述ECC生成原理不难推断:将从OOB区中读出的原ECC校验和新ECC校验和按位异或,若结果为0,则表示不存在错(或是出现了ECC无法检测的错误);若3个字节异或结果中存在11个比特位为1,表示存在一个比特错误,且可纠正;若3个字节异或结果中只存在1个比特位为1,表示OOB区出错;其他情况均表示出现了无法纠正的错误。
再跟你解析一下为什么AM335x可以支持这个nand flash:
The MT29F8G08ABACA NAND 要求最小 8-bit ECC per 540 bytes of data. 我们ROM core可以满足这个要求,因为采用算法-- BCH8 algorithm, 是采用 14 bytes of ECC for every 512 bytes of data (112 bytes per 4k page)
对于 4k 的page中,你的nand flash的OOB 是 224 bytes.
OOB除了存ECC,还存有:.
• Bad block marker for a bad block (mandatory),一般是2-bytes
所以NAND flash 的OOB空间要求是…
OOB Area (spare region) >= B * ( Page_Size / 512 ) + 2
where
B = 8 bytes for BCH4
B = 14 bytes for BCH8 ***
B = 26 bytes for BCH16
当我们用 BCH8 (8-bit ECC), 我们依然有 110 bytes 剩余
当我们用BCH16 ,我们有14 bytes 剩余
所以是可以使用这款Nand flash的
谢谢您的指导,我仔细看了AM335x的技术手册,是支持的,我这边出错是很大原因是因为uboot中oob区相关的配置错误,像这些配置有没有什么资料可以参考参考
这个链接可以参考一下,建议还是换成新的PDK,旧 的版本,4096page 的BH8好像不支持,我目前看到是这样的
楼主,你们用这款Nand Flash跑起来了吗?我们计划升级系统,Nand Flash也是选的这款。
刚好我们的u-boot也是这个版本,我刚刚对了下代码,除了你修改的那些配置项,有一个地方要试一下:
// u-boot/drivers/mtd/nand/nand_base.c /* * Get the flash and manufacturer id and lookup if the type is supported */ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, struct nand_chip *chip, int busw, int *maf_id, int *dev_id, const struct nand_flash_dev *type) { ............................................. } else { /* Calc pagesize */ mtd->writesize = 1024 << (extid & 0x03); extid >>= 2; /* Calc oobsize */ //mtd->oobsize = (8 << (extid & 0x01)) * // (mtd->writesize >> 9); mtd->oobsize = 224; extid >>= 2; /* Calc blocksize. Blocksize is multiples of 64KiB */ mtd->erasesize = (64 * 1024) << (extid & 0x03); extid >>= 2; /* Get buswidth information */ busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; } ............................................. }
注意那个mtd->oobsize,按默认的算法计算出来的是128,但实际是224,所以,可以强制设置成224试一下。至于计算结果为什么会等于128,请参考附件Nand flash的datasheet,page 36 - 37:Table 10: READ ID Parameters for Address 00h --> Byte 3。
另外,如果你的Nand flash已经写入了之前配置错误的MLO和u-boot,再次写之前一定要完全擦除,否则oob区可能已经被写坏了,新的MLO和u-boot同样无法启动。
尝试完后,无论结果如何,还请回下贴。刚好我过两天就开始调试,大家多点交流。
Eggsy Pang,
如果将8bits的MT29F8G08ABACA改成16bits的MT29F8G16ABACA可不可以呢!
这么考虑的原因是,16bits的pagesize是2k,是不是就可以使用BCH8了?
如果可以用BCH8,那么,换成16bits的后还有什么问题需要考虑,会不会由于其它原因,平台又不支持?
以下是两个型号的基本参数:
--------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------
Jesdy Hou 首先谢谢你的分享。
我想下你用什么版本的SDK?
关于第一个问题修改这个mtd->oobsize和不修改这个,你运行的结果有什么区别吗?
第二个问题是硬件平台是可以支持的,只不过BCH8/16的在新的SDK支持性软件更好
Eggsy,
我们的平台是TI-Android-ICS-4.0.3_AM335x_3.0.1,配套的u-boot是v2011.09版本,只支持1bit的Hamming码ECC校验。去年更换过一次Nand Flash,需要支持BCH8,所以移植了TI_Android_JB_4.2.2_DevKit_4.1.1中的u-boot,版本是v2013.01.01。Kernel到不用改,Android 4.0.3中带的Kernel就支持BCH8。
关于mtd->oobsize,我还没测试,我们现在只是在做一些前期准备,Nand Flash样片申请中,估计这两天能拿到。
不过昨天我发完贴后继续研究,发现除了楼主列出的那些参数,还有其它参数要修改,比如:
1. eccsteps
// u-boot/include/configs/am335x_evm.h #define CONFIG_SYS_NAND_ECCSIZE 512 #define CONFIG_SYS_NAND_ECCBYTES 14 //#define CONFIG_SYS_NAND_ECCSTEPS 4 #define CONFIG_SYS_NAND_ECCSTEPS 8
由于BCH8中eccsize是512,之前pagesize是2048,eccsteps为4,现在,pagesize是4096,eccsteps应该改成8。
2. ecc_layout
// u-boot/arch/arm/include/asm/arch-am33xx/omap_gpmc.h #define GPMC_NAND_HW_BCH8_ECC_LAYOUT {\ .eccbytes = 56,\ .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\ 52, 53, 54, 55, 56, 57},\ .oobfree = {\ {.offset = 58,\ .length = 6 } } \ } // 改成 #define GPMC_NAND_HW_BCH8_ECC_LAYOUT {\ .eccbytes = 112,\ .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,\ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,\ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,\ 110, 111, 112, 113},\ .oobfree = {\ {.offset = 114,\ .length = 110 } } \ }
这里应该有
eccbytes = CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS = 14 * 8 = 112,
offset = eccbytes + 2 = 112 + 2 = 114,
eccpos,从2依次填充,共112个,所以填充到113,
length = CONFIG_SYS_NAND_OOBSIZE - offset = 224 - 114 = 110。
如果以上修改过程会导致BCH8无法处理,那么,是不是意味着BCH8支持不了4k pagesize。
暂时只发现以上这些,继续研究中......
当然,kernel中相应的参数也应该同步修改。
下面这个也要改下,MLO中要用到:
// u-boot/include/configs/am335x_evm.h #define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \ 10, 11, 12, 13, 14, 15, 16, 17, \ 18, 19, 20, 21, 22, 23, 24, 25, \ 26, 27, 28, 29, 30, 31, 32, 33, \ 34, 35, 36, 37, 38, 39, 40, 41, \ 42, 43, 44, 45, 46, 47, 48, 49, \ 50, 51, 52, 53, 54, 55, 56, 57, } // 改成 #define CONFIG_SYS_NAND_ECCPOS { \ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, \ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, \ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, \ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, \ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, \ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, \ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, \ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, \ 110, 111, 112, 113, }
我觉得你可以这样测试:
1.先把4096的nand flash 在Uboot阶段用BCH16来驱动,我想在新的或老的uboot版本都能够支持,应该是可以驱动起来。
2.如果第一步骤成功了,再做用4096的nand 在uboot 阶段像你所说的那样修改,用BCH8启动,看一下效果。
3.如果第一步骤成功, 第二步骤失败了,证明4096 nand一定要用BCH16来实现。
4. 得到第三步骤的结论,你只能用2048的8g flash来搞了。
我这项目比较着急,没仔细去研究,不过在uboot中我也做过类似楼上的修改,始终都没有效果,不过我大部分时间是修改AM335X_starterware里的nand_flash_writer_AM335x.out源码,使用CCS调试的,不过也没出结果,你也可以试试,这样可以更直观一些。后来换了个8G2k页大小的nand,不需要修改任何地方,可以直接nand启动。
S34ML08G101TFI00,如果你有时间,可以研究一下镁光的,硬件工程师建议是使用镁光的,项目周期的原因选的这款
1. 一个就是前面我说的16 bits总线宽度的Nand flash,按你的说法,系统是支持的,是吧!我也看到代码里是有处理的。
是 的,没错, 4096 page的用BCH16是支持的!
2. 另一个是使用两个die的Nand flash(如下图),总线宽度仍然为8 bits,不过代码里没有看到针对性的处理,不知道能不能支持。
这个2048page ,应该可以,请问它的device ID是多少
看一下TAM手册是否支持,Table 26-14. Supported NAND Devices
刚刚收到样片,不过代理商发错货,收到的不是MT29F8G08ABACA(Device ID:0xD3),而是MT29F8G08ABABA(Device ID:0x38),这个型号不在MPU的支持列表中,只能暂时做调试用。强制修改nand_flash_ids,添加对Device ID为0x38的支持,使用BCH8,按照前面我所说的修改,下载到Nand Flash后,MLO和u-boot运行均正常,Kernel启动到加载UBIFS时出现一连串的ECC错误:
UBI error: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 7:0, read 64 bytes
UBI error: ubi_io_read: error -74 (ECC error) while reading 4096 bytes from PEB 7:4096, read 4096 bytes
...............................................................
看来内核还需要进一步调试。
总算拿到MT29F8G08ABACAWP(Device ID:0xD3)的样片了,换了两片试跑一下,系统可以正常启动,未出现任何错误。Kernel代码也不需要修改什么,还跟以前一样使用默认的BCH8即可。理论上,对于不支持ONFI的Nand Flash,需要将oobsize直接改成224,因为源码中那个算法算出的结果不对。
-
另外,前面一直忘了说了,由于Page size和Block size与之前用的2 Gbits的不一样:
8 Gbits | 2 Gbits | |
Page size | 4096 Bytes | 2048 Bytes |
Block size | 256 KBytes | 128 KBytes |
所以,以下三点要修改:
1. 对Flash重新分区,每个分区的起始地址和结束地址都必须“块对齐”,u-boot(包括环境变量)和kernel中修改必须一致;
2. 所有与Page size和Block size相关的配置项;
3. 制作UBIFS时的相关参数。
每个点涉及的代码都不多,但有点散,这里就不贴出来了。
-
至于前面拿到的那个错误的样片 MT29F8G08ABABA(Device ID:0x38),Kernel启动时会出现ECC错误,简单调试了下没解决,就没管它了。
主要不同是它的Block size是512 KBytes,还有就是Device ID不在MPU的支持列表中。
Dear Hou工:
我同样也在同一个芯片上遇到同一个问题,但是我尝试使用您的方法去修改,但是修改完了发现的 nandflash 烧入后坏块变的很多。
不知道您还有没有相关的笔记,有偿咨询这个问题。