MTD應用學習札記

今天做升級方案用到了mtd-utils中的flash_eraseallflash_cp兩個工具,在進行方案驗證的時候,遭遇到各種不解和疑惑,因對MTD的原理不熟悉,所以只能多次嘗試,雖然最后把方案搞定了,不過覺得MTD中的mtdmtdblock區別這塊還是值得總結學習一下。這里先說明一下問題現象,然后在進行具體的區別原理解釋。?

MTD設備(Nor Flash)使用中的問題現象表現?

  1. mtd-utils工具對mtdmtdblock分區設備的區別處理?
  2. / $ 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
  3. / $ flashcp rootfs_version /dev/mtdblock2
    This doesn't seem to be a valid MTD flash device!
    / $ flashcp rootfs_version /dev/mtdblock/2
    This doesn't seem to be a valid MTD flash device!
    / $ flashcp rootfs_version /dev/mtd2
    / $ ls


  4. mtdmtdblock分區設備mount時的區別?
  5. / $ 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

  6. mtdblock掛載成功,單擦除后卸載失敗?
  7. / $ 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,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-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: Couldn't umount /qqzm: Inappropriate ioctl for device
    / $ umount /dev/mtdblock/2
    umount: Couldn't umount /dev/mtdblock/2: Inappropriate ioctl for device
    / $



通過上面的不斷嘗試和錯誤反饋,我把方案基本驗證通過了,只是對其中的原理不清楚:?

  • 為什么mtdmtdblock明明是同一個設備分區卻有不同的操作??
  • mount命令只能掛載塊設備嗎??
  • 卸載mtdblock設備時,Inappropriate ioctl for device是什么意思??
  • unable to get MTD device info,又是什么意思??

MTD技術的基本原理?

MTD(memory technology device內存技術設備)是用于訪問memory設備(ROMflash)的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/NmtdblockN和對應的/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;

}

MEMGETINFOLinux 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"

~ $

可以發現,實際上mtdNmtdblockN描述的是同一個MTD分區,對應同一個硬件分區,兩者的大小是一樣的,只不過是MTD設備層提供給上層的視圖不一樣,給上層提供了字符和塊設備兩種操作視圖——為了上層使用的便利和需要,比如mount命令的需求,你只能掛載塊設備(有文件系統),而不能對字符設備進行掛載,否則會出現上面的現象2:無效參數。?

這里對于mtdmtdblock設備的使用場景進行簡單總結:?

  1. mtd-utils工具只能應用與/dev/mtdNMTD字符設備?
  2. mountumount命令只對/dev/mtdblockNMTD塊設備有效?
  3. /dev/mtdN/dev/mtdblockN是同一個MTD設備的同一個分區(N一樣)








Linux系統中/dev/mtd/dev/mtdblock的區別



MTD(memory technology device內存技術設備)是用于訪問memory設備(ROMflash)的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的數目,每個block1KB

而每個字符設備,其實就是對應著上面的每個塊設備。即/dev/mtd0對應/dev/mtdblock0,其他以此類推。換句話說,mtdblockN的一些屬性,也就是mtdN的屬性,比如大小。

4。對每個mtd字符設備的操作,比如利用nandwrite去對/dev/mtd0寫數據,實際就是操作/dev/mtdblock0

而這些操作里面涉及到的偏移量offset,都指的是此mtd 分區內的偏移。比如向/dev/mtd1offset0的位置寫入數據,實際操作的是物理偏移offset=/dev/mtd0的大小=1MB=0x100000

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
為什么eraseallmtd0操作?而不對mtdblock0操作?nand不是塊設備嘛,mtdblock就是塊設備呀。mtd0,mtd1mtdblock0,mtdblock1是不是一一對應的?







mtd-utils 工具的使用?

.下載源碼包。

.編譯

1.修改Makefile ?

CROSS=mipsel-linux-

2.make

3.將編譯生成的可執行文件COPY到開發板上


.命令的使用

使用命令前用cat /proc/mtd 查看一下mtdchar字符設備;或者用ls -l /dev/mtd*

#cat /proc/mtd

dev:? ? size ? erasesize? name

mtd0: 00c00000 00020000 &quot;ROOTFS&quot;

mtd1: 00200000 00020000 &quot;BOOTLOADER&quot;

mtd2: 00200000 00020000 &quot;KERNEL&quot;

mtd3: 03200000 00020000 &quot;NAND ROOTFS partition&quot;

mtd4: 04b00000 00020000 &quot;NAND DATAFS partition&quot;

為了更詳細了解分區信息用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;filename&gt; &lt;device&gt;

?? ? ? 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, --start=addr set start address (default is 0)

? -p, --pad ? ? ? ? ? ? pad to page size

? -b, --blockalign=1|2|4 set multiple of eraseblocks to align to

? -q, --quiet ? ? ? ? ? don't display progress messages

? ? ? --help? ? ? ? ? ? display this help and exit

? ? ? --version ? ? ? ? output version information and exit

?? ?

eg: ./nandwrite -p /dev/mtd0? /tmp/rootfs.jffs2


命令:nanddump

作用:dumpnand 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? ? --file=file? ? ? ? ? dump to file

-i ? ? ? ? --ignoreerrors ? ? ? ignore errors

-l length? --length=length? ? ? length

-o ? ? ? ? --omitoob? ? ? ? ? ? omit oob data

-b ? ? ? ? --omitbad? ? ? ? ? ? omit bad blocks from the dump

-p ? ? ? ? --prettyprint? ? ? ? print nice (hexdump)

-s addr? ? --startaddress=addr? start address

eg:./nanddump -p -f nandinfo.txt /dev/mtd0? //dumpnand flash /dev/mtd0數據并保存到 nandinfo.txt?


命令:mtd_debug

作用: mtd 調試作用

用法:

usage: mtd_debug info &lt;device&gt;

?? ? ? mtd_debug read &lt;device&gt; &lt;offset&gt; &lt;len&gt; &lt;dest-filename&gt;

?? ? ? mtd_debug write &lt;device&gt; &lt;offset&gt; &lt;len&gt; &lt;source-filename&gt;

?? ? ? mtd_debug erase &lt;device&gt; &lt;offset&gt; &lt;len&gt;

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驅動也不是很好,用nandwritenanddump這兩個工具或許更好點。然后可以用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? //dumpnand flash /dev/mtd1數據,可以看到現在的數據全是ff

step3:

#./nandwrite -p ? /dev/mtd1 cq8401.img? // cq8401.img文件系統寫入mtd0分區

step4:

#./nanddump -p? /dev/mtd1? //dumpnand 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 'mem=64M console=ttyS0,115200n8 ip=192.168.4.201:::::eth0:off? root=/dev/mtdblock0 rootfstype=jffs2 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 'mem=64M console=ttyS0,115200n8 ip=192.168.4.201:::::eth0:off? root=/dev/mtdblock1 rootfstype=jffs2 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分區


root@ubuntu:~# 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"


root@ubuntu:~# 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

root@ubuntu:~#?


2、查看mtd4的信息?

root@ubuntu:~# 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


root@ubuntu:~# mtdinfo -m 2 -u?

root@ubuntu:~# 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 root@ubuntu:~# 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

root@ubuntu:~#?



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-size=SIZE? ? ? 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的命令輸出:


root@ubuntu:~# 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)

root@ubuntu:~#?


ubinize.cfg文件


[ubifs]

mode=ubi

image=ubifs.img

vol_id=0

vol_size=450MiB

vol_type=dynamic

vol_alignment=1

vol_name=rootfs

vol_flags=autoresize



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中設置如下信息:

? root=ubi0:rootfs ubi.mtd=4 rootfstype=ubifs


?配置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文件系統了



本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383283.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383283.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383283.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c++中的文件讀寫的操作

寫文件 ofstreamopen指定打開方式isopen判斷是否打開成功ifs<<“數據”ofs.close&#xff08;&#xff09; 讀文件 ifstream ifs 指定打開方式ios::in isopen判斷是否打開成功 讀取有三種方式 #include<iostream>using namespace std;//文件讀寫頭文件#incl…

udhcpc命令

由于要使用網絡通訊&#xff0c;所以不可避免的要用到dhcp。理想的網絡通訊方式是下面3種都要支持: 1,接入已有網絡。這便要求可以作為dhcp客戶端。 2,作為DHCP服務器&#xff0c;動態分配IP。 3,指定固定IP 第3種情況沒有什么好說的&#xff0c;簡單說下前2種情況。 使用步驟&…

c++的STL--1概念通述

STL的概念 什么是STL? STL(standard template libaray-標準模板庫)&#xff1a;是C標準庫的重要組成部分&#xff0c;不僅是一個可復用的組件庫&#xff0c;而且 是一個包羅數據結構與算法的軟件框架。 STL從廣義上分為&#xff1a;容器(container)&#xff0c;算法(algorit…

socket通信和異常處理札記

Linux socket通信出現CLOSE_WAIT狀態的原因與解決方法 這個問題之前沒有怎么留意過&#xff0c;是最近在面試過程中遇到的一個問題&#xff0c;面了兩家公司&#xff0c;兩家公司竟然都面到到了這個問題&#xff0c;不得不使我開始關注這個問題。說起CLOSE_WAIT狀態&#xff0c…

mac 下使用wireshark監聽網絡上的數據

分三個步驟&#xff1a; 1.wireshark安裝 wireshark運行需要mac上安裝X11&#xff0c;mac 10.8的系統上默認是沒有X11的。先去http://xquartz.macosforge.org/landing/下載最新的 xquartz安裝&#xff0c;安裝好就有X11了。 wireshark的下載&#xff0c;網…

c++的vector容器

vector容器概念 vector是表示可變大小數組的序列容器。就像數組一樣&#xff0c;vector也采用的連續存儲空間來存儲元素。也就是意味著可以采用下標對vector的元素 進行訪問&#xff0c;和數組一樣高效。但是又不像數組&#xff0c;它的大小是可以動態改變的&#xff0c;而且它…

嵌入式Linux下3G USB Modem的使用

busybox中需打開&#xff1a;wc&#xff0c;pidof&#xff1b; busybox中shell下打開getopts 百度搜索“Serial connection established. using channel 1”包含大量問題解答 2013-12-22 0個評論 收藏 我要投稿 一.ARM-Linux ARM-Linux-2.6.17 3G USB Modem:hu…

新一代數據庫技術

新一代非關系型數據庫有以下5個主要類型&#xff1a; 面向文件存儲&#xff1a;適用于存儲海量文件&#xff0c;代表產品MongoDb 列存儲(wide column store/column-family)數據庫&#xff1a;快速查找相關數據&#xff0c;相關數據被放在同一列中&#xff0c;代表產品Cassandra…

c++中stack容器

Stack 簡介 stack 是堆棧容器&#xff0c;是一種“先進后出”的容器。stack 是簡單地裝飾 deque 容器而成為另外的一種容器。#include stack沒有迭代器 Stack所有元素的進出都必須符合“先進后出”的條件&#xff0c;只有stack頂端的元素&#xff0c;才有機會被外界取用&am…

詳解udev

如果你使用Linux比較長時間了&#xff0c;那你就知道&#xff0c;在對待設備文件這塊&#xff0c;Linux改變了幾次策略。在Linux早期&#xff0c;設備文件僅僅是是一些帶有適當的屬性集的普通文件&#xff0c;它由mknod命令創建&#xff0c;文件存放在/dev目錄下。后來&#xf…

c++中的queue容器

queue容器 隊列是一種容器適配器&#xff0c;專門用于在FIFO上下文(先進先出)中操作&#xff0c;其中從容器一端插入元素&#xff0c;另一端 提取元素。 隊列作為容器適配器實現&#xff0c;容器適配器即將特定容器類封裝作為其底層容器類&#xff0c;queue提供一組特定的 成員…

NAU8810相關問題

1.ADC和DAC有什么區別&#xff1f; 不&#xff0c;這不是一個“愚弄人的”問題或腦筋急轉彎&#xff0c;并且我認為我們的讀者都非常清楚模數轉換器(ADC)及數模轉換器(DAC)的基本功能。 但在如何使用這些轉換器以及人們的認知度上也存在著哲理性區別。用最簡單的話講&#xff0…

c++中list容器

list概念 list是可以在常數范圍內在任意位置進行插入和刪除的序列式容器&#xff0c;并且該容器可以前后雙向迭代。list的底層是雙向鏈表結構&#xff0c;雙向鏈表中每個元素存儲在互不相關的獨立節點中&#xff0c;在節點中通過指針指向 其前一個元素和后一個元素。list與for…

Linux中rc的含義

在Linux中&#xff0c;最為常用的縮略語也許是“rc”&#xff0c;它是“runcomm”的縮寫――即名詞“run command”(運行命令)的簡寫。rc”是任何腳本類文件的后綴&#xff0c;這些腳本通常在程序的啟動階段被調用&#xff0c;通常是Linux系統啟動時。如/etc/rc&#xff08;連接…

c++中的set容器和multiset容器

set容器基本概念 set的特性是&#xff0c;所有元素都會根據元素的鍵值自動被排序。set的元素不像map那樣可以同時擁有實值和鍵值&#xff0c;set的元素即是鍵值又是實值。set不允許兩個元素又相同的鍵值。我們不可以通過set的迭代器改變set元素的值&#xff0c;因為set元素值就…

linux下的僵尸進程處理SIGCHLD信號

什么是僵尸進程&#xff1f; 首先內核會釋放終止進程(調用了exit系統調用)所使用的所有存儲區&#xff0c;關閉所有打開的文件等&#xff0c;但內核為每一個終止子進程保存了一定量的信息。這些信息至少包括進程ID&#xff0c;進程的終止狀態&#xff0c;以及該進程使用的CPU時…

c++中的map容器

map/multimap基本概念 Map的特性是&#xff0c;所有元素都會根據元素的鍵值自動排序。Map所有的元素都是pair&#xff0c;同時擁有實值和鍵值&#xff0c;pair的第一元素被視為鍵值&#xff0c;第二元素被視為實值&#xff0c;map不允許兩個元素有相同的鍵值我們可以通過map的…

mknod指令詳解

mknod - make block or character special files mknod [OPTION]... NAME TYPE [MAJOR MINOR] option 有用的就是 -m 了 name 自定義 type 有 b 和 c 還有 p 主設備號 次設備號 主設備號是由linux/major.h定義的&#xff0c;如下定義了一個DOC設備&am…

c++中容器(STL)的共性與使用的時機

容器的共通能力 C模板是容器的概念 理論提高&#xff1a;所有容器提供的都是值&#xff08;value&#xff09;語意&#xff0c;而非引用&#xff08;reference&#xff09;語意。容器執 行插入元素的操作時&#xff0c;內部實施拷貝動作。所以 STL 容器內存儲的元素必須能夠被…

Qt Creator 窗體控件自適應窗口大小布局

常見的軟件窗口大小改變&#xff08;最大化、手動改變時&#xff09;需要窗口的部件能夠自適應布局&#xff0c;而在Qt的應用程序界面設計中&#xff0c;對于像我一樣的初學者如何實現窗口自適應調整還是要繞點彎路的。網上百度了很多&#xff0c;多數說的很含糊&#xff0c;還…