mtd介紹


轉:http://blog.csdn.net/lwj103862095/article/details/21545791

MTD,Memory Technology Device即內存技術設備

字符設備和塊設備的區別在於前者只能被順序讀寫,后者可以隨機訪問;同時,兩者讀寫數據的基本單元不同。

字符設備,以字節為基本單位,在Linux中,字符設備實現的比較簡單,不需要緩沖區即可直接讀寫,內核例程和用戶態API一一對應,用戶層的Read函數直接對應了內核中的Read例程,這種映射關系由字符設備的file_operations維護。

塊設備,則以塊為單位接受輸入和返回輸出。對這種設備的讀寫是按塊進行的,其接口相對於字符設備復雜,read、write API沒有直接到塊設備層,而是直接到文件系統層,然后再由文件系統層發起讀寫請求。 
同時,由於塊設備的IO性能與CPU相比很差,因此,塊設備的數據流往往會引入文件系統的Cache機制。

MTD設備既非塊設備也不是字符設備,但可以同時提供字符設備和塊設備接口來操作它。

MTD總概述

Linux中MTD的所有源碼位於/drivers/mtd子目錄下,

MTD設備通常可分為四層 
這四層從上到下依次是:設備節點、MTD設備層、MTD原始設備層和硬件驅動層。

一、Flash硬件驅動層 
硬件驅動層負責在init時驅動Flash硬件並建立從具體設備到MTD原始設備映射關系 
tip: 映射關系通常包括 分區信息、I/O映射及特定函數的映射 
drivers/mtd/chips :   CFI/jedec接口通用驅動 
drivers/mtd/nand :   nand通用驅動和部分底層驅動程序 
drivers/mtd/maps :   nor flash映射關系相關函數 
drivers/mtd/devices:   nor flash底層驅動

二、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字符設備和塊設備 
具體參考:  working-with-mtd-devices

五、文件系統 
內核啟動后,通過mount 命令可以將flash中的其余分區作為文件系統掛載到mountpoint上。

MTD數據結構 

重要的數據結構: 
1. mtd_info 表示mtd原始設備, 所有mtd_info結構體被存放在mtd_info數組mtd_table中

2. mtd_part   表示MTD分區,其中包含了 mtd_info,每一個分區都是被看成一個MTD 原始設備 
在mtd_table中,mtd_part.mtd_info中的大部分數據都從該分區的主分區mtd_part->master中獲得 
tip: master不作為一個mtd原始設備加入mtd_table

各層之間的交互如下圖

image    
mtd_info的主要數據結構

作用
type mtd類型, 包括MTD_NORFLASH,MTD_NANDFLASH等(See mtd-abi.h)
flags 標志位, MTD_WRITEABLE,MTD_NO_ERASE等(See mtd-abi.h)
size mtd設備的大小
erasesize 主要的擦除大小, 即Flash的塊大小 (tip: mtd設備可能有多個erasesize)
writesize 寫大小, 對於norFlash是字節,對nandFlash為一頁
oobsize 每塊oob數據量, eg 16
oobavail  
name 命名
index  
ecclayout nand_ecclayout結構體指針, 表示的是ecc布局,可參考硬件手冊的OOB中ecc布局
numeraseregions 可變擦除區域的數目, 通常為1
eraseregions mtd_erase_region_info結構體指針, 可變擦除區域
erase 擦除Flash函數
read/write 讀寫Flash函數
read_oob/write_oob 帶oob讀寫Flash函數
suspend/resume Power Management functions
priv 私有數據, cfi接口flash指向map_info結構, 或指向自定義flash相關結構體
   

mtd_part的主要數據結構

作用
mtd 分區信息, 大部分由master決定
master 分區的主分區
offset 分區的偏移地址
index 分區號 (3.0后不存在該字段)
list 將mtd_part鏈成一個鏈表mtd_partitons
   

mtd_partition的主要數據結構

作用
name  
size  
offset  
mask_flags  
ecclayout  
mtdp  
   

map_info的主要數據結構

作用
name 名稱
size 大小
phys 物理地址
bankwidth 總線寬度(in octets)
virt 虛擬地址,通常通過ioremap將物理地址進行映射得到
read/copy_from/write/copy_to 讀寫函數
map_priv_1/map_priv_2 驅動可用的私有數據
   

nand_chip的主要數據結構

作用
IO_ADDR_R/IO_ADDR_W 讀/寫8根io線的地址
read_byte/read_word 從芯片讀一個字節/字
read_buf/write_buf 讀芯片讀取內容至緩沖區/將緩沖區內容寫入芯片
verify_buf  
select_chip  
block_bad 檢查是否壞塊
block_markbad 標識壞塊
cmd_ctrl 硬件相關控制函數
init_size  
dev_ready  
cmdfunc 命令處理函數
waitfunc  
erase_cmd 擦除命令
scan_bbt 掃描壞塊
errstat  
write_page  
options 與具體的NAND 芯片相關的選項, 如NAND_USE_FLASH_BBT等(nand.h)
page_shift  
   
ecclayout nand_ecclayout類型結構體, ECC布局信息
ecc nand_ecc_ctrl類型結構體, ECC控制結構
   
   
   

nand_ecclayout的主要數據結構

作用
eccbytes ecc的字節數(For 512B-per-page, eccbytes is 3)
eccpos ecc數據在oob中的位置
oobavail oob中可用的字節數, MTD 會根據其它三個變量自動計算得到
oobfree nand_oobfree類型結構體, 顯示定義空閑的oob 字節
   

MTD相關層實現

MTD設備層

mtd字符設備接口: 
mtdchar.c 實現了字符設備接口,通過它,用戶可以直接操作Flash 設備。 
Ø 通過read()、write()系統調用可以讀寫Flash。 
Ø 通過一系列IOCTL 命令可以獲取Flash 設備信息、擦除Flash、讀寫NAND 的OOB、獲取OOB layout 及檢查NAND 壞塊等(MEMGETINFO、MEMERASE、MEMREADOOB、MEMWRITEOOB、MEMGETBADBLOCK IOCRL) 
tip: mtd_read和mtd_write直接直接調用mtd_info的read 函數,因此,字符設備接口跳過patition這一層

mtd塊設備接口: 
主要原理是將Flash的erase block 中的數據在內存中建立映射,然后對其進行修改,最后擦除Flash 上的block,將內存中的映射塊寫入Flash 塊。整個過程被稱為read/modify/erase/rewrite 周期。 
但是,這樣做是不安全的,當下列操作序列發生時,read/modify/erase/poweroff,就會丟失這個block 塊的數據。 
塊設備模擬驅動按照block 號和偏移量來定位文件,因此在Flash 上除了文件數據,基本沒有額外的控制數據。

 

MTD原始設備層

 

MTD硬件驅動層

1. NOR Flash驅動結構

Linux系統實現了針對cfi,jedec等接口的通用NOR Flash驅動 
在上述接口驅動基礎上,芯片級驅動較簡單 
     定義具體內存映射結構體map_info,然后通過接口類型后調用do_map_probe()  
以h720x-flash.c為例(位於drivers/mtd/maps) 
- 定義map_info結構體, 初始化成員name, size, phys, bankwidth 
- 通過ioremap映射成員virt(虛擬內存地址) 
- 通過函數simple_map_init初始化map_info成員函數read,write,copy_from,copy_to 
- 調用do_map_probe進行cfi接口探測, 返回mtd_info結構體 
- 通過parse_mtd_partitions, add_mtd_partitions注冊mtd原始設備

2. NAND Flash驅動結構 

Linux實現了通用NAND驅動(drivers/mtd/nand/nand_base.c) 
tip: For more, check 內核中的NAND代碼布局  
芯片級驅動需要實現nand_chip結構體 
MTD使用nand_chip來表示一個NAND FLASH芯片, 該結構體包含了關於Nand Flash的地址信息,讀寫方法,ECC模式,硬件控制等一系列底層機制。 
Ø NAND芯片級初始化 
主要有以下幾個步驟: 
- 分配nand_chip內存,根據目標板及NAND控制器初始化nand_chip中成員函數(若未初始化則使用nand_base.c中的默認函數),將mtd_info中的priv指向nand_chip(或板相關私有結構),設置ecc模式及處理函數 
- 以mtd_info為參數調用nand_scan()探測NAND FLash。 
   nand_scan()會讀取nand芯片ID,並根據mtd->priv即nand_chip中成員初始化mtd_info 
- 若有分區,則以mtd_info和mtd_partition為參數調用add_mtd_partitions()添加分區信息 
-

Ø MTD對NAND芯片的讀寫 
主要分三部分: 
A、struct mtd_info中的讀寫函數,如read,write_oob等,這是MTD原始設備層與FLASH硬件層之間的接口; 
B、struct nand_ecc_ctrl中的讀寫函數,如read_page_raw,write_page等,主要用來做一些與ecc有關的操作; 
C、struct nand_chip中的讀寫函數,如read_buf,cmdfunc等,與具體的NAND controller相關,就是這部分函數與硬件交互,通常需要我們自己來實現。 
tip: nand_chip中的讀寫函數雖然與具體的NAND controller相關,但是MTD也為我們提供了默認的讀寫函數,如果NAND controller比較通用(使用PIO模式),那么對NAND芯片的讀寫與MTD提供的這些函數一致,就不必自己實現這些函數。

上面三部分讀寫函數相互配合完成對NAND芯片的讀寫 
首先,MTD上層需要讀寫NAND芯片時,會調用struct mtd_info中的讀寫函數,接着struct mtd_info中的讀寫函數就會調用struct nand_chip或struct nand_ecc_ctrl中的讀寫函數,最后,若調用的是struct nand_ecc_ctrl中的讀寫函數,那么它又會接着調用struct nand_chip中的讀寫函數。 
eg:  以讀為例 
MTD上層會調用struct mtd_info中的讀page函數,即nand_read函數。 
接着nand_read函數會調用struct nand_chip中cmdfunc函數,這個cmdfunc函數與具體的NAND controller相關,它的作用是使NAND controller向NAND 芯片發出讀命令,NAND芯片收到命令后,就會做好准備等待NAND controller下一步的讀取。 
接着nand_read函數又會調用struct nand_ecc_ctrl中的read_page函數,而read_page函數又會調用struct nand_chip中read_buf函數,從而真正把NAND芯片中的數據讀取到buffer中(所以這個read_buf的意思其實應該是read into buffer,另外,這個buffer是struct mtd_info中的nand_read函數傳下來的)。 
read_buf函數返回后,read_page函數就會對buffer中的數據做一些處理,比如校驗ecc,以及若數據有錯,就根據ecc對數據修正之類的,最后read_page函數返回到nand_read函數中。 
對NAND芯片的其它操作,如寫,擦除等,都與讀操作類似 

http://www.cnblogs.com/hzl6255/archive/2012/12/18/2824043.html

 

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

http://www.cnblogs.com/hoys/archive/2012/05/30/2526230.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM