基于MTD的NAND驱动开发(二)
基于MTD的NAND驅(qū)動開發(fā)(二)
基于MTD的NAND驅(qū)動開發(fā)(三)
http://blog.csdn.net/leibniz_zsu/article/details/4977853
http://blog.csdn.net/leibniz_zsu/article/details/4977869
四、基于MTD的NAND 驅(qū)動架構(gòu) ? 1 、platform_device 和platform_driver 的定義和注冊 對于我們的NAND driver ,以下是一個典型的例子:| ?static struct platform_driver caorr_nand_driver = { |
| ?struct platform_device caorr_nand_device = { |
其中num_resources 和resource 與具體的硬件相關,主要包括一些寄存器地址范圍和中斷的定義。caorr_platform_default_nand 待會兒再說。需要注意的是,這個platform_device 中name 的值必須與platform_driver->driver->name 的值完全一致,因為platform_bus_type 的match 函數(shù)是根據(jù)這兩者的name 值來進行匹配的。
其二是用platform_device_alloc 函數(shù)動態(tài)分配一個platform_device ,然后再用platform_device_add 函數(shù)把這個platform_device 加入到內(nèi)核中去。具體不再細說,Linux 內(nèi)核中有很多例子可以參考。 相對來說,第一種方式更加方便和直觀一點,而第二種方式則更加靈活一點。 C、 在加載NAND 驅(qū)動時,我們還需要向MTD Core 提供一個信息,那就是NAND 的分區(qū)信息,caorr_platform_default_nand 主要就是起這個作用,更加詳細的容后再說。 2 、MTD 架構(gòu)的簡單描述 ? MTD(memory technology device 存儲技術設備) 是用于訪問memory 設備(ROM 、flash )的Linux 的子系統(tǒng)。MTD 的主要目的是為了使新的memory 設備的驅(qū)動更加簡單,為此它在硬件和上層之間提供了一個抽象的接口。MTD 的所有源代碼在/drivers/mtd 子目錄下。MTD 設備可分為四層(從設備節(jié)點直到底層硬件驅(qū)動),這四層從上到下依次是:設備節(jié)點、MTD 設備層、MTD 原始設備層和硬件驅(qū)動層。A、Flash硬件驅(qū)動層:硬件驅(qū)動層負責驅(qū)動Flash硬件。 B、MTD原始設備:原始設備層有兩部分組成,一部分是MTD原始設備的通用代碼,另一部分是各個特定的Flash的數(shù)據(jù),例如分區(qū)。 用于描述MTD原始設備的數(shù)據(jù)結(jié)構(gòu)是mtd_info,這其中定義了大量的關于MTD的數(shù)據(jù)和操作函數(shù)。mtd_table(mtdcore.c)則是所有MTD原始設備的列表,mtd_part(mtd_part.c)是用于表示MTD原始設備分區(qū)的結(jié)構(gòu),其中包含了mtd_info,因為每一個分區(qū)都是被看成一個MTD原始設備加在mtd_table中的,mtd_part.mtd_info中的大部分數(shù)據(jù)都從該分區(qū)的主分區(qū)mtd_part->master中獲得。 在drivers/mtd/maps/子目錄下存放的是特定的flash的數(shù)據(jù),每一個文件都描述了一塊板子上的flash。其中調(diào)用add_mtd_device()、del_mtd_device()建立/刪除 mtd_info結(jié)構(gòu)并將其加入/刪除mtd_table(或者調(diào)用add_mtd_partition()、del_mtd_partition() (mtdpart.c)建立/刪除mtd_part結(jié)構(gòu)并將mtd_part.mtd_info加入/刪除mtd_table 中)。 C、MTD設備層:基于MTD原始設備,linux系統(tǒng)可以定義出MTD的塊設備(主設備號31)和字符設備(設備號90)。MTD字符設備的定義在mtdchar.c中實現(xiàn),通過注冊一系列file operation函數(shù)(lseek、open、close、read、write)。MTD塊設備則是定義了一個描述MTD塊設備的結(jié)構(gòu) mtdblk_dev,并聲明了一個名為mtdblks的指針數(shù)組,這數(shù)組中的每一個mtdblk_dev和mtd_table中的每一個 mtd_info一一對應。 D、設備節(jié)點:通過mknod在/dev子目錄下建立MTD字符設備節(jié)點(主設備號為90)和MTD塊設備節(jié)點(主設備號為31),通過訪問此設備節(jié)點即可訪問MTD字符設備和塊設備。 E、根文件系統(tǒng):在Bootloader中將JFFS(或JFFS2)的文件系統(tǒng)映像jffs.image(或jffs2.img)燒到flash的某一個分區(qū)中,在/arch/arm/mach-your/arch.c文件的 your_fixup函數(shù)中將該分區(qū)作為根文件系統(tǒng)掛載。 F、文件系統(tǒng):內(nèi)核啟動后,通過mount 命令可以將flash中的其余分區(qū)作為文件系統(tǒng)掛載到mountpoint上。 以上是從網(wǎng)上找到的一些資料,我只是斷斷續(xù)續(xù)地看過一些code,沒有系統(tǒng)地研究過,所以這里只能講一下MTD原始設備層與FLASH硬件驅(qū)動之間的交互。 一個MTD原始設備可以通過mtd_part分割成數(shù)個MTD原始設備注冊進mtd_table,mtd_table中的每個MTD原始設備都可以被注冊成一個MTD設備,有兩個函數(shù)可以完成這個工作,即 add_mtd_device函數(shù)和add_mtd_partitions函數(shù)。 其中add_mtd_device函數(shù)是把整個NAND?FLASH注冊進MTD Core,而add_mtd_partitions函數(shù)則是把NAND?FLASH的各個分區(qū)分別注冊進MTD Core。 add_mtd_partitions函數(shù)的原型是:
| int add_mtd_partitions( struct mtd_info * master, ??????????? ?const struct mtd_partition * parts, int nbparts) ; |
| ?static struct mtd_partition caorr_platform_default_nand[ ] = { |
以讀NAND芯片為例,講解一下這三部分讀寫函數(shù)的工作過程。 首先,MTD上層會調(diào)用struct mtd_info中的讀page函數(shù),即nand_read函數(shù)。 接著nand_read函數(shù)會調(diào)用struct nand_chip中cmdfunc函數(shù),這個cmdfunc函數(shù)與具體的NAND controller相關,它的作用是使NAND controller向NAND 芯片發(fā)出讀命令,NAND芯片收到命令后,就會做好準備等待NAND controller下一步的讀取。 接著nand_read函數(shù)又會調(diào)用struct nand_ecc_ctrl中的read_page函數(shù),而read_page函數(shù)又會調(diào)用struct nand_chip中read_buf函數(shù),從而真正把NAND芯片中的數(shù)據(jù)讀取到buffer中(所以這個read_buf的意思其實應該是read into buffer,另外,這個buffer是struct mtd_info中的nand_read函數(shù)傳下來的)。 read_buf函數(shù)返回后,read_page函數(shù)就會對buffer中的數(shù)據(jù)做一些處理,比如校驗ecc,以及若數(shù)據(jù)有錯,就根據(jù)ecc對數(shù)據(jù)修正之類的,最后read_page函數(shù)返回到nand_read函數(shù)中。 對NAND芯片的其它操作,如寫,擦除等,都與讀操作類似。
?
總結(jié)
以上是生活随笔為你收集整理的基于MTD的NAND驱动开发(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 光纤传感技术:基于Matlab的OFDR
- 下一篇: U-boot中TFTP 解释