`
womendu
  • 浏览: 1516566 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

MTD系列 - 关于linux MTD的一些理解

阅读更多

<!-- [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-1.0.0.tar.gz

    在嵌入式系统开发领域,MTD(Memory Technology Device)是Linux内核中用于处理非易失性存储器如闪存的一种抽象层。mtd-utils是一个针对MTD设备的实用工具集合,包括了对这些设备的读写、擦除等操作。本文将围绕"mtd...

    mtd-utils-1.4.8.tar.gz

    总的来说,mtd-utils-1.4.8.tar.gz是一个对MTD设备进行管理和维护的重要工具集,其源代码对于理解Linux系统对非易失性存储的管理方式,以及如何编写针对这类硬件的实用程序具有极高的学习价值。无论是对驱动开发人员...

    mtd-utils移植

    《MTD-utils移植详解》 ...完成MTD-utils的移植工作,不仅可以提升对嵌入式系统和Linux内核的理解,也有助于掌握软件编译、调试和依赖管理的技能。对于从事嵌入式开发的工程师来说,这是一项非常有价值的实践。

    mtd-for-linux.zip_mtd _mtd nand

    在你提供的压缩包"mtd-for-linux.zip_mtd_mtd_nand"中,包含了一系列与MTD相关的源代码文件,主要针对S3C2410芯片上的NAND Flash驱动。 S3C2410是一款由Samsung生产的微处理器,广泛应用于嵌入式系统和移动设备,它...

    mtd-snapshot_20050519.tar.gz

    标题 "mtd-snapshot_20050519.tar.gz" ...总的来说,"mtd-snapshot_20050519.tar.gz" 是一个关于Linux MTD子系统的资源包,可能包含源码、文档或更新,适用于开发者和系统管理员,他们需要理解和维护使用MTD的系统。

    mtd-utils-2.0.0-mkfs.zip

    2. **理解MTD**:MTD模型与传统的块设备(如硬盘)不同,它不支持随机写入,而是采用擦除/写入的方式,因此对应的文件系统需要特别设计以适应这种特性。 3. **编译与配置**:mtd-utils通常需要针对具体硬件进行编译...

    mtd-utils_2.0.0.orig.tar.gz

    解决这些问题需要深入理解mtd-utils的内部机制、Linux内核驱动模型以及Hi3516A的硬件特性。同时,查阅官方文档、在线论坛和技术博客将有助于找到解决方案。 总之,mtd-utils 2.0.0是海思Hi3516A开发环境的关键组成...

    mini2440 安装 mtd-utils

    2. **理解WITHOUT_XATTR参数**:该参数的作用是让mtd-utils的某些源码不使用acl.h的库文件,而是使用zlib.h中的库文件。例如,在mkfs.jffs2.c源码文件中,可以看到如下代码段: ```c #ifndef WITHOUT_XATTR #...

    mtd-util arm源码

    总结,mtd-utils arm源码的分析有助于我们理解嵌入式Linux系统中MTD设备的管理方法,特别是对于开发和维护基于ARM架构的嵌入式系统具有重要的实践意义。通过对源码的阅读和研究,开发者可以更好地掌握如何利用这些...

    mtd-utils-1.4.5.tar.gz

    mtd-utils是一个用于Linux MTD子系统的命令行工具包,它包含了诸如nandwrite、nandread、flash_eraseall等一系列命令,用于对MTD设备进行读写、擦除等操作。例如,nandwrite用于将数据写入 NAND 闪存,而nandread则...

    在ubuntu 10.10上交叉编译编译 mtd-utils及使用UBIFS

    mtd-utils包含了一系列用于管理和操作MTD设备的实用程序,如NAND闪存等。 - 下载mtd-utils源码:`wget http://debian.mirror.inra.fr/debian/pool/main/m/mtd-utils/mtd-utils_20090606.orig.tar.gz` - 修改`...

    mtd-utils v1.5.2 版本

    对于那些需要对嵌入式系统进行深度定制和管理的开发者而言,理解和掌握mtd-utils的使用至关重要。通过这个工具集,他们能够更高效地管理存储资源,提高系统的可靠性和耐用性。 总之,mtd-utils v1.5.2是Linux环境下...

    mtd-utils-1.4.5

    《mtd-utils-1.4.5:OpenWrt构建中的关键工具》 在嵌入式系统和物联网(IoT)领域,OpenWrt是一个广泛使用...对于任何涉及OpenWrt项目的工程师来说,理解和熟练使用`mtd-utils`都是提升工作效率和系统可靠性的必要技能。

    Linux_MTD.rar_Linux_MTD_jim_linux mtd_mtd linux

    "Linux MTD源代码分析"文档可能详细解释了这些概念,并通过实例展示了如何理解和调试MTD驱动。文档可能包括了代码片段、流程图和实际操作步骤,帮助读者理解源代码的逻辑。 www.pudn.com.txt文件可能是链接到更详细...

    Linux_MTD.rar_Linux_MTD_linux mtd_mtd

    总之,Linux MTD是Linux内核中一个至关重要的部分,对于理解和开发与非易失性存储器相关的系统和应用有着深远的影响。通过深入研究MTD的源代码和相关文档,开发者可以掌握构建高效、可靠的闪存驱动的技巧。

    mtd.rar_linux mtd flash_linux 分区_mtd _mtd driver

    标题中的“mtd.rar_linux”可能是指一个关于Linux MTD驱动程序的压缩包,可能包含了源代码、文档或示例。它关注的是如何在Linux环境下对MTD驱动进行操作,特别是在处理闪存分区方面。 描述中提到的“实现了多个分区...

    mtd.rar_MTD软件_linux mtd_linux mtd设备_modbus_mtd

    "mtd.rar"中包含的源代码可能是用于Linux环境下的MTD设备操作工具,可能包括了设备驱动、用户空间的应用程序或者是一些实用工具。移植源代码到新的工程中,需要确保目标系统支持MTD子系统,并且要根据目标硬件的特性...

    linux_mtd.rar_linux mtd_mtd 层_mtd层

    在描述中提到的代码可能是对MTD层的源代码分析或修改,包含了一些注释以帮助理解代码的工作原理。通过这些代码,开发者可以学习如何编写MTD驱动,理解设备是如何被初始化、如何处理I/O请求,以及如何处理擦除和编程...

Global site tag (gtag.js) - Google Analytics