Jffs2文件系统移植时不能写

lovejava759 2009-06-25 10:49:30
我的板子*M的flash空间,我划了5个MTD分区
0x000000-------0x40000) bootloader
0x40000-------------x700000 linux kernel + rootfs(squashfs)
0x700000-------9x7f0000) jffs2
0x7f0000-------9x800000) nvram

开始jffs2分区并没有使用, 所以我想在里面建立第二个可写的文件系统,一切准备就绪之后,mount到了根文件系统之上,ls cat这些涉及读操作的命令都很正常, 可是只要是涉及写操作的命令就报告错误Input/output error, 最后我跟踪内核代码看了,发现是在MTD的驱动里面的mtd->write()函数出现了问题。 比方chmod这条命令,最后在内核代码中追踪到mtd_writev(xxxxx)这个函数时,本来是往flash中写入68个byte,最后返回的结果是写进去了68*2=136 byte, 怎么会出现这种现象? 我的flash芯片是intel CFI 接口的nor flash, 支持的cmdset不清楚, 我对底层的flash芯片运作的机制不是很懂,所以搞了一个多星期这个问题还没有解决,请各位大侠帮忙指点一下怎么解决啊!、、、
注意我的jffs2分区是以rw的方式挂载的,我换了几个mkfs.jffs2工具制作文件系统image 都是这样的问题。 我的内核版本是2.4.20 我怀疑是MTD最底层的mtd_info->write( )这个函数出了问题, 可是怎么也不知道它到底哪里出了问题
...全文
420 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
lovejava759 2009-07-06
  • 打赏
  • 举报
回复
第四个nvram分区本来能写的,加大了jffs2的大小后(超过1M后),往nvram分区写时同样也报告Input/output error
怎么这么奇怪, 并没有改变nvram分区的大小了起始地址啊, 并且jffs2的大小也不是太大,没有覆盖前面的rootfs
分区
lovejava759 2009-07-01
  • 打赏
  • 举报
回复
直接用 dd 出现的问题是一样的 不是烧image时出了问题 否则mount ls cat 怎么正常?
pottichu 2009-07-01
  • 打赏
  • 举报
回复
直接用 dd 往分区里写数据会出错吗? 如果不会,那说明确实是 jffs2的问题了。
lovejava759 2009-07-01
  • 打赏
  • 举报
回复
通过自己板子上的bootloader烧 或kernel启动后通过tftp应用烧都没问题
pottichu 2009-07-01
  • 打赏
  • 举报
回复
烧写的时候是通过 uboot 烧写的吗?
lovejava759 2009-07-01
  • 打赏
  • 举报
回复
我就奇怪,烧代码时调用的也是mtd->write()函数,jffs2中调用的也是mtd->write,同一个函数,
为什么在jffs2中调用就出了问题呢?
lovejava759 2009-07-01
  • 打赏
  • 举报
回复
mtdblock 这一层会先缓存数据 等数据达到一定数量,或者 sync 被调用才会去写数据。
=================================================

我用的是NOR Flash, jffs2文件系统中是直接调用mtd->write(),mtd->write()中没有进行数据缓存,
而直接把不足一个block的数据写进去,mtd->write是flash驱动定义的一个callback函数,我就怀疑这里
是不是有问题?
再者,烧写jffs2文件系统的分区开始地址0x700000-----------0x7f0000
边界已经对齐 大小960KB 应该没问题了吧?
Wenxy1 2009-06-28
  • 打赏
  • 举报
回复
MTD可以写要条件的。边界与MTD的大小要符合一个条件。
lovejava759 2009-06-28
  • 打赏
  • 举报
回复
我使用dd命令试了,还是出现相同的问题。 确实是flash芯片驱动的问题,板子上以前运行的都是只读的文件系统,
所以每发现这个问题,现在用jffs2只要是调用到mtd->write,问题就来了

我研究了下flash chip的驱动,发现不是内核中自带的cfi flash驱动(我开始是这么以为
的),现在发现是broadcom自己写的驱动代码在
mtd/device/sflash.c中, 可是就是奇怪,为什么烧代码时能写进去呢? 无论是在bootloader还是在
内核启动后通过tftp协议打开/dev/mtdblock/3块设备来烧,最终都调用的是同一个mtd->write(即sflash_write)这个函数,唯一的区别就是在烧代码时往里面写之前会调用mtd->erase(即sflash_erase),在
jffs2文件系统中因为写的字节比较少,我看就是直接调用的mtd->write,没有调用mtd->erase,是不是
因为这个差别的原因?
我想调用mtd->write()往flash写少量数据时,如果不足一个扇区,要先擦除这个扇区再写,
这应该是mtd->write()函数里面完成的事情吧?还是在调用mtd->write之前,一定要调用mtd->erase
手动擦除?? 难道ST serial flash只能整块整块写 不能随机写吧??
pottichu 2009-06-28
  • 打赏
  • 举报
回复
jffs2文件系统中因为写的字节比较少,我看就是直接调用的mtd->write,没有调用mtd->erase,是不是
因为这个差别的原因?
========================================================================
nand flash 在写之前是一定会erase, 这是硬件特性决定的。
mtdblock 这一层会先缓存数据,等数据达到一定数量,或者 sync 被调用才会去写数据。
写的最小单位是 一个page, 擦除的最小单位是一个block。

nor flash 我不确定,你应该去研究一下 nor flash的工作原理。

leeyiqun 2009-06-28
  • 打赏
  • 举报
回复
在bootloader那边把该分区给擦掉后再试试看。有可能分区里面原先有东西,而且该分区已经写满了。有可能会出现这样的问题。
hefuhua 2009-06-28
  • 打赏
  • 举报
回复
如果其他的分区可以写,那么jffs2区不能写就是驱动的问题

如果是驱动问题,建议楼主移植个2.6的内核对比下,如果2.6的内核可以解决,如果一定要用2.4的内核,也可以把高2.6版本的移植到2.4
guan323333 2009-06-28
  • 打赏
  • 举报
回复
来学习的
pottichu 2009-06-26
  • 打赏
  • 举报
回复
最后返回的结果是写进去了68*2=136 byte, 怎么会出现这种现象
================================
jffs2 文件系统在 flash 里写入一些 jffs2 分区特有的信息。

struct jffs2_raw_inode
{
__u16 magic; /* A constant magic number. */
__u16 nodetype; /* == JFFS_NODETYPE_INODE */
__u32 totlen; /* Total length of this node (inc data, etc.) */
__u32 hdr_crc;
__u32 ino; /* Inode number. */
__u32 version; /* Version number. */
__u32 mode; /* The file's type or mode. */
__u16 uid; /* The file's owner. */
__u16 gid; /* The file's group. */
__u32 isize; /* Total resultant size of this inode (used for truncations) */
__u32 atime; /* Last access time. */
__u32 mtime; /* Last modification time. */
__u32 ctime; /* Change time. */
__u32 offset; /* Where to begin to write. */
__u32 csize; /* (Compressed) data size */
__u32 dsize; /* Size of the node's data. (after decompression) */
__u8 compr; /* Compression algorithm used */
__u8 usercompr; /* Compression algorithm requested by the user */
__u16 flags; /* See JFFS2_INO_FLAG_* */
__u32 data_crc; /* CRC for the (compressed) data. */
__u32 node_crc; /* CRC for the raw inode (excluding data) */
// __u8 data;
} __attri

而这个结构的大小刚好是 68 byte

建议你用 mtd_util 工具格式化一下分区, 然后直接把你 用 mkfs.jffs2 做出来的包 dd 进该分区.
/bin/dd if=/mnt/rootfs.jffs2 of=/dev/mtdblock2
pottichu 2009-06-26
  • 打赏
  • 举报
回复
我进行的是chmod操作,setAttr写进去的就只是是一个struct jffs2_raw_inode 结构  就是这个68bytes
可是mtd_writev却写进去了136byte 
============================================================
这个我不确定, chmod 的时候要修改文件的属性,也就是说会修改文件的 inode,
至于写了多少字节,我不确定,应为没有读过jffs2 写文件部分的代码,只看过读文件部分的代码,所以不确定。

返回时代码检查写进去的长度不一样  就返回了
========================================
这个可能和硬件的时序有关系,也就是说,驱动有问题,等待操作flash的时间可能需要修改, nand flash 的我倒是知道,
nor flash的没接触过。 不过,你可以查看一下nor flash相关部分的代码。 这个跟jffs2 是没有关系的。

我的板子上没有mtd_util 工具  编译不通过   格式化就是实用erase命令擦除分区吗??还是像磁盘那样格式化????
==================================
mtd_util 工具可以从网上下载, 格式化就是用 flash_eraseall 命令 比如:
flash_eraseall /dev/mtd2
注意擦出需要按字符设备去擦, 也就是 mtd2


lovejava759 2009-06-26
  • 打赏
  • 举报
回复
我进行的是chmod操作,setAttr写进去的就只是是一个struct jffs2_raw_inode 结构  就是这个68bytes
可是mtd_writev却写进去了136byte 
 返回时代码检查写进去的长度不一样  就返回了
metadata error

我的板子上没有mtd_util 工具  编译不通过   格式化就是实用erase命令擦除分区吗??还是像磁盘那样格式化????

4,436

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧