ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:25.48KB ,
资源ID:12012484      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/12012484.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(NandFlash驱动超详细分析报告报告材料.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

NandFlash驱动超详细分析报告报告材料.docx

1、NandFlash驱动超详细分析报告报告材料实用标准文案 今天学习了NandFlash的驱动,硬件操作非常简单,就是这个linux下的驱动比较复杂,主要还是MTD层的问题,用了一下午时间整理出来一份详细的分析,只是分析函数结构和调用关系,具体代码实现就不看了,里面有N个结构体,搞得我头大。 我用linux2.6.25内核,2440板子,先从启动信息入手。 内核启动信息,NAND部分: S3C24XX NAND Driver, (c) 2004 Simtec Electronics s3c2440-nand s3c2440-nand: Tacls=2, 20ns Twrph0=3 30ns, T

2、wrph1=2 20ns NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit) Scanning device for bad blocks Creating 3 MTD partitions on NAND 64MiB 3,3V 8-bit: 砰?扜潯屴 砰?日挴?歜牥敮屬 砰?昳捦?祜晡獦尲 第一行,在driver/mtd/nand/s3c2410.c中第910行,s3c2410_nand_init函数: printk(S3C24XX NAND Driver, (c) 2004 S

3、imtec Electronicsn); 行二行,同一文件,第212行,s3c2410_nand_inithw函数: 精彩文档实用标准文案 dev_info(info-device, Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dnsn, tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate); 第三行,在driver/mtd/nand/nand_base.c中第2346行, printk(KERN_INFO NAND dev

4、ice: Manufacturer ID: 0xx, Chip ID: 0xx (%s %s)n, *maf_id, dev_id, nand_manuf_idsmaf_idx.name, type-name); 第四行,在driver/mtd/nand/nand_bbt.c中第380行,creat_bbt函数: Printk(KERN INFO Scanning device for bad blocks n); 第五行,在driver/mtd/mtdpart.c中第340行,add_mtd_partitions函数: printk (KERN_NOTICE Creating %d MTD

5、partitions on %s:n, nbparts, master-name); 下面三行,是flash分区表,也在mtdpart.c同一函数中,第430行: printk (KERN_NOTICE slave-offset + slave-mtd.size, slave-mtd.name); MTD体系结构: 在linux中提供了MTD(Memory Technology Device,内存技术设备)系统来建立Flash针对linux的统一、抽象的接口 引入MTD后,linux系统中的Flash设备驱动及接口可分为4层: 设备节点 精彩文档实用标准文案 MTD设备层 MTD原始设备层 硬

6、件驱动层 硬件驱动层:Flash硬件驱动层负责底层硬件设备实际的读、写、擦除,Linux MTD设备的NAND型Flash驱动位于driver/mtd/nand子目录下 s3c2410对应的nand Flash驱动为s3c2410.c MTD原始设备层:MTD原始设备层由两部分构成,一部分是MTD原始设备的通用代码,另一部分是各个特定Flash的数据,比如分区 主要构成的文件有: drivers/mtd/mtdcore.c 支持mtd字符设备 driver/mtd/mtdpart.c 支持mtd块设备 MTD设备层:基于MTD原始设备,Linux系统可以定义出MTD的块设备(主设备号31) 和

7、字符设备(设备号90),构成MTD设备层 简单的说就是:使用一个mtd层来作为具体的硬件设备驱动和上层文件系统的桥梁。mtd给出了系统中所有mtd设备(nand,nor,diskonchip)的统一组织方式。 mtd层用一个数组struct mtd_info *mtd_tableMAX_MTD_DEVICES保存系统中所有的设备,mtd设备利用struct mtd_info 这个结构来描述,该结构中描述了存储设备的基本信息和具体操作所需要的内核函数,mtd系统的那个机制主要就是围绕这个结构来实现的。结构体在include/linux/mtd/mtd.h中定义: 精彩文档实用标准文案 struc

8、t mtd_info u_char type; /MTD 设备类型 u_int32_t flags; /MTD设备属性标志 u_int32_t size; /标示了这个mtd设备的大小 u_int32_t erasesize; /MTD设备的擦除单元大小,对于NandFlash来说就是Block的大小 u_int32_t oobblock; /oob区在页内的位置,对于512字节一页的nand来说是512 u_int32_t oobsize; /oob区的大小,对于512字节一页的nand来说是16 u_int32_t ecctype; /ecc校验类型 u_int32_t eccsize;

9、/ecc的大小 char *name; /设备的名字 int index; /设备在MTD列表中的位置 struct nand_oobinfo oobinfo; /oob区的信息,包括是否使用ecc,ecc的大小 /以下是关于mtd的一些读写函数,将在nand_base中的nand_scan中重载 int (*erase) int (*read) int (*write) 精彩文档实用标准文案 int (*read_ecc) int (*write_ecc) int (*read_oob) int (*read_oob) void *priv;/设备私有数据指针,对于NandFlash来说指n

10、and芯片的结构 下面看nand_chip结构,在include/linux/mtd/nand.h中定义: struct nand_chip void _iomem *IO_ADDR_R; /这是nandflash的读写寄存器 void _iomem *IO_ADDR_W; /以下都是nandflash的操作函数,这些函数将根据相应的配置进行重载 u_char (*read_byte)(struct mtd_info *mtd); void (*write_byte)(struct mtd_info *mtd, u_char byte); u16 (*read_word)(struct mtd

11、_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); void (*select_chip)(struct mtd_info

12、 *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); 精彩文档实用标准文案 int (*dev_ready)(struct mtd_info *mtd); void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int

13、column, int page_addr); int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); void (*enable_hwecc)(struct m

14、td_info *mtd, int mode); void (*erase_cmd)(struct mtd_info *mtd, int page); int (*scan_bbt)(struct mtd_info *mtd); int eccmode; /ecc的校验模式(软件,硬件) int chip_delay; /芯片时序延迟参数 int page_shift; /页偏移,对于512B/页的,一般是9 u_char *data_buf; /数据缓存区 跟NAND操作相关的函数: 1、 nand_base.c: 定义了NAND驱动中对NAND芯片最基本的操作函数和操作流程,如擦除、读写p

15、age、读写oob等。当然这些函数都只是进行一些常规的操作,若你的系统在对NAND操作时有一些特殊的动作,则需要在你自己的驱动代码中进行定义。 精彩文档实用标准文案 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和厂商为自己的NA

16、ND芯片定义的芯片ID。当NAND加载时会找这两个结构体,读出ID,如果找不到,就会加载失败。 4、 nand_ecc.c: 定义了NAND驱动中与softeware ECC有关的函数和结构体,若你的系统支持hardware ECC,且不需要software ECC,则该文件也不需理会。 我们需要关心的是/nand/s3c2410,这个文件实现的是s3c2410/2440nandflash控制器最基本的硬件操作,读写擦除操作由上层函数完成。 s3c2410.c分析: 首先看一下要用到的结构体的注册: struct s3c2410_nand_mtd struct mtd_info mtd; /m

17、td_info的结构体 chip; /nand_chip的结构体struct nand_chip struct s3c2410_nand_set *set; struct s3c2410_nand_info *info; int scan_res; 精彩文档实用标准文案 ; enum s3c_cpu_type /用来枚举CPU类型 TYPE_S3C2410, TYPE_S3C2412, TYPE_S3C2440, ; struct s3c2410_nand_info /* mtd info */ struct nand_hw_control controller; *mtds;struct s

18、3c2410_nand_mtd *platform; struct s3c2410_platform_nand /* device info */ struct device *device; *area; struct resource *clk;struct clk *regs;void _iomem void _iomem *sel_reg; int sel_bit; mtd_count;int save_nfconf;unsigned long enum s3c_cpu_type cpu_type; 精彩文档实用标准文案 ; 设备的注册: static int _init s3c241

19、0_nand_init(void) printk(S3C24XX NAND Driver, (c) 2004 Simtec Electronicsn); platform_driver_register(&s3c2412_nand_driver); platform_driver_register(&s3c2440_nand_driver); return platform_driver_register(&s3c2410_nand_driver); platform_driver_register向内核注册设备,同时支持这三种CPU。 &s3c2440_nand_driver是一个platf

20、orm_driver类型的结构体: static struct platform_driver s3c2440_nand_driver = .probe = s3c2440_nand_probe, = s3c2410_nand_remove,.remove .suspend = s3c24xx_nand_suspend, .resume = s3c24xx_nand_resume, = .driver = s3c2440-nand, .name .owner = THIS_MODULE, , ; 精彩文档实用标准文案 最主要的函数就是s3c2440_nand_probe,(调用s3c24XX_

21、nand_probe),完成对nand设备的探测, static int s3c24xx_nand_probe(struct platform_device *pdev, enum s3c_cpu_type cpu_type) */ 主要完成一些硬件的初始化,其中调用函数:/* (info, nmtd, sets); s3c2410_nand_init_chip mtd_infoflash 的探测及 /*init_chip结束后,调用nand_scan完成对*/读写函数的赋值 (&nmtd-mtd, (sets) ? nand_scannmtd-scan_res = sets-nr_chips

22、 : 1); if (nmtd-scan_res = 0) s3c2410_nand_add_partition(info, nmtd, sets); 进行的一步非常好重要的操作,nand的时候对nand是在初始化Nand_scan结nand_scan在中会对我们所写的关于特定芯片的读写函数重载到nand_chipmtdnandmtd_info并会将构中去,结构体中的函数用的函数来重载,实现了到底层驱动的联系。 芯片的设备号和厂家号自动在芯片并且在nand_scan函数中会通过读取nand列表中寻找相应的型号和参数,并将其注册进去。 精彩文档实用标准文案 static void s3c2410

23、_nand_init_chip(struct s3c2410_nand_info *info, struct s3c2410_nand_mtd *nmtd, struct s3c2410_nand_set *set) struct nand_chip *chip = &nmtd-chip; void _iomem *regs = info-regs; /*以下都是对chip赋值,对应 nand_chip中的函数*/ chip-write_buf = s3c2410_nand_write_buf; /写buf chip-read_buf = s3c2410_nand_read_buf; / 读b

24、uf chip-select_chip = s3c2410_nand_select_chip;/片选 chip-chip_delay = 50; chip-priv = nmtd; chip-options = 0; chip-controller = &info-controller; /? switch (info-cpu_type) case TYPE_S3C2440: chip-IO_ADDR_W = regs + S3C2440_NFDATA; /数据寄存器 info-sel_reg = regs + S3C2440_NFCONT; /控制寄存器 info-sel_bit = S3C

25、2440_NFCONT_nFCE; chip-cmd_ctrl = s3c2440_nand_hwcontrol; /硬件控制 chip-dev_ready = s3c2440_nand_devready; / 设备就绪 精彩文档实用标准文案 chip-read_buf = s3c2440_nand_read_buf; /读buf chip-write_buf = s3c2440_nand_write_buf;/写buf break; chip-IO_ADDR_R = chip-IO_ADDR_W; /读写寄存器都是同一个 nmtd-info = info; nmtd-mtd.priv = c

26、hip; /私有数据指针指向chip nmtd-mtd.owner = THIS_MODULE; nmtd-set = set; /*后面是和 ECC校验有关的,省略*/ 初始化后,实现对nand的基本硬件操作就可以了,包括以下函数: s3c2410_nand_inithw /初始化硬件,在probe中调用 s3c2410_nand_select_chip /片选 s3c2440_nand_hwcontrol /硬件控制,其实就是片选 s3c2440_nand_devready /设备就绪 s3c2440_nand_enable_hwecc /使能硬件ECC校验 s3c2440_nand_ca

27、lculate_ecc /计算ECC s3c2440_nand_read_buf s3c2440_nand_write_buf 注册nand设备到MTD原始设备层:(这个函数由probe调用) #ifdef CONFIG_MTD_PARTITIONS /如果定义了MTD分区 精彩文档实用标准文案 static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, struct s3c2410_nand_mtd *mtd, struct s3c2410_nand_set *set) if (set = NULL) retur

28、n add_mtd_device(&mtd-mtd); if (set-nr_partitions 0 & set-partitions != NULL) return add_mtd_partitions(&mtd-mtd, set-partitions, set-nr_partitions); return add_mtd_device(&mtd-mtd); #else 注册设备用这两个函数: 整体不分区,用这个, /如果nandadd_mtd_device 中实现该函数在/mtdcore.c 是分区结构,用这个,nandadd_mtd_partitions /如果 中实现/mtdpart

29、.c该函数在 同样,注销设备也有两个函数: del_mtd_device del_mtd_partitions 精彩文档实用标准文案 NandFlash还有一个分区表结构体,mtd_partition,这个是在arch/arm/plat-s3c24XX/common-smdk.c中定义的。 static struct mtd_partition smdk_default_nand_part = 0 = .name = oot, .size = 0x00040000, .offset = 0, , 1 = = kernel, .name .offset = 0x0004C000, = 0x00200000, .size , 2 = = yaffs2,.name .offset = 0x0024C000, = 0x03DB0000, .size , ; 有几个分区,每个分区的名字,大小,偏移量是多少记录了当前的nand flash 系统就是依靠这些分区表找到各个文件系统的 精彩文档实用标准文案 这些分区表nand中的文件系统没有必然关系,分区表只是把flash分成不同的部分 如果自己编写一个nandflash驱动,只需要填充这三个结构体: Mtd_info nand_chip

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1