linux下Nand Flash的JFFS2文件系统的移植
来源:百度文库 编辑:神马文学网 时间:2024/04/29 00:57:33
uclinux下Nand Flash的JFFS2文件系统的移植(写在前面)
现在(2005-12-5),linux对mtd设备支持的好得多,远没有我当时(大概2.5年前吧)做得那么复杂了,这里仍然要发原文,是因为想给初学者提供一个参考思路,介绍一下我对linux的学习了解的整个过程,希望对大家有借鉴意义。但是,建议还是使用最新的mtd补丁,新版本的mtd包括了对2k page 的nand flash的支持,要使用大于128MB的Nand flash,就用这个吧。文件系统方面,建议在Nor flash上,使用jffs2(jffs3也有,但是,我没用过,没有发言权)。在Nand flash上强烈建议使用yaffs,这比jffs2快很多,而且支持direct模式,在其他系统,比如:uCOS-II、winCE等都可以使用。我已经做到了在uCOS-II下和Linux下通过yaffs文件系统实现共享。但是,要想使用2k page的nand flash,只有使用yaffs2了。现在,yaffs2开源的代码有点问题,不能直接和mtd设备配合使用,稍作修改可以实现,有兴趣,我可以专门再写一片yaffs2的移植心得。
下面是,很早以前的心得了.....
uclinux下Nand Flash的JFFS2文件系统的移植(1)
继续上一篇《uClinux下移植Ne2000兼容的网卡驱动程序》中介绍的平台和操作系统,开始写JFF2的感想。虽然JFFS2的移植弄出来有一段时间了,但是,前一段时间忙着期末考试,无心写心得。昨天总算考完了,我就继续罗嗦那段时期的经历吧,希望把我遇到的问题和解决的方法和大家共享。错误之处也请不吝指出。
我使用的uClinux的硬件平台还是44B0那个板子具体的情况参见《uClinux下移植Ne2000兼容的网卡驱动程序》中的介绍。Flash我用的是三星公司的K9F2808——16MByte的Nand Flash。
开始,先看看有没有其他人的经验或者文章什么。用uclinux和jffs2关键词google了一下,找到了很多乱七八糟的东西,感觉唯一有用的也就是《The Linux MTD, JFFS HOWTO》,这篇文章写的比较细,我就是看这个逐渐地入了门。
首先,make menuconfig,把mtd打开。可是,发现我拿到的内核中,没有这个mtd选项。比较一下,发现uClinux-dist-20030305里面,编译4510的时候,就有mtd这个选项。比较郁闷,不过还是不甘心,仔细看看arch/armnommu/config.in文件,发现如下:
if [ "$CONFIG_ALIGNMENT_TRAP" = "y" ]; then
source drivers/mtd/Config.in
fi
这就是问题了。不过还是不清楚这个CONFIG_ALIGNMENT_TRAP是干什么的。从字面上猜测可能是处理非对齐异常的。不过,如果我在前面定义了CONFIG_ALIGNMENT_TRAP,那么我的内核就不能正常的运行,看了半天源码,也没看懂,算了,索性把这个就给注释掉了(因为uClinux-dist-20030305里面就没有这个if)。这样,mtd就可以使用了。
接下来就是定制内核,在MTD中,开启CONFIG_MTD_PARTITIONS、CONFIG_MTD_CHAR、CONFIG_MTD_BLOCK,选中NAND Device Support中的全部选项(因为我用的是Nand Flash)。再到File system中选重JFFS2文件系统。
系统是怎么加载底层的Flash设备呢,很容易在/drivers/mtd/nand/目录下找到相关的代码。先看看Makefile,有如下一行:
obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
看来只有编译的时候定义了CONFIG_MTD_NAND_SPIA,spia.c才可以被编译。spia.c是一个关键的问题,Nand Flash的驱动程序就是从这里加载的。我不想改spia.c中的东西,就照着spia.c复制了一个文件arm_nand.c,在/drivers/mtd/nand/Makefile中添加
obj-$(CONFIG_MTD_NAND_ARM) +=arm_nand.o
并修改drivers/mtd/nand/config.in文件,添加如下内容:
if [ "$CONFIG_ARM" = "y" ]; then
dep_tristate 'NAND Flash device on ARM board' CONFIG_MTD_NAND_ARM $CONFIG_MTD_NAND
fi
这样,在定制内核的时候,只要是ARM的开发平台就可以使用我的这个arm_nand.c驱动程序了。这个arm_nand.c代码(原来的spia.c),很容易读懂,就是不熟悉Nand Flash的人,对照着芯片的Datasheet也很快就能看明白,需要改的就是你的板子上的Nand Flash几个控制信号线(主要是ALE、CLE、CE)的地址,输入输出的地址等等。我为了以后方便,把这些地址都通过宏定义放到了config.in中。
然后,在arm_nand.c代码中,最关键的就是partition_info的定义,我改成如下:
const static struct mtd_partition partition_info[] = {
/* { name: "SPIA flash partition 1",
offset: 0,
size: 2*1024*1024 },*/
#ifdef CONFIG_ARCH_S3C44B0
{ name: "Nand flash partition",
offset: 2*1024*1024,
size: 14*1024*1024 }
#endif
};
#define NUM_PARTITIONS 1
很容易理解,因为我的
New Roman">nand flash中,前2M的空间,用于存放uclinux的kernel和romdisk,启动的时候通过bootloader加载到内存中。所以,这个空间是不能用的。剩下的14MB,就是划分成一个Flash盘准备上JFFS2了。
这样,似乎就可以了。编译内核,然后运行,
结果有如下错误:
readb called, but not implemented<2>kernel BUG at traps.c
待续
uclinux下Nand Flash的JFFS2文件系统的移植(2)
readb的这个问题其实很简单,用SourceInsight跟踪基层调用就知道,是因为在我的44b0的这个移植版本中根本就没有readb的定义,在include/asm-armnommu/arch-s3c44b0/io.h文件中添加:
#define readb(b) __arch_getb(b)
#define readw(b) __arch_getw(b)
#define readl(b) __arch_getl(b)
#define writeb(v,b) __arch_putb(v,b)
#define writew(v,b) __arch_putw(v,b)
#define writel(v,b) __arch_putl(v,b)
其中__arch_xxx也是在这个文件中定义,或者可以干脆直接(*(volatile unsigned xxx *)(xxx))。好了,系统启动,果然,找到Nand Flash:
NAND device: Manufacture ID: 0xec, Chip ID: 0x73 (Samsung KM29U128T)
Creating 1 MTD partitions on "Samsung KM29U128T":
0x00200000-0x01000000 : "Nand flash partition"
mtd: Giving out device 0 to Nand flash partition
系统启动以后,用cat /proc/mtd,可以显示如下信息。
dev: size erasesize name
mtd0: 00e00000 00004000 "Nand flash partition"
没错了,Nand Flash的信息,容量,还有擦除的block的大小都没有问题。
然后,按照《The Linux MTD, JFFS HOWTO》所说,编译mtd工具,我是从网上下的mtd-snapshot-20030508,用mkfs.jffs2生成jffs2的映象文件(jffs2.img),这个和genromfs差不多。然后,在交叉编译mtd-snapshot-20030508,主要是用erase来擦除Flash。
接着,编辑romdisk,在/dev目录下,建立创建文件@mtd0,c,90,0、@mtdblock0,b,31,0。这就是用来访问的设备了。前者是字符设备类型,后者是block类型。
下面就可以用在目标板上
cp /var/mnt/jffs2.img /dev/mtd0
把前面生成的jffs2格式的映象复制到mtd0设备中就是我们的Nand Flash了。
结果,发现系统死掉了。5555555555
在内核中把所有的跟踪信息开启,发现系统是在drivers/mtd/nand/nand.c中的nand_write_ecc中死掉了。用printk继续定位,把结果锁定在了下面的调用
wake_up (&this->wq);
因为我对系统内核不了解,当时连这个wake_up的函数是干什么的都不知道:(,用SourceInsight跟踪了好几天都没有头绪,最后,干脆放弃了,整天上课的时候捧着一本《Linux内核源码情景分析》来看(主要是上册),感觉写得不错,几天下来,收获颇丰。不过,感还是不能解决前面的问题……
待续...
现在(2005-12-5),linux对mtd设备支持的好得多,远没有我当时(大概2.5年前吧)做得那么复杂了,这里仍然要发原文,是因为想给初学者提供一个参考思路,介绍一下我对linux的学习了解的整个过程,希望对大家有借鉴意义。但是,建议还是使用最新的mtd补丁,新版本的mtd包括了对2k page 的nand flash的支持,要使用大于128MB的Nand flash,就用这个吧。文件系统方面,建议在Nor flash上,使用jffs2(jffs3也有,但是,我没用过,没有发言权)。在Nand flash上强烈建议使用yaffs,这比jffs2快很多,而且支持direct模式,在其他系统,比如:uCOS-II、winCE等都可以使用。我已经做到了在uCOS-II下和Linux下通过yaffs文件系统实现共享。但是,要想使用2k page的nand flash,只有使用yaffs2了。现在,yaffs2开源的代码有点问题,不能直接和mtd设备配合使用,稍作修改可以实现,有兴趣,我可以专门再写一片yaffs2的移植心得。
下面是,很早以前的心得了.....
uclinux下Nand Flash的JFFS2文件系统的移植(1)
继续上一篇《uClinux下移植Ne2000兼容的网卡驱动程序》中介绍的平台和操作系统,开始写JFF2的感想。虽然JFFS2的移植弄出来有一段时间了,但是,前一段时间忙着期末考试,无心写心得。昨天总算考完了,我就继续罗嗦那段时期的经历吧,希望把我遇到的问题和解决的方法和大家共享。错误之处也请不吝指出。
我使用的uClinux的硬件平台还是44B0那个板子具体的情况参见《uClinux下移植Ne2000兼容的网卡驱动程序》中的介绍。Flash我用的是三星公司的K9F2808——16MByte的Nand Flash。
开始,先看看有没有其他人的经验或者文章什么。用uclinux和jffs2关键词google了一下,找到了很多乱七八糟的东西,感觉唯一有用的也就是《The Linux MTD, JFFS HOWTO》,这篇文章写的比较细,我就是看这个逐渐地入了门。
首先,make menuconfig,把mtd打开。可是,发现我拿到的内核中,没有这个mtd选项。比较一下,发现uClinux-dist-20030305里面,编译4510的时候,就有mtd这个选项。比较郁闷,不过还是不甘心,仔细看看arch/armnommu/config.in文件,发现如下:
if [ "$CONFIG_ALIGNMENT_TRAP" = "y" ]; then
source drivers/mtd/Config.in
fi
这就是问题了。不过还是不清楚这个CONFIG_ALIGNMENT_TRAP是干什么的。从字面上猜测可能是处理非对齐异常的。不过,如果我在前面定义了CONFIG_ALIGNMENT_TRAP,那么我的内核就不能正常的运行,看了半天源码,也没看懂,算了,索性把这个就给注释掉了(因为uClinux-dist-20030305里面就没有这个if)。这样,mtd就可以使用了。
接下来就是定制内核,在MTD中,开启CONFIG_MTD_PARTITIONS、CONFIG_MTD_CHAR、CONFIG_MTD_BLOCK,选中NAND Device Support中的全部选项(因为我用的是Nand Flash)。再到File system中选重JFFS2文件系统。
系统是怎么加载底层的Flash设备呢,很容易在/drivers/mtd/nand/目录下找到相关的代码。先看看Makefile,有如下一行:
obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
看来只有编译的时候定义了CONFIG_MTD_NAND_SPIA,spia.c才可以被编译。spia.c是一个关键的问题,Nand Flash的驱动程序就是从这里加载的。我不想改spia.c中的东西,就照着spia.c复制了一个文件arm_nand.c,在/drivers/mtd/nand/Makefile中添加
obj-$(CONFIG_MTD_NAND_ARM) +=arm_nand.o
并修改drivers/mtd/nand/config.in文件,添加如下内容:
if [ "$CONFIG_ARM" = "y" ]; then
dep_tristate 'NAND Flash device on ARM board' CONFIG_MTD_NAND_ARM $CONFIG_MTD_NAND
fi
这样,在定制内核的时候,只要是ARM的开发平台就可以使用我的这个arm_nand.c驱动程序了。这个arm_nand.c代码(原来的spia.c),很容易读懂,就是不熟悉Nand Flash的人,对照着芯片的Datasheet也很快就能看明白,需要改的就是你的板子上的Nand Flash几个控制信号线(主要是ALE、CLE、CE)的地址,输入输出的地址等等。我为了以后方便,把这些地址都通过宏定义放到了config.in中。
然后,在arm_nand.c代码中,最关键的就是partition_info的定义,我改成如下:
const static struct mtd_partition partition_info[] = {
/* { name: "SPIA flash partition 1",
offset: 0,
size: 2*1024*1024 },*/
#ifdef CONFIG_ARCH_S3C44B0
{ name: "Nand flash partition",
offset: 2*1024*1024,
size: 14*1024*1024 }
#endif
};
#define NUM_PARTITIONS 1
很容易理解,因为我的
New Roman">nand flash中,前2M的空间,用于存放uclinux的kernel和romdisk,启动的时候通过bootloader加载到内存中。所以,这个空间是不能用的。剩下的14MB,就是划分成一个Flash盘准备上JFFS2了。
这样,似乎就可以了。编译内核,然后运行,
结果有如下错误:
readb called, but not implemented<2>kernel BUG at traps.c
待续
uclinux下Nand Flash的JFFS2文件系统的移植(2)
readb的这个问题其实很简单,用SourceInsight跟踪基层调用就知道,是因为在我的44b0的这个移植版本中根本就没有readb的定义,在include/asm-armnommu/arch-s3c44b0/io.h文件中添加:
#define readb(b) __arch_getb(b)
#define readw(b) __arch_getw(b)
#define readl(b) __arch_getl(b)
#define writeb(v,b) __arch_putb(v,b)
#define writew(v,b) __arch_putw(v,b)
#define writel(v,b) __arch_putl(v,b)
其中__arch_xxx也是在这个文件中定义,或者可以干脆直接(*(volatile unsigned xxx *)(xxx))。好了,系统启动,果然,找到Nand Flash:
NAND device: Manufacture ID: 0xec, Chip ID: 0x73 (Samsung KM29U128T)
Creating 1 MTD partitions on "Samsung KM29U128T":
0x00200000-0x01000000 : "Nand flash partition"
mtd: Giving out device 0 to Nand flash partition
系统启动以后,用cat /proc/mtd,可以显示如下信息。
dev: size erasesize name
mtd0: 00e00000 00004000 "Nand flash partition"
没错了,Nand Flash的信息,容量,还有擦除的block的大小都没有问题。
然后,按照《The Linux MTD, JFFS HOWTO》所说,编译mtd工具,我是从网上下的mtd-snapshot-20030508,用mkfs.jffs2生成jffs2的映象文件(jffs2.img),这个和genromfs差不多。然后,在交叉编译mtd-snapshot-20030508,主要是用erase来擦除Flash。
接着,编辑romdisk,在/dev目录下,建立创建文件@mtd0,c,90,0、@mtdblock0,b,31,0。这就是用来访问的设备了。前者是字符设备类型,后者是block类型。
下面就可以用在目标板上
cp /var/mnt/jffs2.img /dev/mtd0
把前面生成的jffs2格式的映象复制到mtd0设备中就是我们的Nand Flash了。
结果,发现系统死掉了。5555555555
在内核中把所有的跟踪信息开启,发现系统是在drivers/mtd/nand/nand.c中的nand_write_ecc中死掉了。用printk继续定位,把结果锁定在了下面的调用
wake_up (&this->wq);
因为我对系统内核不了解,当时连这个wake_up的函数是干什么的都不知道:(,用SourceInsight跟踪了好几天都没有头绪,最后,干脆放弃了,整天上课的时候捧着一本《Linux内核源码情景分析》来看(主要是上册),感觉写得不错,几天下来,收获颇丰。不过,感还是不能解决前面的问题……
待续...
linux下Nand Flash的JFFS2文件系统的移植
移植jffs2文件系统中碰到的问题
uClinux下Nor Flash的JFFS2文件系统构建
关于linux下的嵌入式文件系统以及flash文件系统选择-2 - 嵌入式相关 - 无为
Linux下文件系统的比较和选择
Linux环境下的ReiserFS文件系统
Linux下加挂文件系统的小结
嵌入式Linux下NAND存储系统的设计与实现hxy
基于Linux2.6的YAFFS文件系统移植
Linux操作系统下文件系统的比较和选择
Linux下NFS(网络文件系统)的建立与配置方法
构造嵌入式Linux的文件系统||Linux|
NOR FLASH与NAND FLASH的区别
nor flash 和nand flash 的区别
NOR FLASH 和NAND FLASH的区别
nor flash 和nand flash 的区别
Nor Flash 和Nand Flash 的区别
Windows下程序向Linux下移植细节 - wenhm的专栏 - CSDNBlog
FreeBSD下的内存文件系统
FreeBSD下的内存文件系统
Linux的文件系统结构 - 隼之 - CSDNBlog
Linux的文件系统结构 - 隼之 - CSDNBlog
如何在44b0开发板armsys上建立基于nandflash的jffs2文件系统--平淡中的激情
【转】Python的ARM-Linux平台移植