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

nandflash学习经历

发布时间:2020-12-15 07:07:46 所属栏目:百科 来源:网络整理
导读:经过一段时间的奋斗,? 终于对nandflash的框架有点了解! 首先nandflash的框架: ? ????????????????? APP: open? read? write ? ?---------------------------------------------------------------------- ? ?vfs:? sys_open? sys_read??? sys_write ? ?-

经过一段时间的奋斗,? 终于对nandflash的框架有点了解!

首先nandflash的框架:
?
????????????????? APP: open? read? write
?
?----------------------------------------------------------------------
?
?vfs:? sys_open? sys_read??? sys_write
?
?------------------------------------------------------------------
?
?字符设备?????????????????????? |FS:? VFAT? EXT2?? YAFFS2
?
?????????????????????????????????? | --------------------------------------
?
?????????????????????????????????? | 块设备(优化)
?
?-----------------------------------------------------------------------------
?
????????????? nandflash协议层(知道 读写、扫描nandflsh...)
?
?--------------------------------------------------------------------------------
?
?????????????????? nandflash硬件层? (实现nandchip 结构
?
??????????????????????????????????????? |
?
??????????????????????????????????????? |__(1)? 分配nandchip结构
?
???????????????????????????????????????????? (2)设置nandchip?
?
???????????????????????????????????????????? (3) 硬件相关设置
?
???????????????????????????????????????????? (4)使用nandchip结构?? nand_scan?? add_parition....

?

首先从/drivers/mtd/nand/AT91_nand.c开始分析

?

at91_nand_probe
?//获得nandflash 的类型
?//drivers/mtd/nand/Nand_base.c
?nand_scan
??//获得真正nandflash?? 的类型
??nand_scan_ident
???nand_get_flash_type
???
???
??//初始化nandflash使用的函数
??nand_scan_tail
???mtd->read = nand_read;
???mtd->write = nand_write;
??
?
?//添加分区信息
?//drivers/mtd/nand/Mtdpart.c
?add_mtd_partitions
??//drivers/mtd/Mtdcore.c
??add_mtd_device
???list_for_each(this,&mtd_notifiers) {//mtd_notifiers在哪初始化此链表?
??????????? // 在register_mtd_user?? 中添加链表,那此函数哪个中被调用呢?
??????????? //被driversmtdMtdchar.c? 和? driversmtdMtd_blkdevs.c 调用
???struct mtd_notifier *not = list_entry(this,struct mtd_notifier,list);
???not->add(mtd);
???}
???
???//driversmtdMtdchar.c
???//初始化时调用register_mtd_user 函数对 mtd_notifiers进行注册
???init_mtdchar
????register_mtd_user(&notifier);
?????//注册链表的时候,? 上面的not->add(mtd); 实际上就是调用下面结构mtd_notify_add的函数
?????//static struct mtd_notifier notifier = {
?????//.add?= mtd_notify_add,
?????//.remove?= mtd_notify_remove,
?????//};

???mtd_notify_add ????//创建两个设备节点? mtd*?? mtd*ro ????class_device_create ????class_device_create ???? ??? ??? ???//driversmtdMtd_blkdevs.c ???//调用?register_mtd_blktrans对mtd_notifiers进行注册 ???register_mtd_blktrans? ????register_mtd_user(&blktrans_notifier); ????//注册链表的时候,上面的not->add(mtd);实际就是调用blktrans_notify_add此函数 ????//?static struct mtd_notifier blktrans_notifier = { ????//?.add = blktrans_notify_add,????//?.remove = blktrans_notify_remove,????//?}; ???//添加函数中又出现个链表blktrans_majors?????? ???blktrans_notify_add?? ????//list_for_each(this,&blktrans_majors) {//这个链表blktrans_majors又是被谁初始化和添加呢? ?????????//(1)初始化还是被register_mtd_blktrans ?????????//??list_add(&tr->list,&blktrans_majors); ????????? ????//?struct mtd_blktrans_ops *tr = list_entry(this,struct mtd_blktrans_ops,list);? ????//?tr->add_mtd(tr,mtd); ????//} ???? ???register_mtd_blktrans?? 被谁调用呢? ???//driversmtdMtdblock.c?? 和? driversmtdMtdblock_ro.c ???//这两个文件初始化的时候,调用register_mtd_blktrans此函数对链表进行初始化 ???init_mtdblock(void) ???? register_mtd_blktrans(&mtdblock_tr); ???? //但是上面链表的.add调用谁呢? ???? //答:会调用mtdblock_tr 结构中mtdblock_add_mtd??? driversmtdMtdblock.c ???? static struct mtd_blktrans_ops mtdblock_tr = { ?????.name??= "mtdblock",?????.major??= 31,?????.part_bits?= 0,?????.blksize ?= 512,?????.open??= mtdblock_open,?????.flush??= mtdblock_flush,?????.release?= mtdblock_release,?????.readsect?= mtdblock_readsect,?????.writesect?= mtdblock_writesect,?????.add_mtd?= mtdblock_add_mtd,?????.remove_dev?= mtdblock_remove_dev,?????.owner??= THIS_MODULE,????}; ???? ????//上面的.add_mtd会调用此函数 ????mtdblock_add_mtd ?????//那这个函数中会做写什么呢? ?????//drivers/mtd/Mtd_blkdev.c ?????add_mtd_blktrans_dev ?????//分配一个struct gendisk? 结构,又回到用内存模仿nandflsh那一套 ?????alloc_disk ?????//设置容量 ?????set_capacity ?????//初始化一个默认的队列 ?????gd->queue = tr->blkcore_priv->rq;//blk_init_queue(mtd_blktrans_request,&tr->blkcore_priv->queue_lock); ?????add_disk(gd); ????? ???? ?????//那队列mtd_blktrans_request? 唤醒函数做些什么呢? ???????//唤醒队列,那运行等待队列在哪实现的呢? ???????wake_up_process(tr->blkcore_priv->thread); ??????? ???????register_mtd_blktrans ????????//在register_mtd_blktrans注册函数中,有个线程mtd_blktrans_thread ????????tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread,????????tr,"%sd",tr->name); ???????? ????????mtd_blktrans_thread ?????????//电梯调度算法 ?????????req = elv_next_request(rq); ?????????//唤醒后执行do_blktrans_request,没有一直在这休眠 ?????????do_blktrans_request ??????????//最终还是调用读、写块函数???? ????????? ???????????struct mtd_blktrans_ops *tr ???????????tr->readsect(dev,block,buf) ???????????//实际上就是调用 ???????????.readsect?= mtdblock_readsect,??????????? ???????????//而mtdblock_readsect? 实际上内部就是调用 ???????????//mtd->read(mtd,pos,size,&retlen,buf); ????

(编辑:李大同)

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

    推荐文章
      热点阅读