mtd,memory technology device即記憶體技術裝置,在linux核心中,引入mtd層為nor flash和nand flash裝置提供統一介面。mtd將檔案系統與底層flash儲存器進行了隔離。
如上圖所示,mtd裝置通常可分為四層,從上到下依次是:裝置節點、mtd裝置層、mtd原始裝置層、硬體驅動層。
flash硬體驅動層
:flash硬體驅動層負責對flash硬體的讀、寫和擦除操作。mtd裝置的nand flash晶元的驅動則drivers/mtd/nand/子目錄下,nor flash晶元驅動位於drivers/mtd/chips/子目錄下。
mtd原始裝置層:
用於描述mtd原始裝置的資料結構是mtd_info,它定義了大量的關於mtd的資料和操作函式。
其中mtdcore.c
: mtd原始裝置介面相關實現,mtdpart.c
: mtd分割槽介面相關實現。
mtd裝置層:
基於mtd原始裝置,linux系統可以定義出mtd的塊裝置(主裝置號31)
和字元裝置(裝置號90)
。其中mtdchar.c
: mtd字元裝置介面相關實現,mtdblock.c
: mtd塊裝置介面相關實現。
裝置節點:
通過mknod在/dev子目錄下建立mtd塊裝置節點(主裝置號為31)
和mtd字元裝置節點(主裝置號為90)
。通過訪問此裝置節點即可訪問mtd字元裝置和塊裝置
mtd資料結構:
1.linux核心使用mtd_info
結構體表示mtd原始裝置,這其中定義了大量關於mtd的資料和操作函式(後面將會看到),所有的mtd_info結構體存放在mtd_table結構體資料裡。在/drivers/mtd/mtdcore.c裡:
[cpp]view plain
copy
struct
mtd_info *mtd_table[max_mtd_devices];
2.linux核心使用
mtd_part
結構體表示分割槽,其中mtd_info結構體成員用於描述該分割槽,大部分成員由其主分割槽mtd_part->master決定,各種函式也指向主分割槽的相應函式。
[cpp]view plain
copy
struct
mtd_part ;
mtd_info結構體主要成員,為了便於觀察,將重要的資料放在前面,不大重要的編寫在後面。
[cpp]view plain
copy
struct
mtd_info ;
mtd_info結構體中的read()、write()、read_oob()、write_oob()、erase()是mtd裝置驅動要實現的主要函式,幸運的是linux大牛已經幫我們實現了一套適合大部分flash裝置的mtd_info成員函式。
如果mtd裝置只有乙個分割槽
,那麼使用下面兩個函式註冊和登出mtd裝置。
[cpp]view plain
copy
intadd_mtd_device(
struct
mtd_info *mtd)
intdel_mtd_device (
struct
mtd_info *mtd)
如果mtd裝置存在其他分割槽,那麼使用下面兩個函式註冊和登出mtd裝置。
[cpp]view plain
copy
intadd_mtd_partitions(
struct
mtd_info *master,
const
struct
mtd_partition *parts,
intnbparts)
intdel_mtd_partitions(
struct
mtd_info *master)
其中mtd_partition
結構體表示分割槽的資訊
[cpp]view plain
copy
struct
mtd_partition ;
其中nand_ecclayout結構體:
struct
nand_ecclayout ;
關於nand_ecclayout結構體例項,更多可參考drivers/mtd/nand/nand_base.c下的nand_oob_8、nand_oob_16、nand_oob_64例項。
mtd裝置層:
mtd字元裝置介面:
/drivers/mtd/mtdchar.c檔案實現了mtd字元裝置介面,通過它,可以直接訪問flash裝置,與前面的字元驅動一樣,通過file_operations結構體裡面的open()、read()、write()、ioctl()可以讀寫flash,通過一系列ioctl 命令可以獲取flash 裝置資訊、擦除flash、讀寫nand 的oob、獲取oob layout 及檢查nand 壞塊等(memgetinfo、memerase、memreadoob、memwriteoob、memgetbadblock iocrl)
mtd塊裝置介面:
/drivers/mtd/mtdblock.c檔案實現了mtd塊裝置介面,主要原理是將flash的erase block 中的資料在記憶體中建立對映,然後對其進行修改,最後擦除flash 上的block,將記憶體中的對映塊寫入flash 塊。整個過程被稱為read/modify/erase/rewrite 週期。 但是,這樣做是不安全的,當下列操作序列發生時,read/modify/erase/poweroff,就會丟失這個block 塊的資料。
mtd硬體驅動層:
linux核心再mtd層下實現了通用的nand驅動(/driver/mtd/nand/nand_base.c),因此晶元級的nand驅動不再需要實現mtd_info結構體中的read()、write()、read_oob()、write_oob()等成員函式。
mtd使用nand_chip
來表示乙個nand flash晶元, 該結構體包含了關於nand flash的位址資訊,讀寫方法,ecc模式,硬體控制等一系列底層機制。
[cpp]view plain
copy
struct
nand_chip ;
最後,我們來用圖表的形式來總結一下,mtd裝置層、mtd原始裝置層、flash硬體驅動層之間的聯絡。
Linux MTD子系統學習(一)
mtd memory technology device 記憶體技術裝置,是linux用於描述rom,nand,nor等裝置的子系統的抽象,mtd裝置可以按塊讀寫也可以按位元組讀寫,也就是說mtd裝置既可以是塊裝置也可以是字元裝置,塊裝置 mtdblackx 操作針對檔案系統,字元裝置 mtdx 操...
Linux mtd子系統專欄分析之一 概述
從今天開始,我們進行linux mtd子系統的分析。mtd子系統即為記憶體技術裝置子系統,主要包括nor flash nand flash等快閃儲存器裝置相關的子系統模組,而針對sd tf等儲存裝置,則主要由mmc子系統模組進行管理並建立對應的塊裝置。而針對mtd子系統,則會基於mtd原始裝置,建立...
read 系統呼叫剖析
注 所有清單中 均來自 linux2.6.11 核心原 讀資料之前,必須先開啟檔案。處理 open 系統呼叫的核心函式為 sys open 所以我們先來看一下該函式都作了哪些事。清單1顯示了 sys open 的 省略了部分內容,以後的程式清單同樣方式處理 清單1 sys open 函式 asmli...