Chinaunix首页 | 论坛 | 博客
  • 博客访问: 477070
  • 博文数量: 100
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 955
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-21 09:30
文章分类

全部博文(100)

文章存档

2017年(1)

2016年(16)

2015年(83)

我的朋友

分类: 嵌入式

2015-08-31 23:26:02


点击(此处)折叠或打开

  1. static int write_object_header(int id, enum yaffs_obj_type t, struct stat *s, int parent, const char *name, int equivalentObj, const char * alias)
  2. {
  3.     u8 bytes[chunkSize];
  4.     
  5.     
  6.     struct yaffs_obj_hdr *oh = (struct yaffs_obj_hdr *)bytes;
  7.     
  8.     memset(bytes,0xff,sizeof(bytes));
  9.     
  10.     oh->type = t;

  11.     oh->parent_obj_id = parent;
  12.     
  13.     if (strlen(name)+1 > sizeof(oh->name))
  14.     {
  15.         errno = ENAMETOOLONG;
  16.         return warn("object name");
  17.     }
  18.     memset(oh->name,0,sizeof(oh->name));
  19.     strcpy(oh->name,name);
  20.     
  21.     
  22.     if(t != YAFFS_OBJECT_TYPE_HARDLINK)
  23.     {
  24.         oh->yst_mode = s->st_mode;
  25.         oh->yst_uid = s->st_uid;
  26. // NCB 12/9/02        oh->yst_gid = s->yst_uid;
  27.         oh->yst_gid = s->st_gid;
  28.         oh->yst_atime = s->st_atime;
  29.         oh->yst_mtime = s->st_mtime;
  30.         oh->yst_ctime = s->st_ctime;
  31.         oh->yst_rdev = s->st_rdev;
  32.     }
  33.     
  34.     if(t == YAFFS_OBJECT_TYPE_FILE)
  35.     {
  36.         oh->file_size_low = s->st_size;
  37.         oh->file_size_high = (s->st_size >> 32);
  38.     }
  39.     
  40.     if(t == YAFFS_OBJECT_TYPE_HARDLINK)
  41.     {
  42.         oh->equiv_id = equivalentObj;
  43.     }
  44.     
  45.     if(t == YAFFS_OBJECT_TYPE_SYMLINK)
  46.     {
  47.         if (strlen(alias)+1 > sizeof(oh->alias))
  48.         {
  49.             errno = ENAMETOOLONG;
  50.             return warn("object alias");
  51.         }
  52.         memset(oh->alias,0,sizeof(oh->alias));
  53.         strcpy(oh->alias,alias);
  54.     }

  55.     if (convert_endian)
  56.     {
  57.             object_header_little_to_big_endian(oh);
  58.     }
  59.     
  60.     return write_chunk(bytes,id,0,0xffff);
  61.     
  62. }


  63. static int write_chunk(u8 *data, u32 id, u32 chunk_id, u32 n_bytes)
  64. {
  65.     struct yaffs_ext_tags t;
  66.     struct yaffs_packed_tags2 pt;//28byte
  67.     char spareData[spareSize];

  68.     if (write(outFile,data,chunkSize) != chunkSize)
  69.         fatal("write");

  70.     memset(&t, 0, sizeof(t));
  71.     
  72.     t.chunk_id = chunk_id;
  73. //    t.serial_number = 0;
  74.     t.serial_number = 1;    // **CHECK**
  75.     t.n_bytes = n_bytes;    // 0xffff=65536
  76.     t.obj_id = id;
  77.     
  78.     t.seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;

  79. // added NCB **CHECK**
  80.     t.chunk_used = 1;

  81.     if (convert_endian)
  82.     {
  83.          little_to_big_endian(&t);
  84.     }

  85.     nPages++;

  86.     memset(&pt, 0, sizeof(pt));//28bytes
  87.     yaffs_pack_tags2(&pt,&t,1);//(struct yaffs_packed_tags2 *pt,
  88.          //const struct yaffs_ext_tags *t, int tags_ecc)

  89.     memset(spareData, 0xff, sizeof(spareData));//先全部置0xff
  90.     shuffle_oob(spareData, &pt);//填充28bytes

  91.     if (write(outFile,spareData,sizeof(spareData)) != sizeof(spareData))
  92.         fatal("write");
  93.     return 0;
  94. }


  95. struct yaffs_ext_tags {
  96.     unsigned chunk_used;    /* Status of the chunk: used or unused */
  97.     unsigned obj_id;    /* If 0 this is not used */
  98.     unsigned chunk_id;    /* If 0 this is a header, else a data chunk */
  99.     unsigned n_bytes;    /* Only valid for data chunks */

  100.     /* The following stuff only has meaning when we read */
  101.     enum yaffs_ecc_result ecc_result;
  102.     unsigned block_bad;

  103.     /* YAFFS 1 stuff */
  104.     unsigned is_deleted;    /* The chunk is marked deleted */
  105.     unsigned serial_number;    /* Yaffs1 2-bit serial number */

  106.     /* YAFFS2 stuff */
  107.     unsigned seq_number;    /* The sequence number of this block */

  108.     /* Extra info if this is an object header (YAFFS2 only) */

  109.     unsigned extra_available;    /* Extra info available if not zero */
  110.     unsigned extra_parent_id;    /* The parent object */
  111.     unsigned extra_is_shrink;    /* Is it a shrink header? */
  112.     unsigned extra_shadows;    /* Does this shadow another object? */

  113.     enum yaffs_obj_type extra_obj_type;    /* What object type? */

  114.     loff_t extra_file_size;        /* Length if it is a file */
  115.     unsigned extra_equiv_id;    /* Equivalent object for a hard link */
  116. };

  117. struct yaffs_packed_tags2 {
  118.     struct yaffs_packed_tags2_tags_only t;    //16byte
  119.     struct yaffs_ecc_other ecc;                //12byte
  120. };

  121. struct yaffs_packed_tags2_tags_only {
  122.     unsigned seq_number;
  123.     unsigned obj_id;
  124.     unsigned chunk_id;
  125.     unsigned n_bytes;
  126. };//16 byte

  127. struct yaffs_ecc_other {
  128.     unsigned char col_parity;
  129.     unsigned line_parity;
  130.     unsigned line_parity_prime;
  131. };//3*4 = 12byte
关键是yaffs_packed_tags2这个数据,在write_chunk函数中有shuffle_oob(spareData, &pt)函数,实际上就是向OOB填充了28字节yaffs_packed_tags2,因此yaffs2需要占用28字节的OOB空间。
这里就可以看出yaffs2会造成u-boot提示坏块了,因为OOB前面两个字节被填写了tags的内容,不再是0xff。如果不想uboot提示坏块,可以将shuffle_oob(spareData, &pt);修改为shuffle_oob(spareData + 2, &pt);
更合理的做法是使用MTD_OPS_AUTO_OOB方式写入数据,这样yaffs tags就能正常写入了。

阅读(3196) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~