1. 程式人生 > >關於塊裝置與nand flash的初步小結

關於塊裝置與nand flash的初步小結

塊裝置驅動的框架:

呼叫過程自上而下為:應用程式讀寫檔案—>虛擬檔案系統(ext3, yaffs2, jffs2)—>由ll_rw_block函式轉換成扇區的讀寫—>塊裝置驅動程式—>讀寫硬體

塊裝置驅動程式提供一個佇列,將讀操作和寫操作放入佇列內,並且在佇列中優化讀寫順序使得讀寫佔用時間減小(這就是為什麼有時候讀的資料可能並不是真正從磁碟上讀來的而是cache中),裝置驅動另外必要的功能就是要註冊裝置。原理上字元裝置也同樣可以對字盤讀寫,只是少了塊裝置驅動那樣的電梯排程演算法。

塊裝置驅動中重要的資料結構:

struct gendisk:可使用函式alloc_disk分配;

一個簡單的塊裝置驅動需要給以下結構體內的值進行賦值:

struct gendisk {
/* major, first_minor and minors are input parameters only,
* don't use directly.  Use disk_devt() and disk_max_parts().
*/

…………

struct request_queue *queue;//使用blk_init_queue函式設定佇列,佇列中包括讀寫的操作

int major; /* major number of driver *///使用register_blkdev註冊到一個主裝置號

int first_minor;

int minors;                     /* maximum number of minors, =1 for
                                         * disks that can't be partitioned. */

char disk_name[DISK_NAME_LEN];/* name of major driver */

struct block_device_operations *fops;
struct hd_struct part0;//使用set_capacity函式設定有多少個扇區

…………
};

最後註冊gendisk,使用函式:add_disk函式。

對以上相關的結構體進行反註冊的函式有:unregister_blkdev(major, "blockdisk");del_gendisk(block_disk);put_disk(block_disk);blk_cleanup_queue(block_queue);

關於除錯塊裝置的相關命令:

mkdosfs:第一次使用一塊塊裝置需要對其進行格式化;fdisk對一個塊裝置進行分割槽。

nand flash的驅動相關:

nand flash硬體:

如果所示:


其中:

I/O0 ~ I/O7:用於輸入地址/資料/命令,輸出資料;

WP#:Write Protect,防寫;

WE#:Write Enable,寫使能, 在寫取資料之前,要先使WE#有效;

ALE:Address Latch Enable,地址鎖存使能,在輸入地址之前,要先在模式暫存器中,設定ALE使能;

CLE:Command Latch Enable,命令鎖存使能,在輸入命令之前,要先在模式暫存器中,設定CLE使能;PS:當ALE和CLE都不使能的時候表示當前傳輸的是資料;

CE#:Chip Enable,片選使能,在操作Nand Flash之前,要先選中此晶片,才能操作;

RE#:Read Enable,讀使能,在讀取資料之前,要先使CE#有效;

R/B#:Ready/Busy Output,就緒/忙,主要用於在傳送完程式設計/擦除命令後,檢測這些操作是否完成,忙,表示程式設計/擦除操作仍在進行中,就緒表示操作完成;

S3C2440中NFCONF中三個比較重要的引數:

TACLS、TWRPH0、TWRPH1:S3C的資料手冊如下:


如上圖可猜測

TACLS為CLE/ALE使能至nFRE/nFWE使能之間的時間段;TACLS設值範圍0-3,持續時間的公式為TACLS*HCLK

TWRPH0為nFRE/nFWE使能的時間段;TWRPH0設值範圍0-7,持續時間的公式為(TWRPH0+1)*HCLK

TWRPH1為nFRE/nFWE不使能至CLE/ALE不使能的時間段;TWRPH1設值範圍0-7,持續時間的公式為(TWRPH1+1)*HCLK

查閱NAND FLASH的資料手冊:


觀察時序圖以及下圖可以發現:

TACLS:對應於nand flash手冊中時序圖(tCLS-tWP)和(tALS-tWP)這兩個值中的較小的那個。12ns-12ns=0。所以TACLS可設定為0。

TWRPH0:對應於nand flash手冊中時序圖tWP和tRP這兩個值中的較小的那個。(tRP也是12ns,未截圖)。12ns。假設HCLK為100Mhz,根據公式(TWRPH0+1)*HCLK=12ns,可算得TWRPH0=1.2=2。

TWRPH1:對應於nand flash手冊中時序圖tCLH和tALH這兩個值中的較小的那個。同上。

關於S3C中對NAND FLASH操作的暫存器:

nfconf  ;0x4E000000
nfcont  ;
nfcmd   ;
nfaddr  ;
nfdata  ;
nfeccd0 ;
nfeccd1 ;
nfeccd  ;
nfstat  ;
nfestat0;
nfestat1;
nfmecc0 ;
nfmecc1 ;
nfsecc  ;
nfsblk  ;
nfeblk  ;

關於NAND FLASH驅動的基本框架:

基本的結構體:

struct nand_chip、struct mtd_info、struct mtd_partition

nand_chip結構體中需要滿足的結構體成員:

select_chip   //為片選NAND FLASH的操作函式
cmd_ctrl//為傳送命令或者地址的操作函式(把資料放入CMD暫存器還是ADD暫存器)
IO_ADDR_R //為讀資料的暫存器
IO_ADDR_W//為寫資料的暫存器
dev_ready//為檢測nand flash是否忙的函式
ecc.mode//為是否ECC校驗的標誌位如NAND_ECC_SOFT或者NAND_ECC_NONE等

mtd_info結構體中需要滿足的結構體成員:

owner //THIS_MODULE;
priv  = s3c_nand;//指向nand_chip的結構體,用於nand_scan識別nand flash用。

識別之後註冊分割槽add_mtd_partitions函式。(反註冊函式del_mtd_partitions)。

PS:過程中需要使能NAND FLASH控制器的時鐘,使用函式clk_get、clk_enable。

以上完成了nand flash塊裝置的初始化,其中呼叫的函式中肯定呼叫了一開始說的那些函式,底層裝置的初始化都會一步步呼叫到上層的函式,因為初始化完成之後就可以用應用程式對其訪問。

NOR FLASH:


上圖可得其資料位有16位,地址位有22位除去兩位NC為22位,2^20=1024*1024,由資料位為16位可得,總共容量有2Mb(這樣我們也大概清楚為什麼nand不用這樣的匯流排定址了,因為容量太大線太多了)。

關於為什麼是LADDR1接A0而不是LADDR0接,是因為S3C2440每個地址的容量為一個位元組而非此NOR中兩個位元組,為了讓這樣一倍的差距對應起來,如果ARM程式中匯流排的地址為0x2而對應NOR中的地址就是0x1,如果匯流排地址為0x3那麼NOR中還是0x1,因為0x2、0x3兩個地址的值都位於地址為0x1的16位寄存值中。

nor程式設計系統框架:

結構體:map_info、s3c_nor_parts

函式:

simple_map_init、do_map_probe、add_mtd_partitions

參考文章:

http://blog.csdn.net/juana1/article/details/6577556

http://funexploit.readthedocs.org/en/latest/sources/embeddedsystem.html