测试yaffs direct interface 无MTD支持
  ZklfkKGn8hpZ 2023年11月02日 46 0


打了一晚的麻将,渐渐啊有手感了。午夜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<REQUIREDTALLNESS< span="">时候,需要补齐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.

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  zzwpYXrztNx3   2023年11月30日   24   0   0 爬虫测试
ZklfkKGn8hpZ
最新推荐 更多