前言

前面我们已经写过一个块设备驱动程序,用内存来模拟块设备。假如我们想写一个NAND FLASH驱动程序,又应该怎么做呢?我们先看一下kernel代码中别人现成的驱动程序,分析一下流程框架,总结出一个套路,我们就能开始写自己的驱动程序了。

之前写过一个裸板的nand flash程序:NAND FLASH的读操作及原理,可以参考一下。

正文

我参考的是这个驱动程序:drivers\mtd\nand\at91_nand.c。在调用platform_driver_register()平台注册函数后,如果找到device的name同样为"at91_nand",就会调用driver的probe函数(为什么会自动调用probe函数?可以参考我之前写的文章:设备、驱动、总线模型简介)。

static struct platform_driver at91_nand_driver = {.probe        = at91_nand_probe,.remove      = at91_nand_remove,.driver     = {.name   = "at91_nand",.owner = THIS_MODULE,},
};static int __init at91_nand_init(void)
{return platform_driver_register(&at91_nand_driver);
}

这里也顺便看一下相关设备资源的注册,其实就是NAND flash的需要设置的寄存器的首地址和结束地址

static struct resource nand_resources[] = {{.start  = NAND_BASE,.end   = NAND_BASE + SZ_8M - 1,.flags    = IORESOURCE_MEM,}
};static struct platform_device at91rm9200_nand_device = {.name        = "at91_nand",.id        = -1,.dev      = {.platform_data  = &nand_data,},.resource   = nand_resources,.num_resources    = ARRAY_SIZE(nand_resources),
};void __init at91_add_device_nand(struct at91_nand_data *data)
{...platform_device_register(&at91rm9200_nand_device);
}

假如已经调用到了probe函数,我们看一下注册函数里面大概做了什么

static int __init at91_nand_probe(struct platform_device *pdev)
{struct at91_nand_host *host;struct mtd_info *mtd;struct nand_chip *nand_chip; //分配nand_chip结构体mtd->priv = nand_chip;mtd = &host->mtd;nand_chip = &host->nand_chip;... //设置nand_chip结构体if (host->board->bus_width_16)     /* 16-bit bus width */nand_chip->options |= NAND_BUSWIDTH_16;nand_scan(mtd, 1)add_mtd_partitions(mtd, partitions, num_partitions);
}

由上面的代码可以看出

(1)首先是分配了三个结构体:其中我们重点关注一下mtd_info和nand_chip结构体

(2)然后就是设置nand_chip结构体中的参数等等

(3)最后就是调用了nand_scan()和add_mtd_parttions()函数

下面我们先看一下nand_scan()中具体做了什么。

int nand_scan(struct mtd_info *mtd, int maxchips)
{int ret;...ret = nand_scan_ident(mtd, maxchips);if (!ret)ret = nand_scan_tail(mtd);return ret;
}

继续看一下nand_scan_ident()和nand_scan_tail()里面做了什么

int nand_scan_ident(struct mtd_info *mtd, int maxchips)
{struct nand_chip *chip = mtd->priv;/* Get buswidth to select the correct functions */busw = chip->options & NAND_BUSWIDTH_16; //总线的宽度/* Set the default functions */nand_set_defaults(chip, busw); //设置一些默认的函数,比如选中芯片的函数、发命令函数、读取寄存器值的函数等等/* Read the flash type */type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id);
}
int nand_scan_tail(struct mtd_info *mtd)
{//内容比较多,但是总体就是设置mtd结构体中的读、写、擦除nand flash的操作函数等等mtd->erase = nand_erase;mtd->read = nand_read;mtd->write = nand_write;
}

真正跟到代码里面的话,内容非常多,总结起来就是调用nand_scan()函数,完成一些读、写或者擦除nand flash等等的一些操作函数。设置完后,应该就是注册我们的设置的结构体了,下面继续看一下probe函数最后的add_mtd_partitions()里面的各种调用关系。

add_mtd_partitions(struct mtd_info *master, const struct mtd_partition *parts, int nbparts)//设置slave->mtd,比如读、写、擦除函数等等/* register our partition */add_mtd_device(&slave->mtd); //注册设置过的slave->mtdlist_for_each(this, &mtd_notifiers) {// mtd_notifiers在哪设置?drivers/mtd/mtdchar.c,mtd_blkdev.c调用register_mtd_userstruct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);not->add(mtd);}/* 其中,not->add函数可以分为两部分:* mtd_notify_add -- 字符设备部分* blktrans_notify_add -- 块设备部分*/

先看一下字符设备部分:

static void mtd_notify_add(struct mtd_info* mtd)
{if (!mtd)return;class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),NULL, "mtd%d", mtd->index);class_device_create(mtd_class, NULL,MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),NULL, "mtd%dro", mtd->index);
}

是我们之前写字符设备常见的class_device_create函数,在/sys/class目录创建了相应的设备类目录/sys/class/mtd/

再看一下块设备部分:

static void blktrans_notify_add(struct mtd_info *mtd)list_for_each(this, &blktrans_majors) {struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);tr->add_mtd(tr, mtd); //调用到了drivers\mtd\mtdblock.c的mtdblock_add_mtd函数}

最后再进到mtdblock_add_mtd()函数里面的各种调用关系

mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)add_mtd_blktrans_dev(dev);//下面就是我们熟悉的,块设备书写的流程了struct gendisk *gd;gd = alloc_disk(1 << tr->part_bits);add_disk(gd);

可以看出来,还是我们熟悉的块设备驱动程序的书写套路。

结语

虽然前面写了很多的内容,而且kernel中代码的流程也非常的复杂,但其实很大一部分是前人为我们抽象出来的一套框架,我们需要做的主要是底层硬件的操作。

在分析流程的时候,我们不难看出,我们要书写一个新的驱动程序,主要就参考probe函数中的部分就好了。下面给出一个别人总结的驱动框架流程图:

NAND flash驱动程序(1)相关推荐

  1. Linux NAND FLASH驱动程序分析(mini2440)

    Linux NAND FLASH驱动程序分析(mini2440) 一.Linux-MTD Subsystem介绍 FLASH在嵌入式系统中是必不可少的,它是bootloader.linux内核和文件系 ...

  2. MTD 设备驱动 和 NAND Flash 驱动程序分析。

    硬件环境: 飞凌OK6410,256MB DDR,2GB NAND Flash.   NAND Flash 型号:K9G8G08U9A   .     分析源码:Linux 2.6.36.2 内核源码 ...

  3. 块设备驱动之NAND FLASH驱动程序

    转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/25240909 一.框架总结 二.硬件原理 相比于nor flash.我们能够清 ...

  4. Linux操作系统下 NAND FLASH驱动程序框架

    当我们需要在操作系统上读写普通文件的时候,总是需要一层层往下,最终到达硬件相关操作,当然底层设备大多数都是块设备 NAND FLASH就作为一个最底层的块设备. 而我们写驱动,就是要构建硬件与操作系统 ...

  5. Nand flash驱动的编写与移植

    1 Nand flash工作原理     S3C2410板的Nand Flash支持由两部分组成:Nand Flash控制器(集成在S3C2410 CPU)和Nand Flash存储 芯片(K9F12 ...

  6. 15.NAND FLASH驱动

    NAND FLASH 原理以及操作详见:https://blog.csdn.net/qq_16933601/article/details/100001443 一.基本的问题 NAND FLASH是一 ...

  7. 《Linux驱动:nand flash驱动看这一篇就够了》

    文章目录 一,前言 二,硬件电路 2.1 Nand flash相关 2.2 S3c2440相关 2.3 Nand flash 位反转 三,Nand flash驱动框架 四,S3c2440 Nand F ...

  8. ARM9 2410移植之Nand flash 驱动的编写与移植

    1 Nand flash 工作原理 S3C2410 板的Nand Flash 支持由两部分组成:Nand Flash 控制器(集成在S3C2410 CPU)和Nand Flash 存储 芯片(K9F1 ...

  9. [转]ARM9 2410移植之Nand flash 驱动的编写与移植

    1 Nand flash 工作原理 S3C2410 板的Nand Flash 支持由两部分组成:Nand Flash 控制器(集成在S3C2410 CPU)和Nand Flash 存储 芯片(K9F1 ...

最新文章

  1. Arrays.asList问题
  2. MySQL跑在CentOS 6 和 7上的性能比较
  3. modelMapper.map的一个使用例子
  4. 齐头并进(51Nod-1649)
  5. 详说 Subversion备份
  6. PowerDesigner(六)-物理数据模型(PDM逆向工程)
  7. php sql update 字段a=字段b的信息_企业级PHP求职最全精品面试100问(附答案)
  8. python multiprocessing 批量下载图片+tqdm
  9. 威逼司机二选一,是滴滴垄断,还是嘀嗒碰瓷?
  10. Redis Sentinel 机制与用法(二)
  11. 人工智能ai应用高管指南_解决AI中的种族偏见:好奇心指南
  12. FbinstTool最简单制作U盘启动ISO格式(金测)
  13. ng-alain php,Angular 中后台前端解决方案 - Ng Alain 介绍
  14. svn怎么执行清理命令_C盘又见红了?一个C盘清理强迫症教你真正有效的解决方法!...
  15. try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行
  16. [刷题]2017百度之星资格赛 - 度度熊与邪恶大魔王
  17. 多线程(二)互斥锁详解
  18. win7打开计算机 多窗口,win7电脑无法在一个窗口中打开多个文件夹怎么办?
  19. Siammask源码demo运行配置
  20. 挖掘肖特基二极管的作用及其接法

热门文章

  1. Linux多命令执行
  2. 50行Python代码实现视频中物体颜色识别和跟踪(必须以红色为例)
  3. 学习分析技术文章笔记
  4. 确定性随机数发生器测试向量——DRBG-HMAC-SHA512
  5. 在小地图中NPC和Player以图标显示
  6. 西电计算机原理与系统组装实验报告,西电计组实验报告.docx
  7. 全球与中国中性服装市场现状及未来发展趋势(2022)
  8. 【太原seo】seo入门看什么书好_seo入门书籍推荐
  9. 在华为云专属月,找到开启互联网第二增长曲线的一把钥匙
  10. 失业的程序员(九):创业就是一场戏