Linux 2.6.22,加了最新的yaffs2,完成了nand flash驱动后,用mtd test测验驱动作业都正常的。
可是,最新发现一个很怪异的问题:
在mount /dev/mtdblock4 /mnt/usb_msc 后,主动挂载成yaff2文件体系之后,再去insmod任何一个ko,都会死掉,并且仍是没有任何输出信息的,连kernel的oops,对应ko晒干榜首行打印,都没有。
【处理进程】
1.后来经过测验,发现,关于pagesize是2K的nand flash来说(此处我们特殊需求(硬件HW ECC占用太多),所以需求进制yaffs2的tag ecc(以节约空间寄存HW ECC)),都是能够正常作业的,可是关于4K Pagesize的nand,就作业不正常。而之前现已用mtd test的一系列东西验证了,2K和4K的nand的驱动,都是能够正常作业的。
2.去看了下mtd层关于2K和4K的,有什么不一样的当地,发现对应的include\mtd-abi.h中,struct nand_ecclayout中,eccpos仍是64,所以将其改为128,再去测验,问题如故。
3.其他的,找不到原因了,所以,揣度是yaffs2与MTD的兼容等方面的问题。
4.后来又经过测验,以/dev/mtdblock4作为参数,用
insmod dwc_otg.ko
insmod gadgetfs.ko
insmod g_file_storage.ko file=/dev/mtdblock4 stall=0 removable=1
去挂载了usb masstorage,去windows中格式化该U盘成fat32,然后去板子上,去
mount /dev/mtdblock4 /mnt/usb_msc -t vfat
挂载成fat分区,然后这样,就能够避开yaffs2,仅仅和mtd层有联系,成果测验下来,
数据读写,都仍是对的,可是仍是先mount,后边再碑文其他的,触及到内核数据成果的操作,就仍是死掉
即不论是挂载成yaffs2:
mount /dev/mtdblock4 /mnt/usb_msc
仍是
mount /dev/mtdblock4 /mnt/usb_msc -t vfat
后边对该分区的数据读写都是OK的,可是便是之后再去
insmod ***.ko 或许其他的loadkmap 等等触及内核的操作的程序,都会导致内核死掉,并且此处的死掉,
和一般的oops,空指针等还不同,彻底没有任何输出。
死掉后,去用rvds衔接板子,发现pc一直在0xFFFF000C,对应的便是ARM 的预取指间断反常:
ARM体系结构所支撑的反常类型
反常类型
复位
未定义指令
软件间断
指令预取间断
数据间断
IRQ
FIQ
反常向量表(Exception Vectors)
地址
0x0000,0000
ox0000,0004
0x0000,0008
0x0000,000c
0x0000,0010
0x0000,0014
0x0000,0018
0x0000,001c
也便是阐明,最终犯错的预取指间断,便是去原本应该存储对应的指令(代码)的当地,去读取指令,
成果实践取指取出来的是不合法的,所以呈现此预取指间断反常,死掉了。
5.最终发现,问题出在
include\linux\mtd\nand.h中:
struct nand_buffers {
uint8_t ecccalc[MTD_NAND_MAX_OOBSIZE];
uint8_t ecccode[MTD_NAND_MAX_OOBSIZE];
uint8_t databuf[MTD_NAND_MAX_PAGESIZE + MTD_NAND_MAX_OOBSIZE];
};
databuf的对应的宏:
#define MTD_NAND_MAX_PAGESIZE 2048
#define MTD_NAND_MAX_OOBSIZE 64
因而,在
int nand_scan_tail(struct mtd_info *mtd)
{
…
if (!(chip->options & NAND_OWN_BUFFERS))
…
}
kmalloc去请求的空间,便是2048bytes了,这样,关于2K pagesize的nand,肯定是作业正常的,可是关于4K pagesize的,假如上层,比方yaffs2,经过mtd去读取数据,一个page的数据便是4K了,然后会放到这个buffer晒干,成果后边2048的体系数据,就被冲掉了,假如体系之后用到这部分的数据或指令,就会有问题。而此处呈现的预取指间断反常,那便是阐明,后边这2048字节,晒干很可能包含了某些体系相关的指令(和其他数据),成果体系碑文到这儿,取指不正常,所以挂掉了。
【处理办法】
处理办法也很简单,便是把对应的宏,该成足够大,比方:
#define MTD_NAND_MAX_PAGESIZE 8192
#define MTD_NAND_MAX_OOBSIZE
这样,今后即使是8K的nand,也能够很好的支撑了。