驱动程序之_2_块设备_4_Nand Flash_2_驱动框架分析

驱动程序之_2_块设备_4_Nand Flash_2_驱动框架分析

 

启动内核时,有如下打印信息:

从信息可以找到内核的Nand Flash驱动,位于/drivers/mtd/nand/s3c2410.c中

初始化的调度关系如下,完成

1、控制器初始化

2、芯片初始化

3、读取芯片信息,分配mtd_info结构体,提供读写等函数接口

4、添加分区

s3c24xx_nand_probe

    err = s3c2410_nand_inithw(info, pdev);
        
    s3c2410_nand_init_chip(info, nmtd, sets);

    nmtd->scan_res = nand_scan(&nmtd->mtd, (sets) ? sets->nr_chips : 1);

    s3c2410_nand_add_partition(info, nmtd, sets);
            add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions);
                add_mtd_device(&mtd->mtd);
		        	list_for_each(this, &mtd_notifiers) {
		    	    	struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);    
		    	    	not->add(mtd);
			    }


/******************************/
//字符设备
not->add(mtd); //=>mtd_notify_add
    //回到以前字符设备分配操作

//块设备
not->add(mtd); //=》blktrans_notify_add
	list_for_each(this, &blktrans_majors) {
		struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
		tr->add_mtd(tr, mtd); //=》mtdblock_add_mtd
            add_mtd_blktrans_dev(dev);
                //回到以前块设备简单实例的gendisk操作
	}

mtd_notifiers在register_mtd_user中设置,register_mtd_user在两个地方被调用,分别属于字符设备和块设备

字符设备下:

init_mtdchar调用register_mtd_user

返回上层函数后,又调用了mtd_notifiers的add函数,在这是mtd_notify_add,创建设备

static int __init init_mtdchar(void)
{
	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;
	}

	mtd_class = class_create(THIS_MODULE, "mtd");

	if (IS_ERR(mtd_class)) {
		printk(KERN_ERR "Error creating mtd class.\n");
		unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
		return PTR_ERR(mtd_class);
	}

	register_mtd_user(&notifier);    //!!!!!!!!
	return 0;
}


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);
}

块设备下:

register_mtd_blktrans调用register_mtd_user

返回上层函数后,又调用了mtd_notifiers的add函数,在这是blktrans_notify_add,创建设备

blktrans_majors也在register_mtd_blktrans中设置

register_mtd_blktrans在init_mtdblock被调用

返回上层,调用tr的add_mtd函数,就是调用mtdblock_add_mtd

在mtdblock_add_mtd中分配、添加了块设备

int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
{
/****************************/
    register_mtd_user(&blktrans_notifier);
/****************************/
}

static void blktrans_notify_add(struct mtd_info *mtd)
{
	struct list_head *this;

	if (mtd->type == MTD_ABSENT)
		return;

	list_for_each(this, &blktrans_majors) {
		struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);

		tr->add_mtd(tr, mtd);
	}

}

static int __init init_mtdblock(void)
{
	return register_mtd_blktrans(&mtdblock_tr);
}

static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
{
	struct mtd_blktrans_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL);

	if (!dev)
		return;

	dev->mtd = mtd;
	dev->devnum = mtd->index;

	dev->size = mtd->size >> 9;
	dev->tr = tr;
	dev->readonly = 1;

	add_mtd_blktrans_dev(dev);
}

 

 

分析代码可以知道,Nand Flash驱动层次结构如下,其中

1、硬件层负责控制传送

2、协议层负责管理操作命令

3、块设备负责优化

4、应用层负责给出传送内容

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值