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也没有好,那只能通过一个好系统来做了。