嵌入式Linux下Nand Flash驅動分析
一、Nand Flash驅動源碼檔案含義
在Linux核心中,MTD原始碼放在/driver/mtd目錄下,該目錄中包含chips、devices、maps、nand、onenand和ubi六個子目錄。其中只有nand和onenand目錄中的代碼才與Nand驅動有關,nand目錄中的代碼比較通用,而onenand目錄中的代碼相對於nand中的代碼而言簡化了許多,是三星公司開發的另類nand Flash。市場佔有率不是很高。所以,開發基於MTD的nand驅動程式,基本上只需要關注nand目錄了,包括Kconfig、Makefile以及如下重要檔案:
1、nand_base.c
定義了Nand驅動中對nand晶片最基本的操作函數和操作流程,如擦除、讀/寫page、讀寫oob等,是nand驅動的核心檔案
2、nand_bbt.c
定義了nand驅動中與壞塊管理有關的函數和結構體
3、nand_ids.c
定義了兩個全域類型的結構體:struct nand_flash_dev nand_flash_ids[ ]和struct nand_manufacturers nand_manuf_ids[ ]。其中前者定義了一些Nand晶片的類型,後者定義了nand晶片的幾個廠商資訊。nand_flash_ids[ ]中有三項屬性比較重要,即pagesize、chipsize和erasesize,驅動就是一句這三項屬性來進行擦除、讀寫等資料大小的操作。
4、nand_ecc.c
定義了nand驅動中與softwareECC有關的函數和結構體。
5、nandsim,c
定義了Nokia開發的類比Nand裝置,預設是Toshiba Nand 8MB。
6、diskonchip.c
定義了片上磁碟相關的一些函數,開發普通的nand flash驅動時不用理會。
7、s3c2410.c
S3C2440系統Nand Flash驅動執行個體,我們要針對不同的CPU移植Nand Flash驅動,主要就是實現這個Nand Flash的驅動源碼檔案。
二、Nand Flash驅動架構
(1)、Nand Flash平台裝置 主要涉及的檔案是dev-nand.c
註冊Nand Flash平台裝置是在mach-mini2440.c中實現:
static void __init mini2440_machine_init(void)
{
#if defined (LCD_WIDTH)
s3c24xx_fb_set_platdata(&mini2440_fb_info);
#endif
s3c_i2c0_set_platdata(NULL);
s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
//設定Nand Flash平台裝置的私人資料friendly_arm_nand_info,
s3c_device_nand.dev.platform_data = &friendly_arm_nand_info;
s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;
//註冊平台裝置到核心的platform匯流排,platform_device_register()函數內部也是通過platform_add_devices()實現,
platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
s3c_pm_init();
}
而結構體struct s3c2410_platform_nandfriendly_arm_nand_info為:
static struct s3c2410_platform_nand friendly_arm_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(friendly_arm_nand_sets),
.sets = friendly_arm_nand_sets,
.ignore_unset_ecc = 1,
};
(2)、Nand Flash平台裝置驅動 主要涉及的檔案是s3c2410.c檔案
static struct platform_driver s3c24xx_nand_driver = {
.probe = s3c24xx_nand_probe,
.remove = s3c24xx_nand_remove,
.suspend = s3c24xx_nand_suspend,
.resume = s3c24xx_nand_resume,
.id_table = s3c24xx_driver_ids,
.driver = {
.name = "s3c24xx-nand",
.owner = THIS_MODULE,
},
};
static int __init s3c2410_nand_init(void)
{
printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");
return platform_driver_register(&s3c24xx_nand_driver);
}
static void __exit s3c2410_nand_exit(void)
{
platform_driver_unregister(&s3c24xx_nand_driver);
}
module_init(s3c2410_nand_init);
module_exit(s3c2410_nand_exit);
嵌入式Linux作業系統下平台裝置驅動的開發主要分為以下三個步驟:
(1)、定義並該平台裝置的平台裝置驅動結構體變數struct platform_driver s3c24xx_nand_driver,並將其初始化。
(2)、註冊平台裝置驅動結構體變數struct platform_driver s3c24xx_nand_driver到核心中。
(3)、實現平台裝置驅動結構體變數struct platform_driver s3c24xx_nand_driver中的成員函數。