Linux系统中/dev/mtd与/dev/mtdblock的区别

无论以x86平台下面的grub还是ARM、MIPS下的uboot来启动内核,多需要在启动参数中设定根文件在硬盘(flash)上面的分区位置。

MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。

MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。
MTD的所有源代码在/drivers/mtd子目录下。CFI接口的MTD设备分为四层(从设备节点直到底层硬件驱动),
这四层从上到下依次是:设备节点、MTD设备层、MTD原始设备层和硬件驱动层。

 块设备节点 

一、Flash硬件驱动层:硬件驱动层负责在init时驱动Flash硬件,Linux MTD设备的NOR Flash芯片驱动遵循CFI接口标准,其驱动程序位于drivers/mtd/chips子目录下。NAND型Flash的驱动程序则位于/drivers/mtd/nand子目录下

二、MTD原始设备:原始设备层有两部分组成,一部分是MTD原始设备的通用代码,另一部分是各个特定的Flash的数据,例如分区。用于描述MTD原始设备的数据结构是mtd_info,这其中定义了大量的关于MTD的数据和操作函数。mtd_table(mtdcore.c)则是所有MTD原始设备的列表,mtd_part(mtd_part.c)是用于表示MTD原始设备分区的结构,其中包含了mtd_info,因为每一个分区都是被看成一个MTD原始设备加在mtd_table中的,
mtd_part.mtd_info中的大部分数据都从该分区的主分区mtd_part->master中获得。
  在drivers/mtd/maps/子目录下存放的是特定的flash的数据,每一个文件都描述了一块板子上的flash。
其中调用add_mtd_device()、del_mtd_device()建立/删除 mtd_info结构并将其加入/删除mtd_table(或者调用add_mtd_partition()、del_mtd_partition() (mtdpart.c)建立/删除mtd_part结构并将mtd_part.mtd_info加入/删除mtd_table 中)。
三、MTD设备层:基于MTD原始设备,linux系统可以定义出MTD的块设备(主设备号31)和字符设备(设备号90)。MTD字符设备的定义在mtdchar.c中实现,通过注册一系列file operation函数(lseek、open、close、read、write)。MTD块设备则是定义了一个描述MTD块设备的结构 mtdblk_dev,并声明了一个名为mtdblks的指针数组,这数组中的每一个mtdblk_dev和mtd_table中的每一个 mtd_info一一对应。
四、设备节点:通过mknod在/dev子目录下建立MTD字符设备节点(主设备号为90)和MTD块设备节点(主设备号为31),通过访问此设备节点即可访问MTD字符设备和块设备。
五、根文件系统:在Bootloader中将JFFS(或JFFS2)的文件系统映像jffs.image(或jffs2.img)烧到flash的某一个分区中,在/arch/arm/mach-your/arch.c文件的 your_fixup函数中将该分区作为根文件系统挂载。
六、文件系统:内核启动后,通过mount 命令可以将flash中的其余分区作为文件系统挂载到mountpoint上。
设备层和原始设备层的函数调用关系(红色部分需要我们实现):一个MTD原始设备可以通过mtd_part分割成数个MTD原始设备注册进 mtd_table,mtd_table中的每个MTD原始设备都可以被注册成一个MTD设备,其中字符设备的主设备号为90,次设备号为0、2、4、 6…(奇数次设备号为只读设备),块设备的主设备号为31,次设备号为0、1、2、3…
1. /dev/mtdN 是Linux 中的MTD架构中,系统自己实现的mtd分区所对应的字符设备,其里面添加了一些ioctl,支持很多命令,如MEMGETINFO,MEMERASE等。
而/dev/mtdblockN,是Nand Flash驱动中,驱动在用add_mtd_partitions()添加MTD设备分区,而生成的对应的块设备。根据以上内容,也就更加明白,为什么不能用nandwrite,flash_eraseall,flash_erase等工具去对/dev/mtdblockN去操作了。因为/dev/mtdblock中不包含对应的ioctl,不支持你这么操作。
2. mtd char 设备的主设备号是90,而mtd block设备的主设备号是31:
root@OpenWrt:/dev# ls -al mtd*
crw-r--r--    1 root     root       90,   0 Jul 28 09:41 mtd0
crw-r--r--    1 root     root       90,   1 Jul 28 09:41 mtd0ro
crw-r--r--    1 root     root       90,   2 Jul 28 09:41 mtd1
crw-r--r--    1 root     root       90,   3 Jul 28 09:41 mtd1ro
brw-r--r--    1 root     root       31,   0 Jul 28 09:41 mtdblock0
brw-r--r--    1 root     root       31,   1 Jul 28 09:41 mtdblock1
此设备号,定义在/include/linux/mtd/mtd.h中 :
#define MTD_CHAR_MAJOR   90

#define MTD_BLOCK_MAJOR 31


root@OpenWrt:/proc# cat mtd
dev:    size   erasesize  name
mtd0: 03030000 00010000 "rootfs"
mtd1: 02dc0000 00010000 "rootfs_data"
root@OpenWrt:/proc# cat partitions 
major minor  #blocks  name
   8        0    3917592 sda
   8        1       4504 sda1
   8        2      49360 sda2
  31        0      49344 mtdblock0
  31        1      46848 mtdblock1
   8       16   16416768 sdb
   8       17   16040064 sdb1

1、/dev/mtdn是linux中的MTD架构中,系统自己实现的mtd分区所对应的字符设备,其里面添加了一些ioctl,支持很多命令,如MEMGETINFO,MEMERASE等。
     而mtd-util中的flash_eraseall等工具,就是以这些ioctl为基础而实现的工具,实现一些关于flash的操作,比如,mtd工具中的flash_eraseall中的:
 
 if(ioctl(fd,MEMGETINFO,&meminfo) != 0)
 {
  perror("MEMGETINFO");
  close(fd);
  exit(1);
 }
 
其中,MEMGETINFO,就是linux mtd中的/drivers/mtd/nand/mtdchar.c中的:
 
 case MEMGETINFO:
  info.type = mtd->type;
  info.flags = mtd->flags;
  info.size = mtd->size;
  info.erasesize = mtd->erasesize;
  info.writesize = mtd->writesize;
  info.oobsize = mtd->oobsize;
  /* The below fields are obsolete */
  info.ecctype = -1;
  info.eccsize = 0;
  if (copy_to_user(argp, &info, sizeof(struct mtd_info_user)))
   return -EFAULT;
  break;
 
而/dev/mtdblockn,是NandFlash驱动中,驱动在用add_mtd_partitions()添加MTD设备分区而生成的对应的块设备。根据以上内容也更加明白,为什么不能用nandwrite,flash_eraseall,flash_erase等工具去对/dev/mtdblockn去操作了,因为/dev/mtdblock中不包含对应的ioctl,不支持你这么操作。
 
2、mtd char设备的主设备号是90;而mtdblock设备的主设备号是31;
     此设备号定义在/include/linux/mtd/mtd.h中
 
3、mtd块设备的大小可以通过查看分区信息来得到:
# cat /proc/partitions

major minor  #blocks  name
  31        0        128 mtdblock0
  31        1        128 mtdblock1
  31        2        512 mtdblock2
  31        3       2048 mtdblock3
  31        4      32768 mtdblock4
  31        5     486400 mtdblock5
 
上面显示的块设备的大小,是block的数目,每个block是1KB;
而每个字符设备,其实就是对应着上面的每个设备,即/dev/mtd0对应/dev/mtdblock0,以此类推,换句话说,mtdblockn的一些属性,也就是mtdn的属性,比如大小。
 
4、对每个mtd字符设备的操作,比如利用nandwrite去对/dev/mtd0写数据,实际就是操作/dev/mtdblock0。而这些操作里面涉及到得offset都指的是mtd分区内的偏移。比如向/dev/mtd1的offset为0的位置写入数据,实际操作的物理偏移是offset=/dev/mtd0的大小=128KB。
 

5、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

char device

char

90

mtdblockN

block device, read-only block device, JFFS, and JFFS2

block

31

nftlLN

NFTL

block

93

ftlLN

FTL

block

44

 


  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值