MTD技术介绍
MTD(Memory Technology device)是用于访问memory设备(ROM、Flash)的Linux子系统,在Linux中引入这一层的主要目的是为了更加简单的添加新的Memory存储设备,它提供一层抽象的接口。
从上图可以看出,mtd原始设备层可以让底层Flash以字符设备呈现为应用层,表现形式为/dev/mtdN,也可以以块设备呈现给应用层,表现形式为/dev/mtdblockN。在应用层面上,对于字符形式的Flash设备,可以通过mtd-utils工具来控制。对于块设备形式的Flash设备,可以通过mount、umount命令来控制。
1. 硬件驱动层
硬件驱动层负责在初始化时,驱动Flash硬件,Linux MTD设备的Nor Flash芯片驱动遵循CFI接口标准规范,其驱动程序位于drivers/mtd/chips目录下。Nand Flash驱动代码位于/drivers/mtd/nand/子目录下。
2. MTD原始设备层
该层的上面为MTD原始设备的通用代码,下面为各个特定Flash的接口代码。因为这一层要封装不同Flash的操作接口,向上提供统一接口,因此,应该是有一个通用的操作接口设备描述符,里面包含了常见的所有flash设备的操作数据和操作方法。在MTD中,使用mtd_info来描述。
mtd_info,描述MTD原始设备层,定义了大量关于mtd的数据和操作函数。每一个mtd_info都代表一个抽象的MTD设备分区,这些设备保存在一个设备数组mtd_table中。对于每一个虚拟的MTD设备,它应该包含一些分区相关的信息,这些信息用mtd_part来描述。
1: struct mtd_part {
2: struct mtd_info mtd; //mtd_info数据结构,会被加入mtd_table中
3: struct mtd_info *master; //该分区的主分区
4: uint64_t offset; //该分区的偏移地址
5: struct list_head list; //分区链表
6: };
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
从内核代码的函数组织构造上来看,对于上述mtd_info和mtd_table的操作,肯定有相关函数。
add_mtd_device : 将特定mtd_info分区信息加入mtd_table中,
del_mtd_device : 将特定mtd_info分区信息从mtd_tabe中移除。
add_mtd_partitions:将特定mtd_info的特定分区信息加入mtd_table中,函数原型如下:
/*
* This function, given a master MTD object and a partition table, creates
* and registers slave MTD objects which are bound to the master according to
* the partition definitions.
* (Q: should we register the master MTD object as well?)
*/ int add_mtd_partitions(struct mtd_info *master, //MTD原始设备
const struct mtd_partition *parts, //Nand 分区信息
int nbparts) //有几个分区
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
其中的parts和nbparts是由static struct mtd_partition XXXXXXXX[ ] 来决定,可以在kernel中硬编码,也可以通过bootloader传递给kernel来决定。一般只要给出每个分区的name,offset和size就足够了。
一个MTD原始设备可以通过mtd_part分割成数个MTD原 始设备注册进mtd_table,
mtd_table中的每个MTD原始设备都可以被注册成一个MTD设备,
有两个函数可以完成这个工作,即 add_mtd_device函数和add_mtd_partitions函数。
其中add_mtd_device函数是把整个NAND FLASH注册进MTD Core,
而add_mtd_partitions函数则是把NAND FLASH的各个分区分别注册进MTD Core。
3. MTD设备层
基于MTD原始设备层,Linux系统定义出MTD的块设备(主设备号为31)和字符设备(主设备号为90)。其中,块设备通过一个描述mtd块设备的结构体mtdblk_dev,结合对于的mtdblks的指针数组,形成于mtd_table中的mtd_info的一一对应关系。
字符设备和普通字符设备一样,通过注册一系列file_operation函数(lseek,open,close,write,read)。
4. 设备节点
在系统初始化时,通过udev或者mdev自动发现挂载设备,在dev目录下创建mtd字符设备节点(/dev/)和块设备节点
5. 根文件系统和文件系统
内核启动之后,通过mount命令将flash中其他分区作为文件系统挂载上。
从类型上来看,mtd核心部分初始化可以分为两个部分,字符设备的mtd层初始化和块设备的mtd层初始化。
MTD读写操作
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相关,就是这部分函数与硬件交互,通常需要我们自己来实现。(注:这里提到的read,write_oob,cmdfunc等,其实 都是些函数指针,所以这里所说的函数,是指这些函数指针所指向的函数,以后本文将不再另做说明。)
值得一提的是,struct nand_chip中的读写函数虽然与具体的NAND controller相关,但是MTD也为我们提供了default的读写函数,如果你的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中的读写函数。
以读NAND芯片为例,讲解一下这三部分读写函数的工作过程。
首先,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://blog.csdn.net/leibniz_zsu/article/details/4977650
http://blog.csdn.net/leibniz_zsu/article/details/4977842
http://blog.csdn.net/leibniz_zsu/article/details/4977842
MTD技术介绍的更多相关文章
- .Net环境下的缓存技术介绍 (转)
.Net环境下的缓存技术介绍 (转) 摘要:介绍缓存的基本概念和常用的缓存技术,给出了各种技术的实现机制的简单介绍和适用范围说明,以及设计缓存方案应该考虑的问题(共17页) 1 概念 ...
- RAID技术介绍
RAID技术介绍 简介 RAID是一个我们经常能见到的名词.但却因为很少能在实际环境中体验,所以很难对其原理 能有很清楚的认识和掌握.本文将对RAID技术进行介绍和总结,以期能尽量阐明其概念. RAI ...
- .Net环境下的缓存技术介绍
.Net环境下的缓存技术介绍 摘要: 介绍缓存的基本概念和常用的缓存技术,给出了各种技术的实现机制的简单介绍和适用范围说明,以及设计缓存方案应该考虑的问题(共17页) 1 概念 1.1 ...
- 网络存储技术介绍(1) ( based on zt)
最近由于某同学微信发了一些网络存储的文章,开始感兴趣,稍微收集了一些 一. 网络存储技术 http://ask.zol.com.cn/q/187044.html (yxr:很老的技术介绍吧) 网络 ...
- (转) SLAM系统的研究点介绍 与 Kinect视觉SLAM技术介绍
首页 视界智尚 算法技术 每日技术 来打我呀 注册 SLAM系统的研究点介绍 本文主要谈谈SLAM中的各个研究点,为研究生们(应该是博客的多数读者吧)作一个提纲挈领的摘要.然后,我 ...
- VPS技术介绍以及分析
VPS的全称为Virtual Private Server,叫做虚拟专用服务器(Godaddy称之为Virtual Dedicated Server,VDS).就是利用各种虚拟化手段把单台物理服务器虚 ...
- 转:Android 2.3 代码混淆proguard技术介绍
ProGuard简介 ProGuard是一个SourceForge上非常知名的开源项目.官网网址是:http://proguard.sourceforge.net/. Java的字节码一般是非常容易反 ...
- WPF开发技术介绍
本月做了一个小讲座,主要是WPF的开发技术介绍,由于是上班时间,去听的人不多,但对于自己来说至少是又巩固了Winform的知识,抽时间写一篇文章,在此分享给大家,有什么宝贵建议大家也可以提给我,谢谢. ...
- Portal技术介绍
Portal技术介绍 Portal是web应用发展的一个重要趋势,目前几乎所有大的软件厂商都有自己的Portal产品.并且Portal技术已经形成规范.本文对Portal技术和产品进行了分析,目的 ...
随机推荐
- 死锁相关 变量 与 PURGE 线程停止
http://www.tuicool.com/articles/NzAFZn https://github.com/percona/percona-server/pull/83/commits/091 ...
- MySQL数据库InnoDB存储引擎中的锁机制
MySQL数据库InnoDB存储引擎中的锁机制 http://www.uml.org.cn/sjjm/201205302.asp 00 – 基本概念 当并发事务同时访问一个资源的时候,有可能 ...
- Visual Studio Code 1.0.1 for python
1. 安 F1健 ext install python E:\test\.vscode下的三个文件 2.launch.json { "version": "0.1.0&q ...
- 无需图片,使用CSS3实现圆角按钮[转]
首先来看看效果: 事例HTML代码: <a href="#" class="button green">button</a> < ...
- c#如何在win7下设置IE代理的完美解决方案
有人还发现:在window7下, 在一个进程中, 设置和取消不能都执行,---- 要么设置,要么取消. 但如果第一次运行时,只进行设置代理,退出后再进运行,只进行取消,这是没有问题的. 简单说说中医 ...
- 如何在Fedora或CentOS上使用Samba共享
如今,无论在家里或者是办公场所,不同的电脑之间共享文件夹已不是什么新鲜事了.在这种趋势下,现代操作系统通过网络文件系统的方式使得电脑间数据的交换变得简单而透明.如果您工作的环境中既有微软的Window ...
- 项目源码--Android美图秀秀源码
下载源码 技术要点: 1. 多种分类分享高清图片 2. 图片缓存技术 3. 图片缩图显示 4. 图片实时加载技术 5. 多点触控技术 6. HTTP网络数据搜索技术 7. 精美UI图片显示 ...
- 如何编写自己的Linux安全检查脚本?
因为本人工作中要涉及到很多东西,审计(日志.数据神马的).源代码审计.渗透测试.开发一大堆东西,有些东西,越是深入去做,越会发现,没有工具或脚本,工作起来是有多么的坑. 工作的这段时间,自己写了几个工 ...
- 从零开始学JAVA(04)-连接数据库MSSQL(JDBC准备篇)
在JAVA中可以使用JDBC连接数据库,不管是哪种数据库,首先必须下载驱动,包括Windows的MSSQL. 1.下载MSSQL的JDBC驱动,可以通过百度“Microsoft JDBC Driver ...
- 测试你是否和LTC水平一样高
Problem Description 大家提到LTC都佩服的不行,不过,如果竞赛只有这一个题目,我敢保证你和他绝对在一个水平线上!你的任务是:计算方程x^2+y^2+z^2= num的一个正整数解. ...