网络网站建设10大指标,深圳办公室装修设计,wordpress 使用 相对路径,网站安全体系建设方案今天做升级方案用到了mtd-utils中的flash_eraseall和flash_cp两个工具#xff0c;在进行方案验证的时候#xff0c;遭遇到各种不解和疑惑#xff0c;因对MTD的原理不熟悉#xff0c;所以只能多次尝试#xff0c;虽然最后把方案搞定了#xff0c;不过觉得MTD中的mtd和mtdb… 今天做升级方案用到了mtd-utils中的flash_eraseall和flash_cp两个工具在进行方案验证的时候遭遇到各种不解和疑惑因对MTD的原理不熟悉所以只能多次尝试虽然最后把方案搞定了不过觉得MTD中的mtd和mtdblock区别这块还是值得总结学习一下。这里先说明一下问题现象然后在进行具体的区别原理解释。 MTD设备(Nor Flash)使用中的问题现象表现
mtd-utils工具对mtd和mtdblock分区设备的区别处理 / $ flash_eraseall /dev/mtdblock/2 flash_eraseall: /dev/mtdblock/2: unable to get MTD device info / $ flash_eraseall /dev/mtdblock/2 flash_eraseall: /dev/mtdblock/2: unable to get MTD device info / $ flash_eraseall /dev/mtd/2 Erasing 128 Kibyte 8e0000 -- 98 % complete. / $ ls / $ flashcp rootfs_version /dev/mtdblock2 This doesnt seem to be a valid MTD flash device! / $ flashcp rootfs_version /dev/mtdblock/2 This doesnt seem to be a valid MTD flash device! / $ flashcp rootfs_version /dev/mtd2 / $ ls mtd和mtdblock分区设备mount时的区别 / $ mount -t jffs2 /dev/mtd/2 qqzm/ mount: Mounting /dev/mtd/2 on qqzm/ failed: Invalid argument / $ mount -t jffs2 /dev/mtd2 qqzm/ mount: Mounting /dev/mtd2 on qqzm/ failed: Invalid argument / $ mount -t jffs2 /dev/mtdblock/2 qqzm/ / $ ls mtdblock挂载成功单擦除后卸载失败 / $ flash_eraseall /dev/mtd/2 span/span Erasing 128 Kibyte 8e0000 -- 98 % complete. /qqzm $ mount /dev/root on / type jffs2 (rw,noatime) proc on /proc type proc (rw,nodiratime) sysfs on /sys type sysfs (rw) devfs on /dev type devfs (rw) devpts on /dev/pts type devpts (rw) /dev/mmcblk0p1 on /mnt/sd type vfat (rw,nodiratime,fmask0022,dmask0022,codepagecp437,iocharsetiso8859-1) /dev/mtdblock/2 on /qqzm type jffs2 (rw,noatime) none on /qqzm/www/cgi-bin/tmp type ramfs (rw) /qqzm $ cd .. / $ umount /qqzm umount: Couldnt umount /qqzm: Inappropriate ioctl for device / $ umount /dev/mtdblock/2 umount: Couldnt umount /dev/mtdblock/2: Inappropriate ioctl for device / $ 通过上面的不断尝试和错误反馈我把方案基本验证通过了只是对其中的原理不清楚
为什么mtd和mtdblock明明是同一个设备分区却有不同的操作 mount命令只能挂载块设备吗 卸载mtdblock设备时Inappropriate ioctl for device是什么意思 unable to get MTD device info又是什么意思 MTD技术的基本原理 MTD(memory technology device内存技术设备)是用于访问memory设备ROM、flash的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单为此它在硬件和上层之间提供了一个抽象的接口并进行了一个层次划分层次从上到下大致为设备文件、MTD设备层、MTD原始设备层、硬件驱动层。MTD的所有源代码在/drivers/mtd子目录下。 系统中的MTD设备文件 ~ $ ls /dev/mtd* -l crw-rw---- 1 root root 90, 0 Jan 1 00:00 /dev/mtd0 crw-rw---- 1 root root 90, 1 Jan 1 00:00 /dev/mtd0ro crw-rw---- 1 root root 90, 2 Jan 1 00:00 /dev/mtd1 crw-rw---- 1 root root 90, 3 Jan 1 00:00 /dev/mtd1ro crw-rw---- 1 root root 90, 4 Jan 1 00:00 /dev/mtd2 crw-rw---- 1 root root 90, 5 Jan 1 00:00 /dev/mtd2ro crw-rw---- 1 root root 90, 6 Jan 1 00:00 /dev/mtd3 crw-rw---- 1 root root 90, 7 Jan 1 00:00 /dev/mtd3ro brw-rw---- 1 root root 31, 0 Jan 1 00:00 /dev/mtdblock0 brw-rw---- 1 root root 31, 1 Jan 1 00:00 /dev/mtdblock1 brw-rw---- 1 root root 31, 2 Jan 1 00:00 /dev/mtdblock2 brw-rw---- 1 root root 31, 3 Jan 1 00:00 /dev/mtdblock3 /dev/mtd: crw-rw-rw- 1 root root 90, 0 Jan 1 00:00 0 cr--r--r-- 1 root root 90, 1 Jan 1 00:00 0ro crw-rw-rw- 1 root root 90, 2 Jan 1 00:00 1 cr--r--r-- 1 root root 90, 3 Jan 1 00:00 1ro crw-rw-rw- 1 root root 90, 4 Jan 1 00:00 2 cr--r--r-- 1 root root 90, 5 Jan 1 00:00 2ro crw-rw-rw- 1 root root 90, 6 Jan 1 00:00 3 cr--r--r-- 1 root root 90, 7 Jan 1 00:00 3ro /dev/mtdblock: brw------- 1 root root 31, 0 Jan 1 00:00 0 brw------- 1 root root 31, 1 Jan 1 00:00 1 brw------- 1 root root 31, 2 Jan 1 00:00 2 brw------- 1 root root 31, 3 Jan 1 00:00 3 ~ $ 可以看到有mtdN和对应的/dev/mtd/N、mtdblockN和对应的/dev/mtdblock/N两类MTD设备分别是字符设备主设备号90和块设备主设备号31。其中/dev/mtd0和/dev/mtd/0是完全等价的/dev/mtdblock0和/dev/mtdblock/0是完全等价的而/dev/mtd0和/dev/mtdblock0则是同一个MTD分区的两种不同应用描述操作上是有区别的。 /dev/mtdN设备 /dev/mtdN 是MTD架构中实现的mtd分区所对应的字符设备(将mtd设备分成多个区每个区就为一个字符设备)其里面添加了一些ioctl支持很多命令如MEMGETINFOMEMERASE等。 mtd-utils中的flash_eraseall等工具就是以这些ioctl为基础而实现的工具实现一些关于Flash的操作。比如mtd 工具中 flash_eraseall中 if (ioctl(fd, MEMGETINFO, meminfo) ! 0) { fprintf(stderr, %s: %s: unable to get MTD device info\n,exe_name, mtd_device); return 1; } MEMGETINFO是Linux MTD中的drivers/mtd/mtdchar.c中的ioctl命令使用mtd字符设备需要加载mtdchar内核模块。该代码解释了上面的第一个现象。 /dev/mtdblockN设备 /dev/mtdblockN是Flash驱动中用add_mtd_partitions()添加MTD设备分区而生成的对应的块设备。MTD块设备驱动程序可以让flash器件伪装成块设备实际上它通过把整块的erase block放到ram里面进行访问然后再更新到flash用户可以在这个块设备上创建通常的文件系统。 而对于MTD块设备MTD设备层是不提供ioctl的实现方法的也就不会有对应的MEMGETINFO命令之类因此不能使用nandwrite,flash_eraseall,flash_erase等工具去对/dev/mtdblockN去进行操作否则就会出现上面的现象一同时也解释了现象3——用mtd2擦除分区后在用mtdblock2进行umount就会造成混乱。 mtd块设备的大小可以通过proc文件系统进行查看 ~ $ cat /proc/partitions major minor #blocks name 31 0 512 mtdblock0 31 1 1024 mtdblock1 31 2 5632 mtdblock2 31 3 9216 mtdblock3 254 0 30760960 mmcblk0 254 1 30756864 mmcblk0p1 ~ $ 后面的两个是SD块设备的分区大小。每个block的大小是1KB。 MTD设备分区和总结 通过proc文件系统查看mtd设备的分区情况 ~ $ cat /proc/mtd dev: size erasesize name mtd0: 00080000 00020000 boot mtd1: 00100000 00020000 kernel mtd2: 00580000 00020000 roofs70 mtd3: 00900000 00020000 app ~ $ 可以发现实际上mtdN和mtdblockN描述的是同一个MTD分区对应同一个硬件分区两者的大小是一样的只不过是MTD设备层提供给上层的视图不一样给上层提供了字符和块设备两种操作视图——为了上层使用的便利和需要比如mount命令的需求你只能挂载块设备(有文件系统)而不能对字符设备进行挂载否则会出现上面的现象2:无效参数。 这里对于mtd和mtdblock设备的使用场景进行简单总结 mtd-utils工具只能应用与/dev/mtdN的MTD字符设备 mount、umount命令只对/dev/mtdblockN的MTD块设备有效 /dev/mtdN和/dev/mtdblockN是同一个MTD设备的同一个分区N一样 Linux系统中/dev/mtd与/dev/mtdblock的区别 MTD(memory technology device内存技术设备)是用于访问memory设备ROM、flash的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱 动更加简单为此它在硬件和上层之间提供了一个抽象的接口。MTD的所有源代码在/drivers/mtd子目录下。我将CFI接口的MTD设备分为四层 从设备节点直到底层硬件驱动这四层从上到下依次是设备节点、MTD设备层、MTD原始设备层和硬件驱动层。 MTD字符驱动程序允许直接访问flash器件通常用来在flash上创建文件系统也可以用来直接访问不频繁修改的数据。 MTD块设备驱动程序可以让flash器件伪装成块设备实际上它通过把整块的erase block放到ram里面进行访问然后再更新到flash用户可以在这个块设备上创建通常的文件系统。 1. /dev/mtdN 是Linux 中的MTD架构中系统自己实现的mtd分区所对应的字符设备(将mtd设备分成多个区每个区就为一个字符设备)其里面添加了一些ioctl支持很多命令如MEMGETINFOMEMERASE等。 而mtd-util中的flash_eraseall等工具就是以这些ioctl为基础而实现的工具实现一些关于Flash的操作。比如mtd 工具中的 flash_eraseall中的 if (ioctl(fd, MEMGETINFO, meminfo) ! 0) { fprintf(stderr, %s: %s: unable to get MTD device info\n, exe_name, mtd_device); return 1; } 其中MEMGETINFO就是Linux MTD中的drivers/mtd/mtdchar.c中的 static int mtd_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) { 。。。。。 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是Nand Flash驱动中驱动用add_mtd_partitions()添加MTD设备分区其实就是将mtd设备进行不同的分区当mtd设备还是一样的所以mtdblock分区与mtd分区肯定是对应的而生成的对应的块设备。 根据以上内容也就更加明白为什么不能用nandwrite,flash_eraseall,flash_erase等工具去对/dev/mtdblockN去操作了。因为/dev/mtdblock中不包含对应的ioctl也就没有定义对应的命令不支持你这么操作。 2. mtd char 设备的主设备号是90而mtd block设备的主设备号是31 # ls /dev/mtd* -l crw-r----- 1 root root 90, 0 May 30 2007 /dev/mtd0 crw-r----- 1 root root 90, 2 May 30 2007 /dev/mtd1 crw-r----- 1 root root 90, 4 Jul 17 2009 /dev/mtd2 crw-r----- 1 root root 90, 6 May 30 2007 /dev/mtd3 crwxrwxrwx 1 root root 90, 8 May 30 2007 /dev/mtd4 crwxrwxrwx 1 root root 90, 10 May 30 2007 /dev/mtd5 crwxrwxrwx 1 root root 90, 12 May 30 2007 /dev/mtd6 crwxrwxrwx 1 root root 90, 14 May 30 2007 /dev/mtd7 crwxrwxrwx 1 root root 90, 16 May 30 2007 /dev/mtd8 crwxrwxrwx 1 root root 90, 18 May 30 2007 /dev/mtd9 # ls /dev/mtdblock* -l brw-r----- 1 root root 31, 0 May 30 2007 /dev/mtdblock0 brw-r----- 1 root root 31, 1 May 30 2007 /dev/mtdblock1 brw-r----- 1 root root 31, 2 May 30 2007 /dev/mtdblock2 brw-r----- 1 root root 31, 3 May 30 2007 /dev/mtdblock3 brwxrwxrwx 1 root root 31, 4 May 30 2007 /dev/mtdblock4 brwxrwxrwx 1 root root 31, 5 May 30 2007 /dev/mtdblock5 brwxrwxrwx 1 root root 31, 6 May 30 2007 /dev/mtdblock6 brwxrwxrwx 1 root root 31, 7 May 30 2007 /dev/mtdblock7 brwxrwxrwx 1 root root 31, 8 May 30 2007 /dev/mtdblock8 brwxrwxrwx 1 root root 31, 9 May 30 2007 /dev/mtdblock9 此设备号定义在/include/linux/mtd/mtd.h中 #define MTD_CHAR_MAJOR 90 #define MTD_BLOCK_MAJOR 31 3. 其中mtd的块设备的大小可以通过查看分区信息获得 # cat /proc/partitions major minor #blocks name 31 0 1024 mtdblock0 31 1 8192 mtdblock1 31 2 204800 mtdblock2 31 3 65536 mtdblock3 31 4 225280 mtdblock4 上面中显示的块设备大小是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的大小1MB0x100000。 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 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. The Linux MTD,YAFFS Howto上面这样写道 Erase the mtdblock0 /eraseall /dev/mtd0 Create the mount directory and mount /mkdir -p /mnt/flash0 /mount -t yaffs /dev/mtdblock0 /mnt/flash0 为什么eraseall对mtd0操作而不对mtdblock0操作nand不是块设备嘛mtdblock就是块设备呀。mtd0,mtd1与mtdblock0,mtdblock1是不是一一对应的 mtd-utils 工具的使用 一.下载源码包。 二.编译 1.修改Makefile CROSSmipsel-linux- 2.make 3.将编译生成的可执行文件COPY到开发板上 三.命令的使用 使用命令前用cat /proc/mtd 查看一下mtdchar字符设备或者用ls -l /dev/mtd* #cat /proc/mtd dev: size erasesize name mtd0: 00c00000 00020000 quot;ROOTFSquot; mtd1: 00200000 00020000 quot;BOOTLOADERquot; mtd2: 00200000 00020000 quot;KERNELquot; mtd3: 03200000 00020000 quot;NAND ROOTFS partitionquot; mtd4: 04b00000 00020000 quot;NAND DATAFS partitionquot; 为了更详细了解分区信息用mtd_debug命令 #mtd_debug info /dev/mtdX (不能使用mtdblockX, mtdblockX 只是提供用來 mount 而已) mtd.type MTD_NORFLASH mtd.flags mtd.size 12582912 (12M) mtd.erasesize 131072 (128K) mtd.oobblock 1 mtd.oobsize 0 mtd.ecctype (unknown ECC type - new MTD API maybe?) regions 0 命令flash_erase 作用擦出指定范围内flash的内容如果不指定默认擦出起始位置的第一块使相应flash变为全1 用法 flash_erase MTD-device [start] [cnt (# erase blocks)] [lock] MTDdevice:待擦出的分区如/dev/mtd0 start:起始位置设置这里必须设置为0x20000(128K)的整数倍 cnt: 从start开始计算要擦出的块数 lock: 写保护 eg: ./flash_erase /dev/mtd0 0x40000 5 //擦出mtd0分区上从0x40000开始的5块数据 128K/块 命令flash_eraseall 作用擦出整个分区的数据,同时也会作坏块检测 用法 flash_eraseall [OPTION] MTD_DEVICE -q, --quiet 不显示打印信息 -j, --jffs2 一jffs2 格式化分区 eg: ./flash_eraseall -j /dev/mtd0 命令flashcp 作用:copy 数据到 flash 中 用法 usage: flashcp [ -v | --verbose ] lt;filenamegt; lt;devicegt; flashcp -h | --help filename:待写入的数据 device: 写入的分区如/dev/mtd0 eg: filename制作mkfs.jffs2 -e 0x20000 -d cq8401 -o cq8401.img -n //这里的-e 0x20000 必须更你芯片的erasesize 相等 ./flashcp cq8401.img /dev/mtd0 // copy cq8401.img文件系统到 /dev/mtd0分区中 当然这个命令的功能跟 dd if/tmp/fs.img of/dev/mtd0差不多 命令nandwrite 作用向nand flash中写数据 用法 nandwrite [OPTION] MTD_DEVICE INPUTFILE -a, --autoplace Use auto oob layout -j, --jffs2 force jffs2 oob layout (legacy support) -y, --yaffs force yaffs oob layout (legacy support) -f, --forcelegacy force legacy support on autoplacement enabled mtd device -n, --noecc write without ecc -o, --oob image contains oob data -s addr, --startaddr set start address (default is 0) -p, --pad pad to page size -b, --blockalign1|2|4 set multiple of eraseblocks to align to -q, --quiet dont display progress messages --help display this help and exit --version output version information and exit eg: ./nandwrite -p /dev/mtd0 /tmp/rootfs.jffs2 命令nanddump 作用:dump出nand flash一些信息如block size,erasesize,oobblock 大小oob data ,page data等同时也会作坏块检测 用法 nanddump [OPTIONS] MTD-device --help display this help and exit --version output version information and exit -f file --filefile dump to file -i --ignoreerrors ignore errors -l length --lengthlength length -o --omitoob omit oob data -b --omitbad omit bad blocks from the dump -p --prettyprint print nice (hexdump) -s addr --startaddressaddr start address eg:./nanddump -p -f nandinfo.txt /dev/mtd0 //dump出nand flash /dev/mtd0数据并保存到 nandinfo.txt 命令mtd_debug 作用: 对mtd 调试作用 用法 usage: mtd_debug info lt;devicegt; mtd_debug read lt;devicegt; lt;offsetgt; lt;lengt; lt;dest-filenamegt; mtd_debug write lt;devicegt; lt;offsetgt; lt;lengt; lt;source-filenamegt; mtd_debug erase lt;devicegt; lt;offsetgt; lt;lengt; eg: #./mtd_debug info /dev/mtd0 // 输出/dev/mtd0上的一些信息,这里必须用mtdx #./mtd_debug erase /dev/mtd0 0x0 0x40000 // 擦出/dev/mtd0 分区上 从0x0开始的 128K2 大小的数据 #./mtd_debug write /dev/mtdblock0 ox0 0x360810 cq8401.img //向mtdblock0分区写入 3.6M 大小的文件系统cq8401.img,这里最好用mtdblockx #./mtd_debug read /dev/mtdblock0 ox0 0x360810 read.img //从mtdblock0中读出 3.6M 数据保存到read.img # cmp -l cq8401.img read.img // 验证write to flash 和 read from flash 中的数据是否一致;也可以使用diff命令来比较 另外针对nand flash,mtd_debug这个工具来测试mtd驱动也不是很好用nandwrite和nanddump这两个工具或许更好点。然后可以用cmp这个命令来比较一下nanddump出来的数据和nandwrite写入的数据是否一致。 命令ftl_format 解释In order to use one of conventional file systems Ext2, ext3, XFS, JFS, FAT over an MTD device, you need a software layer which emulates a block device over the MTD device. These layers are often called Flash Translation Layers (FTLs). 例一如何测试nor flash 驱动 step1: #./mtd_debug info /dev/mtd0 // 输出/dev/mtd0上的一些信息,这里必须用mtdx step2: #./mtd_debug erase /dev/mtd0 0x0 0x40000 // 擦出/dev/mtd0 分区上 从0x0开始的 128K2 大小的数据 step3: #./mtd_debug write /dev/mtdblock0 ox0 0x360810 cq8401.img //向mtdblock0分区写入 3.6M 大小的文件系统cq8401.img,这里最好用mtdblockx step4: #./mtd_debug read /dev/mtdblock0 ox0 0x360810 read.img //从mtdblock0中读出 3.6M 数据保存到read.img,当然这里的长度应该相等 step5: # cmp -l cq8401.img read.img // 验证write to flash 和 read from flash 中的数据是否一致;也可以使用diff命令来比较 例二如何测试nand flash 驱动 其实nand flash 驱动同样可以用例一的方法测试但既然有nandwrite,nanddump命令为何不用呢 step1: #./flash_eraseall -j /dev/mtd1 //用jffs2格式化该分区 step2: #./nanddump -p /dev/mtd1 //dump出nand flash /dev/mtd1数据,可以看到现在的数据全是ff step3: #./nandwrite -p /dev/mtd1 cq8401.img // 将cq8401.img文件系统写入mtd0分区 step4: #./nanddump -p /dev/mtd1 //dump出nand flash /dev/mtd1数据,可以看到现在的数据不再是全ff 例三如何用mtd-util 工具向nand flash写入文件系统jffs2.img,并修改启动参数使文件系统从nand flash 启动假设已分好区mtd0为文件系统分区 方式一 step1: NFS起文件系统 #./flash_eraseall -j /dev/mtd0 //用jffs2格式化该分区 #./nandwrite -j -f -p -q /dev/mtd0 jffs2.img // 将jffs2.img文件系统写入mtd0分区 step2: 然后再看看我们新写入的JFFS2文件系统能不能mount上. #mount -t jffs2 /dev/mtdblock0 /mnt #ls /mnt setp3: 重启开发板在UBOOT里 设置启动参数 #setenv bootargs mem64M consolettyS0,115200n8 ip192.168.4.201:::::eth0:off root/dev/mtdblock0 rootfstypejffs2 rw #reset 方式二 NAND 起内核NAND起文件系统 1. 网起文件系统 nerase 0 55 amp;amp; nprog 0 192.168.4.200 n-boot.bin.hg amp;amp; nprog 128 192.168.4.200 zImage-6pci amp;amp; reset 2.进入网起的文件系统 cat /proc/mtd 3. 制作JIFFS的文件系统 mkfs.jffs2 -e 0x20000 -d root-vw -o dvr20000.img -n 4. cp dvr20000.img /dev/mtdblock1 5.修改NAND BOOT启动参数 include/cq8401_board.h 修改NAND BOOT setenv bootargs mem64M consolettyS0,115200n8 ip192.168.4.201:::::eth0:off root/dev/mtdblock1 rootfstypejffs2 rw 6. 从新烧写 nerase 0 55 amp;amp; nprog 0 192.168.4.200 n-boot.bin.local amp;amp; nprog 128 192.168.4.200 zImage-6pci amp;amp; reset 例四 如何将一个 .tar.gz文件系统 写到 nor 或者 nand flash中 target$ mkdir /mnt/flash target$ mount -t jffs2 /dev/mtdblock0 /mnt/flash (mtdblockx只是用来挂载的) target$ cd /mnt/flash target$ tar zxvf rootfs.tar.gz mtd命令及制作ubi镜像做根文件系统 2013-09-25 17:22 2315人阅读 评论(0) 收藏 举报 在linux2.6.28后才加入对ubifs的支持 1 查看nand分区 rootubuntu:~# cat /proc/mtd dev: size erasesize name mtd0: 00020000 00020000 U-Boot-min mtd1: 00240000 00020000 U-Boot mtd2: 00020000 00020000 U-Boot Env mtd3: 00440000 00020000 Kernel mtd4: 1f400000 00020000 File System mtd5: 00540000 00020000 Reserved rootubuntu:~# cat /proc/partitions major minor #blocks name 31 0 128 mtdblock0 31 1 2304 mtdblock1 31 2 128 mtdblock2 31 3 4352 mtdblock3 31 4 512000 mtdblock4 31 5 5376 mtdblock5 rootubuntu:~# 2、查看mtd4的信息 rootubuntu:~# mtdinfo -m 4 -u mtd4 Name: File System Type: nand Eraseblock size: 131072 bytes, 128.0 KiB Amount of eraseblocks: 4000 (524288000 bytes, 500.0 MiB) Minimum input/output unit size: 2048 bytes Sub-page size: 512 bytes OOB size: 64 bytes Character device major/minor: 90:8 Bad blocks are allowed: true Device is writable: true Default UBI VID header offset: 512 Default UBI data offset: 2048 Default UBI LEB size: 129024 bytes, 126.0 KiB Maximum UBI volumes count: 128 rootubuntu:~# mtdinfo -m 2 -u 或 rootubuntu:~# mtdinfo /dev/mtd4 mtd2 Name: U-Boot Env Type: nand Eraseblock size: 131072 bytes, 128.0 KiB // FLASH物理擦除块大小 Amount of eraseblocks: 1 (131072 bytes, 128.0 KiB) Minimum input/output unit size: 2048 bytes 1nor flash:通常是1个字节 2nand falsh一个页面 Sub-page size: 512 bytes //对于nand flash来说子页大小 OOB size: 64 bytes Character device major/minor: 90:4 Bad blocks are allowed: true Device is writable: true Default UBI VID header offset: 512 Default UBI data offset: 2048 Default UBI LEB size: 129024 bytes, 126.0 KiB //逻辑擦除块大小 Maximum UBI volumes count: 128 mtd4大小为500MiB,擦除单元大小(一般即为块大小)为128KiB名字是NAND simulator partition 0。 NandFlash 擦除是以块(block)为单位读写是以页(page)为单位。 3 rootubuntu:~# ls -lah /dev/mtd* crw------- 1 root root 90, 0 Jan 1 00:00 /dev/mtd0 //字符设备 crw------- 1 root root 90, 1 Jan 1 00:00 /dev/mtd0ro crw------- 1 root root 90, 2 Jan 1 00:00 /dev/mtd1 crw------- 1 root root 90, 3 Jan 1 00:00 /dev/mtd1ro crw------- 1 root root 90, 4 Jan 1 00:00 /dev/mtd2 crw------- 1 root root 90, 5 Jan 1 00:00 /dev/mtd2ro crw------- 1 root root 90, 6 Jan 1 00:00 /dev/mtd3 crw------- 1 root root 90, 7 Jan 1 00:00 /dev/mtd3ro crw------- 1 root root 90, 8 Jan 1 00:00 /dev/mtd4 crw------- 1 root root 90, 9 Jan 1 00:00 /dev/mtd4ro crw------- 1 root root 90, 10 Jan 1 00:00 /dev/mtd5 crw------- 1 root root 90, 11 Jan 1 00:00 /dev/mtd5ro brw-rw---- 1 root disk 31, 0 Jan 1 00:00 /dev/mtdblock0 //块设备与mtd0对应 brw-rw---- 1 root disk 31, 1 Jan 1 00:00 /dev/mtdblock1 brw-rw---- 1 root disk 31, 2 Jan 1 00:00 /dev/mtdblock2 brw-rw---- 1 root disk 31, 3 Jan 1 00:00 /dev/mtdblock3 brw-rw---- 1 root disk 31, 4 Jan 1 00:00 /dev/mtdblock4 brw-rw---- 1 root disk 31, 5 Jan 1 00:00 /dev/mtdblock5 rootubuntu:~# 4. 关于mtd工具集的安装 sudo apt-get install mtd-utils UBI文件系统镜像文件的制作 ubuntu:~$ sudo mkfs.ubifs -r targetfs -m 2048 -e 129024 -c 3900 -o ubifs.img ubuntu:~$ sudo ubinize -o ubi.img -m 2048 -p 128KiB -s 512 ubinize.cfg 关于mkfs.ubifs参数的算法 -m minimum I/O unit size -e, --leb-sizeSIZE logical erase block size -c maximum logical erase block count -x compression type - lzo, favor_lzo, zlib or none (default: lzo) -p size of the physical eraseblock of the flash this UBI image is created for in bytes wear_level_reserved_blocks is 1% of total blcoks per device *logical_erase_block_size* is physical erase block size minus 2 pages for UBI Block size page_size * pages_per_block physical blocks on a partition partition size / block size Logical blocks on a partition physical blocks on a partitiion - reserved for wear level File-system volume Logical blocks in a partition * Logical erase block size 关于参数可以参考attach的命令输出 rootubuntu:~# ubiattach /dev/ubi_ctrl -m 4 -d 0 UBI device number 0, total 4000 LEBs (516096000 bytes, 492.2 MiB), available 0 LEBs (0 bytes), LEB size 129024 bytes (126.0 KiB) rootubuntu:~# ubinize.cfg文件 [ubifs] modeubi imageubifs.img vol_id0 vol_size450MiB vol_typedynamic vol_alignment1 vol_namerootfs vol_flagsautoresize 5. UBI文件系统镜像在Linux下的烧写 flash_eraseall /dev/mtd4 ubiformat /dev/mtd4 -s 512 -f /xxx/ubi.img 6、 UBI文件系统镜像在U-BOOT下的烧写 //load ubi image to RAM tftp ubi.img //erase MTD4 nand space nand erase 0x6c0000 0xc820000 //write image to nand nand write.i 0x81000000 0x6c0000 0xxxxx(image size) 7. UBI文件系统镜像在Linux下的挂载和卸载 挂载 ubiattach /dev/ubi_ctrl -m 4 -d 0 mount -t ubifs ubi0_0 /mnt/ubi 卸载 umount /mnt/ubi ubidetach -d 0 8、使用ubi做根文件系统 需要在bootargs中设置如下信息 rootubi0:rootfs ubi.mtd4 rootfstypeubifs 配置linux内核 配置的时候选上 1)Device Drivers ---Memory Technology Device (MTD) support ---UBI - Unsorted block images ---Enable UBI 2)File systems ---Miscellaneous filesystems ---UBIFS file system support 这样我们的内核就支持UBIFS文件系统了