测试yaffs direct interface 无MTD支持

 

打了一晚的麻将,渐渐啊有手感了。午夜 2 点回宿舍睡觉了, 7 1 ,一早 8 点起床,北京今天难得的出太阳了,看了会杂志,继续研究代码吧。昨天 bootlstst.c 就算看完了,相当失望啊!居然无用啊!感叹一下先辈们做研究也不容易啊,我接下来看 dtest.c

Dtest 就是调用 BeatsTest 函数。

进入这个函数,先是 yaffs_startup() ,初始化几个 DEV 的一些参数。然后 yaffs_mount(“/ram”) yaffs_mount 函数目前在我的代码中不能正确调用,所以,下面研究这个函数。

yaffs_mount 函数写得比较简洁,主要就是找到 DEV ,然后 yaffs_GutsInitialise(dev)

再进入这个函数 yaffs_GutsInitialise() ,在 yaffs_guts.c 中。

字面上理解, gut 是内脏的意思,所以该函数差不多就是初始化 yaffs 的各个基本函数吧。

yaffs_GutsInitialise() 初始化完 yaffs_Device 结构的各项参数后,就进行 yaffs_scan() 了,这真是个恼人的函数啊。

下面是关于 yaffs_scan 函数的理解。

进入 yaffs_scan 函数,首先是一个大循环 A ,对每一个 block ,标出 bad block ,对正常 block ,又是个循环 B ,对其中的每一个 chunk 进行处理。

在循环B内部,读该 chunk spare ,把 spare 结构转化为 Tags 结构。

然后对这个 chunk 作各种判断,以实行不同的操作:

1.       spare 结构中( char pageStatus 中“ 1 的位数 <6 ,则该 chunk 是一个删除了的 chunk;

2.       tags 结构中的 ObjectID==yaffs_unused_object_id;

1 )若是第 0 chunk ,则该 Block 未被使用

  2 )否则,该 Block 为当前正在分配的 Block.

3.   tags 结构中 chunkID>0 ,表明是一个 datachunk( 相对 ObjectHeader 而言 ) ,则 setChunkBits()( 作用后面说 ) ,然后 yaffs_FindOrCreateObjectByNumber(), 该函数根据 ObjectID 找到 ( 或创建并找到 ) 一个 yaffs_Object_Type_File 类型的 yaffs_Object 。然后通过 yaffs_putChunkIntoFile ,将当前的 chunk 加入到某个 File (其实是 Object TreeNode 中)。

yaffs_putChunkIntoFile() 函数后面会具体解释。

4.       tags 结构中 chunkID==0 ,表明是一个 ObjectHeader ,也就是说该 chunk data 区域可以转化为一个 yaffs_ObjectHeader 结构。然后 setChunkBits() ,再将该 chunk data 读出后转化为一个 yaffs_ObjectHeader 结构,用 yaffs_FindOrCreateObjectByNumber() 函数根据 ObjectID 找到 ( 或创建并找到 ) 一个 yaffs_ObjectHeader->ObjectTyep 类型的 yaffs_Object

 

关于 yaffs_scan 函数的解析还没有完呢,等过阵子吧。

 

 

上面提到的 clearChunkBits(dev,blk);

                setChunkBits(dev,blk);

有什么用呢?

系统在 yaffs_Struct 结构中维护着一张位图 bitmap ,该位图每一位都代表着 flash 上一个 chunk 的状态, yaffs_SetChunkBits() 讲刚分配得到的 chunk 在位图中对于位置置 1 ,表明该 chunk 已经使用。


yaffs_PutChunkIntoFile() 函数的代码理解,字面意思就是将一个 chunk 归到一个 file 中去。

static int yaffs_PutChunkIntoFile(yaffs_Object *in,int chunkInInode, int chunkInNAND, int inScan) ,这里有个非常值得注意的地方,单从函数的字面意思是没法了解到的。

yaffs_PutChunkIntoFile() 函数有这样一个注释:

                            // PutChunkIntoFIle checks for a clash (two data chunks with

                            // the same chunkId).

注释中提到的情况发生在突然掉电时候,新的 chunk 已经写好了,但是旧的没有删除,所以在 scan 的时候把旧的删除了。

首先调用了 tn = yaffs_AddOrFindLevel0Tnode(dev,&in->variant.fileVariant, chunkInInode);

 

那么先进入这个函数 yaffs_AddOrFindLevel0Tnode ()吧

     首先是根据 chunkInTnode 计算出 Tnode Tree 的高度 x.

  3bits  3bits  3bits  ~~~~~~~~~    4bits

|--------|--------|--------|~~~~~~~~~~~|------------|         ( 这一行表示 chunkInTnode)

  x              x-1  x-2                  0

注意,每个 3bits 的值都是非零的。此时的 x 称为 requiredTallness.

fStruct 中有个( int topLevel ,所以当 topLevel 时候,需要补齐 Tallness

补齐 Tallness 后,进入一个 while 循环:

     fStruct->top( 是一个 Tnode) 开始,根据 chunkInTnode 从高到低位每次用 3bits index 依次往下搜索, tn->interna[i]( 其中 tn 是一个 Tnode i 是每 3bits 的值 ) 就是下一级的 Tnode ,若不存在该 Tnode ,创建后继续往下遍历。找到最后一个 Tnode 后,返回,由此,已经找到(或创建并找到)了该 chunkInInode 号对应的 chunk Tnode Tree 中的位置。返回该 Chunk 对应的 Tnode.

yaffs_AddOrFindLevel0Tnode ()函数返回。

 

然后, existingChunk = tn->level0[chunkInInode & YAFFS_TNODES_LEVEL0_MASK];

此处得到了 chunkIdInNAND

( 这里有个注意点, Tnode->level0[] U16 型的,因此只能表示 2^16 chunk ,每个 Chunk 512Byte ,一共是 2^6 × 1K × 512Byte = 32MByte) ,当 flash 的容量 ( 确切的说是 Partiation 的容量 ) 大于 32M 时, existingChunk 表示的值不是真正的 chunkIdInNAND.

 

下面的一段程序只在 scan 过程执行。

1.    existingChunk =0 ,读取当前 chunkIdInNAND Tags 结构,放在 NewTags 里边。
      
然后通过函数 yaffs_FindChunkInFile() 函数找出真正的 existingChunk 号,并且读出   existingChunk Tags existingTags

       如果 existingChunk <=0 ,那么就是说没找到真正的 existingChunk 号。

       出错信息: yaffs tragedy: existing chunk < 0 in scan

       newSerial = newTags.serialNumber;

       existingSerial = existingTags.serialNumber;

然后

如果 ( existingChunk <= 0 || ((existingSerial+1) & 3) == newSerial) ,那么就用新的       chunk ,删除旧的, yaffs_DeleteChunk(dev,existingChunk,1)

否则,用旧的,删除新的, yaffs_DeleteChunk(dev,chunkInNAND,1); 因为用的旧的 chunk

所以 Tnode Tree 也不用改了,提前返回。

2.       existingChunk==0 ;说明没有冲突啊,则 in->nDataChunks++;

 

(上边讲到的 yaffs_FindChunkInFile() 函数是怎么工作的呢?

int yaffs_FindChunkInFile(yaffs_Object *in,int chunkInInode,yaffs_Tags *tags)

首先根据 in chunkInInode 找到对应的 level0 Tnode (令为 tn

然后,

tn->level0[chunkInInode & YAFFS_TNODES_LEVEL0_MASK] << dev->chunkGroupBits 这个 chunkId 开始,搜索 chunkGroupSize 次,读每个 chunk Tags ,看 Tags 结构中 ObjectId ,以及 chunkInInode 号是否符合,找到后将 tags 给参数。若找到,返回 chunkIdInNAND ,否则,返回 -1.

 

最后,把新的 chunk 放到 Tnode 里边去。

 

现在的问题是,总是报错:“ yaffs tragedy: existing chunk < 0 in scan ”。

我的猜测是这样的, NAND 的每个 chunk 中, spare 部分的信息在原始状态下就不正确,使得不能正常 mount.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值