編者:linux中的nand的移植由於使用了MTD技術,所以就沒有想象的那麼復雜了。
1 Linux-2.6.32.2 內核所支持的Nand Flash 類型
Linux2.6.32.2 已經自帶了大部分Nand Flash 驅動, 在linux-2.6.32.2/drivers/mtd/nand/nand_ids.c 文件中,定義了所支持的各種Nand Flash 類型。
2 修改Nand Flash 分區表
但是系統默認的分區不是我們所需的,所以要自已修改,除此之外,還有Nand Flash的結構信息需要增加填寫,以便能夠適合系統自帶的Nand Flash 驅動接口,這可以參考SMDK2440 中關於Nand Flash 設備注冊的一些信息。
打開/arch/arm/plat-24xx/common-smdk.c,可以看到這樣一個結構體:
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "Boot Agent",
.size = SZ_16K,
.offset = 0,
},
[1] = {
.name = "S3C2410 flash partition 1",
.offset = 0,
.size = SZ_2M,
},
[2] = {
.name = "S3C2410 flash partition 2",
.offset = SZ_4M,
.size = SZ_4M,
},
[3] = {
.name = "S3C2410 flash partition 3",
.offset = SZ_8M,
.size = SZ_2M,
},
[4] = {
.name = "S3C2410 flash partition 4",
.offset = SZ_1M * 10,
.size = SZ_4M,
},
[5] = {
.name = "S3C2410 flash partition 5",
.offset = SZ_1M * 14,
.size = SZ_1M * 10,
},
[6] = {
.name = "S3C2410 flash partition 6",
.offset = SZ_1M * 24,
.size = SZ_1M * 24,
},
[7] = {
.name = "S3C2410 flash partition 7",
.offset = SZ_1M * 48,
.size = SZ_16M,
}
};
這其實就是Nand Flash 的分區表,在Linux-2.6.32.2 中,nand 驅動是被注冊為平台設備的,這同樣在/arch/arm/plat-24xx/common-smdk.c 文件中看出,如下:
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
/* devices we initialise */
static struct platform_device __initdata *smdk_devs[] = {
&s3c_device_nand,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
};
參考以上結構信息,我們也在自己的mach-mini2440.c 中照此添加實現,同時需要參考友善之臂原廠內核中的Nand 分區表,如下圖所示:
因此,在mach-mini2440.c 中加入以下代碼;;以下藍色部分為說明文字
static struct mtd_partition mini2440_default_nand_part[] = {
[0] = {
.name = "supervivi", ;這裡是bootloader 所在的分區,可以放置u-boot, supervivi 等內容,對應/dev/mtdblock0
.size = 0x00040000,
.offset = 0,
},
[1] = {
.name = "param", ;這裡是supervivi 的參數區,其實也屬於bootloader 的一部分,如果u-boot 比較大,可以把此區域覆蓋掉,不會影響系統啟動,對應/dev/mtdblock1
.offset = 0x00040000,
.size = 0x00020000,
},
[2] = {
.name = "Kernel", ;內核所在的分區,大小為5M,足夠放下大部分自己定制的巨型內核了,比如內核使用了更大的Linux Logo 圖片等,對應/dev/mtdblock2
.offset = 0x00060000,
.size = 0x00500000,
},
[3] = {
.name = "root", ;文件系統分區,友善之臂主要用來存放yaffs2 文件系統內容,對應/dev/mtdblock3
.offset = 0x00560000,
.size = 1024 * 1024 * 1024, //
},
[4] = {
.name = "nand", ;此區域代表了整片的nand flash,主要是預留使用,比如以後可以通過應用程序訪問讀取/dev/mtdblock4 就能實現備份整片nand flash 了。
.offset = 0x00000000,
.size = 1024 * 1024 * 1024, //
}
};
;這裡是開發板的nand flash 設置表,因為板子上只有一片,因此也就只有一個表
static struct s3c2410_nand_set mini2440_nand_sets[] = {
[0] = {
.name = "NAND",
.nr_chips = 1,
.nr_partitions = ARRAY_SIZE(mini2440_default_nand_part),
.partitions = mini2440_default_nand_part,
},
};
;這裡是nand flash 本身的一些特性,一般需要對照datasheet 填寫,大部分情況下按照以下參數填寫即可
static struct s3c2410_platform_nand mini2440_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(mini2440_nand_sets),
.sets = mini2440_nand_sets,
.ignore_unset_ecc = 1,
};
除此之外,還需要把nand flash 設備注冊到系統中,
static struct platform_device *mini2440_devices[] __initdata = {
& s3c_device_usb,
& s3c_device_lcd,
& s3c_device_wdt,
& s3c_device_i2c0,
& s3c_device_iis,
& s3c_device_nand, ;把nand flash 設備添加到開發板的設備列表結構
};
3 從啟動信息中查看分區表
至此,就完成了nand flash 驅動的移植,此時在內核根目錄執行“make zImage”,把生成的zImage 燒寫到開發板,可以在啟動時看到信息,它們正是我們剛剛添加的nandflash 分區信息,以及開發板本身nand flash 的一些信息,這裡可以看到是256M 的nand flash。
PS:上面是按手冊介紹的,說了一大堆,但是很明顯我們剛才聲明的結構體信息沒有和s3c_device_nand產生任何關聯,這樣肯定就不會正常工作了。同樣使在這個文件裡面,一定要在下面的這個函數中加上一句這樣的話:
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);
s3c_device_nand.dev.platform_data = &mini2440_nand_info;
s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;
platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
s3c_pm_init();
}
這樣才把這個信息關聯到設備,就可以正常工作了。