<!-- [if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]--><!-- [if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning/>
<w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:SpaceForUL/>
<w:BalanceSingleByteDoubleByteWidth/>
<w:DoNotLeaveBackslashAlone/>
<w:ULTrailSpace/>
<w:DoNotExpandShiftReturn/>
<w:AdjustLineHeightInTable/>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:UseFELayout/>
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!-- [if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><!-- [if !mso]>
<
classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id=ieooui>
</object>
<style>
st1\:*{behavior:url(#ieooui) }
</style>
<![endif]-->
<!--
/* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-alt:SimSun;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 680460288 22 0 262145 0;}
@font-face
{font-family:"\@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 680460288 22 0 262145 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
mso-pagination:none;
font-size:10.5pt;
mso-bidi-font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:宋体;
mso-font-kerning:1.0pt;}
/* Page Definitions */
@page
{mso-page-border-surround-header:no;
mso-page-border-surround-footer:no;}
@page Section1
{size:595.3pt 841.9pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:42.55pt;
mso-footer-margin:49.6pt;
mso-paper-source:0;
layout-grid:15.6pt;}
div.Section1
{page:Section1;}
-->
<!-- [if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]-->
参考资料:
1.
http://baike.baidu.com/view/1741385.htm
--
百度百科
MTD
2.
http://code.google.com/p/readingnotesofjoseph/source/browse/trunk/docs/soft-dev/mtd.txt?spec=svn85&r=85
--
mtd.txt
3.
http://www.linux-mtd.infradead.org/archive/index.html
--
Memory Technology Device (MTD) Subsystem for Linux
一、MTD
的概念和层次
MTD(memory
technology device
存储
技术设备
)
是用于访问
memory
设备(
ROM
、
flash
)的
Linux
的子系统。
MTD
的主要目的是为了使新的
memory
设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。
MTD
的所有源代码在
/drivers/mtd
子目录下
。[1]
传统上,
UNIX
只认识块设备和字符设备。字符设备是类似键盘或者鼠标的这类设备,你必须从它读取当前数据,但是不可以定位也没有大小。块设备有固定的大小并且可以定位,
它们恰好组织成许多字节的块,通常为
512
字节。
闪存既不满足块设备描述也不满足字符设备的描述。它们表现的类似块设备,但又有所不同。比如,块设备不区分写和擦除操作。因此,一种符合闪存特性的特殊设备类型诞生了,
就是
MTD
设备。所以
MTD
既不是块设备,也不是字符设备
。
[2]
关于
MTD
的层次,网络上有一张流传盛广的图片,如下所示,但是最初我看了这幅图根本是一点概念都没有的,不过通过看代码和网上查阅资料,知道了详细一点的分层结构,也纠正了一些前期对这张图的误解。
<!-- [if gte vml 1]><v:shapetype
id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t"
path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
<v:stroke joinstyle="miter"/>
<v:formulas>
<v:f eqn="if lineDrawn pixelLineWidth 0"/>
<v:f eqn="sum @0 1 0"/>
<v:f eqn="sum 0 0 @1"/>
<v:f eqn="prod @2 1 2"/>
<v:f eqn="prod @3 21600 pixelWidth"/>
<v:f eqn="prod @3 21600 pixelHeight"/>
<v:f eqn="sum @0 0 1"/>
<v:f eqn="prod @6 1 2"/>
<v:f eqn="prod @7 21600 pixelWidth"/>
<v:f eqn="sum @8 21600 0"/>
<v:f eqn="prod @7 21600 pixelHeight"/>
<v:f eqn="sum @10 21600 0"/>
</v:formulas>
<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
<o:lock v:ext="edit" aspectratio="t"/>
</v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" alt="" style='width:382.8pt;
height:213pt'/><![endif]--><!-- [if !vml]--><!-- [endif]-->
(
以下这部分纯属个人理解,如果有误,请高人拍砖
!)
为了方便理解,先声明两点:
1. xxx
层
(MTD
原始设备层,
MTD
块设备层
)
,实现封装的代码。
2. xxx
设备
(MTD
原始设备,
MTD
块设备
)
,是
xxx
层向下封装后呈现给上层的表象就
是一个
xxx
设备。
Flash
硬件驱动层:该层的基于特定处理器和特定
flash
芯片,这里以
pxa935
和Hynix
NAND 512MB 1.8V 16-bit
为例。使用类型为
nand_chip,
pxa3xx_nand_info, dfc_context, pxa3xx_bbm
这几个结构体来实现硬 件驱动。代码位于
drivers/mtd/nand
目录下。
MTD
原始设备层: 用类型
mtd_info
的结构体来描述
MTD
原始设备,该结构体中有一 个域会指向
Flash
硬件驱动层中所有使用的结构体
(
串联形式,另外
pxa3xx_bbm
结构体是只在底层驱动中使用
)
。
NAND flash
在嵌入式系统中通常需要划分多个分区,系统没有运
行起来的时候分区表现为
mtd_partition
类型的结构体数组,该数组由 工程师自己决定。在系统初始化,确切的说是在
nand
的驱动加载时 执行相应的
prob
函数时,会将上述数组中的每一个分区用类型为 mtd_part
的结构体来描述。因为
mtd_part
结构体中内嵌了一个 mtd_info
的结构体,所以每一个分区在系统看来都是一个
MTD
原始 设备,另外
mtd_part
种还有一个
master
指针,指向描述整片
flash
原 始设备的
mtd_info
结构体,所以这个描述整片
nand
的
mtd_info
结构 体也被叫做主分区。
在
MTD
原始设备层和其上层
MTD
块设备层
(FTL)
活跃着一个牛
X
的指针数组
mtd_table
,定义于文件
mtdcore.c
中,该数组就是所有 MTD
原始设备的指针列表
(
当然有数量限制,这里限制在
32
范围内
)
。 不过上面所说的主分区没有在
mtd_table
之列。
如果你系统中有
2
片
nand flash
,每个有
8
个分区,那么系统中总 共存在有
18
个
mtd_info
结构体对象,
mtd_table
数组中有
16
个指针 已经有归属。
本层和其上层
FTL
之间就全靠
mtd_table
数组和
mtd_notifiers
链表来
联系了
,至于如何联系的,下文再详细解释。
MTD
块设备层: 该层也叫flash
翻译层
(FTL)
。以前为了在
MTD
设备上使用某种传统 的文件系统,
linux
系统中存在一个叫做
flash
翻译层
(FTL)
,该
FTL
是在
MTD
原始设备的基础上模拟出块设备,所以
FTL
以下的所有内 容呈现给上层的就是一个块设备。这样可以使用通用的块设备的接口 了。
这里也存在一个著名的结构体指针数组,定义于
mtdblock.c
文件中, 其中的每一个指针均指向一个
struct mtdblk_dev
的类型的对象,每一 个
struct mtdblk_dev
类型的对象都是一个
MTD
块设备。
网上流传着说使用该
FTL
如何不好,这种观点其实是基于使用传统
文件系统存在的问题,现在有专门针对
nand flash
的
yaffs
日志型文 件系统了。所以那种掉电丢失数据的风险降低到了很小很小。
通用磁盘层:
再上层就是通用磁盘层了,其实每个分区在最后都是向通用磁盘层注 册成了一个
disk
来使用的,后面分析代码会看到这部分。当然对于 block
层的分析不在本文之中讨论。
<!-- [if gte vml 1]><v:shape
id="_x0000_i1029" type="#_x0000_t75" alt="" style='width:6.6pt;height:11.4pt'/><![endif]--><!-- [if !vml]--><!-- [endif]--><!-- [if gte vml 1]><v:shape id="_x0000_i1030"
type="#_x0000_t75" alt="" style='width:6.6pt;height:12.6pt'/><![endif]--><!-- [if !vml]--><!-- [endif]-->
下图是我自己画的草图, 表示向下封装,
表示向上呈现:
<!-- [if gte vml 1]><v:shape
id="_x0000_i1026" type="#_x0000_t75" alt="" style='width:400.2pt;height:234pt'/><![endif]--><!-- [if !vml]--><!-- [endif]-->
或许你读了上面的内容还是感触不深,不要紧,接下来和我一起分析代码吧!
我一直在纠结该怎么来安排代码分析的顺序,如果直接从硬件驱动开始,那细节的东西太多,不足以体现出
MTD
机制来,看来还是先来分析一下
MTD
块设备层
(FTL)
这一承上启下的一层吧。
下面是打印出来的模块初始化调用顺序,供大家娱乐一下:
...
[
3.513214] lizgo:calling
init_mtd+0x0/0x44 @ 1
[
3.517883] lizgo:calling
cmdline_parser_init+0x0/0x1c
@ 1
[
3.523468] lizgo:calling
init_mtdchar+0x0/0x98 @ 1
[
3.528594] lizgo:calling
init_mtdblock+0x0/0x1c
@ 1
[
3.533813] lizgo:calling
nand_base_init+0x0/0x14 @ 1
[
3.538909] lizgo:calling
pxa3xx_nand_init+0x0/0x30 @ 1
...
二、英文资料原文及翻译
[3]
:
MTD User modules
These are the modules which provide interfaces that
can be used directly from userspace. The user modules currently planned
include:
(MTD
子系统向上层提供的几种用户空间可直接使用的接口
)
Raw character access
(
原始字符设备
)
A character device which allows direct access to
the underlying memory. Useful for creating filesystems on the devices, before
using some of the translation drivers below, or for raw storage on
infrequently-changed flash, or RAM devices.
Raw block access
(
原始块设备
)
A block device driver which allows you to pretend(
假设
)
that the flash is a normal device with sensible(
合理的
) sector size. It actually works by caching a
whole flash erase block in RAM, modifying it as requested, then erasing the
whole block and writing back the modified data.
(
块设备驱动允许你假设
flash
有合理的扇区大小。它实际上是依靠缓存整个擦除块到
RAM
中,修改之后,擦除整个块,然后将数据回写到
flash
上。
)
This allows you to use normal filesystems on flash
parts. Obviously(
显然地
)
it's not particularly(
格外地
)
robust(
健壮
)
when you are writing to it - you lose a whole erase
block's worth of data if your read/modify/erase/rewrite cycle actually goes
read/modify/erase/poweroff. But for development, and for setting up filesystems
which are actually going to be mounted read-only in production units, it should
be fine.
(
这样就会允许你在某个分区上使用传统的文件系统,但是当你写数据的时候就会明显地降低了它的健壮性
-
当你的
read/modify/erase/rewrite
正常周期突然变成了
read/modify/erase/power
off
的话,那么你就会丢失正常的数据。如果你将存在于其上的文件系统
mount
成只读文件系统,这是没有问题的。
)
There is also a read-only version of this driver
which doesn't have the capacity to do the caching and erase/writeback, mainly
for use with uCLinux where the extra RAM requirement was considered too large.
(
存在一个只读版本的原始块设备驱动,该驱动没有缓存和擦除回写的能力,主要使用在
uCLinux
上
)
Flash Translation Layer (FTL)
NFTL
Block device drivers which implement an FTL/NFTL filesystem
on the underlying memory device.
FTL is fully functional. NFTL is currently working for both reading and
writing, but could probably do with some more field testing before being used
on production systems.
Journalling Flash File System, v2
This provides a filesystem directly on
the flash
, rather than emulating(
模拟
) a block device. For more information, see
sources.redhat.com
.
MTD hardware device drivers
These provide physical access(
物理访问
)
to memory devices, and are not used directly - they
are accessed through the user modules above(
他们是通过上层的用户模块来访问的
)
.
On-board memory
Many PC chipsets(
芯片组
)
are incapable of correctly(
不能正确地
)
caching system memory above 64M or 512M.
A driver exists which allows you to use this memory with the linux-mtd system. (
有些
PC
芯片组不能正确缓存高于
64M
或者
512M
的系统内存,那么就可以通过
linux
的
mtd
来使用这些内存
)
PCMCIA devices
PCMCIA flash (not CompactFlash but real flash) cards
are now supported by the pcmciamtd driver in CVS. (PCMCIA
闪存卡
-
不是
CF
卡但是是真实的
flash)
Common Flash Interface (CFI) onboard NOR
flash
This is a common solution and is well-tested and
supported, most often using JFFS2 or cramfs file systems.
Onboard NAND flash
NAND flash is rapidly overtaking NOR flash due to
its larger size and lower cost; JFFS2 support for NAND flash is approaching
production quality. (NAND
因其大容量和低成本正在飞速超越
NOR)
M-Systems' DiskOnChip 2000 and Millennium
The DiskOnChip 2000, Millennium and Millennium Plus
devices should be fully supported, using their native NFTL and INFTL
'translation layers'. Support for JFFS2 on DiskOnChip 2000 and Millennium is
also operational although lacking proper support for bad block handling.
CompactFlash
-
http://www.compactflash.org/
CompactFlash emulates an IDE disk, either through
the PCMCIA-ATA standard, or by connecting directly to an IDE interface.
As such, it has no business being on this page, as
to the best of my knowledge it doesn't have any alternative method of accessing
the flash - you have to use the IDE emulation - I mention it here for
completeness.
读了上面这些,下面的这张图应该比较容易理解吧!
<!-- [if gte vml 1]><v:shape
id="_x0000_i1027" type="#_x0000_t75" alt="" style='width:96pt;height:46.2pt'/><![endif]--><!-- [if !vml]--><!-- [endif]--><!-- [if gte vml 1]><v:shape id="_x0000_i1028"
type="#_x0000_t75" alt="" style='width:297pt;height:387pt'/><![endif]--><!-- [if !vml]--><!-- [endif]-->
下面是
MTD
设备节点的命名规则,这个使用什么样的用户访问接口有关系。
Table 7-1.
MTD /dev
/
entries, corresponding
(
对应的
) MTD user modules, and relevant
(
相应的
) device major numbers
|
/dev entry
|
Accessible
MTD user module
|
Device type
|
Major number
|
mtdN
|
char device
|
char
|
90
|
mtdrN
|
read-only
char device
|
char
|
90
|
mtdblockN
|
Block
device,
read-only
block
device, JFFS, and JFFS2
|
block
|
31
|
nftlLN
|
NFTL
|
block
|
93
|
ftlLN
|
FTL
|
block
|
44
|
Table 7-2.
MTD /dev
/
entries, minor
numbers, and naming schemes(
方案
)
|
/dev entry
|
Minor number
range
|
Naming scheme
|
|
mtdN
|
0 to 32 per
increments of 2
|
N
= minor / 2
偶数
|
|
mtdrN
|
1 to 33 per
increments of 2
|
N
= (minor - 1) / 2
奇数
|
|
mtdblockN
|
0 to 16 per
increments of 1
|
N
= minor
|
|
nftlLN
|
0 to 255 per sets of
16
|
L
= set;[2]
N
= minor -
(set - 1) x 16;N
is
not appended to entry name if its value is zero.
|
|
ftlLN
|
0 to 255 per sets of
16
|
Same as NFTL.
|
|
有了上面的这些预备知识,以后的代码分析或许会更加容易理解些!
分享到:
相关推荐
mtd-utils-2.0.2.tar.bz2 在使用openwrt进行编译的时候很容易出现下载 mtd-utils-2.0.2.tar.bz2 失败,那么就将该资源下载后放到openwrt/dl/文件夹下面
mtd-utils-1.5.0-2.el6.nux.i686.rpm安装包,需要的可以下载安装,mtd-utils工具
里面包含安装mtd-utils所有涉及到的安装包,给具有同样需求的人方便: mtd-utils-1.5.0.tar.bz2 lzo-2.06.tar.gz zlib-1.2.8.tar.gz
mtd-utils-arm
在S3C2410,AT91RM9200上移植的LINUX MTD驱动源码,已通过调试
最近在搞嵌入式linux运行下自动升级系统zImage,rootfs镜像等,需要用到mtd工具,下载了mtd-utils许多的版本,最后编译通过,拷贝到板子上使用,升级系统成功了
mtd-utils_arm-none-linux-gnueabi-gcc
mtd-utils-05.07.23.tar.bz2是MTD设备的工具包,编译它生成mkfs.jffs2工具,用它来将一个目录制作成jffs2文件系统映像. 这个工具包需要zlib压缩包,需要有zlib源码zlib-1.2.3.tar.gz
mtd-utils-1.5.0.tar.bz2,编译ubinize
mtd-utils v1.5.2 版本 mtd-utils v1.5.2 版本 mtd-utils v1.5.2 版本 mtd-utils v1.5.2 版本 mtd-utils v1.5.2 版本
到三个工具,分别是:lzo-2.03.tar.gz 、zlib-1.2.3.tar.bz2 、mtd-utils-1.2.0.tar.bz2 安装的过程如下: 1、首先创建工具的安装目录。 #mkdir /build_dir/build_jffs2 #cd /build_dir/build_jffs2 将上述三个工具...
mtd-utils-1.4.9.tar.bz2
mtd-utils-1.4.8.tar.gz源代码
mtd-utils 2020年6月份更新的版本
mtd-utils-1.4.1.tar.bz2,ftp://ftp.infradead.org/pub/mtd-utils/
mtd-utils-1.0.0.tar.gz源码,要的就下了,哈哈。 我行好吧,将一些相关资料也打包上来了
mtd-utils系列工具包源碼及fs-test測試檔
当前最新的mtd-utils版本1.5的源码,需要的拿去
Linux系统下的flash驱动程序源代码,芯片为s3c2410,nand Flash驱动位置文件主要在nand目录下,nor Flash 驱动配置文件主要在maps目录下。
MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。mtd-utils提供了操作flash的工具集。