S5PV210 nand flash 驱动移植
环境:debian? 6???linux?2.6.35.7 arm-linux-gcc: 做完核心的内核移植之后,接下来要做的驱动移植,第一步移植的是nand?flash驱动。 在做驱动移植之前,我们有必要了解一下linux的platform机制: 从Linux?2.6起引入了一套新的驱动管理和注册机制:platform_device和platform_driver。Linux中大部分的设备驱动,都可以使用这套机制,设备用platform_device表示,驱动用platform_driver进行注册。 Linux?platform.?driver机制和传统的device?driver?机制(通过driver_register函数进行注册)相比,一个十分明显的优势在于platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform.?device提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性(这些标准接口是安全的)。platform机制的本身使用并不复杂,由两部分组成:platform_device和platfrom_driver。通过platform机制开发底层设备驱动的大致流程如图所示。
??? platform机制开发驱动流程 platform_device结构体用来描述设备的名称、资源信息等。该结构被定义在include/linux/platform_device.h中,定义原型如下: struct?platform_device?{ const?char?*?name;????//定义平台设备的名称 int?id; struct?device?dev; u32?num_resources; struct?resource?*?resource;?//定义平台设备的资源。 }; 下面来看一下platform_device结构体中最重要的一个成员struct?resource?*?resource。struct?resource被定义在include/linux/ioport.h中,定义原型如下: struct?resource?{ resource_size_t?start;??//定义资源的起始地址 resource_size_t?end;??//定义资源的结束地址 const?char?*name;????//定义资源的名称 unsigned?long?flags;?//定义资源的类型,比如MEM,IO,IRQ,DMA类型 struct?resource?*parent,?*sibling,?*child;??//资源链表指针 通过调用函数platform_add_devices()向系统中添加该设备了,该函数内部调用platform_device_register(?)进行设备注册。要注意的是,这里的platform_device设备的注册过程必须在相应设备驱动加载之前被调用,即执行platform_driver_register()之前,原因是驱动注册时需要匹配内核中所有已注册的设备名。 接下来来看platform_driver结构体的原型定义,在include/linux/platform_device.h中,代码如下: struct?platform_driver?{ int?(*probe)(struct?platform_device?*); int?(*remove)(struct?platform_device?*); void?(*shutdown)(struct?platform_device?*); int?(*suspend)(struct?platform_device?*,?pm_message_t?state); int?(*suspend_late)(struct?platform_device?*,'Microsoft YaHei'"> int?(*resume_early)(struct?platform_device?*); int?(*resume)(struct?platform_device?*); struct?device_driver?driver; 内核提供的platform_driver结构体的注册函数为platform_driver_register(),其原型定义在driver/base/platform.c文件中,具体实现代码如下: int?platform_driver_register(struct?platform_driver?*drv) { drv->driver.bus?=?&platform_bus_type; if?(drv->probe) drv->driver.probe?=?platform_drv_probe; if?(drv->remove) drv->driver.remove?=?platform_drv_remove; if?(drv->shutdown) drv->driver.shutdown?=?platform_drv_shutdown; if?(drv->suspend) drv->driver.suspend?=?platform_drv_suspend; if?(drv->resume) drv->driver.resume?=?platform_drv_resume; return?driver_register(&drv->driver); } 总结,通常情况下只要和内核本身运行依赖性不大的外围设备,相对独立的,拥有各自独自的资源(地址总线和IRQs),都可以用platform_driver实现。如:LCD,网卡、USB、UART等,都可以用platfrom_driver写,而timer,irq等小系统之内的设备则最好不用platfrom_driver机制。 以上关于platfrom机制均为网络转载。 ?现在开始来进行nand?flash驱动移植 首先下载nand?flash驱动?s3c_nand.c?,此文件包含着nand?flash驱动具体的实现,将其复制到drivers/mtd/nand下; ?s3c_nand.c?下载地址?s3c_nand.c 在s3c_nand.c中添加nand?flash分区信息,分区内容可以自由设定。 #if?defined(CONFIG_ARCH_S5PV210) struct?mtd_partition?s3c_partition_info[]?=?{ { .name=?"misc", .offset=?(768*SZ_1K),??????????/*?for?bootloader?*/ .size=?(256*SZ_1K),'Microsoft YaHei'">.mask_flags=?MTD_CAP_NANDFLASH,'Microsoft YaHei'">},'Microsoft YaHei'">.name=?"recovery",'Microsoft YaHei'">.offset=?MTDPART_OFS_APPEND,'Microsoft YaHei'">.size=?(5*SZ_1M),'Microsoft YaHei'">.name=?"kernel",'Microsoft YaHei'">.name=?"ramdisk",'Microsoft YaHei'">.size=?(3*SZ_1M),STHeiti; font-size:14px; line-height:21px"> .name=?"system",'Microsoft YaHei'">.size=?MTDPART_SIZ_FULL,'Microsoft YaHei'">} .size=?(110*SZ_1M),'Microsoft YaHei'">.name=?"cache",'Microsoft YaHei'">.size=?(80*SZ_1M),'Microsoft YaHei'">.name=?"userdata",'Microsoft YaHei'">#endif }; struct?s3c_nand_mtd_info?s3c_nand_mtd_part_info?=?{ .chip_nr?=?1,'Microsoft YaHei'">.mtd_part_nr?=?ARRAY_SIZE(s3c_partition_info),'Microsoft YaHei'">.partition?=?s3c_partition_info,'Microsoft YaHei'">}; ? 结构体s3c_nand_mtd_info在源代码是没有的,所以要将其添加进去;
修改?arch/arm/plat-samsung/include/plat/nand.h?添加如下内容:
struct?s3c_nand_mtd_info?{
uint?chip_nr;
uint?mtd_part_nr;
struct?matd_partition?*partition;
};
为了能使s3c_nand.c正确编译,还要修改该目录下,也就是的drivers/mtd/nand的Makefile和Kconfig: 修改driver/mtd/nand/Kconfig添加如下内容:
config?MTD_NAND_S3C
tristate?"NAND?Flash?support?for?S3C?Soc"
depends?on?ARCH_S5PV210?&&?MTD_NAND
help
This?enables?the?NAND?flash?controller?on?the?S3C.
No?board?specfic?support?is?done?by?this?driver?,?each?board
must?advertise?a?platform_device?for?the?driver?to?attach.
config?MTD_NAND_S3C_DEBUG
bool?"S3C?NAND?driver?debug"
depends?on?MTD_NAND_S3C
Enable?debugging?of?the?S3C?NAND?driver
config?MTD_NAND_S3C_HWECC
bool?"S3C?NAND?Hardware?ECC"
help??www.2cto.com??
Enable?the?use?of?the?S3C's?internal?ECC?generator?when?
using?NAND.?Early?versons?of?the?chip?have?had?problems?with
incorrect?ECC?generation,?and?if?using?these,?the?default?of
software?ECC?is?preferable
If?you?lay?down?a?device?with?the?hardware?ECC,?the?you?will
currently?not?be?able?to?switch?to?software,?as?there?is?no
implementation?for?ECC?method?used?by?the?S3C
修改drivers/mtd/nand/Makefile添加如下内容:
obj-$(CONFIG_MTD_NAND_S3C)????????+=?s3c_nand.o
?在Mach-smdkv210.c?(archarmmach-s5pv210)?中添加nand?flash?source,platform_device,需要头文件map.h?map.h下载,下载将其放在(archarmmach-s5pv210includemach),在Mach-smdkv210.c中加入#include?<asm/mach/map.h>。 ? 添加nand?flash?source /*?NAND?Controller?*/ static?struct?resource?s3c_nand_resource[]?=?{ [0]?=?{ .start=?S5PV210_PA_NAND,'Microsoft YaHei'">.end=?S5PV210_PA_NAND?+?S5PV210_SZ_NAND?-?1,'Microsoft YaHei'">.flags=?IORESOURCE_MEM,'Microsoft YaHei'">struct?platform_device?s3c_device_nand?=?{ .name=?"s5pv210-nand",'Microsoft YaHei'">.id=?-1,'Microsoft YaHei'">.num_resources=?ARRAY_SIZE(s3c_nand_resource),'Microsoft YaHei'">.resource=?s3c_nand_resource,'Microsoft YaHei'">}; ? 添加platform_device ?找到static?struct?platform_device?*smdkv210_devices[]?__initdata ?添加 #if?defined(CONFIG_MTD_NAND_S3C)
&s3c_device_nand,
#endif
?添加时钟信息 在Clock.c?(archarmmach-s5pv210)?中找到static?struct?clk?init_clocks_off[],添加 { 以上操作完成后,开始配置内核 根目录下make?menuconfig ? Device?Drivers?--->
<*>?Memory?Technology?Device?(MTD)?support?--->
[*]?MTD?partitioning?support
<*>?Caching?block?device?access?to?MTD?devices
<*>?NAND?Device?Support?--->
<*>?NAND?Flash?support?for?S3C?SoCs
[*]?S3C?NAND?Hardware?ECC
到了这里,开发板已经支持nand?flash驱动。 接下来 配置后保存,make?clean?,make?zImage 将zImage下载进开发板。从串口信息可以看出nand?flash驱动是否完成: S3C?NAND?Driver,?(c)?2008?Samsung?Electronics S3C?NAND?Driver?is?using?hardware?ECC. NAND?device:?Manufacturer?ID:?0xec,?Chip?ID:?0xda?(Samsung?NAND?256MiB?3,3V?8-bit) Creating?5?MTD?partitions?on?"s5pv210-nand": 0x0000000c0000-0x000000100000?:?"misc" 0x000000100000-0x000000600000?:?"recovery" 0x000000600000-0x000000b00000?:?"kernel" 0x000000b00000-0x000000e00000?:?"ramdisk" 0x000000e00000-0x000010000000?:?"system" (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |