MTD和 uboot中的bootargs 下属 mtdparts

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中的注释找到相关描述。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383450.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux应用程序在内存中的地址布局

栈&#xff1a;局部变量&#xff08;初始化的和未初始化的&#xff0c;但不包含局部静态变量&#xff09;、局部只读变量&#xff08;const&#xff09;堆&#xff1a;动态分配的区域&#xff08;如使用malloc函数申请的区域&#xff09;BSS段&#xff1a;存储未初始化的全局变…

比较zImage和uImage的区别

一、vmlinuz vmlinuz是可引导的、压缩的内核。“vm”代表“Virtual Memory”。Linux 支持虚拟内存&#xff0c;不像老的操作系统比如DOS有640KB内存的限制。Linux能够使用硬盘空间作为虚拟内存&#xff0c;因此得名“vm”。 vmlinuz的建立有两种方式。一是编译内核时通过“make…

编译faac错误分析

编译faac时遇到了以下的编译错误&#xff1a; /home/xuxuequan/Ingenicwork/toolchain/mips-gcc472-glibc216-32bit/mips-linux-gnu/libc/usr/include/string.h:365:26: error:ambiguates old declaration const char* strcasestr(const char*, const char*) 解决方案&#x…

gcc与g++的区别

一&#xff1a;gcc与g比较 编译c/c代码的时候&#xff0c;有人用gcc&#xff0c;有人用g&#xff0c;于是各种说法都来了&#xff0c;譬如c代码用gcc&#xff0c;而 c代码用g&#xff0c;或者说编译用gcc&#xff0c;链接用g&#xff0c;一时也不知哪个说法正确&#xff0c;如果…

交叉编译openssl不修改Makefile的方法

网上流传的方法都是要修改Makefile的cc值&#xff0c;我来说个不用修改的方法作者&#xff1a;帅得不敢出门 C哈哈堂<31843264>openssl 下载http://www.openssl.org/source/tar -xvf openssl-1.0.1c.tar.gzcd openssl-1.0.1c/CCarm-linux-gcc ./config no-asm shared -…

编译boa过程记录

boa是比较老的HTTP的本地Server&#xff0c;本文是针对0.94.13版本的编译过程做出记录 1.下载boa的程序包&#xff0c;本文的编译是针对misp平台的交叉编译 2.在编译之前&#xff0c;需要针对产品的文件系统和修改编译时可能遇到的错误&#xff0c;修改相关的文件。 &#xff…

/dev/null 21 的作用

shell中可能经常能看到&#xff1a;>/dev/null 2>&1命令的结果可以通过%>的形式来定义输出/dev/null 代表空设备文件> 代表重定向到哪里&#xff0c;例如&#xff1a;echo "123" > /home/123.txt1 表示stdout标准输出&#xff0c;系统默认值是1&a…

移植wpa_supplicant 2.2问题

1.编译libnl1.1问题 In file included from addr.c:28:0: ../include/netlink-local.h: In function __str2type: ../include/netlink-local.h:218:11: error: ULONG_MAX undeclared (first use in this function) ../include/netlink-local.h:218:11: note: each undeclared …

wpa_supplicant与wpa_cli之间通信过程

wpa_supplicant编译&#xff1a; 1. wpa_supplicant/Android.mk : -- wpa_cli -- wpa_supplicant -- libwpa_client.so 2. hostapd/Android.mk : -- hostapd_cli -- hostapd 从通信层次上划分&#xff0c;wpa_supplicant提供向上的控制接口 control interface&#xff0c;用于与…

Linux内核驱动之GPIO子系统(一)GPIO的使用

一 概述 Linux内核中gpio是最简单&#xff0c;最常用的资源(和 interrupt ,dma,timer一样)驱动程序&#xff0c;应用程序都能够通过相应的接口使用gpio&#xff0c;gpio使用0&#xff5e;MAX_INT之间的整数标识&#xff0c;不能使用负数,gpio与硬件体系密切相关的,不过linux有一…

gpio_direction_output 与 gpio_set_value

gpio_set_value&#xff08;port_num,0/1&#xff09; 一般只是在这个GPIO口的寄存器上写上某个值&#xff0c;至于这个端口是否设置为输出&#xff0c;它就管不了&#xff01; 而gpio_direction_output &#xff08;port_num,0/1)&#xff0c;在某个GPIO口写上某个值之后&…

内核ko模块strip使用

编译一个内核时&#xff0c;习惯性的在install目标下加了命令&#xff1a; $(STRIP) --strip-all --remove-section.note --remove-section.comment test.ko 结果在insmod test.ko时出现错误&#xff1a; test: module has no symbols (stripped?) .................. 上…

ubuntu下修复U盘只读问题

1.通过mount指令查看u盘挂载的实际设备 /dev/sdb1 on /media/xuxuequan/0BEB-331A type vfat (rw,nosuid,nodev,uid1000,gid1000,shortnamemixed,dmask0077,utf81,showexec,flush,uhelperudisks2) 2.umount挂载点 umount /media/xuxuequan/0BEB-331A 3.fsck修复u盘设备 s…

mkfs.jffs2参数详解

实例&#xff1a;mkfs.jffs2 -r rootfs -o rootfs.jffs2 -e 0x4000 --pad0x1000000 -s 0x200 -n mkfs.jffs2: Usage: mkfs.jffs2 [OPTIONS] Make a JFFS2 file system image from an existing directory tree Options: -p, --pad[SIZE] 用16進制來表示所要輸出檔案的大小&…

关于c语言字符串函数和一些内存函数的的简介

关于c语言字符串函数和一些内存函数的的简介 求字符串长度的函数 strlen函数介绍![在这里插入图片描述](https://img-blog.csdnimg.cn/20190301142458376.jpg)注模拟实现 . [1 ]计数器方式 因为strlen 是求字符串长度的函数&#xff0c;所以不能改变字符串本身&#xff0c;所…

君正T20平台生成jffs2格式rootfs

基于系统升级的考虑&#xff0c;这两天在君正T20平台上折腾如何生成jffs2 格式的rootfs。详细的过程如下&#xff1a; 1.修改uboot中的分区参数&#xff1a; 修改为rootfs格式为jffs2的&#xff0c;且适当扩大rootfs分区大小。&#xff08;因jffs2的压缩比不如只读的squashfs…

用结构体写一个简单的通讯录

一个简单的通讯录 通讯录应该具备简单的一些功能 1 增添联系人 2 删除联系人 3 查找联系人 4 修改联系人 5 按名字给联系人排序 6 查看通讯录 除此之外&#xff0c;应该在实现上还应该具备一些其他的功能函数 比如 初始化通讯录 这些都是功能函数&#xff0c;而整个函数入口应…

jffs2 启动的常见的问题

Q&#xff1a;在启动过程中出现at91sam user.warn kernel: Empty flash at 0x00f0fffc ends at 0x00f10000问题 A&#xff1a;在mkfs.jffs2的时候&#xff0c;加上-e 0x20000指定擦除块的大小。-e是指定擦除块的大小&#xff0c;我们使用的nandflash的块大小为128K字节&#xf…

c动态内存管理

动态内存管理 我们之前要开辟内存用的方法都是定义变量&#xff0c;比如 但是上述开辟内存的方法有两个特点 1空间开辟大小是固定的 2数组在申明的时候&#xff0c;必须指定数组的长度&#xff0c;它所需要的内存在编译时分配 malloc和free c中提供一个动态内存开辟函数 这…

JFFS2文件系统挂载过程优化的分析报告

一 问题描述 在上电启动优化中发现Linux系统下挂载JFFS2文件系统耗时较长&#xff0c;以128M的NOR FLASH为例&#xff0c;用时接近20秒。后续单板的FLASH容量为256M&#xff0c;时间会更长。如此长的挂载时间&#xff0c;会大增加系统的上电启动时间。希望能对mount功能或JFFS…