mtd基础介绍(收藏)
MTD,Memory Technology Device即内存技术设备
字符设备和块设备的区别在于前者只能被顺序读写,后者可以随机访问;同时,两者读写数据的基本单元不同。
字符设备,以字节为基本单位,在Linux中,字符设备实现的比较简单,不需要缓冲区即可直接读写,内核例程和用户态API一一对应,用户层的Read函数直接对应了内核中的Read例程,这种映射关系由字符设备的file_operations维护。
块设备,则以块为单位接受输入和返回输出。对这种设备的读写是按块进行的,其接口相对于字符设备复杂,read、write API没有直接到块设备层,而是直接到文件系统层,然后再由文件系统层发起读写请求。
同时,由于块设备的IO性能与CPU相比很差,因此,块设备的数据流往往会引入文件系统的Cache机制。
MTD设备既非块设备也不是字符设备,但可以同时提供字符设备和块设备接口来操作它。
MTD总概述
Linux中MTD的所有源码位于/drivers/mtd子目录下,
MTD设备通常可分为四层
这四层从上到下依次是:设备节点、MTD设备层、MTD原始设备层和硬件驱动层。
一、Flash硬件驱动层
硬件驱动层负责在init时驱动Flash硬件并建立从具体设备到MTD原始设备映射关系
tip: 映射关系通常包括 分区信息、I/O映射及特定函数的映射
drivers/mtd/chips : CFI/jedec接口通用驱动
drivers/mtd/nand : nand通用驱动和部分底层驱动程序
drivers/mtd/maps : nor flash映射关系相关函数
drivers/mtd/devices: nor flash底层驱动
二、MTD原始设备
用于描述MTD原始设备的数据结构是mtd_info,它定义了大量的关于MTD的数据和操作函数。
mtdcore.c : MTD原始设备接口相关实现
mtdpart.c : MTD分区接口相关实现
三、MTD设备层
基于MTD原始设备,linux系统可以定义出MTD的块设备(主设备号31)和字符设备(设备号90)。
mtdchar.c : MTD字符设备接口相关实现
mtdblock.c : MTD块设备接口相关实现
四、设备节点
通过mknod在/dev子目录下建立MTD块设备节点(主设备号为31)和MTD字符设备节点(主设备号为90)
通过访问此设备节点即可访问MTD字符设备和块设备
具体参考: working-with-mtd-devices
五、文件系统
内核启动后,通过mount 命令可以将flash中的其余分区作为文件系统挂载到mountpoint上。
MTD数据结构
重要的数据结构:
1. mtd_info 表示mtd原始设备, 所有mtd_info结构体被存放在mtd_info数组mtd_table中
2. mtd_part 表示MTD分区,其中包含了 mtd_info,每一个分区都是被看成一个MTD 原始设备
在mtd_table中,mtd_part.mtd_info中的大部分数据都从该分区的主分区mtd_part->master中获得
tip: master不作为一个mtd原始设备加入mtd_table
各层之间的交互如下图
mtd_info的主要数据结构
域 | 作用 |
type | mtd类型, 包括MTD_NORFLASH,MTD_NANDFLASH等(See mtd-abi.h) |
flags | 标志位, MTD_WRITEABLE,MTD_NO_ERASE等(See mtd-abi.h) |
size | mtd设备的大小 |
erasesize | 主要的擦除大小, 即Flash的块大小 (tip: mtd设备可能有多个erasesize) |
writesize | 写大小, 对于norFlash是字节,对nandFlash为一页 |
oobsize | 每块oob数据量, eg 16 |
oobavail | |
name | 命名 |
index | |
ecclayout | nand_ecclayout结构体指针, 表示的是ecc布局,可参考硬件手册的OOB中ecc布局 |
numeraseregions | 可变擦除区域的数目, 通常为1 |
eraseregions | mtd_erase_region_info结构体指针, 可变擦除区域 |
erase | 擦除Flash函数 |
read/write | 读写Flash函数 |
read_oob/write_oob | 带oob读写Flash函数 |
suspend/resume | Power Management functions |
priv | 私有数据, cfi接口flash指向map_info结构, 或指向自定义flash相关结构体 |
mtd_part的主要数据结构
域 | 作用 |
mtd | 分区信息, 大部分由master决定 |
master | 分区的主分区 |
offset | 分区的偏移地址 |
index | 分区号 (3.0后不存在该字段) |
list | 将mtd_part链成一个链表mtd_partitons |
mtd_partition的主要数据结构
域 | 作用 |
name | |
size | |
offset | |
mask_flags | |
ecclayout | |
mtdp | |
map_info的主要数据结构
域 | 作用 |
name | 名称 |
size | 大小 |
phys | 物理地址 |
bankwidth | 总线宽度(in octets) |
virt | 虚拟地址,通常通过ioremap将物理地址进行映射得到 |
read/copy_from/write/copy_to | 读写函数 |
map_priv_1/map_priv_2 | 驱动可用的私有数据 |
nand_chip的主要数据结构
域 | 作用 |
IO_ADDR_R/IO_ADDR_W | 读/写8根io线的地址 |
read_byte/read_word | 从芯片读一个字节/字 |
read_buf/write_buf | 读芯片读取内容至缓冲区/将缓冲区内容写入芯片 |
verify_buf | |
select_chip | |
block_bad | 检查是否坏块 |
block_markbad | 标识坏块 |
cmd_ctrl | 硬件相关控制函数 |
init_size | |
dev_ready | |
cmdfunc | 命令处理函数 |
waitfunc | |
erase_cmd | 擦除命令 |
scan_bbt | 扫描坏块 |
errstat | |
write_page | |
options | 与具体的NAND 芯片相关的选项, 如NAND_USE_FLASH_BBT等(nand.h) |
page_shift | |
ecclayout | nand_ecclayout类型结构体, ECC布局信息 |
ecc | nand_ecc_ctrl类型结构体, ECC控制结构 |
nand_ecclayout的主要数据结构
域 | 作用 |
eccbytes | ecc的字节数(For 512B-per-page, eccbytes is 3) |
eccpos | ecc数据在oob中的位置 |
oobavail | oob中可用的字节数, MTD 会根据其它三个变量自动计算得到 |
oobfree | nand_oobfree类型结构体, 显示定义空闲的oob 字节 |
MTD相关层实现
MTD设备层
mtd字符设备接口:
mtdchar.c 实现了字符设备接口,通过它,用户可以直接操作Flash 设备。
Ø 通过read()、write()系统调用可以读写Flash。
Ø 通过一系列IOCTL 命令可以获取Flash 设备信息、擦除Flash、读写NAND 的OOB、获取OOB layout 及检查NAND 坏块等(MEMGETINFO、MEMERASE、MEMREADOOB、MEMWRITEOOB、MEMGETBADBLOCK IOCRL)
tip: mtd_read和mtd_write直接直接调用mtd_info的read 函数,因此,字符设备接口跳过patition这一层
mtd块设备接口:
主要原理是将Flash的erase block 中的数据在内存中建立映射,然后对其进行修改,最后擦除Flash 上的block,将内存中的映射块写入Flash 块。整个过程被称为read/modify/erase/rewrite 周期。
但是,这样做是不安全的,当下列操作序列发生时,read/modify/erase/poweroff,就会丢失这个block 块的数据。
块设备模拟驱动按照block 号和偏移量来定位文件,因此在Flash 上除了文件数据,基本没有额外的控制数据。
MTD原始设备层
MTD硬件驱动层
1. NOR Flash驱动结构
Linux系统实现了针对cfi,jedec等接口的通用NOR Flash驱动
在上述接口驱动基础上,芯片级驱动较简单
定义具体内存映射结构体map_info,然后通过接口类型后调用do_map_probe()
以h720x-flash.c为例(位于drivers/mtd/maps)
- 定义map_info结构体, 初始化成员name, size, phys, bankwidth
- 通过ioremap映射成员virt(虚拟内存地址)
- 通过函数simple_map_init初始化map_info成员函数read,write,copy_from,copy_to
- 调用do_map_probe进行cfi接口探测, 返回mtd_info结构体
- 通过parse_mtd_partitions, add_mtd_partitions注册mtd原始设备
2. NAND Flash驱动结构
Linux实现了通用NAND驱动(drivers/mtd/nand/nand_base.c)
tip: For more, check 内核中的NAND代码布局
芯片级驱动需要实现nand_chip结构体
MTD使用nand_chip来表示一个NAND FLASH芯片, 该结构体包含了关于Nand Flash的地址信息,读写方法,ECC模式,硬件控制等一系列底层机制。
Ø NAND芯片级初始化
主要有以下几个步骤:
- 分配nand_chip内存,根据目标板及NAND控制器初始化nand_chip中成员函数(若未初始化则使用nand_base.c中的默认函数),将mtd_info中的priv指向nand_chip(或板相关私有结构),设置ecc模式及处理函数
- 以mtd_info为参数调用nand_scan()探测NAND FLash。
nand_scan()会读取nand芯片ID,并根据mtd->priv即nand_chip中成员初始化mtd_info
- 若有分区,则以mtd_info和mtd_partition为参数调用add_mtd_partitions()添加分区信息
-
Ø MTD对NAND芯片的读写
主要分三部分:
A、struct mtd_info中的读写函数,如read,write_oob等,这是MTD原始设备层与FLASH硬件层之间的接口;
B、struct nand_ecc_ctrl中的读写函数,如read_page_raw,write_page等,主要用来做一些与ecc有关的操作;
C、struct nand_chip中的读写函数,如read_buf,cmdfunc等,与具体的NAND controller相关,就是这部分函数与硬件交互,通常需要我们自己来实现。
tip: nand_chip中的读写函数虽然与具体的NAND controller相关,但是MTD也为我们提供了默认的读写函数,如果NAND controller比较通用(使用PIO模式),那么对NAND芯片的读写与MTD提供的这些函数一致,就不必自己实现这些函数。
上面三部分读写函数相互配合完成对NAND芯片的读写
首先,MTD上层需要读写NAND芯片时,会调用struct mtd_info中的读写函数,接着struct mtd_info中的读写函数就会调用struct nand_chip或struct nand_ecc_ctrl中的读写函数,最后,若调用的是struct nand_ecc_ctrl中的读写函数,那么它又会接着调用struct nand_chip中的读写函数。
eg: 以读为例
MTD上层会调用struct mtd_info中的读page函数,即nand_read函数。
接着nand_read函数会调用struct nand_chip中cmdfunc函数,这个cmdfunc函数与具体的NAND controller相关,它的作用是使NAND controller向NAND 芯片发出读命令,NAND芯片收到命令后,就会做好准备等待NAND controller下一步的读取。
接着nand_read函数又会调用struct nand_ecc_ctrl中的read_page函数,而read_page函数又会调用struct nand_chip中read_buf函数,从而真正把NAND芯片中的数据读取到buffer中(所以这个read_buf的意思其实应该是read into buffer,另外,这个buffer是struct mtd_info中的nand_read函数传下来的)。
read_buf函数返回后,read_page函数就会对buffer中的数据做一些处理,比如校验ecc,以及若数据有错,就根据ecc对数据修正之类的,最后read_page函数返回到nand_read函数中。
对NAND芯片的其它操作,如写,擦除等,都与读操作类似
http://www.cnblogs.com/hzl6255/archive/2012/12/18/2824043.html
MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱 动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。MTD的所有源代码在/drivers/mtd子目录下。我将CFI接口的MTD设备分为四层 (从设备节点直到底层硬件驱动),这四层从上到下依次是:设备节点、MTD设备层、MTD原始设备层和硬件驱动层。
一、Flash硬件驱动层:硬件驱动层负责在init时驱动Flash硬件,Linux MTD设备的NOR Flash芯片驱动遵循CFI接口标准,其驱动程序位于drivers/mtd/chips子目录下。NAND型Flash的驱动程 序则位于/drivers/mtd/nand子目录下。
二、MTD原始设备:原始设备层有两部分组成,一部分是MTD原始设备的通用代码,另一部分是各个特定的Flash的数据,例如分区。 用于描述MTD原始设备的数据结构是mtd_info,这其中定义了大量的关于MTD的数据和操作函数。mtd_table(mtdcore.c)则是所 有MTD原始设备的列表,mtd_part(mtd_part.c)是用于表示MTD原始设备分区的结构,其中包含了mtd_info,因为每一个分区都 是被看成一个MTD原始设备加在mtd_table中的,mtd_part.mtd_info中的大部分数据都从该分区的主分区 mtd_part->master中获得。 在drivers/mtd/maps/子目录下存放的是特定的flash的数据,每一个文件都描述了一块板子上的flash。其中调用 add_mtd_device()、del_mtd_device()建立/删除mtd_info结构并将其加入/删除mtd_table(或者调用 add_mtd_partition()、del_mtd_partition()(mtdpart.c)建立/删除mtd_part结构并将 mtd_part.mtd_info加入/删除mtd_table 中)。
三、MTD设备层:基于MTD原始设备,linux系统可以定义出MTD的块设备(主设备号31)和字符设备(设备号90)。MTD字符设备的定义在 mtdchar.c中实现,通过注册一系列file operation函数(lseek、open、close、read、write)。MTD块设备则是定义了一个描述MTD块设备的结构 mtdblk_dev,并声明了一个名为mtdblks的指针数组,这数组中的每一个mtdblk_dev和mtd_table中的每一个 mtd_info一一对应。
四、设备节点:通过mknod在/dev子目录下建立MTD字符设备节点(主设备号为90)和MTD块设备节点(主设备号为31),通过访问此设备节点即可访问MTD字符设备和块设备。
五、根文件系统:在Bootloader中将JFFS(或JFFS2)的文件系统映像jffs.image(或jffs2.img)烧到flash的 某一个分区中,在/arch/arm/mach-your/arch.c文件的your_fixup函数中将该分区作为根文件系统挂载。
六、文件系统:内核启动后,通过mount 命令可以将flash中的其余分区作为文件系统挂载到mountpoint上。
mtd基础介绍(收藏)相关推荐
- uniapp基础介绍
uni-app基础 uniapp基础介绍 一.uniapp项目的搭建 (1)下载开发工具HBuilderX (2)创建 uni-app 项目 (3)运行 uni-app (4)发布 uni-app 二 ...
- creo视图管理器使用方法_Creo Parametric 4.0 界面基础介绍
原标题:Creo Parametric 4.0 界面基础介绍 作者:科虫先生 Cero4.0是PTC最新的版本,正在使用主流proe5.0的朋友对它的界面与操作还是不习惯.机械六空间是深度系统地和大家 ...
- day23:shell基础介绍 alias及重定向
2019独角兽企业重金招聘Python工程师标准>>> 1.shell基础介绍: shell是一个命令解释器,用于用户与机器的交互: 也支持特定的语法(逻辑判断,循环): 每个用户都 ...
- tabcontainer控件太长_AjaxControlToolKit--TabContainer控件的介绍收藏[摘录]
AjaxControlToolKit--TabContainer控件的介绍收藏 1. Introduction: Tab本身就应该是个以页签形式显示组织网页内容的一个控件.在AJAX Control ...
- Android NDK开发之 NEON基础介绍
原文:http://blog.csdn.net/app_12062011/article/details/50434259 Android NDK开发之 NEON基础介绍 这是官方介绍: http:/ ...
- python介绍和用途-Python基础介绍(一)
Python基础介绍(一) 1. python是什么编程语言 编译型与解释型 编译器吧源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以极其语言来运行此程序,速度很快 ...
- STL体系结构与内核分析-2-STL体系结构基础介绍(侯捷)--笔记
STL体系结构与内核分析(侯捷) 2.STL体系结构基础介绍 STL设计方式与OO(面向对象)不同的地方,OO鼓励数据和处理数据的方法都放在类里,而STL的数据在容器里,操作数据的方法在其他部件里(模 ...
- ai一个线段多个箭头_初学设计却分不清PS和AI?超详细的AI基础介绍包你一看即会!...
以前提到AI,第一个想到的就是人工智能.自从扎进设计的神坑,再提到AI,我可只认软件了~ 包括小ke在内的很多设计小伙伴在最开始入行的时候都认为,只要学好PS就可以稳打设计圈了~毕竟那么多公号一提到设 ...
- 深度学习与计算机视觉系列(1)_基础介绍
转载自: 深度学习与计算机视觉系列(1)_基础介绍 - 龙心尘 - 博客频道 - CSDN.NET http://blog.csdn.net/longxinchen_ml/article/detail ...
最新文章
- 表单美化-原生javascript和jQuery下拉列表(兼容IE6)
- 安卓四大组件之Activity
- android应用窗口模式,[技巧]如何启用Android N开发者预览版中的“自由窗口”模式...
- 使shell用结构化命令
- 最末参与者优化 lpo_优化博客以提高读者参与度的6种方法
- 深圳先进院研究生计算机专业,2020年中科院深圳先进技术研究院全日制硕士研究生统考专业说明...
- 安装MOSS2007全过程及创建网站的过程
- POJ1338 Ugly Numbers
- DHCP详细工作过程(转)
- wininet InternetOpen\InternetOpenUrl\InternetReadFile 等
- opengl画三维点_[500行代码学懂OpenGL]之一画点
- window和Linux下安装JDK配置环境变量
- 最好用的音轨分离软件spleeter:处理一首歌仅几秒,上线一周收获2.4k星 | 附实测...
- 开局一张图教你记住HTTP基本格式
- 机器学习(8): 逻辑回归算法 小结及实验
- c语言大赛评分用数组,C语言大赛现场评分系统
- Mac本终端连接服务器
- Accelerate Activity Tracker隐私政策
- 监听audio是否加载完毕
- 为人处世,请从学会闭嘴开始!
热门文章
- Faster R-CNN文章详细解读
- Oracle数据库命名编码规范
- 销售人员如何抓住客户?
- c语言程序只能有一个源程序文件,下列说法哪个正确?() A.一个程序可以包含多个源文件 B.一个源文件中只能有一个类 C.一个源文件中可以...
- 免费在线绘图软件推荐-processon
- Tushare Day4——导入IPO新股列表new_share并分析基金和盈利
- 灰色关联以及灰色预测GM(1,n),GM(1,1)模型(Python实现)
- 交通事故预测——《RiskOracle: A Minute-level Citywide Traffic Accident Forecasting Framework》
- 读到心醉,很美的文字
- 【ps合成】给男票做个Q版大头像