基于S3C2410上的Yaffs文件系统制作
Yaffs(Yet Another Flash File System)文件系统是专门针对NAND闪存
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
的嵌入式文件系
统,目前有YAFFS和YAFFS2两个版本,两个版本的主要区别之一在于YAFFS2能够更好的支持大容量
的NAND FLASH芯片。这也就是我的系统加载YAFFS2时给我主动切换到YAFFS1的原因,YAFFS文件系
统会根据你的NAND Flash的页面的大小来主动的配置你是使用YAFFS1还是YAFFS2。
目前支持FLASH的文件系统还有JFFS和JFFS2,JFFS和 JFFS2对 NOR Flash的支持还是非常好
的,是基于日志的文件系统。具体的介绍请查看相关文件。
与NOR相比,NAND不是完全可靠的,每块芯片出厂时都有一定比例的坏块存在,对数据的存取
不是使用地址映射而是通过寄存器的操作,串行存取数据。
NAND Flash上的YAFFS文件系统主要包含两个部分,一个部分是NAND Flash上的MTD的驱动,
另一个是YAFFS文件系统的支持。其中YAFFS的文件系统与硬件的相关性比较小,我们先完成内核对
YAFFS文件系统的支持。
1 内核支持YAFFS文件系统
首先通过CVS来获得YAFFS2的源代码。
export CVSROOT=:pserver:anonymous@cvs.aleph1.co.uk:/home/aleph1/cvs
cvs logon
cvs checkout yaffs2
下载
课程表模板下载资产负债表下载英语单词下载学习机资料下载励志文章下载
下来源码之后,在根
目录
工贸企业有限空间作业目录特种设备作业人员作业种类与目录特种设备作业人员目录1类医疗器械目录高值医用耗材参考目录
下存在一个patch-ker.sh,这是一个给linux打补丁的脚本,打
上这个补丁之后,内核的源代码就支持yaffs2了,我们来看一下这个脚本的最后部分。脚本中每个命
令行必须以TAB键开始,这是基本常识。
YAFFSDIR=$LINUXDIR/fs/yaffs2
if [ -e $YAFFSDIR ]
then
echo "$YAFFSDIR exists, not patching"
else
mkdir $LINUXDIR/fs/yaffs2
cp Makefile.kernel $LINUXDIR/fs/yaffs2/Makefile
cp Kconfig $LINUXDIR/fs/yaffs2
cp *.c *.h $LINUXDIR/fs/yaffs2
fi
这实际上就是在kernel/fs下建立了一个yaffs2的文件系统,然后将所有需要的文件拷贝到该
目录下。
那么我们来看fs目录下的kconfig文件有什么变化。
# Patched by YAFFS
source "fs/yaffs2/Kconfig"
config JFFS_FS
tristate "Journalling Flash File System (JFFS) support"
depends on MTD
help
JFFS is the Journaling Flash File System developed by Axis
Communications in Sweden, aimed at providing a crash/powerdown-safe
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
file system for disk-less embedded devices. Further information is
available at (
).
增加了一些目录,这些目录的设置在fs/yaffs2/Kconfig文件中。
查看fs/Makefile文件,看到有这些变化,加入了yaffs2的支持:
# Patched by YAFFS
obj-$(CONFIG_YAFFS_FS) += yaffs2/
这样我们来查看内核的情况:
内核中已经看到yaffs的相关选项了,我们的器件是512bytes/page的产品,这个下面的选项
是关于 ECC校验的处理,在YAFFS文件系统中,有自己的 ECC校验,而MTD文件系统驱动中,也有自
己的 ECC校验,一般会在这两者中两者选 1,如果将Lets Yaffs do its own ECC选上,就表示选择使
用YAFFS的 ECC检查。但是这样的话,要将MTD层的 ECC校验关闭,这个我们在下一节再说。
将其选择为编入内核之后,重新编译内核,下载,我们发现内核已经支持yaffs文件系统,第
一部分工作完成。
/home/ty $ cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev bdev
nodev proc
nodev sockfs
nodev pipefs
nodev futexfs
nodev tmpfs
nodev eventpollfs
nodev devpts
ext3
ext2
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
cramfs
nodev ramfs
nodev devfs
nodev nfs
yaffs
yaffs2
nodev rpc_pipefs
2 MTD层的NAND FLASH驱动。
这是整个NAND FLASH文件系统中最难理解和设计的部分。所幸的是linux的内核已经支持我们的板
级上的NAND FLASH了,我们只要做一些修改就可以了。
MTD层的驱动分为两个部分,MTD设备驱动和NAND FLASH 驱动。
我们也可以看make menuconfig的输出
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
2.1 首先我们来看NAND FLASH的设备驱动:
NAND Flash Decive Driver的配置如下所示:我故意将其编译成模块的方式,是为了在修改的时候
不用去重新编译内核,只需要使用make M=fs/mtd/nand,就可以实现对其模块的卸载和装载。
NAND FLASH的目录结构是:
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
这个文件夹中,与硬件相关的文件是s3c2410.c,我们只要修改这个文件就可以了。如果我们使用其
他的硬件的话,就要替换这个文件。
这个文件是一个驱动模块:
static int __init s3c2410_nand_init(void)
{
printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");
platform_driver_register(&s3c2440_nand_driver);
return platform_driver_register(&s3c2410_nand_driver);
}
static void __exit s3c2410_nand_exit(void)
{
platform_driver_unregister(&s3c2440_nand_driver);
platform_driver_unregister(&s3c2410_nand_driver);
}
上面定义了驱动加载和卸载的函数。
所有在SMDK2410上面的硬件,linux内核都用platform_driver和 platform_device来分别表示驱动
程序和设备。
我们来看变量s3c2410_nand_driver的定义:
static struct platform_driver s3c2410_nand_driver = {
.probe = s3c2410_nand_probe,
.remove = s3c2410_nand_remove,
.driver = {
.name = "s3c2410-nand",
.owner = THIS_MODULE,
},
};
这个driver的成员变量的含义分别是:probe和 remove分别代表驱动加载的方法,.driver的 name
字段很重要,内核根据这个字段来查找 driver对应的platform_device设备。
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
我们先关心驱动加载的函数,我们看驱动加载函数的传递参数就是struct platform_device *dev
(平台设备),而驱动怎么找到相应的设备的,就是我上面说的那样。
static int s3c2410_nand_probe(struct platform_device *dev)
{
return s3c24xx_nand_probe(dev, 0);
}
我们来看这个被调用的函数,由于2410和 2440都使用这个加载函数,就用传递参数0来表示是2410
static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440)
{
struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
struct s3c2410_nand_info *info;
struct s3c2410_nand_mtd *nmtd;
struct s3c2410_nand_set *sets;
struct resource *res;
int err = 0;
int size;
int nr_sets;
int setno;
#ifdef S3C2410_NAND_DEBUG
printk(KERN_INFO "s3c2410_nand_probe(%p)\n", pdev);
#endif
if (info == NULL) {
dev_err(&pdev->dev, "no memory for flash info\n");
err = -ENOMEM;
goto exit_error;
}
memzero(info, sizeof(*info));
platform_set_drvdata(pdev, info);
spin_lock_init(&info->controller.lock);
init_waitqueue_head(&info->controller.wq);
/* get the clock source and enable it */
info->clk = clk_get(&pdev->dev, "nand");
if (IS_ERR(info->clk)) {
dev_err(&pdev->dev, "failed to get clock");
err = -ENOENT;
goto exit_error;
}
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
clk_enable(info->clk);
/* allocate and map the resource */
/* currently we assume we have the one resource */
res = pdev->resource;
size = res->end - res->start + 1;
info->area = request_mem_region(res->start, size, pdev->name);
if (info->area == NULL) {
dev_err(&pdev->dev, "cannot reserve register region\n");
err = -ENOENT;
goto exit_error;
}
info->device = &pdev->dev;
info->platform = plat;
info->regs = ioremap(res->start, size);
info->is_s3c2440 = is_s3c2440;
if (info->regs == NULL) {
dev_err(&pdev->dev, "cannot reserve register region\n");
err = -EIO;
goto exit_error;
}
dev_dbg(&pdev->dev, "mapped registers at %p\n", info->regs);
/* initialise the hardware */
err = s3c2410_nand_inithw(info, pdev);
if (err != 0)
goto exit_error;
sets = (plat != NULL) ? plat->sets : NULL;
nr_sets = (plat != NULL) ? plat->nr_sets : 1;
info->mtd_count = nr_sets;
/* allocate our information */
size = nr_sets * sizeof(*info->mtds);
info->mtds = kmalloc(size, GFP_KERNEL);
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
if (info->mtds == NULL) {
dev_err(&pdev->dev, "failed to allocate mtd storage\n");
err = -ENOMEM;
goto exit_error;
}
memzero(info->mtds, size);
/* initialise all possible chips */
nmtd = info->mtds;
for (setno = 0; setno < nr_sets; setno++, nmtd++) {
#ifdef S3C2410_NAND_DEBUG
printk(KERN_INFO "initialising set %d (%p, info %p)\n",
setno, nmtd, info);
#endif
s3c2410_nand_init_chip(info, nmtd, sets);
nmtd->scan_res = nand_scan(&nmtd->mtd,
(sets) ? sets->nr_chips : 1);
if (nmtd->scan_res == 0) {
s3c2410_nand_add_partition(info, nmtd, sets);
}
if (sets != NULL)
sets++;
}
#ifdef S3C2410_NAND_DEBUG
printk(KERN_INFO "initialised ok\n");
#endif
return 0;
exit_error:
s3c2410_nand_remove(pdev);
if (err == 0)
err = -EINVAL;
return err;
}
这个函数最先使用to_nand_plat获得平台的分区信息:下面是对此分区信息的
分析
定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析
arch/arm/mach-s3c2410/common-smdk.c:
定义了64M的 flash空间,这个文件定义了硬件平台使用的FLASH的分区表。
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "bootloader",
.size = SZ_1M,
.offset = 0,
},
[1] = {
.name = "kernel",
.offset = SZ_1M,
.size = SZ_2M,
},
[2] = {
.name = "root",
.offset = SZ_1M*3,
.size = SZ_8M*5,
},
[3] = {
.name = "user",
.offset = SZ_1M*43,
.size = SZ_1M*21,
},
};
//这里定义了分区表
static struct s3c2410_nand_set smdk_nand_sets[] = {
[0] = {
.name = "NAND",
.nr_chips = 1,
.nr_partitions = ARRAY_SIZE(smdk_default_nand_part),
.partitions = smdk_default_nand_part,
},
};
/* choose a set of timings which should suit most 512Mbit
* chips and beyond.
*/
//代表了该nand flash有多少个分区表
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 0,
.twrph0 = 30,
.twrph1 = 0,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
这两个结构体的定义在 include/asm/arch/nand.h文件。
struct s3c2410_nand_set {
int nr_chips;
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
int nr_partitions;
char *name;
int *nr_map;
struct mtd_partition *partitions;
};
struct s3c2410_platform_nand {
/* timing information for controller, all times in nanoseconds */
int tacls; /* 从 CLE/ALE有效到 nWE/nOE的时间 */
int twrph0; /* nWE/nOE的有效时间 */
int twrph1; /* 从释放 CLE/ALE到nWE/nOE不活动的时间 */
int nr_sets; /* 集合数目 */
struct s3c2410_nand_set *sets; /* 集合列表 */
/* 根据芯片编号 选择 有效集合 */
void (*select_chip)(struct s3c2410_nand_set *,int chip);
};
关于这些结构的具体说明可以参看尚观开发团队写的那本书!
下面创建了一个s3c2410_nand_info结构体,然后对这个结构体进行初始化的操作,
info = kmalloc(sizeof(*info), GFP_KERNEL);
对这个结构体的操作完成之后,使用s3c2410_nand_inithw(info, pdev)开始初始化硬件。
这个函数就是打印出了NAND FLASH的操作时钟和设置NAND FLASH的配置寄存器
然后使用s3c2410_nand_init_chip对每个芯片进行初始化的操作,这个函数完成的操作是,设置每
个芯片读写操作的函数,地址范围,还有就是最重要的,每个芯片的 ECC校验方式。在这个函数中,NAND
FLASH的驱动设计者,本身就不希望我们去掉 NAND FLASH的 ECC校验,所以只有两种方式:
硬件校验 chip->eccmod= NAND_ECC_HW3_512或者软件校验 chip->eccmode= NAND_ECC_SOFT。我们
为了使用YAFFS文件系统自己的 ECC校验的方式的话,就需要自己在这个函数的最后加上这样一句:
chip->eccmode = NAND_ECC_NONE;
不使用MTD的 ECC校验方式。
完成这个初始化操作之后,使用函数nand_scan(&nmtd->mtd,(sets) ? sets->nr_chips : 1)对整个芯
片进行扫描。
这个函数是MTD的基本函数,在drivers/mtd/nand/nand_base.c中。从芯片中读取ID,初始化一些
结构体。
最后调用s3c2410_nand_add_partition,加入当前设备的分区信息。
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
在arch/arm/mach-s3c2410/devs.c文件中有nand控制器的定义
/* NAND Controller */
static struct resource s3c_nand_resource[] = {
[0] = {
.start = S3C2410_PA_NAND,
.end = S3C2410_PA_NAND + S3C24XX_SZ_NAND - 1,
.flags = IORESOURCE_MEM,
}
};
struct platform_device s3c_device_nand = {
.name = "s3c2410-nand",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_nand_resource),
.resource = s3c_nand_resource,
};
EXPORT_SYMBOL(s3c_device_nand);
在arch/arm/mach-s3c2410/mach-smdk2410.c文件中对这个需要初始化的硬件有设置:
static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
/* add by tony */
&s3c_device_nand
};
在查看这个代码的过程中,我有了一个发现,所有SMDK2410平台下的设备,都通过下面的这段定义
来初始化。
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
* to SMDK2410 */
/* Maintainer: Jonas Dietsche */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = smdk2410_map_io,
.init_irq = s3c24xx_init_irq,
.init_machine = smdk_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
其中的 init_machine 就是整个系统的初始化函数。这个函数在arch/arm/mach-s3c2410/common-
smdk.c文件中定义。
到此为止其实我们根本没有修改内核的任何代码,我们只是熟悉了整个驱动的流程,然后,我
们使用 make M=fs/mtd/nand,将NAND FLASH驱动编译成module方式,然后,使用脚本
insmod nand_ecc.ko
insmod nand_ids.ko
insmod nand.ko
insmod s3c2410.ko
执行之后,我们的控制终端会出现下面的信息:
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2410-nand: Tacls=1, 9ns Twrph0=4 39ns, Twrph1=1 9ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bi)
NAND_ECC_NONE selected by board driver. This is not recommended !!
Scanning device for bad blocks
Bad eraseblock 2754 at 0x02b08000
Bad eraseblock 2755 at 0x02b0c000
Creating 4 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00100000 : "bootloader"
0x00100000-0x00300000 : "kernel"
0x00300000-0x02b00000 : "root"
0x02b00000-0x04000000 : "user"
说明我们的硬件驱动工作正常了,加载这所有的模块之后,我们的NAND FLASH驱动就起来了。
我们使用命令查看所有的设备,会发现我们的字符设备和块设备中都已经支持,注意,这也就是我
出错的地方,也是一个比较容易让大家疑惑的地方。
/mnt/flash0 $ cat /proc/devices
Character devices:
1 mem
2 pty
3 ttyp
4 /dev/vc/0
4 tty
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
29 fb
90 mtd
128 ptm
136 pts
180 usb
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
189 usb_device
204 s3c2410_serial
254 devfs
Block devices:
1 ramdisk
31 mtdblock
254 mmc
查看MTD设备,使用:
/mnt/flash0 $ cat /proc/mtd
dev: size erasesize name
mtd0: 00100000 00004000 "bootloader"
mtd1: 00200000 00004000 "kernel"
mtd2: 02800000 00004000 "root"
mtd3: 01500000 00004000 "user"
查看分区信息:
/mnt/flash0 $ cat /proc/partitions
major minor #blocks name
31 0 1024 mtdblock0
31 1 2048 mtdblock1
31 2 40960 mtdblock2
31 3 21504 mtdblock3
但是我们的驱动虽然工作正常了,但是我们的/dev目录下没有出现可用的设备,这怎么办?怎么创
建相关的设备文件?
没有办法进行mount的操作阿?
那就需要创建设备文件,我在网上看到人家建立的设备文件如下:
/dev $ ls
console kmsg mtd ptmx rd urandom
fb mem mtdblock pts shm vc
full misc null pty tts vcc
kmem mmc port random tty zero
/dev/mtd $ ls -al
drwxr-xr-x 1 root root 0 Jan 1 00:01 .
drwxr-xr-x 1 root root 0 Jan 1 00:00 ..
crw-r--r-- 1 root root 90, 0 Jan 1 00:01 0
cr--r--r-- 1 root root 90, 1 Jan 1 00:01 0ro
crw-r--r-- 1 root root 90, 2 Jan 1 00:01 1
cr--r--r-- 1 root root 90, 3 Jan 1 00:01 1ro
crw-r--r-- 1 root root 90, 4 Jan 1 00:01 2
cr--r--r-- 1 root root 90, 5 Jan 1 00:01 2ro
crw-r--r-- 1 root root 90, 6 Jan 1 00:01 3
cr--r--r-- 1 root root 90, 7 Jan 1 00:01 3ro
/dev/mtdblock $ ls -al
drwxr-xr-x 1 root root 0 Jan 1 00:01 .
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
drwxr-xr-x 1 root root 0 Jan 1 00:00 ..
brw-r--r-- 1 root root 31, 0 Jan 1 00:01 0
brw-r--r-- 1 root root 31, 1 Jan 1 00:01 1
brw-r--r-- 1 root root 31, 2 Jan 1 00:01 2
brw-r--r-- 1 root root 31, 3 Jan 1 00:01 3
字符设备的主设备号是 90,块设备的主设备号是31。
我就照这使用下面的脚本创建了这些设备文件。
echo "create nand flash char device"
cd /dev
mkdir mtd
mkdir mtdblock
cd /dev/mtd
mknod 0 c 90 0
mknod 0ro c 90 1
mknod 1 c 90 2
mknod 1ro c 90 3
mknod 2 c 90 4
mknod 2ro c 90 5
mknod 3 c 90 6
mknod 3ro c 90 7
chmod a-w *ro
echo "create nand flash block device"
cd /dev/mtdblock
mknod 0 b 31 0
mknod 1 b 31 1
mknod 2 b 31 2
mknod 3 b 31 3
如果不这样进行的话,文件名也不能更改,那就会出错。然后,我去查看了MTD的驱动程序,找到
了这样做的理论基础。
在fs/mtd目录下有两个文件mtdblock.c和 mtdchar.c。这两个分别是加载Block设备和char设备的。
mtdchar.c文件中,创建字符设备就是这样创建的。
class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
NULL, "mtd%d", mtd->index);
class_device_create(mtd_class, NULL,
MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
NULL, "mtd%dro", mtd->index);
创建了这样的设备之后,我们就可以对其进行格式化了,在yaffs文件系统中提供了工具
mkyaffs,可以格式化分区块。
注意不能使用mkyaffs来初始化块设备,会返回一个操作错误,必须要使用mkyaffs来初始化字符
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
设备。
/dev/mtdblock $ mkyaffs /dev/mtdblock/0
argc 2 sh 0 optcnt 1
MEMGETINFO: Inappropriate ioctl for device
/dev/mtdblock $ mkyaffs /dev/mtd/0
argc 2 sh 0 optcnt 1
Erasing and programming NAND
Erasing block at 0x080
Erasing block at 0x084000
Erasing block at 0x088000
Erasing block at 0x08c000
Erasing block at 0x0810000
Erasing block at 0x0814000
Erasing block at 0x0818000
Erasing block at 0x081c000
Erasing block at 0x0820000
Erasing block at 0x0824000
Erasing block at 0x0828000
Erasing block at 0x082c000
Erasing block at 0x0830000
Erasing block at 0x0834000
Erasing block at 0x0838000
Erasing block at 0x083c000
Erasing block at 0x0840000
Erasing block at 0x0844000
Erasing block at 0x0848000
Erasing block at 0x084c000
Erasing block at 0x0850000
Erasing block at 0x0854000
Erasing block at 0x0858000
Erasing block at 0x085c000
Erasing block at 0x0860000
Erasing block at 0x0864000
Erasing block at 0x0868000
Erasing block at 0x086c000
Erasing block at 0x0870000
Erasing block at 0x0874000
Erasing block at 0x0878000
Erasing block at 0x087c000
Erasing block at 0x0880000
Erasing block at 0x0884000
Erasing block at 0x0888000
Erasing block at 0x088c000
Erasing block at 0x0890000
Erasing block at 0x0894000
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
Erasing block at 0x0898000
Erasing block at 0x089c000
Erasing block at 0x08a0000
Erasing block at 0x08a4000
Erasing block at 0x08a8000
Erasing block at 0x08ac000
Erasing block at 0x08b0000
Erasing block at 0x08b4000
Erasing block at 0x08b8000
Erasing block at 0x08bc000
Erasing block at 0x08c0000
Erasing block at 0x08c4000
Erasing block at 0x08c8000
Erasing block at 0x08cc000
Erasing block at 0x08d0000
Erasing block at 0x08d4000
Erasing block at 0x08d8000
Erasing block at 0x08dc000
Erasing block at 0x08e0000
Erasing block at 0x08e4000
Erasing block at 0x08e8000
Erasing block at 0x08ec000
Erasing block at 0x08f0000
Erasing block at 0x08f4000
Erasing block at 0x08f8000
Erasing block at 0x08fc000
OK
这样格式化所有的分区之后,就可以进行mount的操作了。
mount -t yaffs2 /dev/mtdblock/0 /mnt/flash0
mount -t yaffs2 /dev/mtdblock/1 /mnt/flash1
mount -t yaffs2 /dev/mtdblock/2 /mnt/flash2
mount -t yaffs2 /dev/mtdblock/3 /mnt/flash3
由于我的NAND FLASH的 PAGE SIZE为 512字节,会自动的加载yaffs1文件系统上去。
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2410-nand: Tacls=1, 9ns Twrph0=4 39ns, Twrph1=1 9ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bi)NAND_ECC_NONE
selected by board driver. This is not recommended !!
Scanning device for bad blocks
Bad eraseblock 2754 at 0x02b08000
Bad eraseblock 2755 at 0x02b0c000
Creating 4 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00100000 : "bootloader"
0x00100000-0x00300000 : "kernel"
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
0x00300000-0x02b00000 : "root"
0x02b00000-0x04000000 : "user"
create nand flash char device
create nand flash block device
yaffs: dev is 32505856 name is "mtdblock0"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.0, "mtdblock0"
yaffs: auto selecting yaffs1
yaffs: dev is 32505857 name is "mtdblock1"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.1, "mtdblock1"
yaffs: auto selecting yaffs1
yaffs: dev is 32505858 name is "mtdblock2"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.2, "mtdblock2"
yaffs: auto selecting yaffs1
yaffs: dev is 32505859 name is "mtdblock3"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.3, "mtdblock3"
yaffs: auto selecting yaffs1
block 3 is bad
block 4 is bad
到此,所有的flash文件块加载yaffs文件系统成功!
但是还有一个小问
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
,当我们在mount的文件夹下进行写的操作时,会出现如下的错误:
/mnt/flash0 $ touch t.txt
Reading data from NAND FLASH without ECC is not recommended
Writing data without ECC to NAND-FLASH is not recommended
这个错误是由于我们去掉了MTD层的 ECC校验而导致的。
解决办法就是在函数s3c2410_nand_init_chip中将加上的chip->eccmode = NAND_ECC_NONE这句话
去掉,使用MTD模块的软件校验。同时将yaffs的配置中让 yaffs做ECC校验的选项去掉。
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!
这样,我们的读写操作就是正常的,不会出现上面的提示了。
有疑问请联系ty3247@163.com(23012675) 欢迎大家一起讨论、共同进步!