u-boot nand驱动测试yaffs2文件系统

1. Nand控制器驱动实现

        nand控制器的u-boot驱动支持2种传输模式:DMA和FIFO传输,ECC纠错可以配置为nand控制器内置的ECC模块或者使用u-boot内建的软件ECC算法,配置方法为在u-boot代码根目录下执行make ARCH=arm menuconfig进入u-boot编译配置菜单,进入到Device Drivers->NAND Device Support,选中“Support for Cadence Nand controller”选项使能nand驱动模块,该项目的2个子选项“Enable use of NAND Controller build-in DMA module”和“Enable use of soft-ecc instead of hardware-ecc”分别用于开启内置DMA传输和使能软件ECC功能。后续nand驱动的yaffs2文件系统功能测试时会分别测试DMA/FIFO、HW-ECC/SW-ECC模式。

图1 Nand驱动参数项

        u-boot下nand驱动需要支撑mtd层的功能,上层应用接口通过mtd层调用nand功能,因此相对裸机驱动,u-boot下nand驱动需要支持各种功能接口,并将初始化流程和驱动提供的服务结合到nand_base.c提供的基础公共代码上,因此u-boot下nand驱动程序的测试验证变得更加复杂,为简化对nand驱动的功能测试验证,我们实现在nand驱动层之上挂载完整的yaffs2文件系统,设计由文件系统支持的各种文件、目录的操作过程,以及文件系统的反复挂载、卸载等操作来验证nand驱动的基础功能。

2. mkyaffs2image移植

        Yaffs2文件系统固件制作可以使用Yaffs2源码中的mkyaffs2image生成,该工具需要针对实际nand驱动的ecc布局做相应参数调整。首先在yaffs2官方网站下载最新的Yaffs2源码包,解压后进入到源码目录的utils子目录下,找到mkyaffs2image.c文件,根据nand实际参数修改如下参数:

#define chunkSize     2048
#define spareSize     112
#define pagesPerBlock 64

        chunkSize配置为nand page大小,本例为2KB,spareSize为oob区间大小,pagesPerBlock即为每个block的page个数。

        第二步修改shuffle_oob函数,该函数针对实际的nand ecc布局情况填充yaffs2的oob数据,nand驱动的硬件ECC和软件ECC模式下oob布局基本一致,第0-1字节为坏块标记,中间一段为oob free区域可用于存放yaffs2数据,最后一段空间存放ECC校验数据。因此shuffle_oob函数实现中需要将yaffs tags数据存放到spareData+2的地方,函数修改如下:

static void shuffle_oob(char *spareData, struct yaffs_packed_tags2 *pt)
{
	assert(sizeof(*pt) <= spareSize);
	// NAND LAYOUT: For non-trivial OOB orderings, here would be a good place to shuffle.
	memcpy(spareData + 2, pt, sizeof(*pt));
}

        最后找到write_chunk函数,该函数完成yaffs2镜像文件的写入和yaffs2 tags数据打包的过程,将yaffs_pack_tags2(&dummy_dev, &pt,&t,1)调用改为yaffs_pack_tags2(&dummy_dev, &pt,&t,0),该函数最后一个参数表示是否计算yaffs自带的ECC校验,因为我们nand控制器驱动支持ECC算法,因此此处关闭yaffs附带的ECC功能。

3. u-boot yaffs2测试

3.1 相关命令介绍

        测试验证过程中会使用诸如nand flash的擦除、读写,yaffs2文件系统挂载、卸载操作等各类命令,大致列举如下:

nand read.raw

nand write.raw

nand write.yaffs2

nand erase.chip

nand scrub.chip -y

tftpb

md5sum

md

ydevconfig

ydevls

ymount

yumount

ytrace

yls

ymkdir

ymv

yrd

yrdm

yrm

yrmdir

ywr

ywrm

MTD_OPS_RAW模式no-ecc读取data + oob

MTD_OPS_RAW模式no-ecc依次写入data + oob(适用于关闭ECC时yaffs2镜像写入)

MTD_OPS_PLACE_OOB模式下使能ECC后的yaffs2镜像写入命令

擦除命令,跳过坏块(检测到bbt为NULL时自动启动bbt scan)

擦除命令(包含坏块擦除)

u-boot内建的tftp下载命令

u-boot内建的MD5计算命令

内存显示命令

Yaffs挂载点配置命令

Yaffs挂载点枚举命令

Yaffs文件系统挂载命令

Yaffs文件系统卸载命令

Yaffs文件系统调试开关

Yaffs目录list命令

Yaffs目录创建

Yaffs移动文件

Yaffs文件读取

Yaffs文件读取到内存

Yaffs文件删除

Yaffs目录删除

Yaffs文件写入

Yaffs由内存写入到文件

3.2 修改u-boot

3.2.1 添加nand write.yaffs2命令

        u-boot源码目录cmd/nand.c中仿照nand write.jffs2实现nand write.yaffs2,nand编程接口使用mtd_write_oob函数,其mtd_oob_ops_t参数配置如下:

mtd_oob_ops_t ops = {
	.datbuf = p_buffer,
	.oobbuf = p_buffer + mtd->writesize,
	.len = mtd->writesize,
	.ooblen = mtd->oobsize,
	.ooboffs = 0,
	/*
	 * NOTES:
	 * yaffs2 image contain page+oob data, if using hw-ecc, we must use
	 * nand write.yaffs2 cmd, and using MTD_OPS_PLACE_OOB mode with ooboffs
	 * set to 0.
	 */
	.mode = MTD_OPS_PLACE_OOB
};

        需要注意的是此处采用MTD_OPS_PLACE_OOB模式,ooboffs配置为0,该模式将oob数据写入到oob + ooboffs起始地址中,由于mkyaffs2image工具生成的tags数据已经修改为设置到oob + 2的地方,因此不会和坏块标记以及ECC数据产生冲突,ooboffs是相对于oob free的起始偏移,设置为0即可。另外一点mkyaffs2image仅支持将yaffs tags数据写入到oob区间中,而u-boot yaffs2会检测tags数据大小和oob free空间大小,如果tags数据大于oob free空间,则默认u-boot将tags数据写入到in-band区间中,这点和mkyaffs2image的设计不一致,需要特殊注意。

3.2.2 yaffs2参数修改

        u-boot集成的yaffs2文件系统默认使用自带的ecc算法,实现在yaffs_ecc.c中,我们的nand驱动支持MTD ECC纠错,因此需要关闭yaffs自带的ECC功能,找到u-boot源码文件fs/yaffs2/yaffs_uboot_glue.c,在cmd_yaffs_devconfig函数中将以下2个参数配置为1,即开启使用nand ecc以及关闭tags ecc。

dev->param.use_nand_ecc = 1;
dev->param.no_tags_ecc = 1;

3.3 yaffs2文件系统功能测试

3.3.1 制作yaffs2镜像文件

        参考第2节修改mkyaffs2image源码,编译后生成mkyaffs2image镜像制作工具。然后创建mnt目录,将需要打包到yaffs2中的文件拷贝到该目录下,准备完成后,在mnt的父目录下执行./mkyaffs2image mnt mnt.yaffs2,该命令将mnt目录下所有文件按照对应的层次结构打包到yaffs2文件系统镜像中,mnt.yaffs2即为生成的镜像名称。

3.3.2 yaffs2镜像烧录

        如果没有启用MTD ECC,直接使用nand write.raw命令即可,Nand驱动开启MTD ECC后必须使用合入的nand write.yaffs2命令烧录yaffs镜像,该命令使用带ECC功能的函数接口写入nand数据,并将yaffs的tags数据写入oob中,首先配置u-boot网络参数:

setenv serverip 192.168.0.254
setenv ipaddr 192.168.0.11
setenv netmask 255.255.255.0
setenv gatewayip 192.168.0.1
ping 192.168.0.254

        需要注意的是u-boot必须执行ping操作才会启动网络功能,配置完成后使用tftpb命令将mnt.yaffs2镜像下载到内存中,然后烧录到nand页中:

tftpb 0x1000000 mnt.yaffs2
nand write.yaffs2 0x1000000 0x10000000 0x3b1000

        烧录的起始地址需要对齐到nand block地址,本例0x10000000对应到block 2048,完成后挂载为yaffs2系统即可访问。

3.3.3 yaffs2文件系统测试

        首先需要使用ydevconfig命令配置yaffs挂载点,该命令使用的参数为block index,本例中yaffs镜像烧录到block 2048,因此起始地址设为0x800,配置的挂载点长度需大于或等于yaffs镜像大小,若挂载点长度等于yaffs镜像大小,则无法向挂载目录写入新的文件,会提示device full,此时仅支持读取删除命令。挂载yaffs镜像命令如下:

ydevconfig mnt 0 0x800 0xa00
ymount mnt

        挂载命令执行后即可使用yls mnt枚举挂载点mnt下的系统目录和文件信息:

图2 ydevconfig / ymount / yls执行结果

            接下来可以使用yrdm读取挂载点mnt下的文件数据并做md5计算校验对比,测试结果截图如下:

图3 yrdm文件读取和MD5校验

         ywrm文件写入命令执行结果截图如下:

图4 ywrm执行结果

         测试结束后使用yumount卸载挂载点即可:

图5 yumount执行结果

        最后分别针对u-boot的DMA/FIFO、HW-ECC/SW-ECC共4种组合方式单独进行上述测试流程,以验证nand驱动对yaffs2文件系统的支持性,以较为简化的方式多方位测试驱动程序的功能接口和鲁棒性。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值