ubifs代码解析之ubi_attach_mtd_dev--个人学习

本文详细解析ubifs文件系统在Linux v5.10.135版本中的ubiattach功能,该功能用于将指定的MTD分区连接到UBI上。通过ubiattach命令,如`ubiattach /dev/ubi_ctrl -m 3`,可以将MTD分区3关联到ubi控制器。
摘要由CSDN通过智能技术生成

ubifs文件系统代码解析

注:源码取的是v5.10.135版本,仅供个人学习使用
在线阅读地址:https://elixir.bootlin.com/linux/v5.10.135/source/fs/ubifs
ubiattach
ubimkvol
mount

ubiattach
作用:将指定的mtd分区关联到ubi上
举例:ubiattach /dev/ubi_ctrl -m 3**

int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
		       int vid_hdr_offset, int max_beb_per1024)
{
   
	struct ubi_device *ubi;
	int i, err;
	/* 
	 * max_beb_per1024:maximum expected number of bad PEBs per 1024 PEBs
	 * 翻译过来就是,每1024个PEB中,允许的最大坏块数--块就是PEB,记住这个
	 * ubiattach 使用-b 参数可以指定max_beb_per1024
	 * -b, --max-beb-per1024 maximum expected bad block number per 1024 eraseblock.
	 * The default value is correct for most NAND devices.
	 * Allowed range is 0-768, 0 means the default kernel value.
	 * #define MAX_MTD_UBI_BEB_LIMIT 768
	 * 不用-b指定的预期值,则默认为max_beb_per1024 默认为 MAX_MTD_UBI_BEB_LIMIT 
	 * MAX_MTD_UBI_BEB_LIMIT 由 CONFIG_MTD_UBI_BEB_LIMIT 指定,默认未20
	 * 参考链接:https://zhuanlan.zhihu.com/p/504692426
	 */
	if (max_beb_per1024 < 0 || max_beb_per1024 > MAX_MTD_UBI_BEB_LIMIT)
		return -EINVAL;

	if (!max_beb_per1024)
		max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT;

	/*
	 * Check if we already have the same MTD device attached.
	 *
	 * Note, this function assumes that UBI devices creations and deletions
	 * are serialized, so it does not take the &ubi_devices_lock.
	 */
	/*
	 * 检查这个MTD设备是否已经被attach过了
	 * UBI_MAX_DEVICES:UBI设备最大的支持数,32
	 * ubi_devices[i]:ubi设备的结构体,全局数组,每当有新mtd设备attach的时候,会加入到到全局数组中,i+1
	 * 遍历一下现有ubi设备中,绑定的mtd信息是否与新attach的mtd相同
	 * 如果是则说明该mtd已经被attach过了
	 * struct mtd_info *mtd 结构体中,index 是唯一的
	 */
	for (i = 0; i < UBI_MAX_DEVICES; i++) {
   
		ubi = ubi_devices[i];
		if (ubi && mtd->index == ubi->mtd->index) {
   
			pr_err("ubi: mtd%d is already attached to ubi%d\n",
				mtd->index, i);
			return -EEXIST;
		}
	}

	/*
	 * Make sure this MTD device is not emulated on top of an UBI volume
	 * already. Well, generally this recursion works fine, but there are
	 * different problems like the UBI module takes a reference to itself
	 * by attaching (and thus, opening) the emulated MTD device. This
	 * results in inability to unload the module. And in general it makes
	 * no sense to attach emulated MTD devices, so we prohibit this.
	 */
	/*
	 * 保证MTD设备没有被模拟卷轴,这部分知识不懂,是不是要保证没有被ubimkvol执行过,还是用其他模拟的手段?
	 * 重点遗留,如遇到其他地方有类似的,后续再补充
	 */
	if (mtd->type == MTD_UBIVOLUME) {
   
		pr_err("ubi: refuse attaching mtd%d - it is already emulated on top of UBI\n",
			mtd->index);
		return -EINVAL;
	}

	/*
	 * Both UBI and UBIFS have been designed for SLC NAND and NOR flashes.
	 * MLC NAND is different and needs special care, otherwise UBI or UBIFS
	 * will die soon and you will lose all your data.
	 * Relax this rule if the partition we're attaching to operates in SLC
	 * mode.
	 */

	/*
	 * 所有的UBI和UBIFS文件系统 都是用用来设置给SLC NAND(Single-LevelCell,单层单元闪存) 和 NOR flashes
	 * MLC NAND(Multi-Level Cell,多层单元闪存)比较特殊,需要重点关注,否则很快设备就坏掉了
	 * 可以网上去搜一下,SLC NAND 和 MLC NAND的区别,重点关注擦除次数
	 * 转译一下,就是不支持UBIFS不支持 MLC NAND 设备
	 */
	if (mtd->type == MTD_MLCNANDFLASH &&
	    !(mtd->flags & MTD_SLC_ON_MLC_EMULATION)) {
   
		pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n",
			mtd->index);
		return -EINVAL;
	}

	/*
	 * ubi_num:第二入参,可以通过ubiattach -d参数指定
	 * ubiattach 命令参考链接:https://zhuanlan.zhihu.com/p/504692426
	 * 如果未指定,则自动分配
	 * 基本步骤为遍历一下,在不超过32个ubi设备数的前提下,找到空位给它
	 */
	if (ubi_num == UBI_DEV_NUM_AUTO) {
   
		/* Search for an empty slot in the @ubi_devices array */
		for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++)
			if (!ubi_devices[ubi_num])
				break;
		if (ubi_num == UBI_MAX_DEVICES) {
   
			pr_err("ubi: only %d UBI devices may be created\n",
				UBI_MAX_DEVICES);
			return -ENFILE;
		}
	} else {
   
		if (ubi_num >= UBI_MAX_DEVICES)
			return -EINVAL;

		/* Make sure ubi_num is not busy */
		if (ubi_devices[ubi_num]) {
   
			pr_err("ubi: ubi%i already exists\n", ubi_num);
			return -EEXIST;
		}
	}

	/* 在内核空间,申请一个ubi设备结构体空间,填充数据 */
	ubi = kzalloc(sizeof(struct ubi_device), GFP_KERNEL);
	if (!ubi)
		return -ENOMEM;

	device_initialize(&ubi->dev);	/* 初始化新建的逻辑设备 */
	ubi->dev.release = dev_release;	/* 设备的releas
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值