1. 程式人生 > >linux Nand 驅動的架構整體分析

linux Nand 驅動的架構整體分析

platform device 和 platform driver 的結構,現在看來是初步理解他的用意了,首先 platform device 申請的是資源,而 platform driver 才是真正的驅動。

我一直的疑問就是,如果換個NAND flash晶片,應該怎麼辦,或者說,如果換個CPU,不是三星,而是atmel的又應該怎麼辦?所以應該從整體上理解這個架構。

首先 NAND 裝置的 platform device的註冊:

smdk2410_init --》smdk_machine_init --> platform_add_devices --> s3c_device_nand


資源就是 MEM 資源,1MB,NAND控制器的實體地址
static struct resource s3c_nand_resource[] = {
[0] = {
.start = S3C_PA_NAND,
.end   = S3C_PA_NAND + SZ_1M,
.flags = IORESOURCE_MEM,
}
};


struct platform_device s3c_device_nand = {
.name = "s3c2410-nand",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_nand_resource),
.resource  = s3c_nand_resource,
};


裝置的名字 s3c2410-nand,這個名字必須匹配

裝置的驅動在 /drivers/mtd/nand/s3c2410.C

看看 driver 的名字是怎麼適配的
/* driver device registration */

static struct platform_device_id s3c24xx_driver_ids[] = {
{
.name= "s3c2410-nand",
.driver_data = TYPE_S3C2410,
}, {
.name= "s3c2440-nand",
.driver_data = TYPE_S3C2440,
}, {
.name= "s3c2412-nand",
.driver_data = TYPE_S3C2412,
}, {
.name= "s3c6400-nand",
.driver_data = TYPE_S3C2412, /* compatible with 2412 */
},
{ }
};

MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids);

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,
},
};


可以看出, .id_table 指向的 s3c24xx_driver_ids 裡面就有 s3c2410-nand ,而這裡的id列表有多個,可以支援不同的platfrom device了。接著晶片級別的NAND控制器驅動都在這裡做,操作的是 S3C24XX 的暫存器,所以如果換CPU的話,就應該適配這個驅動的程式碼了。但是這個驅動是沒有指定哪個晶片的,其實NAND FLASH有通用的讀取ID的操作的,可以通過ID來判斷NAND 的廠家,型別,容量,block大小等等的資訊。而這些資訊 \drivers\mtd\nand\nand_ids.c 中描述了flash,例如

struct nand_flash_dev nand_flash_ids[] = {
{"NAND 16MiB 1,8V 8-bit",0x33, 512, 16, 0x4000, 0},
{"NAND 16MiB 3,3V 8-bit",0x73, 512, 16, 0x4000, 0},


struct nand_manufacturers nand_manuf_ids[] = {
{NAND_MFR_TOSHIBA, "Toshiba"},
{NAND_MFR_SAMSUNG, "Samsung"},


理論上,應該選用列表中有的FLASH型號,不過那些都是常用,很實際的事情。如果沒有,(不確定)則會比較痛苦。至於分割槽,那就是邏輯上的事情,實際的NAND裝置適配之後,是沒有問題的。

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,
},


例如,只需要指定 MTD 分割槽的便宜和大小就行了,其他都是邏輯上的事情,不過分析起來,也有一段可以看的了。

到目前為止大概瞭解了需要做什麼事情。nand flash驅動沒有除錯好之前,是沒有檔案系統可用的,所以可以通過NFS先讓系統啟動起來,然後通過除錯NAND驅動來,如果網路也沒有好的話,那唯一的辦法就是通過的 initrd 來啟動系統。然後慢慢調驅動,如果initrd也沒有好,那隻能通過一個好系統來做了。