linux驱动之nand flash

1、 Nand Flash一些名词的解释

1.1 (Bad) Block Management(坏)块管理

Nand Flash由于其物理特性,只有有限的擦写次数,超过那个次数,基本上就是坏了。在使用过程中,有些Nand Flash的block会出现被用坏了,当发现了,要及时将此block标注为坏块,不再使用。

于此相关的管理工作,属于Nand Flash的坏块管理的一部分工作。

1.2 Wear-Leveling负载平衡

Nand Flash的block的管理,还包括负载平衡。

正是由于Nand Flash的block,都是有一定寿命限制的,所以如果你每次都往同一个block擦除然后写入数据,那么那个block就很容易被用坏了,所以我们要去管理一下,将这么多次的对同一个block的操作,平均分布到其他一些block上面,使得在block的使用上,相对较平均,这样相对来说,可以更能充分利用Nand Flash。

关于wear-leveling这个词,再简单解释一下,wear就是穿(衣服)等,用(东西)导致磨损,而leveling就是使得均衡,所以放在一起就是,使得对于Nand Flash的那么多的block的使用磨损,相对均衡一些,以此延长Nand Flash的使用寿命或者说更加充分利用Nand Flash。

1.3 ECC错误校验码

Nand Flash物理特性上使得其数据读写过程中会发生一定几率的错误,所以要有个对应的错误检测和纠正的机制,于是才有此ECC,用于数据错误的检测与纠正。Nand Flash的ECC,常见的算法有海明码和BCH,这类算法的实现,可以是软件也可以是硬件。不同系统,根据自己的需求,采用对应的软件或者是硬件。

相对来说,硬件实现这类ECC算法,肯定要比软件速度要快,但是多加了对应的硬件部分,所以成本相对要高些。如果系统对于性能要求不是很高,那么可以采用软件实现这类ECC算法,但是由于增加了数据读取和写入前后要做的数据错误检测和纠错,所以性能相对要降低一些,即Nand Flash的读取和写入速度相对会有所影响。

其中,Linux中的软件实现ECC算法,即NAND_ECC_SOFT模式,就是用的对应的海明码。

而对于目前常见的MLC的Nand Flash来说,由于容量比较大,动辄2GB,4GB,8GB等,常用BCH算法。BCH算法,相对来说,算法比较复杂。

2、Nand flash硬件特性

2.1什么是Nand flash

nand flash是flash的一种,Flash全名叫做Flash Memory,从名字就能看出,是种数据存储设备,存储设备有很多类,Flash属于非易失性存储设备(Non-volatile Memory Device),与此相对应的是易失性存储设备(Volatile Memory Device)。关于什么是非易失性/易失性,从名字中就可以看出,非易失性就是不容易丢失,数据存储在这类设备中,即使断电了,也不会丢失,这类设备,除了Flash,还有其他比较常见的入硬盘,ROM等,与此相对的,易失性就是断电了,数据就丢失了,比如大家常用的内存,不论是以前的SDRAM,DDR SDRAM,还是现在的DDR2,DDR3等,都是断电后,数据就没了。

Nand flash成本相对低,说白了就是便宜,缺点是使用中数据读写容易出错,所以一般都需要有对应的软件或者硬件的数据校验算法,统称为ECC。但优点是,相对来说容量比较大,现在常见的Nand Flash都是1GB,2GB,更大的8GB的都有了,相对来说,价格便宜,因此适合用来存储大量的数据。其在嵌入式系统中的作用,相当于PC上的硬盘,用于存储大量数据。

2.2 Nand Flash数据存储单元的整体架构

简单说就是,常见的Nand Flash,内部只有一个chip,每个chip只有一个plane。

而有些复杂的,容量更大的Nand Flash,内部有多个chip,每个chip有多个plane。这类的Nand Flash,往往也有更加高级的功能,比如下面要介绍的Multi Plane Program和Interleave Page Program等。

概念上,由大到小来说,就是:

Nand Flash ⇒ Chip ⇒ Plane ⇒ Block ⇒ Page ⇒ oob

用图表来表示,更加易懂,如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mmtwtZSs-1624957150343)(file:///C:\Users\202007~1\AppData\Local\Temp\msohtmlclip1\01\clip_image002.jpg)]

2.3 擦除/写入特性

由于Flash的物理特性,使得内部存储的数据,只能从1变成0,对于最初始值,都是1,所以是0xFFFFFFFF,而数据的写入,即是将对应的变成0,而将数据擦除掉,就是统一地,以block为单位,全部一起充电,所有位,都变成初始的1,而不是像普通存储设备那样,每一个位去擦除为0。而数据的写入,就是电荷放电的过程,代表的数据也从1变为了0。所以,总结一下Flash的特殊性如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cqqCljEW-1624957150345)(file:///C:\Users\202007~1\AppData\Local\Temp\msohtmlclip1\01\clip_image004.jpg)]

2.4位反转特性

所谓的位反转,bit flip,指的是原先Nand Flash中的某个位,变化了,即要么从1变成0了,要么从0变成1了。

对应的位反转的类型,有两种:

(1) 第一种是Nand flash物理上的数据存储的单元上的数据,是正确的,只是在读取此数据出来的数据中的某位,发生变化,出现了位反转,即读取出来的数据中,某位错了,本来是0变成1,或者本来是1变成0了。此处可以称为软件上位反转。此数据位的错误,当然可以通过一定的校验算法检测并纠正;

(2) Nand flash中的物理存储单元中,对应的某个位,物理上发生了变化,原来是1的,变成了0,或原来是0的,变成了1,发生了物理上的位的数据变化。此处可以称为硬件上的位反转。

2.5坏块管理

对于坏块的管理,在Linux系统中,叫做坏块管理(BBM,Bad Block Management),对应的会有一个表去记录好块,坏块的信息,以及坏块是出厂就有的,还是后来使用产生的,这个表叫做坏块表(BBT,Bad Block Table),在加载完驱动之后,如果你没有加入参数主动要求跳过坏块扫描的话,那么都会去主动扫描坏块,建立必要的BBT的,以备后面坏块管理所使用。

3、Linux MTD体系下的nand flash驱动

3.1 MTD概述

MTD(memory technology device)是用于访问memory设备(比如NOR Flash、NAND Flash)的Linux的子系统。MTD将 Nand Flash,nor flash 和其他类型的 flash 等设备,统一抽象成MTD 设备来管理,根据这些设备的特点,上层实现了常见的操作函数封装,而底层具体的内部实现(具体的内部硬件设备的读/写/擦除函数),就需要驱动设计者自己来实现了。

MTD的主要目的是为了使新的存储设备的驱动更加简单并有通用接口函数可用。MTD将文件系统与底层的Flash存储器进行了隔离,使Flash驱动工程师无须关心Flash作为字符设备和块设备与Linux内核的接口。MTD的所有源代码在/kerne/drivers/mtd子目录下。

MTD子系统的层次框图如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zz5zzTji-1624957150346)(file:///C:\Users\202007~1\AppData\Local\Temp\msohtmlclip1\01\clip_image006.jpg)]

3.2 Linux MTD系统层次

通过上图可以再一步凝结成更加简单的系统层次图,如下图:在引入MTD后,Linux系统中的flash设备驱动及接口可以分成4层:设备节点、MTD设备层、MTD原始层和硬件驱动。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IF22cZ2P-1624957150348)(file:///C:\Users\202007~1\AppData\Local\Temp\msohtmlclip1\01\clip_image008.png)]
设备节点:

通过mknod在dev子目录下建立MTD字符设备节点(90)和MTD块设备节点(31)。

设备层:

字符设备的定义在mtdchar.c文件中实现,通过注册一系列file_opreation函数可实现对MTD设备的读写和控制。MTD块设备则是定义了一个描述MTD块设备的结构体mtd_dev,并声明了一个名为mtdblks的指针数组,该数组中的每一个mtd_dev都与mtd_info一一对应。

原始设备层:

MTD原始设备层的通用代码(mtdpart.c)。其中mtdcore.c中定义了描述mtd设备的核心结构mtdinfo。

硬件驱动层:

负责flash硬件设备的读、写、擦除,Linux MTD设备的NAND型flash的驱动代码位于/kerne/drivers/mtd/nand子目录下。

了解了上面的知识,我们就可以了解下他们各个层的接口关系,这样我们能更好的熟悉代码,和他们之间的接口调用关系,接口图如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JD87uD4t-1624957150350)(file:///C:\Users\202007~1\AppData\Local\Temp\msohtmlclip1\01\clip_image010.jpg)]

3.3 一些重要c文件以及结构体介绍

3.3.1 涉及nand flash的重要c文件

1)nand_base.c

定义了NAND 驱动中对NAND 芯片最基本的操作函数和操作流程,如擦除、读写page 、读写oob 等。当然这些函数都只是进行一些default 的操作,若你的系统在对NAND 操作时有一些特殊的动作,则需要在你自己的驱动代码中进行定义,然后Replace 这些default 的函数。

2)nand_bbt.c

定义了NAND 驱动中与坏块管理有关的函数和结构体。

3)nand_ids.c

定义了两个全局类型的结构体:struct nand_flash_dev nand_flash_ids[ ] 和struct nand_manufacturers nand_manuf_ids[ ] 。其中前者定义了一些NAND 芯片的类型,后者定义了NAND 芯片的几个厂商。NAND 芯片的ID 至少包含两项内容:厂商ID 和厂商为自己的NAND 芯片定义的芯片ID 。当NAND 驱动被加载的时候,它会去读取具体NAND 芯片的ID ,然后根据读取的内容到上述定义的nand_manuf_ids[ ] 和nand_flash_ids[ ] 两个结构体中去查找,以此判断该NAND 芯片是那个厂商的产品,以及该NAND 芯片的类型。若查找不到,则NAND 驱动就会加载失败,因此在开发NAND 驱动前必须事先将你的NAND 芯片添加到这两个结构体中去(其实这两个结构体中已经定义了市场上绝大多数的NAND 芯片,所以除非你的NAND 芯片实在比较特殊,否则一般不需要额外添加)。

值得一提的是,nand_flash_ids[ ] 中有三项属性比较重要,即pagesize 、chipsize 和erasesize ,驱动就是依据这三项属性来决定对NAND 芯片进行擦除,读写等操作时的大小的。其中pagesize 即NAND 芯片的页大小,一般为256 、512 或2048 ;chipsize 即NAND 芯片的容量;erasesize 即每次擦除操作的大小,通常就是NAND 芯片的block 大小。

4)nand_ecc.c

定义了NAND 驱动中与softeware ECC 有关的函数和结构体,若你的系统支持hardware ECC ,且不需要software ECC ,则该文件也不需理会。

5)nandsim.c

定义了Nokia 开发的模拟NAND 设备,默认是Toshiba NAND 8MiB 1,8V 8-bit (根据ManufactureID ),开发普通NAND 驱动时不用理会。

6)diskonechip.c

定义了片上磁盘(DOC) 相关的一些函数,开发普通NAND 驱动时不用理会。

3.3.2 MTD下NAND所涉及的几个重要的结构体

1)mtd_info数据结构。(重要的的结构体之一)

mtd_info结构是MTD原始设备层的一个重要结构,表示MTD原始设备的结构,该结构定义了大量的关于MTD的数据和操作,定义在include/linux/mtd/mtd.h头文件。mtd_info结构成员主要由数据成员和操作函数两部分组成。

每个分区也被实现为一个mtd_info,如果有两个MTD原始设备,每个上有三个分区,在系统中就一共有6个mtd_info结构,这些mtd_info的指针被存放在名为mtd_table的数组里.

要强调的是:包含的这些函数指针指向的函数是MTD驱动提供的接口函数(每一个驱动程序的最终目的就是提供一些接口函数实现对底层硬件设备的操作),这些函数是在整个MTD驱动框架中层次最高的函数,他们可以在应用程序中直接调用实现对MTD设备底层硬件的操作。如:static int nand_read_ecc ()。它实现了对NAND flash的读操作。

struct mtd_info {
   

 u_char type;     
 //内存技术类型,例如MTD_RAM,MTD_ROM,MTD_NORFLASH,MTD_NAND_FLASH等  

 u_int32_t flags;   
//标志位,MTD设备的性能描述

 u_int32_t size;
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值