加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

S5PV210 nand flash 驱动移植

发布时间:2020-12-15 18:20:37 所属栏目:百科 来源:网络整理
导读:环境:debian? 6???linux?2.6.35.7 arm-linux-gcc: 做完核心的内核移植之后,接下来要做的驱动移植,第一步移植的是nand?flash驱动。 在做驱动移植之前,我们有必要了解一下linux的platform机制: 从Linux?2.6起引入了一套新的驱动管理和注册机制:platform_

环境: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[],添加

{
??.name??=?"nand",
??.id??=?-1,
??.parent??=?&clk_hclk_psys.clk,
??.enable??=?s5pv210_clk_ip1_ctrl,
??.ctrlbit?=?((1?<<?28)?|?(1?<<?24)),
?},'Microsoft YaHei'">添加之后,nand?flash驱动才能正确获取时钟。

以上操作完成后,开始配置内核

根目录下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"

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读