ubifs使能和禁止压缩_移植不成功胚胎去哪了

ubifs使能和禁止压缩_移植不成功胚胎去哪了我在用TI的dm368开发板,kernel是2.6.32.17,默认的flash文件系统是jffs2,但是jffs2在大分区下,mount速度很慢,而且占用ram较多,因此,我想使用ubifs看看性能是否会更好些。ubifs的原理和配置过程,很多网页都有介绍的,我给一个链接,大家可以看看,我就不转载了,我重点说我移植过程中遇到并解决的问题。http://bbs.chinaunix.net/

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

我在用TI的dm368开发板,kernel是2.6.32.17,默认的flash文件系统是jffs2,但是jffs2在大分区下,mount速度很慢,而且占用ram较多,因此,我想使用ubifs看看性能是否会更好些。

ubifs的原理和配置过程,很多网页都有介绍的,我给一个链接,大家可以看看,我就不转载了,我重点说我移植过程中遇到并解决的问题。

http://bbs.chinaunix.net/thread-1954881-1-1.html

 

kerne的配置很简单,2.6.32里面都有,选上并重新编译就好了。

ubiattach、ubimkvol等工具,TI的dvsdk里面自带了,能用,我就偷了个懒,没有重新编译。

 

很轻松的照着网页说明操作了下,mount 分区也成功了,复制文件也成功了,很高兴:)

ubiattach /dev/ubi_ctrl -m 3

ubimkvol  /dev/ubi0 -N rootfs -s 480MiB

mount -t ubifs  ubi0_0 /mnt/nand/ -o sync

但很快就遇到麻烦了,开发板关机重新启动,我再mout ubi文件系统就出错了,提示了一堆错误,而且分区是空的,之前复制的文件不见了。

问题如下:

ubiattach /dev/ubi_ctrl -m 3

UBI error: ubi_io_read: error -74while reading 64 bytes from PEB 1662:0, read 64 bytes

UBI error: ubi_io_read: error -74while reading 64 bytes from PEB 1663:0, read 64 bytes

 

为了分析问题,我把mtd和ubifs的debug log都打开了,看到了一些信息;

#define   EBADMSG           74   /* Not a data message */

              /*Nand returns -EBADMSG on ecc errors, but it returns

               * the data. For our userspace tools it isimportant

               * to dump areas with ecc errors !

               * For kernel internal usage it also mightreturn -EUCLEAN

               * to signal the caller that a bitflip hasoccured and has

               * been corrected by the ECC algorithm.

               * Userspace software which accesses NAND thisway

               * must be aware of the fact that it deals withNAND

               */

nand_do_read_ops

       stats= mtd->ecc_stats;

       if(mtd->ecc_stats.failed – stats.failed)

              return-EBADMSG;

  

nand_read_page_hwecc

              stat= chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);

              if(stat < 0)

                     mtd->ecc_stats.failed++;

              else

                     mtd->ecc_stats.corrected+= stat;

看样子,应该是ECC出错了,可是我用的是硬件ECC校验,怎么可能几乎全部的page都出现ecc校验错误了呢?

 

root@dm368-evm:~#flash_eraseall  /dev/mtd3

root@dm368-evm:~# ubiattach/dev/ubi_ctrl -m 3

UBI: attaching mtd3 to ubi0

UBI: physical eraseblock size:   131072 bytes (128 KiB)

UBI: logical eraseblock size:    129024 bytes

UBI: smallest flash I/O unit:    2048

UBI: sub-page size:              512

UBI: VID header offset:          512 (aligned 512)

UBI: data offset:                2048

 

分析下UBI写数据的过程,

UBI DBG (pid 1484): ubi_io_write:write 512 bytes to PEB 57:0

int ubi_io_write(struct ubi_device*ubi, const void *buf, int pnum, int offset,

               int len)

       addr= (loff_t)pnum * ubi->peb_size + offset;

       err= ubi->mtd->write(ubi->mtd, addr, len, &written, buf);

在io_init函数中可以看到几个变量的赋值;

       ubi->peb_size   = ubi->mtd->erasesize;

       ubi->peb_count  = mtd_div_by_eb(ubi->mtd->size,ubi->mtd);

       ubi->flash_size= ubi->mtd->size;

从debug log来看,这里一次写了512字节,从某个block的起始page开始,offset是0;

那么到了nand mtd底层驱动,行为就是;

nand_write->nand_do_write_ops:

       subpage= column || (writelen & (mtd->writesize – 1));

这里,subpage就是writelen,512;

也可以得知一点,ubifs没有使用oob,这跟jffs2和yaffs2是不同的;

              /*Partial page write ? */

              if(unlikely(column || writelen < (mtd->writesize – 1))) {

                     cached= 0;

                     bytes= min_t(int, bytes – column, (int) writelen);

                     chip->pagebuf= -1;

                     memset(chip->buffers->databuf,0xff, mtd->writesize);

                     memcpy(&chip->buffers->databuf[column],buf, bytes);

                     wbuf= chip->buffers->databuf;

              }

              ret= chip->write_page(mtd, chip, wbuf, page, cached,

                                   (ops->mode == MTD_OOB_RAW));

下面是write_page函数的代码;

static int nand_write_page(structmtd_info *mtd, struct nand_chip *chip,

                        const uint8_t *buf, int page, int cached,int raw)

{

       intstatus;

 

       chip->cmdfunc(mtd,NAND_CMD_SEQIN, 0x00, page);

 

       if(unlikely(raw))

              chip->ecc.write_page_raw(mtd,chip, buf);

       else

              chip->ecc.write_page(mtd,chip, buf);

 

       /*

        * Cached progamming disabled for now, Not sureif its worth the

        * trouble. The speed gain is not veryimpressive. (2.3->2.6Mib/s)

        */

       cached= 0;

这里需要注意的就是raw,如果是MTD_OOB_RAW,那么不会做ECC校验,也不会把ECC码写入OOB;

如果是这样,在read的时候也必须指定是MTD_OOB_RAW,不需要ECC校验;否则,就会出现我们最开始看到的错误;

       if(mtd->ecc_stats.failed – stats.failed)

              return-EBADMSG;

 

那么,从这里的情况来看,我们可能已经找到出错的原因了;ubi使用了subpage write,而底层nand flash驱动实际上是不支持subpage write的,尽管ubi一次只写了512字节,但这个page的其他部分已经不能再次写入新的数据了。

 

从Nand_base.c(drivers\mtd\nand)来看,large page的nand flash,对subpage write的支持是不完善的,限制条件比较多,比如,不能是MLC的nand flash,不能用硬件ECC;

更严重的问题是代码存在缺陷,在写入部分data的时候,将其他部分的数据填充为0xff了,然后write整个page,并写入全部ecc码到oob,也许这就是前面ecc校验出错的原因吧。

nand_do_write_ops()

              /*Partial page write ? */

memset(chip->buffers->databuf, 0xff, mtd->writesize);

                     memcpy(&chip->buffers->databuf[column],buf, bytes);

因此,我想到的解决办法就是在nand驱动中禁止subpage write。

第一步,在chip options中增加NAND_NO_SUBPAGE_WRITE;

static struct davinci_nand_pdatadavinci_nand_data = {

       .options         = NAND_USE_FLASH_BBT|NAND_NO_SUBPAGE_WRITE,

然后重新编译下载kernel,但问题依旧;

root@dm368-evm:~# ubiattach/dev/ubi_ctrl -m 3

UBI: attaching mtd3 to ubi0

UBI: physical eraseblock size:   131072 bytes (128 KiB)

UBI: logical eraseblock size:    129024 bytes

UBI: smallest flash I/O unit:    2048

UBI: sub-page size:              512

UBI: VID header offset:          512 (aligned 512)

心想很奇怪,为什么 sub-page size还是512?

回头查看代码,想看看sub page size是怎样计算出来的,

 if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
     !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {

  switch(chip->ecc.steps) {

  case 2:
   mtd->subpage_sft = 1;
   break;
  case 4:
  case 8:
  case 16:
   mtd->subpage_sft = 2;
   break;
  }
 }
 chip->subpagesize = mtd->writesize >> mtd->subpage_sft;

可是我已经给options增加了NAND_NO_SUBPAGE_WRITE啊?有些怀疑,我就在此处加了打印log,果然是这里出了问题,

chip->options = 0x10101.

mtd->subpage_sft = 0.

chip->subpagesize = 512.

 

#define NAND_NO_SUBPAGE_WRITE    0x00000200

可是,这里的options 明明是不对的!那我设置的NAND_NO_SUBPAGE_WRITE在哪里丢掉了?

 

在下面的函数中有对chip->options赋值改变;

nand_get_flash_type()

              printk(KERN_INFO”nand_get_flash_type 1, chip->options = 0x%x.\n”,chip->options);

 

       /*Get chip options, preserve non chip based options */

       chip->options &= ~NAND_CHIPOPTIONS_MSK;

       printk(KERN_INFO”nand_get_flash_type 2, chip->options = 0x%x.\n”,chip->options);   

       chip->options|= type->options & NAND_CHIPOPTIONS_MSK;

       printk(KERN_INFO”nand_get_flash_type 3, chip->options = 0x%x.\n”,chip->options);

 

       /*

        * Set chip as a default. Board drivers canoverride it, if necessary

        */

       chip->options|= NAND_NO_AUTOINCR;

 

       /*Check if chip is a not a samsung device. Do not clear the

        * options for chips which are not having anextended id.

        */

       if(*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)

              chip->options&= ~NAND_SAMSUNG_LP_OPTIONS;

       printk(KERN_INFO”nand_get_flash_type 4, chip->options = 0x%x.\n”,chip->options);

 

nand_get_flash_type 1,chip->options = 0x10200.

nand_get_flash_type 2,chip->options = 0x10000.

nand_get_flash_type 3,chip->options = 0x1011c.

nand_get_flash_type 4,chip->options = 0x10101.

 

问题出在这里,红色的代码!

/* Mask to zero out thechip options, which come from the id table */

#defineNAND_CHIPOPTIONS_MSK (0x0000ffff &~NAND_NO_AUTOINCR)

/* Chip can not autoincrement pages */

#define NAND_NO_AUTOINCR  0x00000001

 

找到问题了,解决办法就有了,注释掉红色的那行代码,就是他把NAND_NO_SUBPAGE_WRITE给丢掉了。

//chip->options &=~NAND_CHIPOPTIONS_MSK;

再重新编译下载kernel,问题搞定了!

再次启动开发板,加载ubi,一切正常了。

root@dm368-evm:/# ubiattach/dev/ubi_ctrl -m 3

UBI: attaching mtd3 to ubi0

UBI: physical eraseblock size:   131072 bytes (128 KiB)

UBI: logical eraseblock size:    126976 bytes

UBI: smallest flash I/O unit:    2048

UBI: VID header offset:          2048 (aligned 2048)

UBI: data offset:                4096

UBI: attached mtd3 to ubi0

UBI: MTD device name:            “filesystem1”

UBI: MTD device size:            512 MiB

UBI: number of good PEBs:        4096

UBI: number of bad PEBs:         0

UBI: max. allowed volumes:       128

UBI: wear-leveling threshold:    4096

UBI: number of internal volumes: 1

UBI: number of user volumes:     1

UBI: available PEBs:             3639

UBI: total number of reserved PEBs:457

UBI: number of PEBs reserved for badPEB handling: 40

UBI: max/mean erase counter: 2/1

UBI: image sequence number: 0

UBI: background thread”ubi_bgt0d” started, PID 1483

UBI device number 0, total 4096 LEBs(520093696 bytes, 496.0 MiB), available 3639 LEBs (462065664 bytes, 440.7 MiB),LEB size 126976 bytes (124.0 KiB)

 

root@dm368-evm:/# mount -tubifs  ubi0_0 /mnt/nand/ -o sync

UBIFS: mounted UBI device 0, volume0, name “rootfs”

UBIFS: file system size:   51171328 bytes (49972 KiB, 48 MiB, 403 LEBs)

UBIFS: journal size:       2539520 bytes (2480 KiB, 2 MiB, 20 LEBs)

UBIFS: media format:       w4/r0 (latest is w4/r0)

UBIFS: default compressor: lzo

UBIFS: reserved for root:  2416947 bytes (2360 KiB)

root@dm368-evm:/# df

Filesystem           1K-blocks      Used Available Use% Mounted on

/dev/root             39544232  16239820 21295632  43% /

none                      1024        24     1000   2% /dev

tmpfs                    16384        20    16364   0% /var/volatile

tmpfs                    21760         0    21760   0% /dev/shm

tmpfs                    16384         0    16384   0% /media/ram

ubi0_0                   45528      1528    41640   4% /mnt/nand

 

最后,总结下,就是要禁止nand flash驱动里面的subpage write,让 chip->subpagesize == mtd->writesize 就好了。

这是我的解决办法。如果有人要使用subpage write,那么一定要保证你的读写逻辑是正确的,要么不用ecc,要么各个subpage的ecc都应是正确的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/170242.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • AMC7135_sip soc

    AMC7135_sip soc7.4SiamFC学习目标 目标 知道SiamFC的网络结构特点 掌握SiamFC的网络训练方式 应用 无 任意对象跟踪的问题是通过仅仅在线地学习对象外观的模型来解决,使用视频本身作为唯一的训练数据。尽管这些方法取得了成功,但他们的在线方法本质上限制了他们可以学习的模型的丰富性。需要跟踪的目标是通过起始帧的选择框给出的。框中可能是任意物体,甚至只是物体的某个部分。由于给定跟踪目标的不确定性,我们无法做到提前准备好数据,并且训练出一个.

    2022年10月1日
    2
  • ip addr命令详解_ip命令详解

    ip addr命令详解_ip命令详解ipaddr命令的作用是在Linux系统上查询ip地址。命令效果如下:解析:lo(loopback)环回接口,常被分配到127.0.0.1,用于本机通信,经过内核处理后直接返回,不会在任何网络中出现。net_deviceflags:LOOPBACK,UP,表示网卡处于启动的状态LOWER_UP物理连接正常,就是网卡已经上电(物理指的是物理层)BROADCAST表示这个网卡有广播地址,可以发送广播包MULTICAST表示网卡可以发送多播包MTU1500是指什么意思呢?是哪一层的

    2022年7月27日
    5
  • Python——极客战记codecombat关卡代码

    kithgard地牢地牢深藏的宝石幽灵守卫真实姓名高举之剑焰中舞动KITHMAZE二度历险老对手名称大师矮人之乱KITHMAZE最终历险KithGard之门边地森林平原森林保卫战羊肠小道林地小屋if的盛宴背靠背森林劈斩者边地僵局测距仪发狂的矮人跃火林中乡村漫游者边地之叉交给劈斩者友人和敌人巫师之门未知的距离金币屑返回荆棘农场…

    2022年4月13日
    91
  • 电信网通全国DNS 列表「建议收藏」

    电信网通全国DNS列表电信DNS列表(按拼音排序,共32条)电信A安徽202.102.192.68202.102.199.68电信A澳门202.175.3.8202.175.3.3电信B北京202.96.199.133202.96.0.133202.106.0.20202.106.148.1电信C重庆61.128…

    2022年4月16日
    131
  • 孙鑫的java_孙鑫java视频教程「建议收藏」

    孙鑫的java_孙鑫java视频教程「建议收藏」近几年来,提到java相信很多人都不陌生了吧,Java技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网。也正是由于互联网的快速发展,学习java的人也是越来越多了。需要注意的是,java和我们平时学习的其它计算机语言还是有区别的。Java不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节…

    2022年5月17日
    41
  • Linux进程间通信——使用共享内存

    Linux进程间通信——使用共享内存下面将讲解进程间通信的另一种方式,使用共享内存。一、什么是共享内存顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一

    2025年8月21日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号