snifer

【原创】基于字符型mtd流程分析

0
阅读(2331)

字符型mtd是嵌入式学习当中的一个难点,今天我就分析一下这个流程,以下是其源程序:

/driver/mtd/mtdchar.c

static int __init init_mtdchar(void){

...

ret = __register_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd", &mtd_fops);

...

ret = register_filesystem(&mtd_inodefs_type);

...

register_mtd_user(&mtdchar_notifier);/*注册一个notify机器*/

...

}

static void __exit cleanup_mtdchar(void){

unregister_mtd_user(&mtdchar_notifier);

mntput(mtd_inode_mnt);

unregister_filesystem(&mtd_inodefs_type);

__unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");

}

module_init(init_mtdchar);

module_exit(cleanup_mtdchar);


其中:

register_mtd_user(&mtdchar_notifier);/*注册一个notify机器*/ 表示:

static struct mtd_notifier mtdchar_notifier = {

.add = mtdchar_notify_add,

.remove = mtdchar_notify_remove,

}; 当有新的mtd设备要注册时会调用notifier的add函数,以通知notifier有新的mtd设备注册了, 然后notifier就可以为其做相应的初始化工作

&mtd_fops表示:

static const struct file_operations mtd_fops = {

.owner = THIS_MODULE,

.llseek = mtd_lseek,

.read = mtd_read,

.write = mtd_write,

.unlocked_ioctl = mtd_unlocked_ioctl,

#ifdef CONFIG_COMPAT

.compat_ioctl = mtd_compat_ioctl,

#endif

.open = mtd_open,

.release = mtd_close,

.mmap = mtd_mmap,

#ifndef CONFIG_MMU

.get_unmapped_area = mtd_get_unmapped_area,

#endif

};

其中

.open = mtd_open,

表示为:

static int mtd_open(struct inode *inode, struct file *file){

...

struct mtd_info *mtd;

struct mtd_file_info *mfi;

struct inode *mtd_ino;

...

mtd = get_mtd_device(NULL, devnum);/*得到一个mtd设备*/

...

put_mtd_device(mtd);/*归还一个mtd设备*/

...

} /* mtd_open */

以上程序中

mtd = get_mtd_device(NULL, devnum);/*得到一个mtd设备*/

表示:

driver/mtd/mtdcore.c

struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num){

struct mtd_info *ret = NULL, *other;

...

err = __get_mtd_device(ret);

if (err)

ret = ERR_PTR(err);

...

return ret;

}

int __get_mtd_device(struct mtd_info *mtd){

...

err = mtd->get_device(mtd);

...

}

put_mtd_device(mtd);/*归还一个mtd设备*/

/driver/mtd/mtdcore.c

void put_mtd_device(struct mtd_info *mtd){

mutex_lock(&mtd_table_mutex);

__put_mtd_device(mtd);

mutex_unlock(&mtd_table_mutex);

}

void __put_mtd_device(struct mtd_info *mtd){

...

if (mtd->put_device)

mtd->put_device(mtd);

...

}

mtd->put_device(mtd)的代码如下:

/include/linux/mtd.h

struct mtd_info {

...

/* If the driver is something smart, like UBI, it may need to maintain()

* its own reference counting. The below functions are only for driver.

* The driver may register its callbacks. These callbacks are not

* supposed to be called by MTD users */

int (*get_device) (struct mtd_info *mtd);

void (*put_device) (struct mtd_info *mtd);

};

他们之间的互相引用的关系就是这样,这样写好像不明显,下面我以CFI接口norflash芯片探测为例说明。


Baidu
map