参考:http://blog.csdn.net/IT_114
在自己2.6.33 内核中,分区是:
- 1. static struct mtd_partition smdk_default_nand_part[] = {
-
2. #if defined (CONFIG_256MB_NAND)
-
3. [0] = {
-
4. .name = "ywx-uboot",
-
5. .size = 0x00040000, ##256KB
-
6. .offset = 0x0,
-
7. },
-
8. [1] = {
-
9. .name = "ywx-kernel",
-
10. .offset = 0x00200000,
-
11. .size = 0x00200000, ##2MB
-
12. },
-
13. [2] = {
-
14. .name = "ywx-yaffs2",
-
15. .offset = 0x00400000,
-
16. .size = 0x0fb80000, ##251.5MB
-
17. }
-
18. #endif
-
19. };
在 uboot 中分区如下:
0~0x40000 u-boot (256K)
0x200000~0x400000 kernel (2M)
0x400000~~ (剩余的)
1、通
常一个Nnad Flash存储设备由若干块组成,1个块由若干页组成。一般128MB以下容量的Nand
Flash芯片,一页大小为528B,被依次分为2个256B的主数据区和16B的额外空间。128MB以上容量的Nand
Flash芯片,一页大小通常为2KB。由于Nand
Flash出现位反转的概率较大,一般在读写时需要使用ECC进行错误检验和恢复。TQ2440上的Nandflash型号是K9F2G08,页面大小为
page = 2K + 64Byte。
Yaffs/yaffs2
文件系统的设计充分考虑到Nand
Flash以页为存取单位等的特点,将文件组织成固定大小的段(Chunk)。以528B的页为例,Yaffs/yaffs2文件系统使用前512B存储
数据和16B的额外空间存放数据的ECC和文件系统的组织信息等(称为OOB数据)。通过OOB数据,不但能实现错误检测和坏块处理,同时还可以避免加载
时对整个存储介质的扫描,加快了文件系统的加载速度。以下是Yaffs/yaffs2文件系统页的结构说明
Yaffs页结构说明 ============================================== 字节 用途 ============================================== 0 - 511 存储数据(分为两个半部) 512 - 515 系统信息 516 数据状态字 517 块状态字 518 - 519 系统信息 520 - 522 后半部256字节的ECC 523 - 524 系统信息 525 - 527 前半部256字节的ECC ==============================================
|
好了,在了
解Nand
Flash组成和Yaffs/yaffs2文件系统结构后,我们再回到u-boot中。目前,在u-boot中已经有对Cramfs、Jffs2等文件系
统的读写支持,但与带有数据校验等功能的OOB区的Yaffs/Yaffs2文件系统相比,他们是将所有文件数据简单的以线性表形式组织的。所以,我们只
要在此基础上通过修改u-boot的Nand
Flash读写命令,增加处理00B区域数据的功能,即可以实现对Yaffs/Yaffs2文件系统的读写支持。
2、在include/configs/smdk2440.h头文件中定义一个管理对Yaffs2支持的宏和开启u-boot中对Nand Flash默认分区的宏,如下:
vi include/configs/smdk2440.h
- //定义一个管理对Yaffs2支持的宏
-
#define CONFIG_MTD_NAND_YAFFS2 1
-
//开启Nand Flash默认分区,注意此处的分区要和你的内核中的分区保持一致
-
#define MTDIDS_DEFAULT "nand0=nandflash0"
-
#define MTDPARTS_DEFAULT "mtdparts=nandflash0:256k(bootloader)," \
-
"2m(kernel)," \
-
"-(root)"
3、在原来对Nand操作的命令集列表中添加Yaffs2对Nand的写命令,如下:
vi common/cmd_nand.c
在函数U_BOOT_CMD中添加如下:
//注意:这里只添加了yaffs2的写命令,因为我们只用u-boot下载(即写)功能,所以我们没有添加yaffs2读的命令
- U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand,
-
"NAND sub-system",
-
"info - show available NAND devices\n"
-
"nand device [dev] - show or set current device\n"
-
"nand read - addr off|partition size\n"
-
"nand write - addr off|partition size\n"
-
" read/write 'size' bytes starting at offset 'off'\n"
-
" to/from memory address 'addr', skipping bad blocks.\n"
/*添加 开始*/-
/*注意:这里只添加了yaffs2的写命令,因为我们只用u-boot下载(即写)功能,所以我们没有添加yaffs2读的命令*/
-
#if defined(CONFIG_MTD_NAND_YAFFS2)
-
"nand write[.yaffs2] - addr off|partition size - write `size' byte yaffs image\n"
-
" starting at offset off' from memory address addr' (.yaffs2 for 512+16 NAND)\n"
-
#endif
/*添加结束*/-
"nand erase [clean] [off size] - erase 'size' bytes from\n"
-
" offset 'off' (entire device if not specified)\n"
-
"nand bad - show bad blocks\n"
-
"nand dump[.oob] off - dump page\n"
-
"nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
-
"nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
-
"nand biterr off - make a bit error at offset (UNSAFE)"
-
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
-
"\n"
-
"nand lock [tight] [status]\n"
-
" bring nand to lock state or display locked pages\n"
-
"nand unlock [offset] [size] - unlock section"
-
#endif
-
);
接着,在该文件中对nand操作的do_nand函数中添加yaffs2对nand的操作,如下:- if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
-
int read;
-
-
if (argc < 4)
-
goto usage;
-
-
addr = (ulong)simple_strtoul(argv[2], NULL, 16);
-
-
read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
-
printf("\nNAND %s: ", read ? "read" : "write");
-
if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
-
return 1;
-
-
s = strchr(cmd, '.');
-
if (!s || !strcmp(s, ".jffs2") ||
-
!strcmp(s, ".e") || !strcmp(s, ".i")) {
-
if (read)
-
ret = nand_read_skip_bad(nand, off, &size,
-
(u_char *)addr);
-
else
-
ret = nand_write_skip_bad(nand, off, &size,
-
(u_char *)addr);
-
}
/
*添加开始*/-
/*添加yaffs2相关操作,注意该处又关联到nand_write_skip_bad函数*/
-
-
#if defined(CONFIG_MTD_NAND_YAFFS2)
-
else if (s != NULL && (!strcmp(s, ".yaffs2")))
-
{
-
nand->rw_oob = 1;
-
nand->skipfirstblk = 1;
-
ret = nand_write_skip_bad(nand,off,&size,(u_char *)addr);
-
nand->skipfirstblk = 0;
-
nand->rw_oob = 0;
-
}
-
#endif
- /*添加结束*/
-
else if (!strcmp(s, ".oob")) {
-
/* out-of-band data */
-
mtd_oob_ops_t ops = {
-
.oobbuf = (u8 *)addr,
-
.ooblen = size,
-
.mode = MTD_OOB_RAW
-
};
-
-
if (read)
-
ret = nand->read_oob(nand, off, &ops);
-
else
-
ret = nand->write_oob(nand, off, &ops);
-
} else {
-
printf("Unknown nand command suffix '%s'.\n", s);
-
return 1;
-
}
-
-
printf(" %zu bytes %s: %s\n", size,
-
read ? "read" : "written", ret ? "ERROR" : "OK");
-
-
return ret == 0 ? 0 : 1;
-
}
在include/linux/mtd/mtd.h头文件的mtd_info结构体中添加上面用到rw_oob和skipfirstblk数据成员,如下:#vi include/linux/mtd/mtd.h //在mtd_info结构体中添加- #if defined(CONFIG_MTD_NAND_YAFFS2)
-
u_char rw_oob;
-
u_char skipfirstblk;
-
#endif
在第二步关联的nand_write_skip_bad函数中添加对Nand OOB的相关操作,如下: #vi drivers/mtd/nand/nand_util.c //在nand_write_skip_bad函数中添加
上传 nand_util.c 附件 nand_util.rar - int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
-
u_char *buffer)
-
{
-
int rval;
-
size_t left_to_write = *length;
-
size_t len_incl_bad;
-
u_char *p_buffer = buffer;
/*添加 开始*/-
#if defined(CONFIG_MTD_NAND_YAFFS2) /*add yaffs2 file system support*/
-
if(nand->rw_oob==1)
-
{
-
size_t oobsize = nand->oobsize;
-
size_t datasize = nand->writesize;
-
int datapages = 0;
-
-
if (((*length)%(nand->oobsize+nand->writesize)) != 0)
-
{
-
printf ("Attempt to write error length data!\n");
-
return -EINVAL;
-
}
-
-
datapages = *length/(datasize+oobsize);
-
*length = datapages*datasize;
-
left_to_write = *length;
-
}
-
#endif
/*添加 结束*/-
-
-
/* Reject writes, which are not page aligned */
-
if ((offset & (nand->writesize - 1)) != 0 ||
-
(*length & (nand->writesize - 1)) != 0) {
-
printf ("Attempt to write non page aligned data\n");
-
return -EINVAL;
-
}
-
-
len_incl_bad = get_len_incl_bad (nand, offset, *length);
-
-
if ((offset + len_incl_bad) > nand->size) {
-
printf ("Attempt to write outside the flash area\n");
-
return -EINVAL;
-
}
-
-
/*修改 开始*/
-
#if !defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support
-
-
if (len_incl_bad == *length) {
-
rval = nand_write (nand, offset, length, buffer);
-
if (rval != 0)
-
printf ("NAND write to offset %llx failed %d\n",offset, rval);
-
-
-
return rval;
-
}
-
-
-
#endif
- /*修改 结束*/
-
-
-
while (left_to_write > 0) {
-
size_t block_offset = offset & (nand->erasesize - 1);
-
size_t write_size;
-
-
WATCHDOG_RESET ();
-
-
if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
-
printf ("Skip bad block 0x%08llx\n",
-
offset & ~(nand->erasesize - 1));
-
offset += nand->erasesize - block_offset;
-
continue;
-
}
-
-
-
/*添加 开始*/
-
#if defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support
-
if(nand->skipfirstblk==1)
-
{
-
nand->skipfirstblk=0;
-
printf ("Skip the first good block %llx\n", offset & ~(nand->erasesize - 1));
-
offset += nand->erasesize - block_offset;
-
continue;
-
}
-
#endif
-
-
/*添加 结束*/
-
-
-
if (left_to_write < (nand->erasesize - block_offset))
-
write_size = left_to_write;
-
else
-
write_size = nand->erasesize - block_offset;
- /*添加 开始*/
-
-
printf("\rWriting at 0x%llx -- ",offset); //add yaffs2 file system support
- /*添加 结束*/
-
-
rval = nand_write (nand, offset, &write_size, p_buffer);
-
if (rval != 0) {
-
printf ("NAND write to offset %llx failed %d\n",
-
offset, rval);
-
*length -= left_to_write;
-
return rval;
-
}
-
-
left_to_write -= write_size;
-
offset += write_size;
-
- /*添加 开始*/
-
#if defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support
-
if(nand->rw_oob==1)
-
{
-
p_buffer += write_size+(write_size/nand->writesize*nand->oobsize);
-
}
-
else
-
{
-
p_buffer += write_size;
-
}
-
#else
-
p_buffer += write_size;
-
#endif
-
/*添加 结束*/
-
-
}
-
-
return 0;
-
}
OK,对yaffs2支持的代码已修改完毕,重新编译u-boot并下载到nand中,启动开发板,在u-boot的命令行输入:nand help查看nand的命令,可以看到多了一个nand write[.yaffs2]的命令,这个就是用来下载yaffs2文件系统到nand中的命令了。make smdk2440_config && make all
然后设置,DNW的地址为 0x0, 把根目录下的u-boot.bin 下载到Nandflash的地址0处
1.选择 nor flash启动模式
2.进入 nor flash 下载模式界面
3.选择 “1”
[1] Download u-boot or STEPLDR.nb1 or other bootloader to Nand Flash
4.下载成功后,关机。
5.拨到从 nand flash 启动模式
6.打开电源,开机
- U-Boot 2010.06-rc1 ( 4鏈?17 2011 - 10:15:21)
-
-
DRAM: 64 MiB
-
Flash: 2 MiB
-
NAND: 256 MiB
-
In: serial
-
Out: serial
-
Err: serial
-
Net: dm9000
-
[SMDK2440]# nand help
-
nand - NAND sub-system
-
-
Usage:
-
nand info - show available NAND devices
-
nand device [dev] - show or set current device
-
nand read - addr off|partition size
-
nand write - addr off|partition size
-
read/write 'size' bytes starting at offset 'off'
-
to/from memory address 'addr', skipping bad blocks.
-
nand write[.yaffs2] - addr off|partition size - write `size' byte yaffs image
-
starting at offset off' from memory address addr' (.yaffs2 for 512+16 NAND)
-
nand erase [clean] [off size] - erase 'size' bytes from
-
offset 'off' (entire device if not specified)
-
nand bad - show bad blocks
-
nand dump[.oob] off - dump page
-
nand scrub - really clean NAND erasing bad blocks (UNSAFE)
-
nand markbad off [...] - mark bad block(s) at offset (UNSAFE)
-
nand biterr off - make a bit error at offset (UNSAFE)
-
[SMDK2440]#
阅读(978) | 评论(0) | 转发(0) |