块设备驱动通过register_mtd_blktras 将mtd_table 中的分区注册为 ...
块设备驱动通过register_mtd_blktras 将mtd_table 中的分区注册为 ...
块设备驱动通过register_mtd_blktras 将mtd_table 中的分区注册为 ...
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
块设备驱动通过 register_<strong>mtd</strong>_<strong>blktras</strong> 将 <strong>mtd</strong>_<strong>table</strong> <strong>中的分区注册为</strong> gendisk 设备,以及<br />
<strong>mtd</strong>_blktrans_dev 设备。其中 <strong>mtd</strong>_blktrans_dev 公 NFTL 层使用,调用流程如下。<br />
register_<strong>mtd</strong>_blktrans(<strong>mtd</strong>_blktrans_ops *tr)<br />
register_<strong>mtd</strong>_user (<strong>mtd</strong>_notifier *new)<br />
blktrans_notify_add(<strong>mtd</strong>_info *<strong>mtd</strong>)<br />
<strong>mtd</strong>block_add_<strong>mtd</strong>(<strong>mtd</strong>_blktrans_ops *tr, <strong>mtd</strong>_info *<strong>mtd</strong>)<br />
add_<strong>mtd</strong>_blktrans_dev(struct <strong>mtd</strong>_blktrans_dev *new)<br />
add_disk(struct gendisk *disk)<br />
register_blkdev(tr->major, tr->name)<br />
register_<strong>mtd</strong>_user (&blktrans_notifier)<br />
<strong>mtd</strong>_notifiers<br />
blktrans_notifier<br />
blktrans_notify_add<br />
blktrans_notify_remove<br />
for (i=0; i< MAX_MTD_DEVICES; i++)<br />
if (<strong>mtd</strong>_<strong>table</strong>[i])<br />
blktrans_notify_add(<strong>mtd</strong>_<strong>table</strong>[i]);<br />
blktrans_notify_add( <strong>mtd</strong>_<strong>table</strong>[i])<br />
<strong>mtd</strong>block_add_<strong>mtd</strong>(&<strong>mtd</strong>block_tr, <strong>mtd</strong>_<strong>table</strong>[i])<br />
blktrans_notifer<br />
对<strong>mtd</strong>_<strong>table</strong>中存在的每一<br />
个<strong>mtd</strong>_info设备注册为<br />
<strong>mtd</strong>_blktrans_dev<br />
list_for_each_entry(tr, &blktrans_majors, list)<br />
<strong>mtd</strong>block_tr-><strong>mtd</strong>block_add_<strong>mtd</strong>(&<strong>mtd</strong>block_tr, <strong>mtd</strong>_<strong>table</strong>[i]);<br />
struct <strong>mtd</strong>_blktrans_dev *dev = malloc…<br />
dev-><strong>mtd</strong> = <strong>mtd</strong>;<br />
dev->devnum = <strong>mtd</strong>->index;<br />
dev->size = <strong>mtd</strong>->size >> 9;<br />
dev->tr = &<strong>mtd</strong>block_tr;<br />
add_<strong>mtd</strong>_blktrans_dev(dev);<br />
add_<strong>mtd</strong>_blktrans_dev(dev)<br />
<strong>mtd</strong>_blktrans_ops<br />
list_head devs<br />
list_head list<br />
<strong>mtd</strong>_blktrans_dev<br />
<strong>mtd</strong>_blktrans_ops *tr<br />
list_head list<br />
struct gendisk *gd = alloc_disk(1 part_bits);<br />
gd->major = tr->major;<br />
gd->first_minor = (dev->devnum) part_bits;<br />
gd->fops = &<strong>mtd</strong>_blktrans_ops;<br />
gd->private_data = dev;<br />
dev->blkcore_priv = gd;<br />
gd->queue = tr->blkcore_priv->rq;<br />
gd->driverfs_dev = dev-><strong>mtd</strong>->dev;<br />
add_disk(gd);
egister_<strong>mtd</strong>_<strong>blktras</strong> 调用完成后,MTD 数据结构关系图如下所示:<br />
gendisk<br />
major<br />
first_minor<br />
block_device_operat<br />
ions *fops<br />
request_queue<br />
*queue<br />
*private_data<br />
device<br />
*driverfs_dev<br />
<strong>mtd</strong>_blkcore_priv<br />
task_struct *thread<br />
request_queue *rq<br />
<strong>mtd</strong>_blktrans_dev<br />
<strong>mtd</strong>_blktrans_ops *tr<br />
list_head list<br />
<strong>mtd</strong>_info *<strong>mtd</strong><br />
int devnum<br />
void *blkcore_priv<br />
<strong>mtd</strong>_blktrans_ops<br />
major<br />
int part_bits<br />
int blksize<br />
list_head devs<br />
list_head list<br />
<strong>mtd</strong>_blkcore_priv<br />
*blkcore_priv<br />
<strong>mtd</strong>_info<br />
device dev
egister_<strong>mtd</strong>_<strong>blktras</strong>(&<strong>mtd</strong>block_tr)调用实例:<br />
register_<strong>mtd</strong>_blktrans实例完成后<br />
<strong>mtd</strong>_info,<br />
<strong>mtd</strong>_blktrans_dev,<br />
<strong>mtd</strong>_<strong>blktras</strong>_ops,<br />
gendisk<br />
四者之间的关系图。<br />
最终注册为通用的磁盘设备<br />
blktrans_majors<br />
<strong>mtd</strong>_blkcore_priv<br />
task_struct *thread<br />
request_queue *rq<br />
gendisk<br />
major<br />
first_minor<br />
block_device_operat<br />
ions *fops<br />
request_queue<br />
*queue<br />
*private_data<br />
device<br />
*driverfs_dev<br />
<strong>mtd</strong>_blktrans_ops<br />
<strong>mtd</strong>block_tr<br />
"<strong>mtd</strong>block"<br />
31<br />
0<br />
512<br />
<strong>mtd</strong>block_open<br />
<strong>mtd</strong>block_flush<br />
<strong>mtd</strong>block_release<br />
<strong>mtd</strong>block_readsect<br />
<strong>mtd</strong>block_writesect<br />
<strong>mtd</strong>block_add_<strong>mtd</strong><br />
<strong>mtd</strong>block_remove_dev<br />
<strong>mtd</strong>_blkcore_priv<br />
list_head devs<br />
*blkcore_priv<br />
list_head list<br />
list_head devs<br />
<strong>mtd</strong>_blkcore_priv<br />
*blkcore_priv<br />
rq->request_fn= <strong>mtd</strong>_blktrans_request<br />
tr->blkcore_priv->rq->queuedata = tr<br />
tr->blkcore_priv->thread =<br />
kthread_run(<strong>mtd</strong>_blktrans_thread, tr,"%sd", tr->name);<br />
<strong>mtd</strong>_blktrans_request(struct request_queue *rq)<br />
struct <strong>mtd</strong>_blktrans_ops *tr = rq->queuedata;<br />
wake_up_process(tr->blkcore_priv->thread);<br />
<strong>mtd</strong>_blktrans_thread(void *arg)<br />
do_blktrans_request(tr, dev, req)<br />
<strong>mtd</strong>_blktrans_dev<br />
struct <strong>mtd</strong>_info *<strong>mtd</strong><br />
<strong>mtd</strong>_blktrans_ops *tr<br />
list_head list<br />
int devnum<br />
void *blkcore_priv<br />
<strong>mtd</strong>_notifiers<br />
blktrans_notifier<br />
blktrans_notify_add<br />
blktrans_notify_remove<br />
switch(rq_data_dir(req)) {<br />
case READ:<br />
tr->readsect(dev, block, buf)<br />
case WRITE:<br />
tr->writesect(dev, block, buf)<br />
}<br />
<strong>mtd</strong>_<strong>table</strong><br />
*<strong>mtd</strong>_info<br />
*<strong>mtd</strong>_info<br />
*<strong>mtd</strong>_info<br />
……<br />
<strong>mtd</strong>_blktrans_dev<br />
struct <strong>mtd</strong>_info *<strong>mtd</strong><br />
<strong>mtd</strong>_blktrans_ops *tr<br />
list_head list<br />
int devnum<br />
void *blkcore_priv