NAND FLASH学习笔记之MTD下nand flash驱动(二)

linux驱动之nand flash 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的管理,还包括 阅读详情

在这里补充这一片是为了更好的理解上一篇,补充的内容包括:MTD下NAND的布局中几个重要文件的诠释和MTD涉及的几个重要的结构体(更好的理解接口)


一、内核中的NAND代码布局

在Linux 内核中,MTD 源代码放在/driver/mtd 目录中,该目录中包含chips 、devices 、maps 、nand 、onenand 和ubi 六个子目录。其中只有nand 和onenand 目录中的代码才与NAND 驱动相关,不过nand 目录中的代码比较通用,而onenand 目录中的代码相对于nand 中的代码而言则简化了很多,它是针对三星公司开发的另一类Flash芯片。


      本次报告是基于MTD 的NAND 驱动程序,我们需要关注的代码就基本上全在drivers/mtd/nand 目录中了,而该目录中也不是所有的代码文件都与我们将要开发的NAND 驱动有关,除了Makefile 和Kconfig 之外,其中真正与NAND 驱动有关的代码文件只有6 个,即:


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)diskonchip.c :

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

除 了上述六个文件之外,nand 目录中其他文件基本都是特定系统的NAND 驱动程序例子,但看来真正有参考价值的还有cafe_nand.c 和jz4780_nand.c 两个,而其中又尤以cafe_nand.c 更为详细,另外,nand 目录中也似乎只有cafe_nand.c 中的驱动程序在读写NAND 芯片时用到了DMA 操作。

 芯片级驱动需要实现nand_chip结构体 

MTD使用nand_chip来表示一个NAND FLASH芯片, 该结构体包含了关于Nand Flash的地址信息,读写方法,ECC模式,硬件控制等一系列底层机制。

二、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的读操作。这些函数一般是都在u-boot源码目录下的driver/nand/nand_base.c中实现的通用操作函数。MTD驱动保证这些通用的操作函数支持对各种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;
//MTD设备的大小 
 u_int32_t erasesize;
 //最小的擦除块大小
 u_int32_t writesize; 
//编程大小
 u_int32_t oobsize;
   //oob(Out of band)块大小
 u_int32_t ecctype;
//ECC校验类型
 u_int32_t eccsize;
#define MTD_PROGREGION_CTRLMODE_VALID(mtd) (mtd)->oobsize
#define MTD_PROGREGION_CTRLMODE_INVALID(mtd) (mtd)->ecctype
 char *name;
 int index;
 struct nand_ecclayout *ecclayout;
 //eec布局结构 
 int numeraseregions;
 //擦除区域个数,通常为1  
 struct mtd_erase_region_info *eraseregions;
 //擦除区域的区域信息地址 
 u_int32_t bank_size;
 int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
//函数指针,erase函数的功能是将一个erase_info加入擦除队列
 int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
//point函数功能是允许片内执行(XIP) 
 void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len);
//unpoint函数与point函数相反,是禁止片内执行(XIP)  
 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
//MTD设备的读写函数  
 int (*read_oob) (struct mtd_info *mtd, loff_t from,
 struct mtd_oob_ops *ops);
 int (*write_oob) (struct mtd_info *mtd, loff_t to,
 struct mtd_oob_ops *ops);
//用于MTD设备的OBB数据读写  
 int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
 int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
 int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
 int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
 int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
//访问保护寄存器区
 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
//基于kevc的读写方法
 void (*sync) (struct mtd_info *mtd);
 //MTD设备的同步函数  
 int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len);
 int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len);   
//芯片的加锁和解锁 
 int (*suspend) (struct mtd_info *mtd);
void (*resume) (struct mtd_info *mtd);
  //支持电源管理函数  
 int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
 int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
  //坏块管理函数 
 struct notifier_block reboot_notifier;
 struct mtd_ecc_stats ecc_stats;  //ECC状态信息  
 void *priv;
  //私有数据指针  ,这个指针指向MTD驱动中另一个重要的数据结构struct nand_chip
 struct module *owner;
 int usecount;
};
2、mtd_part结构体信息
mtd_part(mtd_part.c)是用于表示 MTD 原始设备分区的结构,其中包含了 mtd_info,因为每一个分区都是被看成一个MTD 原始设备加在 mtd_table 中的,mtd_part.mtd_info中的大部分数据都从该分区的主分区 mtd_part->master中获得。
static LIST_HEAD(mtd_partitions);
  //分区链表
/* Our partition node structure */  
//分区结构信息  
struct mtd_part {
        struct mtd_info mtd; //mtd_info数据结构体,加入到mtd_table中
        struct mtd_info *master;//该分区的主分区
        uint64_t offset;//该分区的偏移量
        struct list_head list;
};


3、mtd_notifier结构体
mtd_notifier:MTD通知器,加入/删除MTD设备和原始设备时调用的函数,在设备层,当MTD字符设备或块设备注册时,如果定义了CONFIG_DEVFS_FS,则会将一个mtd_notifier加入MTD原始设备层的mtd_notifiers链表,其中的函数会在两种情况下被调用,一是加入/删除新的MTD字符/块设备时,此时调用该MTD字符/块设备的notifier对下层所有的MTD原始设备操作一遍,二是加入/删除新的MTD原始设备时,此时调用所有的notifier对该原始设备执行一遍。
//MTD设备通知结构体 
struct mtd_notifier {
 void (*add)(struct mtd_info *mtd);
//加入MTD原始/字符/块设备时执行  
 void (*remove)(struct mtd_info *mtd);
//移除MTD原始/字符/块设备时执行
 struct list_head list;
//list是双向链表,定义在include/linux/list.h  
};
4、mtd_fops 结构体
在/drivers/mtdchar.c 字符型mtd设备中:
字符设备中定义了mtd_fops字符类的文件指针操作函数,完成字符设备读、写、打开、关闭等功能。
static const struct file_operations mtd_fops = {
        .owner          = THIS_MODULE,
        .llseek         = mtdchar_lseek,
        .read           = mtdchar_read,
        .write          = mtdchar_write,
        .unlocked_ioctl = mtdchar_unlocked_ioctl,
#ifdef CONFIG_COMPAT
        .compat_ioctl   = mtdchar_compat_ioctl,
#endif
        .open           = mtdchar_open,
        .release        = mtdchar_close,
        .mmap           = mtdchar_mmap,
#ifndef CONFIG_MMU
        .get_unmapped_area = mtdchar_get_unmapped_area,
#endif
};
5、mtd_table
mtd_table(mtdcore.c)则是所有 MTD 原始设备的列表
struct mtd_info *mtd_table[MAX_MTD_DEVICES];
最多可以有MAX_MTD_DEVICES(默认定义为16)个设备,每个MTD 分区也算一个MTD 设备。

add_mtd_device添加MTD原始设备到mtd_table中
del_mtd_device从mtd_table中删除MTD原始设备
上面两个函数是底层驱动(nand flash)用来添加/删除其设置好的mtd_info结构。

6、nand_chip(重要结构体之二)
 这个数据结构从结构名nand_chip就可以知道它主要针对MTD设备中NAND flash的描述。在这个数据结构中包含了许多参数和函数指针。其中的成员大致可以分为以下几类:
1、 与芯片有关的参数
如:page_shift、phys_erase_shift、bbt_erase_shift、chip_shift、chipsize、numchips
  2、与坏块管理、ECC校验及oob区管理有关的参数:
如:eccmode、eccsize、eccbyte、eccsteps、calculate_ecc、oob_buf、oobdirty、autooob、bbt、badblockpos、bbt_td、bbt_md、badblock_pattern
   3、与NAND flash控制器寄存器操作有关的参数
 如:IO_ADDR_R、IO_ADDR_W
   4、与NAND flash控制器寄存器操作有关的函数指
如:read_byte、write_byte、read_word、write_word、hwcontrol、dev_ready、cmdfunc、select_chip
   5、与NAND flash操作功能有关的函数指针
如:write_buf、read_buf、verify_buf、waitfunc、erase_cmd
   6、与坏块管理、ECC校验及oob区管理有关的函数指针:
如:block_bad、block_markbad、calculate_ecc、correct_data、enable_hwecc、scan_bbt
综上,nand_chip主要包括了MTD驱动的低层和底层硬件操作函数的函数指针以及坏块管理、ECC校验和oob区管理需要相关函数的函数指针,这些指针指向的函数一部分在源码目录下的driver/nand/nand_base.c定义为通用函数,一部分需要用户在移植时自行编写。那些需要用户自行编写在后续的分析将会提到。nand_chip还包括了一些参数,这些参数与具体芯片型号及坏块管理策略有关,它们会在nand_scan()函数中被初始化。
struct nand_chip的结构声明
它在include/linux/mtd/nand.h中被声明定义,去掉一些编译选项、无关成员及原有注释,添加一些注释后如下;
struct nand_chip {
void  __iomem *IO_ADDR_R;  //NAND flash控制器的寄存器读访问指针,
void  __iomem *IO_ADDR_W;  //NAND flash控制器的寄存器写访问指针,
u_char (*read_byte)(struct mtd_info *mtd); 
//写一字节到NAND flash控制器的寄存器函数的函数指针
void (*write_byte)(struct mtd_info *mtd, u_char byte); 
//从NAND flash控制器的寄存器读一字节函数的函数指针
u16 (*read_word)(struct mtd_info *mtd);  //读字函数指针
void (*write_word)(struct mtd_info *mtd, u16 word); //写字函数指针
    //读写缓冲区函数指针,所谓缓冲区无非就是自行定义的一个数组
void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);
void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
//缓存校验韩式指针,验证从Flash中读取的内容是否与缓存中一致
void (*select_chip)(struct mtd_info *mtd, int chip);
   //芯片片选函数指针,由于涉及底层寄存器操作该函数在移植时一般要自己编写
int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
    //读取坏块标记函数指针
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
   //标记坏块函数指针
void (*hwcontrol)(struct mtd_info *mtd, int cmd);
   //寄存器访问控制函数指针,该函数根据第二个参数cmd使O_ADDR_R/W指向不同的寄存器
int (*dev_ready)(struct mtd_info *mtd);
 //设备状态读取函数指针,该函数读取NAND flash控制器的NFSTAT的bit0,获取R/B状态
void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
//向NAND flash写一个命令字,如果形参column、page_addr不都为-1则还向NAND flash写一个地址
int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);
//操作超时处理函数指针,该函数根据命令的不同设定不同的超时时间并时刻检查R/B位直到R/B状态进入Ready状态否则为操作超时。
int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
   //ECC编码计算函数指针,该函数通过软件算法计算256字节的3字节ECC编码
int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
    //ECC检测纠正函数,该函数检测并纠正256字节块中的1位错误。
void (*enable_hwecc)(struct mtd_info *mtd, int mode);
 //使能硬件计算ECC码函数指针
void (*erase_cmd)(struct mtd_info *mtd, int page);
   //擦除指定块函数的函数指针
int (*scan_bbt)(struct mtd_info *mtd);
   //坏块标记表创建函数指针
int eccmode;// ECC的计算方法, NAND_ECC_SOFT时意指软件运算,即采用calculate_ecc进行运算,利用correct_data进行校正
int eccsize;// ECC校准的数据长度,用calculate_ecc进行校准时,数据长度固定为256字节
int eccbytes;// ECC校验码字节数,软件校准时为3字节
int eccsteps;// ECC校验的步数,当FLASH每页的字节数为512字节,而calculate_ecc每次仅能校验256字节,则需要两步才能校验完成。
int chip_delay;// 等待时间,一般用于等待Flash的R/B管脚
int page_shift;// 页的地址移位数,当为512(2^9)字节的空间,其该值为9
int phys_erase_shift;// 块的地址移位数
int bbt_erase_shift;// 在bbt表中,相间隔两个内容之间的地址差的位数,也即是块的地址位数
int chip_shift;// 芯片总的地址位数
u_char *data_buf; //数据缓冲区指针
u_char *oob_buf;//oob缓冲区指针
int oobdirty;// 表示oob_buf内是否有内容,如为0表示oob_buf为空(0xFF),为1表示oob_buf中已有内容
u_char *data_poi;// 指向一个临时使用的数据区
unsigned int options;
//MTD驱动中配置NAND FALSH芯片的扩展功能,如NAND_IS_AND、NAND_USE_FLASH_BBT、NAND_COPYBACK等等和重要参数,如位宽NAND_BUSWIDTH_16。上述的这些宏在include/linux/mtd/nand.h均有定义,这些宏的定义能保证当它们进行或运算是能保证options能同时接受这些扩展功能和参数。及options某bit位为1时则使用对应的扩展功能。如有:
#define NAND_COPYBACK 0x00000010
那么如果options的bit4位为1则使用copyback功能,在MTD中大量使用了这种技巧,需要注意
int badblockpos;// 坏块标记的位置。当芯片为小页面NAND flashs时值为NAND_SMALL_BADBLOCK_POS(即为5);为大页面时值为NAND_BIG _BADBLOCK_POS(即为0)
int numchips;//开发板上NAND flash芯片的片数
unsigned long chipsize;// 芯片的容量
int pagemask;//页地址掩码
int pagebuf;// 存储Data_buf内的相关的页号
struct nand_oobinfo*autooob;
// oob区布局设计结构体指针。从功能上看,oob区和数据存储区一样可以存储数据,但是oob区一般不会用于存储数据,而是做为坏块标记和ECC校验数据存储。其中坏块标记位置一般有约定俗成的位置,而oob区的布局设计有很多不同的设计,MTD使用一个结构体来描述这种设计,oob区布局设计结构体在include/linux/mtd/mtd_abi.h中定义如下:
其中useecc 为使用ECC校验标志,eccbyte为ECC校验的位数,eccpos为ECC校验所存的位号,oobfree为OOB中ECC未使用到的字节(起始地址+长度)
uint8_t *bbt;// 指向内存中坏块表的指针
struct nand_bbt_descr*bbt_td;// 用以Flash中坏块表搜索的相关描述
struct nand_bbt_descr *bbt_md;// 上述描述的镜像
struct nand_hw_control*controller;// 用以实现互锁操作,此处并未使用
void *priv;//用途不明
};
MTD 使用 nand_chip 数据结构表示一个NAND Flash 芯片,这个结构体中包含了关于 NAND Flash 的地址信息、读写方法、ECC模式、硬件控制等一系列底层机制。
read_byte 和read_word :从NAND 芯片读一个字节或一个字,通常MTD 会在读取NAND 芯片的ID ,STATUS 和OOB 中的坏块信息时调用这两个函数,具体是这样的流程,首先MTD 调用cmdfunc 函数,发起相应的命令,NAND 芯片收到命令后就会做好准备,最后MTD 就会调用read_byte 或read_word 函数从NAND 芯片中读取芯片的ID ,STATUS 或者OOB ;
read_buf 、write_buf 和verify_buf:分别是从NAND 芯片读取数据到buffer、把buffer 中的数据写入到NAND 芯片、和从NAND 芯片中读取数据并验证。调用read_buf 时的流程与read_byte 和read_word 类似,MTD 也是先调用cmdfunc 函数发起读命令( 如NAND_CMD_READ0 命令) ,接着NAND 芯片收到命令后做好准备,最后MTD 再调用read_buf 函数把NAND 芯片中的数据读取到buffer 中。调用write_buf 函数的流程与read_buf 相似;
select_chip :因为系统中可能有不止一片NAND 芯片,所以在对NAND 芯片进行操作前,需要这个函数来指定一片NAND 芯片
cmdfunc :向NAND 芯片发起命令;
waitfunc :NAND 芯片在接收到命令后,并不一定能立即响应NAND controller 的下一步动作,对有些命令,比如erase ,program 等命令,NAND 芯片需要一定的时间来完成,所以就需要这个waitfunc 来等待NAND 芯片完成命令,并再次进入准备好状态;
write_page :把一个page 的数据写入NAND 芯片,这个函数一般不需我们实现,因为它会调用struct nand_ecc_ctrl 中的write_page_raw 或者write_page 函数,关于这两个函数将在稍后介绍。
      以上提到的这些函数指针,都是REPLACEABLE 的,也就是说都是可以被替换的,根据你的NAND controller ,如果你需要自己实现相应的函数,那么只需要把你的函数赋值给这些函数指针就可以了,如果你没有赋值,那么MTD 会把它自己定义的default 的函数赋值给它们。在本地代码上,以上函数指针都采用的默认的方式,通过s3c_nand_probe-》nand_scan-》nand_scan_ident-》nand_set_defaults,在该函数中以上的函数指针都被nand_base.c定义的默认函数赋值。

 八、数据结构struct nand_flash_dev分析
这个数据结构主要描述的是具体的NAND flash芯片型号。这个数据结构比较简单,它在include/linux/mtd/nand.h中被声明定义为一个结构体:
 struct nand_flash_dev {
char *name;  //NAND flash的名称
int id;       //NAND flashd 的设备ID
unsigned long pagesize;//页面大小,单位为KB
unsigned long chipsize;//芯片容量,单位为MB
unsigned long erasesize;//擦除单位大小
unsigned long options;// NAND flashd的扩展功能配置及位宽配置
};
结构体struct nand_flash_dev在drivers/mtd/nand_ids.c中这个数据结构被定义为一个结构体数组并被初始化。其中包含的每一个数组元素即为MTD驱动支持的NAND flashd芯片型号。初始化如下:
struct nand_flash_dev nand_flash_ids[] = {
    ………………………………………………………….
{"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
/* 1 Gigabit */
{"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
/* 2 Gigabit */
{"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
/* 4 Gigabit */
{"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
/* 8 Gigabit */
{"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
/* 16 Gigabit */
{"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{NULL,}
};
要强调的是:移植MTD驱动时一定要确定要移植的NAND flash芯片在这里有对应的nand_flash_dev结构体,没有的话要自行添加。在nand_scan()中,会先读出芯片的设备ID再到该结构体数组中逐个对比,如果没有找到匹配项则会导致在nand_scan()初始化失败返回。
   


U-Boot源码之NAND Flash驱动 这里以u-boot-2009.08版本介绍U-Boot的NAND Flash驱动的实现。要明白U-Boot的NAND Flash驱动的实现,首先要了解NAND Flash的基础知识。 一、NAND Flash简介 关于NAND Flash的介绍,可以参看下面两篇博文: https://blog.youkuaiyun.com/shengnan_wu/article/details/8116861?utm_medium=distribute.pc_relevant_t0.no... 阅读详情

相关推荐

zynq之nand-flash驱动

pl35x_nand驱动程序 按照阅读linux驱动程序的方法,来解读pl35x_nand.c文件。首先也是注册驱动,如果compatible能够与设备树对应上,则调用probe函数,先看下probe函数都干了啥? static int pl35x_nand_probe(struct platform_device *pdev) { struct pl35x_nand_info *xnand; struct mtd_info *mtd; struct nand_chip *nand_chip;

DSP小胖的博客 2714

第19课:nand flash驱动

1、参考自带的nand flash驱动,位于drivers/mtd/nand/s3c2410.c中 1.1 为什么nand在mtd目录下? 因为mtd(memory technology device存储技术设备)是用于访问memory设备(ROM、flash )的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。 1.2首先来看s3c2410.c的入口函数: static int __init ...

赶紧十八丶 2876

RT-Thread下移植添加nand-flash驱动

1:版本 使用的版本上v3.1.4中移除了mtd的相关代码,如果需要添加就从v3.1.3中获取。 由于我要移植yaffs所以需要这个框架 2:注册函数 //mtd.c /* * Register MTD driver * * @parts partion description * @np number of partitions * @return number of unregistered partitions * */ int rt_mtd_register(rt_mtd_t *mas

kayshi的博客 4852

NandFlash驱动移植基础知识

NandFlash驱动移植基础知识 文章借鉴博文:http://blog.youkuaiyun.com/leibniz_zsu/article/details/4977842 博文写的不错,谢谢分享 MTD 驱动程序是专门针对嵌入式 Linux 的一种驱动程序,相对于常规块设备驱动程序(比如PC 中的 IDE 硬盘)而言, MTD 驱动程序能更好的支持和管理闪存设备,因为它本身就是专为闪存设备而设计的。...

qq_41882586的博客 1579

三相Vienna整流器过零点电流畸变?试试这个SVPWM调制波补偿技巧

本文针对三相Vienna整流器在电流过零点附近出现的电流畸变问题,提出了一种基于SVPWM调制波补偿的有效解决方案。该方法通过注入零序分量重构占空比,巧妙解决因拓扑约束导致的调制矛盾,在基本不增加计算复杂度的前提下,显著平滑电流波形,降低THD。

weixin_29212867的博客 114

WD西部数据2TB,2.5寸移动硬盘,因为磁头坏了,长时间通电导致划片划伤,维修过程通过反复更换磁头

WD西部数据2TB,2.5寸移动硬盘,因为磁头坏了,长时间通电导致划片划伤,维修过程通过反复更换磁头,才能利用专业设备,里面找到,镜像,把内容数据恢复出来。 1.说一下经历,借用的别人移动硬盘,去帮别人维修,拷数据出来,别人的文件,数据比较多,且复杂,而且是在PE系统,接口什么的是2.0,没有很好的思考就全选复制拷贝了; 2,拷贝的过程,极其慢,文件多,且文件有损坏,移动硬盘一直处于通电的状态,大概从下午,两点多开始100多G的数据,一直卡住,到,晚上7 。8点拷完还是没拷完。打开的时候就已经,就一直

weixin_43766920的博客 4303

linux 内核 mtd读取,MTD坏块管理(二)-内核获取Nandflash的参数过程

MTD坏块管理机制中,起着核心作用的数据结构是nand_chip,在此以TCC8900-Linux中MTD的坏块管理为例作一次介绍。MTD在Linux内核中同样以模块的形式被启用,TCC_MTD_IO_Init()函数完成了nand_chip初始化、mtd_info初始注册,坏块表的管理机制建立等工作。nand_chip在TCC_MTD_IO_Init函数中的实例名称是this,mtd_info ...

weixin_34093995的博客 1346

化学科学催化反应产率预测之Transformer建模SMILES(Datawhale AI 夏令营)

循环神经网络:由于所有的前文信息都蕴含在一个隐向量中,随着序列长度的增加,早期的上下文信息会逐渐被遗忘。卷积神经网络:受限的上下文窗口在建模长文本时存在天然不足。需要多层卷积操作才能处理长文本。在本篇文章中,我们学习了Transformer的基本架构及其在化学反应产率预测中的应用。通过利用Transformer的Encoder部分对SMILES进行建模,我们能够更有效地捕捉序列数据的特征,从而提高模型的预测性能。

不想宅的冷同学 1096

龙芯处理器 nand 使用教程

龙芯1、2、3号处理器 nand 使用教程 nand分为:nand接口与spi接口,spi接口分spi norflash和spi nandflash 以LS2K为例,描述pmon和内核下的使用例程 一、PMON下使用教程 1、ls2k pmon源码获取路径 ftp://ftp.loongnix.org/embedd/ls2k/pmon-loongson3.tar.gz 2、pmon源码与n...

大猫的博客 4207

【学长笔记】点亮 STM32F411CEU6 板载 LED —— 入门级教程

本文提供了STM32F411CEU6开发板(Black Pill)点亮LED的完整教程。详细介绍了硬件信息(板载LED连接PC13,低电平有效)、CubeMX配置步骤(GPIO输出模式)、Keil5工程设置及完整代码实现(包含GPIO初始化和系统时钟配置)。教程还涵盖ST-Link下载器连接方法、程序下载步骤(需配合BOOT0按键操作)以及验证程序运行的方法。该教程特别适合STM32初学者,通过简单的LED闪烁示例快速入门STM32开发。

apple_53308981的博客 1323

littlefs系列:wear leveling

wear leveling的功能是通过block alloctor实现的。littlefs通过两个方法实现磨损均衡: 1) 检测和恢复bad blocks 2)通过dynamic blocks均衡磨损 检测和恢复bad blocks和block alloctor的关系并不紧密,主要依靠文件系统本身来检测坏块并标记。在littlefs中,检测坏块主要是通过写后回读并比较的方式实现的,如果数据不一致则说明是一个坏块。一旦检测到了坏块就要进行恢复。 如果是写入错误,因为数据才RAM中还有备份,因此需.

nstcl的博客 2570

Linux MTD下获取Nand flash各个参数的过程的详细解析

Linux MTD下获取Nand flash各个参数的过程的详细解析 版本:v1.1 Crifan Li 摘要 本文主要介绍了Nand Flash的一些背景知识和术语,然后详尽分析了Linux的MTD中的nand_base.c中的nand_get_flash_type函数每一步骤的功能。 本文提供多种格式供:

yuyin86的专栏 1462

最新Python爬虫实战(入门爬虫篇)——案例1:某瓣网站Top250图片数据采集(附上完整爬虫代码)

本次案例通过Python爬虫技术实现了某瓣Top250电影封面的批量下载。代码采用模块化设计,函数实现cookies的自动解析,简化了配置流程,涵盖请求、解析、存储的完整流程。学习重点包括:抓包工具定位数据源、正则表达式匹配图片链接、模拟请求头绕过反爬机制、以及自动化文件管理。需要注意控制请求频率并遵守网站使用规范,适用于入门爬虫实践。

努力让自己发光,对的人才能迎着光而来 16万+

Linux MTD架构下的nand flash驱动详解

转载自:http://blog.youkuaiyun.com/wang_zheng_kai/article/details/18988521 有了前面的基础(Nandflash详解:https://blog.youkuaiyun.com/Golden_Chen/article/details/89470673),我们就可以研究MTD下的nand驱动了,我这里用的是jz4780grus开发板,我将以下面几个部分做一个介绍...

Golden_Chen的专栏 1万+

Cadence OrCAD Capture CIS元器件管理时ERROR(ORCIS-6454): Temporary part number tracking is turned on报错的解决方法

使用Part manager对工程的元器件进行批量管理时,出现如下图所示的ERROR(ORCIS-6454): Temporary part number tracking is turned on报错其解决方法如下。

fydar的博客 3506

Unity3D实现视频和模型融合效果

在Unity中,视频和3D模型融合通常涉及到将视频表面内嵌到3D场景中。视频不影响模型的展示, 这可以通过使用Shader和Texture来实现。大家好,我是心疼你的一切,不定时更新Unity开发技巧,觉得有用记得一键三连哦。下面就让我们进入正文吧!提示:以下是本篇文章正文内容,下面案例可供参考本次介绍的就是视频和模型融合的实现,以后有其他的需要添加的会继续添加不定时更新Unity开发技巧,觉得有用记得一键三连哦。么么哒。

心疼你的一切博客 5357

十七、Linux驱动之nand flash驱动

1. 基本概念     Nand-flash存储器是flash存储器的一种,其内部采用非线性宏单元模式,为固态大容量内存的实现提供了廉价有效的解决方案。Nand-flash存储器具有容量较大,改写速度快等优点,适用于大量数据的存储,因而在业界得到了越来越广泛的应用,如嵌入式产品中包括数码相机、MP3随身听记忆卡、体积小巧的U盘等。 2. 硬件分析     本人使用的是韦东山老师的JZ2440...

墨、白的博客 2760

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

NAND FLASH学习笔记之MTD下nand flash驱动(四)

http://blog.youkuaiyun.com/wang_zheng_kai/article/details/19037491 四、Register到MTD子系统 两种注册方式:(我们需要完成的) 1)直接注册整个flash设备(MTD Device)到MTD。 ret = add_mtd_device(mtd); 2)分partion添加到mtd_table,并将每个

kulv 1033

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

NAND FLASH学习笔记之MTD下nand flash驱动(六)

http://blog.youkuaiyun.com/wang_zheng_kai/article/details/19039273 六、驱动层之Flash读操作 MTD对NAND芯片的读写 主要分三部分: A、struct mtd_info中的读写函数,如read,write_oob等,这是MTD原始设备层与FLASH硬件层之间的接口; B、struct nand_ecc

kulv 918

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

NAND FLASH学习笔记之MTD下nand flash驱动(一)

http://blog.youkuaiyun.com/wang_zheng_kai/article/details/18988521 最近公司要去合肥建新公司,比较闹心,耽搁一下!!! 有了前面的基础,我们就可以研究MTD下的nand驱动了,我这里用的是jz4780grus开发板,我将以下面几个部分做一个介绍,如果有没有涉及的或者需要详细介绍的我还会再开几篇博客进行介绍,敬请参阅!! 一

kulv 855

MTD设备驱动--NAND flash

前面的文章MTD设备驱动(http://blog.youkuaiyun.com/paomadi/article/details/9262307)讲了mtd设备的架构组织 其中讲述了调用int add_mtd_partitions(struct mtd_info *master,const struct mtd_partition *parts,int nbparts)  该函数一个作用是mtd_info

paomadi的专栏 3440

NAND FLASH学习笔记之MTD下nand flash驱动(五)

http://blog.youkuaiyun.com/wang_zheng_kai/article/details/19037953 驱动中probe函数的分析 其中探测函数代码执行流程为:  在probe函数中主要是完成了NAND芯片级的初始化,主要有以下几个作用:   -分配nand_chip内存,根据目标板及NAND控制器初始化nand_chip中成员函数

kulv 1487
上一篇: NAND FLASH学习笔记之MTD下nand flash驱动(一)
下一篇: NAND FLASH学习笔记之MTD下nand flash驱动(三)
中華田園犬
博客等级 码龄16年 349粉丝 76原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值