NAND驱动分析--(三)
来源:互联网 发布:t95e6最新版本数据 编辑:程序博客网 时间:2024/06/06 10:06
系统调用add_mtd_partitions(&priv->mtd, p1020_partition_info, 3)函数创建新分区的调用关系如下所示:
->add_mtd_partitions(&priv->mtd, p1020_partition_info, 3)->add_mtd_device(&slave->mtd)->mtd_table[i] = mtd;
由此可知,每个分区的mtd_info结构都添加到了mtd_table[i]数组当中。
现在分析\drivers\mtd\mtdchar.c代码,如下所示:
mtdchar.c是字符设备驱动程序的实现,它只需调用nand硬件驱动层的接口,即可实现对nand flash的操作。
1、file_operations
static struct file_operations mtd_fops = { //字符驱动程序的用户层接口实现 .owner = THIS_MODULE, .llseek = mtd_lseek, //定位操作 .read = mtd_read, //读数据操作 .write = mtd_write, //写数据操作 .ioctl = mtd_ioctl, //特殊控制操作 .open = mtd_open, //打开设备 .release = mtd_close, //关闭设备};
2、mtd_open
static int mtd_open(struct inode *inode, struct file *file){ //打开字符设备 int minor = iminor(inode); //得到打开字符设备的从设备号 int devnum = minor >> 1; //因为1个nand分区对应2个字符从设备,所以需要除以2来得到分区号 struct mtd_info *mtd; DEBUG(MTD_DEBUG_LEVEL0, "MTD_open\n"); if (devnum >= MAX_MTD_DEVICES) return -ENODEV; /* You can't open the RO devices RW */ if ((file->f_mode & 2) && (minor & 1)) //当从设备号为奇数时,只能进行只读访问 return -EACCES; /* 此函数将从mtd_table[i]数组中取得i=devnum时的mtd_info结构体 */ mtd = get_mtd_device(NULL, devnum); //根据分区号来得到对应分区的mtd_info结构体 if (!mtd) return -ENODEV; if (MTD_ABSENT == mtd->type) { put_mtd_device(mtd); return -ENODEV; } file->private_data = mtd; //将取得的mtd_info结构体赋给file的私有数据成员 /* You can't open it RW if it's not a writeable device */ if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) { put_mtd_device(mtd); return -EACCES; } return 0;} /* mtd_open */
3、mtd_read
static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos){ //此函数用于实现字符设备读操作的用户层接口 struct mtd_info *mtd = file->private_data; //首先取得对应分区的file私有数据中的mtd_info结构 size_t retlen=0; size_t total_retlen=0; int ret=0; int len; char *kbuf; //定义一个字符指针,读出的数据首先存放于此 DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); if (*ppos + count > mtd->size) //判断要读取的数据总数是否超出了分区的存储空间 count = mtd->size - *ppos; //超出,修改要读取数据的总数 if (!count) return 0; /* FIXME: Use kiovec in 2.5 to lock down the user's buffers and pass them directly to the MTD functions */ while (count) { /* 判断所要读取的数据大小是否超出了所规定最大空间分配的大小(128K) */ if (count > MAX_KMALLOC_SIZE) len = MAX_KMALLOC_SIZE; //是,则分配最大空间 else len = count; //否,则按count来分配 kbuf=kmalloc(len,GFP_KERNEL); //分配内核空间,来存储读出的数据内容 if (!kbuf) return -ENOMEM; /* 进行读数据操作,这是一个宏,其等价于mdt->read */ ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf); //len是准备读取数据的长度 /* Nand returns -EBADMSG on ecc errors, but it returns * the data. For our userspace tools it is important * to dump areas with ecc errors ! * Userspace software which accesses NAND this way * must be aware of the fact that it deals with NAND */ if (!ret || (ret == -EBADMSG)) { *ppos += retlen; if (copy_to_user(buf, kbuf, retlen)) { //将内核空间的数据传递给用户空间,而此数据就是读出的nand数据 kfree(kbuf); //数据全部传出后,释放此内核空间 return -EFAULT; } else total_retlen += retlen; count -= retlen; //当所要读取的数据总数超出最大分配内存空间时,while循环将继续 buf += retlen; } else { kfree(kbuf); return ret; } kfree(kbuf); } return total_retlen;} /* mtd_read */
其它的字符驱动程序用户层接口的实现就不再详细描述了,方法基本和上面mtd_read接口实现方法一致。
最后对字符设备进行注册后,就可以在用户空间通过应用程序来调用此nand flash的字符驱动了。代码如下:
static int __init init_mtdchar(void){ /* 注册字符驱动程序,其主设备号为90 */ if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) { printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", MTD_CHAR_MAJOR); return -EAGAIN; } mtdchar_devfs_init(); return 0;}
至此nand flash驱动程序基本分析完毕,关于mtdblock.c的块设备驱动程序将不再进行分析。
阅读全文
0 0
- NAND驱动分析--(三)
- NAND驱动分析--(一)
- NAND驱动分析--(二)
- Linux NAND FLASH驱动分析(一)
- nand FLASH 驱动分析
- nand 驱动分析
- NAND FLASH 驱动分析
- nand flash驱动分析
- 基于linux2.6.16的nand驱动开发(三)
- 基于linux2.6.16的nand驱动开发(三)
- NAND FLASH学习笔记之MTD下nand flash驱动(三)
- NAND FLASH学习笔记之MTD下nand flash驱动(三)
- 内核读写nand flash驱动分析(含注释)
- linux nand flash 驱动(一) --- 原理分析
- NAND控制器驱动程序分析(三)
- 基于MTD的NAND驱动开发(三)
- 基于MTD的NAND驱动开发(三)
- 基于MTD的NAND驱动开发(三)
- android和js交互你真的了解吗
- Select下拉框onchange事件获取option的value值
- C#操作符??和?:
- 手机中的AR是怎么实现的
- IMS基本概念之 控制承载通道媒体流的机制(SBLP)
- NAND驱动分析--(三)
- 运维之高级服务篇------ 3.部署LNMP 、 Nginx+FastCGI 、 Nginx高级技术
- CCF编程练习:火车购票(Java)
- 对于行内元素、块级元素的认识
- 腾讯云对象存储 cos-js-sdk-v4 踩坑记
- RabbitMQ 快速安装
- Angularjs购物车订单强化
- 目标跟踪KCF算法一些介绍
- 8.Spring Cloud:服务容错保护(Hystrix断路器)【Dalston版】