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

总所周知,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_driver
	driver_attach
		bus_for_each_drv
			__driver_attach
				driver_probe_device
					really_probe

static int really_probe(void *void_data)
{
	struct stupid_thread_structure *data = void_data;
	struct device_driver *drv = data->drv;//本次platform的driver
	struct device *dev = data->dev;//原先就已经注册的platform
	dev->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 flash
	flash->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之类的。





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PetaLinux是一个基于嵌入式Linux的开发工具链,用于构建嵌入式系统。它提供了许多可定制的组件和功能,其中包括对JFFS2文件系统的支持。 JFFS2(Journaling Flash File System 2)是一种针对闪存存储设备设计的文件系统。它具有很好的压缩率和高度可靠性,适用于嵌入式系统。在嵌入式系统中,闪存是一种常见的存储设备,它通常具有较小的存储容量和有限的周期寿命。因此,选择合适的文件系统对于确保系统的可靠性和性能至关重要。 使用PetaLinux时选择使用JFFS2文件系统有几个优点。首先,JFFS2具有较好的压缩率,可以节省存储空间。这在嵌入式系统中特别重要,因为闪存的容量通常有限。其次,JFFS2采用了日志技术,可以确保数据的完整性和一致性。它可以通过将修改的数据写入日志中,然后再写入闪存中来提供数据持久性。这有助于防止数据损坏和错误。 另外,PetaLinux提供了对JFFS2文件系统的内建支持和集成工具。这些工具使得在构建嵌入式系统时轻松地添加和配置JFFS2文件系统成为可能。开发人员可以使用PetaLinux提供的命令和选项设置文件系统的参数和属性,以满足特定的需求。 综上所述,使用PetaLinux来构建嵌入式系统并选择JFFS2文件系统能够提供较好的存储空间利用率和数据的可靠性。这使得嵌入式系统在具有有限存储容量和闪存设备的情况下,能够更好地运行和维护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值