MTD 设备是象闪存芯片、小型闪存卡、记忆棒等之类的设备,它们在嵌入式设备中的使用正在不断增长。

MTD 驱动程序是在 Linux 下专门为嵌入式环境开发的新的一类驱动程序。相对于常规块设备驱动程序,使用 MTD 驱动程序的主要优点在于 MTD 驱动程序是专门为基于闪存的设备所设计的,所以它们通常有更好的支持、更好的管理和基于扇区的擦除和读写操作的更好的接口。Linux 下的 MTD 驱动程序接口被划分为两类模块:用户模块和硬件模块。

MTD 驱动程序设置 
为了访问特定的闪存设备并将文件系统置于其上,需要将 MTD 子系统编译到内核中。这包括选择适当的 MTD 硬件和用户模块。当前,MTD 子系统支持为数众多的闪存设备 ― 并且有越来越多的驱动程序正被添加进来以用于不同的闪存芯片。

有两个流行的用户模块可启用对闪存的访问: MTD_CHAR 和 MTD_BLOCK 。 
MTD_CHAR 提供对闪存的原始字符访问,而 MTD_BLOCK 将闪存设计为可以在上面创建文件系统的常规块设备(象 IDE 磁盘)。与 MTD_CHAR 关联的设备是 /dev/mtd0、mtd1、mtd2(等等),而与 MTD_BLOCK 关联的设备是 /dev/mtdblock0、mtdblock1(等等)。由于 MTD_BLOCK 设备提供象块设备那样的模拟,通常更可取的是在这个模拟基础上创建象 FTL 和 JFFS2 那样的文件系统。

为了进行这个操作,可能需要创建分区表将闪存设备分拆到引导装载程序节、内核节和文件系统节中。
Linux 中 MTD 子系统的主要目标是在系统的硬件驱动程序和上层,或用户模块之间提供通用接口。硬件驱动程序不需要知道象 JFFS2 和 FTL 那样的用户模块使用的方法。所有它们真正需要提供的就是一组对底层闪存系统进行 read 、 write 和 erase 操作的简单例程。

MTD 驱动程序是专门针对嵌入式Linux的一种驱动程序,相对于常规块设备驱动程序(比如PC中的IDE硬盘)而言,MTD驱动程序能更好的支持和管理闪存设备,因为它本身就是专为闪存设备而设计的。MTD设备是指不同于传统字符设备和块设备的flash存储设备,使得上层的文件系统像访问传统的字符或块设备一样访问flash,为上层软件系统提供一个同一的接口。
    具体地讲,基于MTD的FLASH驱动,承上可以很好地支持cramfs,jffs2和yaffs等文件系统,启下也能对FLASH的擦除,读写,FLASH坏块以及损耗平衡进行很好的管理。所谓损耗平衡,是指对NAND的擦写不能总是集中在某一个或某几个block中,这是由NAND芯片有限的擦写次数的特性决定的。

一、MTD 的概念和层次

MTD(memory technology device 存储 技术设备 ) 是用于访问 memory 设备( ROM 、 flash )的 Linux 的子系统。 MTD 的主要目的是为了使新的 memory 设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。 MTD 的所有源代码在 /drivers/mtd 子目录下 。[1]

传统上, UNIX 只认识块设备和字符设备。字符设备是类似键盘或者鼠标的这类设备,你必须从它读取当前数据,但是不可以定位也没有大小。块设备有固定的大小并且可以定位, 它们恰好组织成许多字节的块,通常为 512字节。

闪存既不满足块设备描述也不满足字符设备的描述。它们表现的类似块设备,但又有所不同。比如,块设备不区分写和擦除操作。因此,一种符合闪存特性的特殊设备类型诞生了, 就是 MTD 设备。所以 MTD 既不是块设备,也不是字符设备 。 [

二. 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.

uboot 与系统内核中MTD分区的关系:

分区只是内核的概念,就是说A~B地址放内核,C~D地址放文件系统,(也就是规定哪个地址区间放内核或者文件系统)等等。

1:在内核MTD中可以定义分区A~B,C~D。。。。。。并予以绝对的地址赋值给每个分区。我们可以来看看在内核中是怎样来对MTD进行分区的:arch/arm/plat-s3c24xx/common-smdk.c

static struct mtd_partition smdk_default_nand_part[] = {
 [0] = {
  .name = "Boot",
  .size = SZ_16K,
  .offset = 0,
 },
 [1] = {
  .name = "S3C2410 flash partition 1",
  .offset = 0,
  .size = SZ_2M,
 },
 [2] = {
  .name = "S3C2410 flash partition 2",
  .offset = SZ_4M,
  .size = SZ_4M,
 },
 [3] = {
  .name = "S3C2410 flash partition 3",
  .offset = SZ_8M,
  .size = SZ_2M,
 },
 [4] = {
  .name = "S3C2410 flash partition 4",
  .offset = SZ_1M * 10,
  .size = SZ_4M,
 },

......
 };

一般我们只需要分3-4个区,第一个为boot区,一个为boot参数区(传递给内核的参数),一个为内核区,一个为文件系统区。

而对于bootloader中只要能将内核下载到A~B区的A地址开始处就可以,C~D区的C起始地址下载文件系统。。。这些起始地址在MTD的分区信息中能找到。所以bootloader对分区的概念不重要,只要它能把内核烧到A位置,把文件系统烧到C位置。
所以,在bootloader对Flash进行操作时,哪块区域放什么是以内核为主。

而为了方便操作,bootloader类似也引入分区的概念,如,可以使用“nand write 0x3000000 kernel 200000”命令将uImage烧到kernel分区,而不必写那么长:nand write 3000000 A 200000,也就是用分区名来代替具体的地址。

这要对bootloader对内核重新分区:这需要重新设置一下bootloader环境参数,就可以同步更新内核分区信息

如:

setenv bootargs 'noinitrd console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2

mtdparts=nand_flash:128k(u-boot)ro,64k(u-boot envs),3m(kernel),30m(root.jffs2),30m(root.yaffs)'

内核配置时选上Device Drivers  ---> Memory Technology Device (MTD) support  ---> Command line partition table parsing

在设置了mtdparts变量之后,就可以在nand read/write/erase命令中直接使用分区的名字而不必指定分区的偏移位置.而这需要内核MTD最好没有规划分区。

如果你是通过uboot的内核命令行给MTD层传递MTD分区信息,这种情况下,内核读取到的分区信息始终和u-boot中的保持一致(推荐的做法)

如果你是把分区信息写在内核源代码MTD里定义好的方法,那最好保证它和u-boot中的保持一致,即同步修改uboot及内核的相关部分。

2:

内核通过bootargs找到文件系统,bootargs中的mtdblockx即代表分区,block1,2,3代表哪个分区。

事实上,bootargs中的"root=/dev/mtdblockx"只是告诉内核,root fs从第x个(x=0,1,2...)MTD分区挂载,mtdblock0对应第一个分区,mtdblock1对应第二个分区,以此类推.

3:分区方法

1) MTD层的分区

2) 通过U-boot传递给内核的命令行中的mtdparts=...

3) 其他可以让内核知道分区信息的任何办法,(内核默认的命令参数)

下面说到mtdparts,及它的用法:

mtdparts

mtdparts=fc000000.nor_flash:1920k(linux),128k(fdt),20M(ramdisk),4M(jffs2),38272k(user),256k(env),384k(uboot)

要想这个参数起作用,内核中的mtd驱动必须要支持,即内核配置时需要选上Device Drivers  ---> Memory Technology Device (MTD) support  ---> Command line partition table parsing

mtdparts的格式如下:

mtdparts=<mtddef>[;<mtddef]

<mtddef>  := <mtd-id>:<partdef>[,<partdef>]

<partdef> := <size>[@offset][<name>][ro]

<mtd-id>  := unique id used in mapping driver/device

<size>    := standard linux memsize OR "-" to denote all remaining space

<name>    := (NAME)

因此你在使用的时候需要按照下面的格式来设置:

mtdparts=mtd-id:<size1>@<offset1>(<name1>),<size2>@<offset2>(<name2>)

这里面有几个必须要注意的:

a.  mtd-id 必须要跟你当前平台的flash的mtd-id一致,不然整个mtdparts会失效 怎样获取到当前平台的flash的mtd-id?

在bootargs参数列表中可以指定当前flash的mtd-id,如指定 mtdids:nand0=gen_nand.1,前面的nand0则表示第一个flash

b.  size在设置的时候可以为实际的size(xxM,xxk,xx),也可以为'-'这表示剩余的所有空间。

相关信息可以查看drivers/mtd/cmdlinepart.c中的注释找到相关描述。

MTD和 uboot中的bootargs 下属 mtdparts相关推荐

  1. 如何写死 u-boot 中的 bootargs

    最近在论坛中有朋友问如何写死 u-boot 中的 bootargs command,这里我就为大家整理一下,方便大家查看.i.mx 系列产品在启动时,最先起来的是 u-boot,u-boot 起来以后 ...

  2. 关于NAND flash的MTD分区与uboot中分区的理解 .

    今天做内核移植,准备添加NAND flash的驱动,做到MTD分区时,想起在一本书上看到的一句话,说的是分区时每个区之间没有间隙,前一个区的结束地址是后一个区的起始地址.可是当我看我的开发板的教程时, ...

  3. U-boot中控制台命令

    u-boot学习笔记如下: 用j-link commder 烧写nand flash(只能借助sdram来间接烧写) nand flash启动时候,我们接着s3c2440芯片内部的sram来烧写. r ...

  4. JZ2440在U-boot中通过网络方式烧录镜像的几种方法

    在线课堂:https://www.100ask.net/index(课程观看) 论  坛:http://bbs.100ask.net/(学术答疑) 开 发 板:https://100ask.taoba ...

  5. U-boot中常用参数设定及常用宏的解释和说明

    uboot功能很强,支持各种各样的启动方式,如:U盘启动,NFS启动,NAND Flash启动,NOR Flash启动-- 1.环境变量的存储设置 如u-boot中的savenv命令,它用来保存系统的 ...

  6. uboot中变量env(收集)

    Env在u-boot中通常有两种存在方式,在永久性存储介质中(flash.NVRAM等),在SDRAM中.可配置不适用env的永久存储方式,但不常用.U-boot在启动时会将存储在永久性存储介质中的e ...

  7. 关于Yaffs2在u-boot中的支持

    开发板是一块2G的MLC的NandFlash,页大小8k+512,为其移植u-boot到yaffs2这了.以前在Mini2440上移植过2k+64的slc的NandFlash的Yaffs2支持,当然也 ...

  8. uboot 下spinand 驱动移植 ———1.驱动接口的添加到uboot中

    前面有篇文章谈到:https://blog.csdn.net/clam_zxf/article/details/108834541 平台驱动和单片机驱动异同,同样可以将uboot 除去它的引导加载:所 ...

  9. u-boot中filesize环境变量【转载】

    转载地址:https://blog.csdn.net/fzs333/article/details/48518559 U-Boot中的环境命令可以使用$(filesize)来确定刚下载(传输)得到的文 ...

最新文章

  1. 数据链路层和传输层的区别
  2. 刚接手的项目代码 怎么看_11.21号动态:音恋今天公告称团队刚接手这个项目没多久...
  3. 【转载】Oracle10g数据类型总结
  4. 文章内容页调用所属栏目地址的标签
  5. 常见Java面试题之静态变量和实例变量的区别
  6. 深入理解JavaScript this
  7. go 字符串替换_Go语言爱好者周刊:第 64 期 — goup 这个工具了解下
  8. mysql执行效率低_如何查询mysql中执行效率低的sql语句
  9. 每日算法系列【LeetCode 810】黑板异或游戏
  10. 关于身份证OCR识别,你知道多少?
  11. 微信小程序问答论坛+后台管理系统
  12. Arduino AT24C02详解读写地址位
  13. 收费java代码_基于jsp的高速公路收费-JavaEE实现高速公路收费 - java项目源码
  14. 冬瓜哥对时间和空间的理解方式—时空参悟(上)
  15. 带你了解软件系统架构的演变
  16. Python 从底层结构聊 Beautiful Soup 4(内置豆瓣最新电影排行榜爬取案例)
  17. RAID5换硬盘重建记录
  18. 自然语言和计算机语言二义性,二级C++精品课程第一章第一节计算机语言及其发展...
  19. SEO人员,为什么要做流量过滤,如何操作?
  20. AndroidQ 锁屏密码验证流程之GateKeeper解析

热门文章

  1. 网站大流量高并发访问的处理解决办法
  2. 138.括号序列(区间型DP)
  3. viewController的生命周期
  4. linux find prune排除某目录或文件
  5. JavaMail中解决中文附件名乱码的问题
  6. js eval()函数
  7. Jquery CheckBox全选方法
  8. 液压支架销轴力学计算分析研究_基于RFID射频精准定位的智能开采研究与应用...
  9. Linux监控CPU关闭服务器,监控Linux服务器CPU和内存
  10. firewallD卸载Linux,在Ubuntu 18.04/16.04系统上安装和使用Firewalld的方法