nandflash 的分区表 对应于内核arch/arm/mach-s3c2440/mach-mini2440.c中(友善官网提供的2.6.32.2的移植内核)
在linux2.6.32.2 中 已经自带了大部分nandflash驱动
在linux-2.6.32.2/drivers/mtd/nand/nand_ids.c这个文件中 里面定义了所支持的各种nandflash类型
在linux 2.6.32 中 nand驱动是被注册为平台设备
在linux统源代码树中 在linux2.6.32/arch/arm 这个文件夹中
目录plat-s3c24xx中
有common-smdk.c文件 里面定义nandflash的默认分区情况 这个是这个s3c24xx平台的 可能并不适合我们的具体的开发板
因此在这个目录外 有相应得开发板的具体的一些硬件结构信息
mach-s3c2440 这个目录 里面 的mach-mini2440.c中就定义了我们自己开发板上自己划分的适合的分区
static struct mtd_partition friendly_arm_default_nand_part[] = {
[0] = {
.name
= "supervivi",//bootloader 所在分区 可以放u-boot supervivi 等对应为/dev/mtdblock0
.size
= 0x00040000,
.offset
= 0,
},
[1] = {
.name
= "param",//这里是supervivi
或bootloader(uboot)等参数区 如果uboot较大 可以覆盖此区域 不会影响系统的启动 对应于/dev/mtdblock1
.offset = 0x00040000,
.size
= 0x00020000,
},
[2] = {
.name
= "Kernel",//内核所在的分区 大小5M 一般内核也就是2点几兆 足够了 对应/dev/mtdblock2
.offset = 0x00060000,
.size
= 0x00500000,
},
[3] = {
.name
= "root",//文件系统分区 nandflash用的多的yaffs2文件系统 对应/dev/mtdblock3
.offset = 0x00560000,
.size
= 1024 * 1024 * 1024, //
},
[4] = {
.name
= "nand",//此区域代表了整片的nandflash 主要是预留使用 比如以后可以通过应用程序访问读取/dev/mtdblock4 就能实现备份整片nandflash了
.offset = 0x00000000,
.size
= 1024 * 1024 * 1024, //
}
};
特别注意:对文件系统的分区大小要是nand页的大小的整数倍 否则会出现readonly错误 flash按页读取
//下面为开发板的nandflash设置表 因为板子上只有一片
因此也就只有一个表
static struct s3c2410_nand_set friendly_arm_nand_sets[] = {
[0] = {
.name
= "NAND",
.nr_chips
= 1,
.nr_partitions
= ARRAY_SIZE(friendly_arm_default_nand_part),
.partitions
= friendly_arm_default_nand_part,
},
};
//下面是nand flash 本身的一些特性 一般需要对照datasheet填写 大部分情况下按照以下参数填写即可
static struct s3c2410_platform_nand friendly_arm_nand_info = {
.tacls
= 20,
.twrph0
= 60,
.twrph1
= 20,
.nr_sets
= ARRAY_SIZE(friendly_arm_nand_sets),
.sets
= friendly_arm_nand_sets,
.ignore_unset_ecc = 1,
};
注意:
mini2440_nand_info需要注册到mini2440_map_io中。
static void __init mini2440_map_io(void)
{
s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
}
//下面把nandflash这个设备注册到系统中
static struct platform_device *mini2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_rtc,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&mini2440_device_eth,
&s3c24xx_uda134x,
&s3c_device_nand,//把nandflash添加到开发板设备列表结构中
&s3c_device_sdi,
&s3c_device_usbgadget,
};
从这里可以看到各分区的地址 也可以自己修改
如果从nor 或者 nand 启动 就可以 将相应的内容下载到相应地址 启动 定好地址 就OK
分区还要注意:
//
启动代码是系统上电或者复位后运行的第一段代码 他的作用是在用户程序运行之前 对系统的硬件与软件运行环境进行必要的初始化 并在最后使程序跳转到用户程序 他直接面对ARM处理器内核以及硬件控制器进行编程
S3C2440 支持从 NOR flash 或者 NAND Flash中启动
NOR Flash 的特点是 程序可以直接在芯片内执行 不必将程序读取到RAM中运行 NOR FLASH虽有这个优点 但是它的性价比远低于NAND FLASH
因为很多系统选择从NAND FLASH 启动,从NAND FLASH中启动需要先把程序拷贝到RAM中去运行
NOR FLASH启动: NOR FLASH --》映射到 nGCD0 其地址被映射为0x00000000
NAND_FLASH启动:S3C2440内部自带一块容量为4K的bootSRAM(叫做起步阶石“Steppingstone”)映射到nGCS0 其地址被映射为0x00000000
但系统上电或启动后 程序会从0地址处开始执行 因此我们需要把启动代码放在0地址处
NOR FLASH启动:程序可以在FLASH芯片中 直接被CPU执行
没有什么太多说的了
NAND FLASH启动:上电或复位后 0地址处为bootSRAM 启动前他里面是空的 启动后S3C2440 先通过硬件机制将NANDFLASH的前4K内容拷贝他里面去
然后再从0地址处开始执行
在这种情况下 我们需要保证将启动代码存放在NANDFLASH开始的位置 并且启动代码的大小要小于4K
如果系统的所有程序 编译链接后大小小于4K 那么系统的启动代码中无需考虑将程序从NANDFLASH 搬运到SDRAM 中去执行这个问题
因为所有的程序在启动时既全部由NANDFLASH 拷贝到了bootSRAM中执行了
如果系统中所编的程序编译后大于4K 那么系统的启动代码中需要包含一段将系统的全部程序从NANDFLASH 搬运到SDRAM的代码
系统启动时 只将NANDFLASH 的前4K 拷贝到了BootSRAM中,还有部分程序保存在NAND FLASH中 是无法内执行的 所以前4K被拷贝到BootSRAM中需要有能将程序拷贝到SDRAM中的代码
因此从NAND FLASH中启动 牵涉到两次拷贝
1:nandflash前4K --> BootSAM 自动 无需人为干扰
2:从nandflash中搬运系统到SDRAM 需要程序员 控制
//
我们的开发板上有两种FLASH芯片 NorFlash(下面简称Nor)
NandFlash (下面简称Nand)
我买的开发板上面的norflash型号是AM29LV160DB(AMD) 2M大小
nandflash型号是K9F2G08U0B 256M
/
硬盘 结构 容量 方面知识
硬盘的分类 一般有 SCSI IDE
SATA
一种硬盘的生产 同时伴随着一定的标准出现 生产技术升级伴随着生产标准升级
SCSI标准-->SCSI1 SCSI2 SCSI3 经常在服务器网站看到的Ultral-160就是基于SCSI-3标准的
IDE标准--> 遵循的是ATA标准
IDE是并口设备
SATA-->ATA标准的升级 SATA是串口设备 SATA发展就是为了替换IDE
硬盘的物理结构是由盘 磁盘表面(heads 一般一个磁盘面就有一个读取磁盘的磁头 所以为heads)
柱面(cylinders) 扇区 组成 最外面的柱面为0柱面 柱面数目等于磁道的数目
硬盘体积换算公式是:heads X cylinders X 扇区个数 X 扇区大小512字节 = 磁盘体积(字节bytes)
其中硬盘在计算容量时
是以10进制来换算的 也就是 而操作系统中是以2进制来换算大小的
80000000 bytes = 80000 K = 80M (向大单位换算,每次除以1000)
硬盘分区情况
硬盘的分区是由主分区
扩展分区 逻辑分区 组成
硬盘分区的主分区(包括扩展分区)最多是4个,分区表最大就能划分出这么多的分区,在扩展分区中可以划分逻辑分区) ,其中一个可以设为活动分区,引导记录从这个活动分区中来启动操作系统....
FLASH的结构
flash芯片的种类有好几类 一般有基于nor 和 nand
nor flash 有地址线 与数据线 这样存储在norflash里面的代码 可以直接在norflash中执行 而不需要拷贝到RAM中去 而nandflash 是没有地址线的 他有专门的控制接口与CPU相连 这样的话 要读取他里面的内容 就需要经过相关的时序控制,他里面的代码就要拷贝到RAM中才能执行,但即使这样他的速度也不慢 我们的SD卡等都是nandflash制作成的 因此要读取nandflash里面的内容 就还得需要nandflash的专门的驱动程序 来读取
nor flash 有可在芯片执行的特点 可是他的成本比nandflash贵 也就是容量比较大时 nandflash相对偏移很多
nandflash强调每bit的低存储成本
NOR和NAND是现在市场上两种主要的非易失闪存技术。Intel于1988年首先开发出NOR flash技术,彻底改变了原先由EPROM和EEPROM一统天下的局面。紧接着,1989年,东芝公司发表了NAND flash结构,强调降低每比特的成本,更高的性能,并且象磁盘一样可以通过接口轻松升级。
NOR的传输效率很高,在1~4MB的小容量时具有很高的成 本效益,但是很低的写入和擦除速度大大影响了它的性能。 NAND结构能提供极高的单元密度,可以达到高存储密度,并且写入和擦除的速度也很快。应用NAND的困难在于flash的管理需要特殊的系统接口。
flash闪存是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。任何flash器件的写入操作只能在空或已擦除的单元内进行,所以大多数 情况下,在进行写入操作之前必须先执行擦除。NAND器件执行擦除操作是十分简单的,而NOR则要求在进行擦除前先要将目标块内所有的位都写为0。由于擦除NOR器件时是以64~128KB的块进行的,执行一个写入/擦除操作的时间为5s,与此相反,擦除NAND器件是以8~32KB的块进行的,执行相同的操作最多只需要4ms。 执行擦除时块尺寸的不同进一步拉大了NOR和NADN之间的性能差距,统计表明,对于给定的一套写入操作(尤其是更新小文件时),更多的擦除操作必须在基于NOR的单元中进行。这样,当选择存储解决方案时,设计师必须权衡以下的各项因素。
l NOR的读速度比NAND稍快一些。
2 NAND的写入速度比NOR快很多。
3 NAND的4ms擦除速度远比NOR的5s快。
4 大多数写入操作需要先进行擦除操作。
5 NAND的擦除单元更小,相应的擦除电路更少。
nandflash 特别说明:
nandflash 的 位操作 只能从1变为0,所以在写之前需要将芯片进行檫除,使之全部变为1,因此也需要使用异地更新策略
nandflash 檫除以块(block)为单位 读写以页(page)为单位
nandflash 从结构上分:可以分为 小页 大页 FLASH
页是最小的可操作区域,页上面包含两个部分:数据(data)区 和 备份(spare)区
小页: 1page = 512bytes(datafield) + 16bytes(Spare Field) 我们算容量时 是不把备份区算入得
大页: 1page = 2k bytes(datafield) + 64bytes(Spare Field)
1 block = 32 page
spare field:作用是
用于在读写操作的时候存放校验码用的,一般不用做普通数据的存储区
,因为nandflash 有可能产生位反转 写干扰 读干扰 引入RCC校验码 这个校验码就存放在备份区中 保证数据的正确性
FLASH一般拥有与页容量相同的页寄存器 用于数据缓存,当读取数据时先从flash存储单元把数据读到页寄存器 外部通过访问flash IO端口输入获得页寄存器中的数据(地址自动累加) 但写数据时 外部通过flash io 端输入的数据首先缓存在页寄存器 在写命令发出后写入到存储器中
nandflash 每个block 檫写次数有限 SLC为10的6次方 次 MLC 为10的5次方 次,这样的话 就很有必要引入磨损控制机制,防止一直檫除同一个块 以使得每个块均匀檫写
NOR flash采用位读写,因为它具有sram的接口,有足够的引脚来寻址,可以很容易的存取其内部的每一个字节。 NAND flash使用复杂的I/O口来串行地存取数据。8个引脚用来传送控制、地址和数据信息(复用)。NAND的读和写单位为512Byte的页,擦写单位为32页的块。
● NOR的读速度比NAND稍快一些。
● NAND的写入速度比NOR快很多。
● NAND的4ms擦除速度远比NOR的5s快。
● 大多数写入操作需要先进行擦除操作。
● NAND的擦除单元更小,相应的擦除电路更少。
在NOR器件上运行代码不需要任何的软件支持,在NAND器件上进行同样操作时,通常需要驱动程序,也就是内存技术驱动程序(MTD),NAND和NOR器件在进行写入和擦除操作时都需要MTD。
再来看看Nand flash自身的特点(部分摘自August0703的文章):
Nand Flash的数据是以bit的方式保存在memory cell中,一般来说,一个cell 中只能存储一个bit。这些cell 以8个或者16个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device的位宽。 多个line(多个位宽大小的数据)会再组成Page。我使用的Nand flash是三星的K9F1208U0M,从datesheet上得知,此flash每页528Bytes(512byte的Main Area + 16byte的Spare Area),每32个page形成一个Block(32*528B)。具体一片flash上有多少个Block视需要所定。我所使用的k9f1208U0M具有4096个block,故总容量为4096*(32*528B)=66MB,但是其中的2MB(Spaer Area)是用来保存ECC校验码等额外数据的,故实际中可使用的为64MB。 Nand flash以页(512Byte)为单位读写数据,而以块(16KB)为单位擦除数据。按照这样的组织方式可以形成所谓的三类地址:
● Column Address:列地址,地址的低8位
● Page Address :页地址
● Block Address :块地址
/
nandflash 拥有与磁盘不同的物理特性,在对其进行读写时,需要使用不同的解决方案,以解决垃圾收集 磨损控制 ECC校验等问题
在linux 中 主要分为 :
1:在FTL上挂载普通磁盘文件 系统
2:在原生flash上使用日志 结构文件系统
FTL 层 与原生文件系统 在linux 内核中的整体结构(关系)如下
虚拟文件系统:VFS 是一个为用户空间提供文件系统相关接口的内核子系统,他主要的设计思想是在底层不同类型的文件系统之上建立一个统一的抽象接口,使用户可以不用关心实际的存储介质与具体部署的文件系统类型,直接使用open() read() write() 等系统调用,VFS提供一个unix风格的文件系统原型框架,该原型框架具有一般文件系统的功能和行为,通过定义基本的文件系统功能接口与数据结构,实际文件系统只需要编程这些抽象功能接口与数据结构 就可以完成VFS的抽象 VFS实际使用了面向对象的设计思想 在内核使用C代码的指针来完成面向对象的语义
VFS拥有四个主要的数据结构对象:
1:struct super_block 超级块结构对象 定义在<linux/fs.h>;
用于保存特定的文件系统的相关信息,对于磁盘文件系统,超级块结构对象一般存储于磁盘的特定扇区,对于非磁盘文件系统 将会现场创建特定的超级块并保存于内存中
2:struct inode 索引节点结构对象
定义在<linux/fs.h>;
索引节点结构对象 包含对特定文件的所有相关信息(如访问权限 大小 创建时间等)
3:struct dentry 目录项结构对象
定义在<linux/decache.h>
目录项结构对象 表示路径中的组成方式 用于加速路径名的查找 并不包括目录的相关信息(Linux中目录被看成一个普通文件)
4:struct file 文件对象
定义在<linux/fs.h>
用于记录文件对象 文件对象是从进程角度在内存中打开的文件表示 它与索引节点结构体对象与目录项对象不同 与文件并不是一一对应的关系
四种结构体对象都以结构体的形式定义了与其相关联的操作 分别是
1:超级块操作
struct super_operation
在超级块结构中成员变量名为s_op,用于保存特定文件系统的一些底层操作,包括对索引节点的分配释放 读写删除索引节点 释放重写超级块等
2:索引节点操作 struct inode_operation
在索引节点结中成员变量名为i_op 用于描述VFS操作索引节点的所有方法 包括在给定节点上创建移动文件 建立连接 创建删除目录等
3:目录项操作
struct dentry_operation
在目录项对象中成员变量为d_op 用于描述目录项的所有方法 包括判断目录对象的有效性 文件名比较等
4:文件操作
struct file_operation
在文件对象中成员变量名为f_op 是一些标准liunx系统调用的基础 包括read write ioctl 等函数的具体实现
我们可以来分析一个实例
linux 内核write() 系统调用最终转换为yaffs2文件系统所注册的write处理函数
1:用户进程要进行write操作 需要打开文件 并在内核中建立一个与文件相对应得struct file对象 以向文件写入数据
2:write()系统调用发起后 程序进入内核态 调用sys.write()处理函数 sys.write()函数检测文件对象中f_op 成员变量 并调用f_op 结构体中所实现的write()函数 这样应用程序中的write()系统调用就转换成了yaffs2文件系统注册的write()处理函数了
在yaffs2文件系统中 f_op ->write() 使用的是定义于filemap.c中的generic_file_write()函数
存储技术设备(MTD)
mtd( memory technology device )子系统为原生flash设备 (包括rom ram )提供一个统一的抽象的接口 将文件系统与原生的flash设备驱动剥离开来 使我们可以使用相同的应用接口 而不需去关心flask设备的种类(如nand ,onenand, nor, ad-and, eccd nor ... )
MTD子系统并不处理非原生FLASH设备(如 MMC eMMC SD CompactFlash等) 这些非原生的FLASH设备内置了FTL固件程序 可以看做磁盘设备 可以直接挂载到linux block 子系统而非MTD子系统
有了MTD后,LINUX系统中的Flash设备驱动从设备节点 到底层硬件驱动将分为4层 依次是:
1:设备节点
2:MTD设备层 3:MTD原始设备层
4:硬件驱动层
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/bfe7a7dab18481d33c61572f15e9491b.jpeg)
在linux2.6.32.2 中 已经自带了大部分nandflash驱动
在linux-2.6.32.2/drivers/mtd/nand/nand_ids.c这个文件中 里面定义了所支持的各种nandflash类型
在linux 2.6.32 中 nand驱动是被注册为平台设备
在linux统源代码树中 在linux2.6.32/arch/arm 这个文件夹中
目录plat-s3c24xx中
因此在这个目录外 有相应得开发板的具体的一些硬件结构信息
mach-s3c2440 这个目录 里面 的mach-mini2440.c中就定义了我们自己开发板上自己划分的适合的分区
static struct mtd_partition friendly_arm_default_nand_part[] = {
};
特别注意:对文件系统的分区大小要是nand页的大小的整数倍 否则会出现readonly错误 flash按页读取
//下面为开发板的nandflash设置表 因为板子上只有一片
static struct s3c2410_nand_set friendly_arm_nand_sets[] = {
};
//下面是nand flash 本身的一些特性 一般需要对照datasheet填写 大部分情况下按照以下参数填写即可
static struct s3c2410_platform_nand friendly_arm_nand_info = {
};
注意:
mini2440_nand_info需要注册到mini2440_map_io中。
static void __init mini2440_map_io(void)
{
}
//下面把nandflash这个设备注册到系统中
static struct platform_device *mini2440_devices[] __initdata = {
};
从这里可以看到各分区的地址 也可以自己修改
如果从nor 或者 nand 启动 就可以 将相应的内容下载到相应地址 启动 定好地址 就OK
分区还要注意:
//
启动代码是系统上电或者复位后运行的第一段代码 他的作用是在用户程序运行之前 对系统的硬件与软件运行环境进行必要的初始化 并在最后使程序跳转到用户程序 他直接面对ARM处理器内核以及硬件控制器进行编程
S3C2440 支持从 NOR flash 或者 NAND Flash中启动
NOR Flash 的特点是 程序可以直接在芯片内执行 不必将程序读取到RAM中运行 NOR FLASH虽有这个优点 但是它的性价比远低于NAND FLASH
NOR FLASH启动: NOR FLASH --》映射到 nGCD0 其地址被映射为0x00000000
NAND_FLASH启动:S3C2440内部自带一块容量为4K的bootSRAM(叫做起步阶石“Steppingstone”)映射到nGCS0 其地址被映射为0x00000000
但系统上电或启动后 程序会从0地址处开始执行 因此我们需要把启动代码放在0地址处
NOR FLASH启动:程序可以在FLASH芯片中 直接被CPU执行
NAND FLASH启动:上电或复位后 0地址处为bootSRAM 启动前他里面是空的 启动后S3C2440 先通过硬件机制将NANDFLASH的前4K内容拷贝他里面去
如果系统的所有程序 编译链接后大小小于4K 那么系统的启动代码中无需考虑将程序从NANDFLASH 搬运到SDRAM 中去执行这个问题
如果系统中所编的程序编译后大于4K 那么系统的启动代码中需要包含一段将系统的全部程序从NANDFLASH 搬运到SDRAM的代码
系统启动时 只将NANDFLASH 的前4K 拷贝到了BootSRAM中,还有部分程序保存在NAND FLASH中 是无法内执行的 所以前4K被拷贝到BootSRAM中需要有能将程序拷贝到SDRAM中的代码
因此从NAND FLASH中启动 牵涉到两次拷贝
1:nandflash前4K --> BootSAM 自动 无需人为干扰
2:从nandflash中搬运系统到SDRAM 需要程序员 控制
//
我们的开发板上有两种FLASH芯片 NorFlash(下面简称Nor)
我买的开发板上面的norflash型号是AM29LV160DB(AMD) 2M大小
/
硬盘 结构 容量 方面知识
硬盘的分类 一般有 SCSI IDE
一种硬盘的生产 同时伴随着一定的标准出现 生产技术升级伴随着生产标准升级
SCSI标准-->SCSI1 SCSI2 SCSI3 经常在服务器网站看到的Ultral-160就是基于SCSI-3标准的
IDE标准--> 遵循的是ATA标准
SATA-->ATA标准的升级 SATA是串口设备 SATA发展就是为了替换IDE
硬盘的物理结构是由盘 磁盘表面(heads 一般一个磁盘面就有一个读取磁盘的磁头 所以为heads)
柱面(cylinders) 扇区 组成 最外面的柱面为0柱面 柱面数目等于磁道的数目
硬盘体积换算公式是:heads X cylinders X 扇区个数 X 扇区大小512字节 = 磁盘体积(字节bytes)
其中硬盘在计算容量时
80000000 bytes = 80000 K = 80M (向大单位换算,每次除以1000)
硬盘分区情况
硬盘的分区是由主分区
硬盘分区的主分区(包括扩展分区)最多是4个,分区表最大就能划分出这么多的分区,在扩展分区中可以划分逻辑分区) ,其中一个可以设为活动分区,引导记录从这个活动分区中来启动操作系统....
[主|分区1] [主|分区2] [主|分区3] [扩展分区] |[逻辑|分区5] [逻辑|分区6] [逻辑|分区7] [逻辑|分区8] ... ...[主|分区1] [主|分区2] [扩展分区] | [逻辑|分区5] [逻辑|分区6] [逻辑|分区7] [逻辑|分区8] ... ...
[主|分区1] [扩展分区] |[逻辑|分区5] [逻辑|分区6] [逻辑|分区7] [逻辑|分区
FLASH的结构
flash芯片的种类有好几类 一般有基于nor 和 nand
nor flash 有地址线 与数据线 这样存储在norflash里面的代码 可以直接在norflash中执行 而不需要拷贝到RAM中去 而nandflash 是没有地址线的 他有专门的控制接口与CPU相连 这样的话 要读取他里面的内容 就需要经过相关的时序控制,他里面的代码就要拷贝到RAM中才能执行,但即使这样他的速度也不慢 我们的SD卡等都是nandflash制作成的 因此要读取nandflash里面的内容 就还得需要nandflash的专门的驱动程序 来读取
nor flash 有可在芯片执行的特点 可是他的成本比nandflash贵 也就是容量比较大时 nandflash相对偏移很多
nandflash强调每bit的低存储成本
NOR和NAND是现在市场上两种主要的非易失闪存技术。Intel于1988年首先开发出NOR flash技术,彻底改变了原先由EPROM和EEPROM一统天下的局面。紧接着,1989年,东芝公司发表了NAND flash结构,强调降低每比特的成本,更高的性能,并且象磁盘一样可以通过接口轻松升级。
NOR的传输效率很高,在1~4MB的小容量时具有很高的成 本效益,但是很低的写入和擦除速度大大影响了它的性能。 NAND结构能提供极高的单元密度,可以达到高存储密度,并且写入和擦除的速度也很快。应用NAND的困难在于flash的管理需要特殊的系统接口。
flash闪存是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。任何flash器件的写入操作只能在空或已擦除的单元内进行,所以大多数 情况下,在进行写入操作之前必须先执行擦除。NAND器件执行擦除操作是十分简单的,而NOR则要求在进行擦除前先要将目标块内所有的位都写为0。由于擦除NOR器件时是以64~128KB的块进行的,执行一个写入/擦除操作的时间为5s,与此相反,擦除NAND器件是以8~32KB的块进行的,执行相同的操作最多只需要4ms。 执行擦除时块尺寸的不同进一步拉大了NOR和NADN之间的性能差距,统计表明,对于给定的一套写入操作(尤其是更新小文件时),更多的擦除操作必须在基于NOR的单元中进行。这样,当选择存储解决方案时,设计师必须权衡以下的各项因素。
l NOR的读速度比NAND稍快一些。
2 NAND的写入速度比NOR快很多。
3 NAND的4ms擦除速度远比NOR的5s快。
4 大多数写入操作需要先进行擦除操作。
5 NAND的擦除单元更小,相应的擦除电路更少。
接口差别
NOR flash带有SRAM接口,有足够的地址引脚来寻址,可以很容易地存取其内部的每一个字节。 NAND器件使用复杂的I/O口来串行地存取数据,各个产品或厂商的方法可能各不相同。8个引脚用来传送控制、地址和数据信息。 NAND读和写操作采用512字节的块,这一点有点像硬盘管理此类操作,很自然地,基于NAND的存储器就可以取代硬盘或其他块设备。容量和成本
NAND flash的单元尺寸几乎是NOR器件的一半,由于生产过程更为简单,NAND结构可以在给定的模具尺寸内提供更高的容量,也就相应地降低了价格。 NOR flash占据了容量为1~16MB闪存市场的大部分,而NAND flash只是用在8~128MB的产品当中,这也说明NOR主要应用在代码存储介质中,NAND适合于数据存储,NAND在CompactFlash、 Secure Digital、PC Cards和MMC(多媒体存储卡Multi Media Card)存储卡市场上所占份额最大。可靠性和耐用性
采用flash介质时一个需要重点考虑的问题是可靠性。对于需要扩展MTBF(平均故障间隔时间Mean Time Between Failures)的系统来说,Flash是非常合适的存储方案。可以从寿命(耐用性)、位交换和坏块处理三个方面来比较NOR和NAND的可靠性。 寿命(耐用性) 在NAND闪存中每个块的最大擦写次数是一百万次,而NOR的擦写次数是十万次。NAND存储器除了具有10比1的块擦除周期优势,典型的NAND块尺寸要比NOR器件小8倍,每个NAND存储器块在给定的时间内的删除次数要少一些位交换
所有flash器件都受位交换现象的困扰。在某些情况下(很少见,NAND发生的次数要比NOR多),一个比特位会发生反转或被报告反转了。 一位的变化可能不很明显,但是如果发生在一个关键文件上,这个小小的故障可能导致系统停机。如果只是报告有问题,多读几次就可能解决了。 当然,如果这个位真的改变了,就必须采用错误探测/错误更正(EDC/ECC)算法。位反转的问题更多见于NAND闪存,NAND的供应商建议使用NAND闪存的时候,同时使用EDC/ECC算法。 这个问题对于用NAND存储多媒体信息时倒不是致命的。当然,如果用本地存储设备来存储操作系统、配置文件或其他敏感信息时,必须使用EDC/ECC系统以确保可靠性。坏块处理
NAND器件中的坏块是随机分布的。以前也曾有过消除坏块的努力,但发现成品率太低,代价太高,根本不划算。 NAND器件需要对介质进行初始化扫描以发现坏块,并将坏块标记为不可用。在已制成的器件中,如果通过可靠的方法不能进行这项处理,将导致高故障率。易于使用
可以非常直接地使用基于NOR的闪存,可以像其他存储器那样连接,并可以在上面直接运行代码。 由于需要I/O接口,NAND要复杂得多。各种NAND器件的存取方法因厂家而异。 在使用NAND器件时,必须先写入驱动程序,才能继续执行其他操作。向NAND器件写入信息需要相当的技巧,因为设计师绝不能向坏块写入,这就意味着在NAND器件上自始至终都必须进行虚拟映射。软件支持
当讨论软件支持的时候,应该区别基本的读/写/擦操作和高一级的用于磁盘仿真和闪存管理算法的软件,包括性能优化。 在NOR器件上运行代码不需要任何的软件支持,在NAND器件上进行同样操作时,通常需要驱动程序,也就是内存技术驱动程序(MTD),NAND和NOR器件在进行写入和擦除操作时都需要MTD(Memory Technology Devices)。 使用NOR器件时所需要的MTD要相对少一些,许多厂商都提供用于NOR器件的更高级软件,这 其中包括M-System的TrueFFS驱动,该驱动被Wind River System、Microsoft、QNX Software System、Symbian和Intel等厂商所采用。 驱动还用于对DiskOnChip产品进行仿真和NAND闪存的管理,包括纠错、坏块处理和损耗平衡nandflash 特别说明:
nandflash 的 位操作 只能从1变为0,所以在写之前需要将芯片进行檫除,使之全部变为1,因此也需要使用异地更新策略
nandflash 檫除以块(block)为单位 读写以页(page)为单位
nandflash 从结构上分:可以分为 小页 大页 FLASH
页是最小的可操作区域,页上面包含两个部分:数据(data)区 和 备份(spare)区
小页: 1page = 512bytes(datafield) + 16bytes(Spare Field) 我们算容量时 是不把备份区算入得
大页: 1page = 2k bytes(datafield) + 64bytes(Spare Field)
1 block = 32 page
FLASH一般拥有与页容量相同的页寄存器 用于数据缓存,当读取数据时先从flash存储单元把数据读到页寄存器 外部通过访问flash IO端口输入获得页寄存器中的数据(地址自动累加) 但写数据时 外部通过flash io 端输入的数据首先缓存在页寄存器 在写命令发出后写入到存储器中
nandflash 每个block 檫写次数有限 SLC为10的6次方 次 MLC 为10的5次方 次,这样的话 就很有必要引入磨损控制机制,防止一直檫除同一个块 以使得每个块均匀檫写
读命令有两个,分别是 Read1,Read2其中Read1用于读取Data Field的数据,而Read2则是用于读取Spare Field的数据。对于Nand Flash来说,读操作的最小操作单位为Page,也就是说当我们给定了读取的起始位置后,读操作将从该位置开始,连续读取到本Page的最后一个 Byte为止(可以包括Spare Field)
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/9d095aaad8d3302d5a02ca2cc10b6b40.jpeg)
NOR flash采用位读写,因为它具有sram的接口,有足够的引脚来寻址,可以很容易的存取其内部的每一个字节。 NAND flash使用复杂的I/O口来串行地存取数据。8个引脚用来传送控制、地址和数据信息(复用)。NAND的读和写单位为512Byte的页,擦写单位为32页的块。
● NOR的读速度比NAND稍快一些。
● NAND的写入速度比NOR快很多。
● NAND的4ms擦除速度远比NOR的5s快。
● 大多数写入操作需要先进行擦除操作。
● NAND的擦除单元更小,相应的擦除电路更少。
再来看看Nand flash自身的特点(部分摘自August0703的文章):
Nand Flash的数据是以bit的方式保存在memory cell中,一般来说,一个cell 中只能存储一个bit。这些cell 以8个或者16个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device的位宽。 多个line(多个位宽大小的数据)会再组成Page。我使用的Nand flash是三星的K9F1208U0M,从datesheet上得知,此flash每页528Bytes(512byte的Main Area + 16byte的Spare Area),每32个page形成一个Block(32*528B)。具体一片flash上有多少个Block视需要所定。我所使用的k9f1208U0M具有4096个block,故总容量为4096*(32*528B)=66MB,但是其中的2MB(Spaer Area)是用来保存ECC校验码等额外数据的,故实际中可使用的为64MB。 Nand flash以页(512Byte)为单位读写数据,而以块(16KB)为单位擦除数据。按照这样的组织方式可以形成所谓的三类地址:
● Column Address:列地址,地址的低8位
● Page Address :页地址
● Block Address :块地址
512bytes理论上被分为1st half 和2sd half,每个half各占256个字节。528个字节按顺序由上而下以列为单位进行排列(1列代表一个Byte。第0行为第0 Byte ,第1行为第1 Byte,以此类推,每个行又由8个位组成,每个位表示1个Byte里面的1bit。
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/4d65e3af2037826aa30350d33aa21ade.jpeg)
/
nandflash 拥有与磁盘不同的物理特性,在对其进行读写时,需要使用不同的解决方案,以解决垃圾收集 磨损控制 ECC校验等问题
在linux 中 主要分为 :
1:在FTL上挂载普通磁盘文件 系统
2:在原生flash上使用日志 结构文件系统
FTL 层 与原生文件系统 在linux 内核中的整体结构(关系)如下
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/75b75f47b416b8c3d65caa3b89c1cb10.jpeg)
虚拟文件系统:VFS 是一个为用户空间提供文件系统相关接口的内核子系统,他主要的设计思想是在底层不同类型的文件系统之上建立一个统一的抽象接口,使用户可以不用关心实际的存储介质与具体部署的文件系统类型,直接使用open() read() write() 等系统调用,VFS提供一个unix风格的文件系统原型框架,该原型框架具有一般文件系统的功能和行为,通过定义基本的文件系统功能接口与数据结构,实际文件系统只需要编程这些抽象功能接口与数据结构 就可以完成VFS的抽象 VFS实际使用了面向对象的设计思想 在内核使用C代码的指针来完成面向对象的语义
VFS拥有四个主要的数据结构对象:
1:struct super_block 超级块结构对象 定义在<linux/fs.h>;
2:struct inode 索引节点结构对象
3:struct dentry 目录项结构对象
4:struct file 文件对象
四种结构体对象都以结构体的形式定义了与其相关联的操作 分别是
1:超级块操作
2:索引节点操作 struct inode_operation
3:目录项操作
4:文件操作
我们可以来分析一个实例
linux 内核write() 系统调用最终转换为yaffs2文件系统所注册的write处理函数
1:用户进程要进行write操作 需要打开文件 并在内核中建立一个与文件相对应得struct file对象 以向文件写入数据
2:write()系统调用发起后 程序进入内核态 调用sys.write()处理函数 sys.write()函数检测文件对象中f_op 成员变量 并调用f_op 结构体中所实现的write()函数 这样应用程序中的write()系统调用就转换成了yaffs2文件系统注册的write()处理函数了
在yaffs2文件系统中 f_op ->write() 使用的是定义于filemap.c中的generic_file_write()函数
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/10df7e125daa6d85101dee351f2bf6ea.jpeg)
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/5f6a2e30d359056576b6a53a20ab8b18.jpeg)
存储技术设备(MTD)
mtd( memory technology device )子系统为原生flash设备 (包括rom ram )提供一个统一的抽象的接口 将文件系统与原生的flash设备驱动剥离开来 使我们可以使用相同的应用接口 而不需去关心flask设备的种类(如nand ,onenand, nor, ad-and, eccd nor ... )
MTD子系统并不处理非原生FLASH设备(如 MMC eMMC SD CompactFlash等) 这些非原生的FLASH设备内置了FTL固件程序 可以看做磁盘设备 可以直接挂载到linux block 子系统而非MTD子系统
有了MTD后,LINUX系统中的Flash设备驱动从设备节点 到底层硬件驱动将分为4层 依次是:
1:设备节点
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/c8e786fcea1f7fa6a38daca7bc5d3805.jpeg)
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/6bf595d837e89f35bf6d401269a19421.jpeg)
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/c34e1fbbeb5dcfe0d00b4fa79c8d0240.jpeg)
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/7ecfc1058f8958ac3443860cb56da05d.jpeg)
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/9a10fa4e5f707de56f20f9a2864f7446.jpeg)
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/9193d2652e9a0e12f8e6630a078a95cf.jpeg)
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/d164cbe5669b5ad178225b4b03915237.jpeg)
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/f6c2ca866bdbfd19638a6f606576a49f.jpeg)
![S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构 S3C2440 <wbr>flash <wbr>分区 <wbr>nor <wbr>nand <wbr>FLASH区别(开发板启动时) <wbr>及 <wbr>结构](https://i-blog.csdnimg.cn/blog_migrate/d063640f34caa3e17a89f36e8547ac1d.jpeg)