Linux MTD&Nand Driver

1、Linux MTD架构

2、MTD创建设备节点。

3、Register一个MTD设备到MTD子系统。

4、MTD file operation 调用底层驱动。

1、架构图


1、设备节点:/devMTD字符设备节点(主设备号为90

2MTD设备层:分为MTD字符设备层(mtdchar.c)MTD块设备层(Mtdblock.c),完成flash的基本操作。

3MTD原始设备层:MTD原始设备的通用代码(mtdcore.c),(mtdpart.c).其中mtdcore.c中定义了描述mtd设备的核心结构mtdinfo.

4FLASH硬件驱动层:

   /mtd/nand目录,实现了对flash的读写擦校验等动作。

2.MTD创建设备节点

流程:

  1mtdchar.c:

  init_mtdchar->register_chrdev(MTD_CHAR_MAJOR, "mtd",&mtd_fops);->cdev_add

  2mtdcore.c:

  init_mtd -> ret =class_register(&mtd_class);

  3)pxa3xx_nand.c:

    add_mtd_partitions->add_mtd_device->device_create(&mtd_class,次设备号)


第一步:MTD设备层。(MTD子系统完成)

   register_chrdev注册字符型mtd设备,并添加该设备到内核,主设备号为90。但是此时还未在/dev下形成mtd设备节点。

第二步:MTD原始设备层。(MTD子系统完成)

 class_register注册一个mtdmtd_class,后面再注册mtd设备时会用到该class

第三步:驱动层。(我们调用接口完成

  在添加MTD设备同时,在原始设备层注册的那个class接口上创建了设备节点。/dev/mtdevent1出现

3.Register到MTD子系统

两种注册方式:

1)直接注册整个flash设备(MTDDevice)到MTD

ret= add_mtd_device(mtd);

2)分partion添加到mtd_table,并将每个partion当成

  一个mtd设备注册到MTD

if(!(partitions&& num_part > 0)

ret= add_mtd_partitions(mtd, parts, num_part);


T920采用方式二分partion注册到MTD:(我们完成)

Flashpartion分区表在N80.C文件中可以查看:

pxa3xx_nand.cpxa3xx_nand_probe中完成:

parse_mtd_partitions()->parse_cmdline_partitions

解析mtd结构中的part成员,并返回partion个数。

add_mtd_partitions()->add_one_partition()

slave->mtd.xxx= master->xxx;

add_mtd_device(&slave->mtd);

master中获得typereadwrite等参数。

并将slave作为一个mtd设备添加到mtd_table.

最后注册设备及创建dev下面的设备节点。

4.MTDFile ops调用底层驱动

文件系统->调用MTD设备层

Mtdchar.c(字符设备,如NANDFLASH)

init_mtdchar(void)中调用了

register_chrdev(MTD_CHAR_MAJOR,"mtd", &mtd_fops);

最终通过cdev->ops =fops;将文件操作赋给了cdev

其中mtd_fops中实现了mtd设备的读写及ioctl.

5.T920之NANDFLASH驱动层架构

驱动实现层:pxa3xx_nand.cn80.c

1)通过platform注册pxa3xx_nand设备及驱动。

2)probe中申请资源及实现chipops操作函数。

3)添加mtd设备到MTD

1)N80.C中注册Device

pxa910_add_nand&pxa910_device_nand,info, xxx

其中pxa910_device_nand定义了flash所需要的资源,如IO

资源占用,中断资源占用。(pxa910.c中定义这些资源)

其中infon80_nand_info

定义了flash分区信息及是否需要DMA

(在n80.c中定义这些信息)

pxa3xx_nand.c中注册flash驱动。

platform_driver_register(&pxa3xx_nand_driver);

pxa3xx_nand_probe(重要,驱动实现的第一步)

 alloc_nand_resource(pdev)分配各种资源,包括pxa910_device_nand定义的资源,然后分配chip函数。

add_mtd_partitions,添加mtd设备到MTD子系统中,与硬件抽象层联系起来了。

6.驱动层之Flash读写操作

  问题:nand_chip(nandflash的描述符)的读写操作是怎么和MTD的读写操作联系起来的呢?

  1probe->调用nand_scan()->scan_tail;

     使用mtd->read= nand_read;这里和mtd挂钩。

  2)在nand_read实现中又调用了nand_do_read_ops(mtd,from, &chip->ops);这里和nand_chip联系起来了。

  PXA920NANDFLASH Controller介绍:

  NDCR寄存器:nandflash control register

  NDTR寄存器: nandflash timing register

  NDSR寄存器: nandflash state register

  NDCB寄存器: nandflash controller buffer

  NDDB寄存器: nandflash data buffer

  我们就是对这些寄存器操作来完成通过BBFLASH控制器操作flash的读写。

  T920NANDFLASH读写控制:NANDFLASH Controller

 

   MTD file ops/MTD

   ->nand_do_read_ops

   ->chip->cmdfunc(mtd,NAND_CMD_READ0, 0x00, page);

   /驱动层

   ->chip->ecc.read_page() 

   ->pxa3xx_read_page

   ->pxa3xx_nand_cmdfunc对寄存器操作

   ->中断到,代表对flash控制器的操作完成。

   ->start_data_dma进行数据读写。

1pxa3xx_nand_cmdfunc发送命令、发送数据、读写数据。

作用:

NANDFLASH 控制器的相关寄存器操作

填充命令,如读,编程,擦除,还有数据。

1)重置timing

2)写控制命令池。

3)清命令缓冲区。

4)设置地址及数据及传输方式。

5)初始化一个完成量。

6)中断到,运行ND_RUN写寄存器。

1pxa3xx_nand_transaction传输数据

 判断是否支持DMA?

 

YES:start_data_dmabuffer地址映射到dma缓冲区。

v prepare_command_pool 中已经将 dma buffer 映射到了数据 buffer 。即 nand->data_buff= nand->dma_buff;
v

NO:handle_data_pio直接使用__raw_writesl读写映射到用户空间的io寄存器nand->mmio_base

2、读一个byteword

无论是DMA或者IO方式:数据都采用page方式放到了

nand->data_buff中,所以当需要读取一个byte时,只需在

buffer中取一个字节即可。

读一个字:

retval=

*((u16*)(nand->data_buff+nand->buf_start));



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值