mtd和mtdblock的區別

2021-07-04 03:19:56 字數 4091 閱讀 3921

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

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

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  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 /dev/mtdblock/2

/ $

?

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

mtd(memory technology device記憶體技術裝置)是用於訪問memory裝置(rom、flash)的linux的子系統。mtd的主要目的是為了使新的memory裝置的驅動更加簡單,為此它在硬體和上層之間提供了乙個抽象的介面,並進行了乙個層次劃分,層次從上到下大致為:裝置檔案、mtd裝置層、mtd原始裝置層、硬體驅動層。mtd的所有源**在/drivers/mtd子目錄下。?

可以看到有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 是mtd架構中實現的mtd分割槽所對應的字元裝置(將mtd裝置分成多個區,每個區就為乙個字元裝置),其裡面新增了一些ioctl,支援很多命令,如memgetinfo,memerase等。

mtd-utils中的flash_eraseall等工具,就是以這些ioctl為基礎而實現的工具,實現一些關於flash的操作。比如,mtd 工具中 flash_eraseall中:?

if (ioctl(fd, memgetinfo, &meminfo) != 0) 

memgetinfo是linux mtd中的drivers/mtd/mtdchar.c中的ioctl命令,使用mtd字元裝置需要載入mtdchar核心模組。該**解釋了上面的第乙個現象。/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。通過proc檔案系統檢視mtd裝置的分割槽情況:

~ $ cat /proc/mtd

dev: size erasesize name

mtd0: 00080000 00020000 "boot"

mtd1: 00100000 00020000 "kernel"

mtd2: 00580000 00020000 "roofs70"

~ $

可以發現,實際上mtdn和mtdblockn描述的是同乙個mtd分割槽,對應同乙個硬體分割槽,兩者的大小是一樣的,只不過是mtd裝置層提供給上層的檢視不一樣,給上層提供了字元和塊裝置兩種操作檢視——為了上層使用的便利和需要,比如mount命令的需求,你只能掛載塊裝置(有檔案系統),而不能對字元裝置進行掛載,否則會出現上面的現象2:無效引數。

這裡對於mtd和mtdblock裝置的使用場景進行簡單總結:

mtd-utils工具只能應用與/dev/mtdn的mtd字元裝置

mount、umount命令只對/dev/mtdblockn的mtd塊裝置有效

/dev/mtdn和/dev/mtdblockn是同乙個mtd裝置的同乙個分割槽(n一樣)

mtd和mtdblock的區別

mtdn 是字元裝置,mtdblockn 是塊裝置 通過proc檔案系統檢視mtd裝置的分割槽情況 cat proc mtd dev size erasesize name mtd0 00100000 00010000 boot mtd1 00400000 00010000 kernel mtd2 ...

mtd和mtdblock的區別

原文 總結 可以發現,實際上mtdn和mtdblockn描述的是同乙個mtd分割槽,對應同乙個硬體分割槽,兩者的大小是一樣的,只不過是mtd裝置層提供給上層的檢視不一樣,給上層提供了字元和塊裝置兩種操作檢視 為了上層使用的便利和需要,比如mount命令的需求,你只能掛載塊裝置 有檔案系統 而不能對字...

MTD和MDd導致的問題

mtd指的是使用的執行時庫為靜態庫libcrtd.lib,mdd則使用動態庫msvcrtd.dll執行時庫作為鏈結版本 靜態庫libcrtd.lib在引用它的工程裡自定義了該靜態庫需要建立的全域性變數 動態庫msvcrtd.dll已經在dll模組內部定義了全域性變數 對malloc和free函式的呼...