内核如何解析 mtdparts 参数,mtd-id 如何确定?

12 篇文章 0 订阅

内核如何解析 mtdparts 参数

网上搜素了 mtdparts 相关资料,没有一篇讲明白mtd_id 该怎么确认,于是自己从源码中找答案:

先看看 linux-4.14.63/Documentation 里面怎么说的

~/opt/linux-4.14.63/Documentation$ grep mtdparts . -rn                   
./admin-guide/kernel-parameters.txt:2408:       mtdparts=       [MTD]
./block/cmdline-partition.txt:10:The format for the command line is just like mtdparts:

./admin-guide/kernel-parameters.txt 里面写到

mtdparts=       [MTD]
                        See drivers/mtd/cmdlinepart.c

好吧,没有一句废话,直接让看源码 drivers/mtd/cmdlinepart.c

先看看 Makefile ,确定什么时候会编译 cmdlinepart.c , 可知需要配置 CONFIG_MTD_CMDLINE_PARTS=y

obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o

好,现在开始看源码

首先是开头注释,这里面写了mtdparts 格式

* The format for the command line is as follows:
 *
 * mtdparts=<mtddef>[;<mtddef]
 * <mtddef>  := <mtd-id>:<partdef>[,<partdef>]
 * <partdef> := <size>[@<offset>][<name>][ro][lk]
 * <mtd-id>  := unique name used in mapping driver/device (mtd->name)
 * <size>    := standard linux memsize OR "-" to denote all remaining space
 *              size is automatically truncated at end of device
 *              if specified or truncated size is 0 the part is skipped
 * <offset>  := standard linux memsize
 *              if omitted the part will immediately follow the previous part
 *              or 0 if the first part
 * <name>    := '(' NAME ')'
 *              NAME will appear in /proc/mtd
 *
 * <size> and <offset> can be specified such that the parts are out of order
 * in physical memory and may even overlap.

这里面的东西都是跟网上能搜到的一样。

关键看 mtd-id

dts , spi_device 的创建,从 spi_register_controller 开始,

spi_register_controller
  dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num); // spimaster 的名字形如 spi0
  of_register_spi_devices
    of_register_spi_device
      struct spi_device *spi;
      spi = spi_alloc_device(ctlr);
        spi->dev.parent = &ctlr->dev;
      spi_add_device(spi);
        /* Set the bus ID string */
	   spi_dev_set_name(spi);
         dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->controller->dev), spi->chip_select); //形如 spi0.0

mtd_device 的注册

m25p_probe
  struct flash_platform_data	*data;
  data = dev_get_platdata(&spi->dev);    // 如果有platdata 就用 platdata->name , dts 时代一般没有
  nor->dev = &spi->dev;                  //
  if (data && data->name)
    nor->mtd.name = data->name;
-> spi_nor_scan
    struct device *dev = nor->dev;
    if (!mtd->name)                      // 如果 mtd.name 仍为空,则
		mtd->name = dev_name(dev);      // 使用 spi->dev 的名字,形如 spi0.0
-> mtd_device_register(&nor->mtd, data ? data->parts : NULL, data ? data->nr_parts : 0);
  -> mtd_device_parse_register
    -> mtd_set_dev_defaults(mtd);      // 
      -> if (!mtd->name)               // 如果 mtd.name 仍为空,则
			mtd->name = dev_name(mtd->dev.parent);   // 使用 mtd->dev.parent 的名字,即spi控制器的名字,形如 spi0
    -> parse_mtd_partitions(mtd, types, parser_data)
      -> types = mtd_is_partition(master) ? default_subpartition_types : default_mtd_part_types;   // "cmdlinepart"
        -> mtd_part_do_parse
          -> ret = (*parser->parse_fn)(master, &pparts->parts, data);    // cmdline_parser 里用mtd-id 与 mtd->name 匹配

cmdline_parser

static int __init mtdpart_setup(char *s)
{
	cmdline = s;
	return 1;
}

__setup("mtdparts=", mtdpart_setup);

static struct mtd_part_parser cmdline_parser = {
	.parse_fn = parse_cmdline_partitions,
	.name = "cmdlinepart",
};

真正的匹配过程:

parse_cmdline_partitions
    const char *mtd_id = master->name;    // master->name 其实就是 mtd->name ,
	/*
	 * Search for the partition definition matching master->name.
	 * If master->name is not set, stop at first partition definition.
	 */
	for (part = partitions; part; part = part->next) {
		if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id)))    // part->mtd_id 是 mtdparts=<mtd-id>:.. 传进来的 mtd-id
			break;
	}
    //....

小结:

CONFIG_MTD_CMDLINE_PARTS=y 开启内核对 mtdparts 参数的支持

dts 时代,mtd-id 写法一般为 spi0.0 , 也可以通过 sysfs 查看,如

/sys/devices/platform/soc/1c68000.spi/spi_master/spi0/spi0.0

举例:

mtdparts=spi0.0:512k(u-boot)ro,64k(env),64k(dtb),5M(kernel),8M(rootfs),-(data)
mtdparts=spi0.0:512k@0(u-boot)ro,64k@512k(env), 64k@576k(dtb) 5M@640k(kernel),8M@5760k(rootfs),-(data)
mtdparts=spi0.0:512k@0(u-boot)ro,64k@0x80000(env)ro,64k@0x90000(dtb),5M@a0000(kernel),8M@5a0000(rootfs),-(data)
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值