jffs2文件系统——MTD驱动挂载

来源:互联网 发布:淘宝购物车加不进去 编辑:程序博客网 时间:2024/06/05 01:11

总所周知,jffs2是主要用到的是mtd驱动,用mtd驱动作为jffs2文件系统的工具。所以在mount jffs2之前,必须要挂载MTD驱动。MTD驱动最关键的其实是往mtd_table[]这张表里添加东西。

platform_driver_register(&a)    a.probe        add_mtd_partitions            add_mtd_device                 mtd_table[i]= mtd
mtd挂载其实就是一个platform_driver_register,但是这个注册的元素,在platform初始化的时候就添加了,所以probe有作用。

probe是被这样调用的bus_add_driverdriver_attachbus_for_each_drv__driver_attachdriver_probe_devicereally_probe

static int really_probe(void *void_data){struct stupid_thread_structure *data = void_data;struct device_driver *drv = data->drv;//本次platform的driverstruct device *dev = data->dev;//原先就已经注册的platformdev->driver = drv;if (dev->bus->probe) {ret = dev->bus->probe(dev);} else if (drv->probe) {ret = drv->probe(dev);//这里}driver_bound(dev);}
从上面这个代码可以得出,probe探测到了元素,参数将是原来的dev,也就是platform初始化的时候添加的元素。

static int __init probe(struct platform_device *plat_dev) //这里的入口参数不是opconn_spi_drive而是plat_dev   flash_device(在platform.c中){/* Platform data helps sort out which chip type we have, as * well as how this board partitions it.  If we don't have * a chip ID, try the JEDEC id commands; they'll work for most * newer chips, even if we don't recognize the particular chip. *///下面的方法是,各种方法去获得flash信息,flash一般是放在一个大表里,通过读jedec去查找//info的扇区数,扇区大小,型号……//接下来是给mtd赋值操作flash->mtd.type = MTD_NORFLASH;//nor flashflash->mtd.writesize = 1;/* writeable */flash->mtd.flags = MTD_CAP_NORFLASH | MTD_WRITEABLE;//电容 nor flash ,可写flash->mtd.size = info->sector_size * info->n_sectors;//flash大小,整片flash的大小flash->mtd.erase = spi_erase;//擦函数flash->mtd.read = spi_read;//读函数flash->mtd.write = spi_write;//写函数/* partitions should match sector boundaries; and it may be good to * use readonly partitions for writeprotected sectors (BP2..BP0). */ //mtd是分区的if (mtd_has_partitions()) {//亲,分区的不?struct mtd_partition    *parts = NULL;int         nr_parts = 0;if (nr_parts <= 0 && data && data->parts) {parts = data->parts;//指向分区数组地址nr_parts = data->nr_parts;//分区数量}if (nr_parts > 0) {//开始分区flash->partitioned = 1;return add_mtd_partitions(&flash->mtd, parts, nr_parts);//在mtdtable那种表中加入,这个分区//入口参数:mtd主要信息,分区信息,分区数量}} }
上面的代码里,分两部分,第一部分是给flash->mtd各种赋值,这个flash->mtd可以理解成master,后面的分区很多信息都得向它继承;第二部分是add_mtd_partitions,这个是将分区一片片放入mtd_table中。

/* * This function, given a master MTD object and a partition table, creates * and registers slave MTD objects which are bound to the master according to * the partition definitions. * (Q: should we register the master MTD object as well?) */int add_mtd_partitions(struct mtd_info *master,       const struct mtd_partition *parts,       int nbparts){for (i = 0; i < nbparts; i++) {list_add(&slave->list, &mtd_partitions);//将这个分区添加到mtd_parttiions的链表中/* set up the MTD object for this partition *///在各个分区的信息设置,slave->master很重要,有些part操作都是定位到master的slave->mtd.type = master->type;slave->mtd.flags = master->flags & ~parts[i].mask_flags;slave->mtd.size = parts[i].size;slave->mtd.writesize = master->writesize;slave->mtd.oobsize = master->oobsize;slave->mtd.oobavail = master->oobavail;slave->mtd.subpage_sft = master->subpage_sft;slave->mtd.name = parts[i].name;slave->mtd.bank_size = master->bank_size;slave->mtd.erase = part_erase;slave->master = master;//这个很重要,那些part操作,很多都是要定位到这位大爷里来的slave->offset = parts[i].offset;slave->index = i;/* let's do some sanity checks *///下面两个if判断,擦除是否能正常进行,必须是一个擦写块一个擦写块if ((slave->mtd.flags & MTD_WRITEABLE) &&    (slave->offset % slave->mtd.erasesize)) {//如果不在擦出块的边界,只可读/* Doesn't start on a boundary of major erase size *//* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */slave->mtd.flags &= ~MTD_WRITEABLE;printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",parts[i].name);}if ((slave->mtd.flags & MTD_WRITEABLE) &&    (slave->mtd.size % slave->mtd.erasesize)) {//如果大小不能整除擦出块,只可读slave->mtd.flags &= ~MTD_WRITEABLE;printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",parts[i].name);}if(parts[i].mtdp)//如果它有私有的mtd表,就私有{/* store the object pointer (caller may or may not register it */*parts[i].mtdp = &slave->mtd;slave->registered = 0;}else//一般都是放入共有的mtdtable{/* register our partition */add_mtd_device(&slave->mtd);//将这个分区的mtd注册到mtd_table中slave->registered = 1;}}}
上面的代码,干的事情很简单,slave可以理解成分区,分区有自己的操作,自己的信息,他可以从master继承过来很多东西,but大小尺寸偏移,这些是私有的,最后将分区信息放进mtd_table中,供系统调用,比如jffs2之类的。





原创粉丝点击