Flash驱动简介

一.块设备的使用:

1.安装块设备驱动:insmod  simple_blk.ko

2.查看一下设备块文件的属性:ls  设备路径/设备文件名(例如:/dev/simp_blk0)(可以通过驱动name来查找设备文件)

3.格式化块设备:mkfs.ext3 /dev/simp_blk0

4.挂在块设备: mkdir -p /mnt/blk; mount  /dev/simp_blk0  /mnt/blk

5.将挂载文件/mnt/blk当作文件夹一样使用就可以了

二.块设备驱动程序的架构:应用程序->虚拟文件系统->具体的文件系统(Ext2,FAT,NFS,设备文件)。Ext:读取速度块,cpu占有率小(ext3相比于ext2速度更快(经常读写的放在内存中),提供日志管理-安全性更高,校验速度快,重新加载块),cpu占有率小。FAT已经被抛弃了,以前用的,空间小,读取速度慢。NFS:网络文件系统

文件系统访问流程:

  1. 虚拟文件系统:vfs
  2. 磁盘缓存:caches—当访问经常读写的文件时,磁盘中会有这些内容,将内容返回,后面的流程也就不走了
  3. 映射层(文件系统):磁盘文件系统(访问磁盘缓存之后再到这一步)或者块设备文件系统(不访问磁盘缓存):作用:1.计算block数量,2.查出block位置
  4. 通用块层:将上层传过来的结构做成bio结构:bio结构对于访问扇区有很好的作用。
  5. I/O调度层:对i/o访问进行合理排序:例如电梯调度(不论传入的顺序是什么,但是按照从上往下以此进行访问)
  6. 块设备驱动:访问硬件的存储寄存器

三.块设备驱动设计:

1.初始化:

1.1注册块设备驱动:register_blkdev(主设备号为0时,系统自动分配)

1.2初始化请求队列:blk_int_queue 其中一个参数为请求处理函数,用来回调处理请求=事件的,返回值为队列的地址,保存好这个地址到自定义的结构中可以,后面要用到这个地址

1.3指明扇区大小:blk_queue_logical_block_size:其中一个参数为队列地址,另外一个为扇区大小

1.4为块设备分配gendisk结构:alloc_disk:在内核中每管理一个磁盘就会有一个这个结构在内核中,返回结构体gendisk类型指针

1.5初始化gendisk这个类型:具体初始化参考内核其他地方的用法,内容有,主,次设备号。操作函数集,工作队列(1.2申请的),私有数据(自己定义可以),disk名字,扇区数

1.6添加disk设备到内核:add_deisk

2.实现读写请求处理:

实现方式:处理函数它是被回调的,在初始化请求队列时进行的注册这个处理函数

2.1从请求队列中获取一个请求:blk_fetch_request,返回值为一个请求结构,参数为回调函数传入的形参

2.2处理一个请求:从请求中获取相应的数据,然后根据对应的数据进行相应的硬件读写

2.3判断请求队列是否为空:__blk_end_request_cur:如果不为空则重复前面两步直到请求队列为空。

四.MTD设备:

作用:

1.将flash进行分区,在uboot被cpu加载后,uboot根据 include/configs/**(项目方案名).h中环境变量设置加载MTD分区的信息 (信息与内核配置的MTD部分相关联)去加载内核,在/proc/mtd文件 中有关于分区表的信息,其分区的块设备文件在目录/dev/mtd*

2.在对文件系统进行操作时,为用户提供中间层,为文件系统操作的相 同部分提供统一的接口

架构:文件系统(yaffs,cramfs),MTD块设备,MTD设备层,MTD原始设备层,MTD通用驱动程序,flash驱动程序。MTD相关的部分内核已经写好了,它完成了文件系统操作的共性部分,例如纠错,flash分区等。

内核支持:内核需要支持MTD设备需要在menuconfig中配置 MTD partitioning support

相关的数据结构:

  1. 在内核代码中,MTD分区相关的配置结构体为 mtd_partition,记载分区表的信息,具体对应文件根据项目的kconfig规则确定。
  2. 在uboot中,

2.1内核信息MTD的信息在文件include/configs/**(项目方案名).h表现为宏定义,其中CONFIG_BOOTCOMMAND的命令nand read 命令以及bootm命令,从flash读取数据到内存,并运行内存的中的数据

2.2文件系统信息:表现为宏CONFIG_BOOTARGS,其值为设备文件名,对应为内核mtd_partition中的分区数值

  • 格式化文件系统

1.使用文件系统工具将编译好的文件系统格式化 例如:

mkyaffs2image  ./rootfs  rootfs.img  使用mkyaffs2image工具将编译好的文件目录rootfs格式化成yaffs2格式的文件系统

  • Linux启动流程:
  1. 上点后运行cpu中固化的BIOS程序进行硬件检测和初始化,然后根据检测顺序加载第一个获取到的可启动装置的boot Loader(一般为uboot)
  2. 启动uboot,分两步走

2.1:uboot加载对应的include/configs/xxx.h配置的参数,完成可配置的硬件参数设置,例如:时钟,内核在flash的位置等

2.2:将部分参数传递给内核,启动内核

  1. 内核再次开始硬件检测与加载驱动,硬件设置不一定会使用uboot设置的或者传递过来的参数,然后再挂在文件系统  
  2. 文件系统:在pc机上,有些文件系统所在硬件设备对应的驱动程序在放在硬件设备上,此时内核无法顺利去读取硬件来挂载文件系统,也无法加载对应的驱动,那么就启动虚拟文件系统,虚拟文件系统中安装读取对应存储硬件设备的驱动,就可以读取硬件,挂在文件系统,在加载文件系统的对应驱动程序,例如:STAT接口的磁盘驱动Linux内核好像不支持
  3. 文件系统被加载后,内核启动第一支程序/sbin/init,其pid=1开始正式用户态的工作,用户的自启动一般被配置在文件/etc/rc.d/rc.local中,里面放入启动应用的脚本
  • Flash驱动编写流程:platform平台驱动设备

7.1 使能时钟:clk_enable

7.2 地址转换:物理地址到虚拟地址 ioremap 将设备资源中的物理地址映射

7.3 硬件纠错:HWECC,硬件纠错支持

7.4 搜nandflash: nand_scan

7.5 注册分区表:add_mtd_patitions

7.6 读写操作:nand_read nand_write 注:在和硬件通信前需要确保各个io口的电平已经拉到相应的数值,然后确保硬件是好的,之后再开始调试-硬件通信,在确保io口已经拉正确的情况下,通信失败就找硬件问题,给硬件工程师去测试硬件,一般内核架构是没问题的

Flash读的流程分为:结合Linux架构,在文件Nand_basic.c中nand_read函数进行读操作,nand_read函数被上层调用,它里面调用函数nand_do_read_ops,这个函数真的去实现读的操作,然后nand_do_read_ops中调用函数nand_command_lp,这个函数又调用chip->cmd_ctl回调,这个函数指针就是flash平台驱动中cmd_ctl指针。不断回调cmd_ctl这个指针,传参,然后flash驱动根据参数对硬件寄存器进行写控制达到数据传输读的目的

传入参数去控制硬件流程为:

7.6.1选芯片

7.6.2清除RnB

7.6.3发出命令0x00

7.6.4发出列地址

7.6.5发出行地址

7.6.6发出命令0x30

7.6.7等待就绪;wait RnB

7.6.8读数据

7.6.9取消片选

猜你喜欢

转载自blog.csdn.net/qq_43706825/article/details/103717800