[uboot]支持mtd分区

参考:

omapl138移植uboot系列之添加MTD分区(第七篇)_uboot增加分区_明故宫的记忆的博客-CSDN博客

问题:

(1)uboot支持nor flash sf命令后,如何与网络配置进行版本更新?

(2)uboot如何支持MTD设备,Nor flash MTD分区如何进行分区划分?

(3)uboot中的分区如何与kernel中的分区进行统一?

(4)uboot变量mtdparts=60000000.nor:2m@0x100000(nor_bank0_uboot),40m@0x1100000(nor_bank0_fit),7m(nor_bank0_user),2m@0x4100000(nor_bank4_uboot),40m@0x5100000(nor_bank4_fit),-(nor_bank4_user);

对于uboot如何起作用的?对于kernel又是怎么起作用的

(5)mtd命令支持

1 相关配置宏

(1)CONFIG_SPI_FLASH_MTD=y
依赖于:
CONFIG_SPI_FLASH=y
CONFIG_MTD=y

(2)CONFIG_MTD_NOR_FLASH //支持多个nor flash会用到?

2 概述

         MTD(memory Teachno Device)中文翻译为“内存技术设备”,是Linux系统对“NorFlash”,“NandFlash”等存储设备抽象出来的一个设备层,它向上提供统一的访问接口,屏蔽底层硬件的操作,而uboot中分区只是为了方便操作。

        例如,我想将SPI Flash地址0x00010000处偏移量为1M的数据加载到内存地址0xC2000000处,一般情况,我们都是这样写:

sf  read  0xC2000000  0x00010000 100000

但如果有了uboot的分区,我们可以写

sf  read 0xC2000000 uboot

一言以蔽之“uboot中的mtd分区只是代码的一种手段,方便我们使用,用名字代替一些数字”

2.1 uboot支持MTD分区

        在spi_flash_std_probe函数中,会调用spi_flash_probe_slave函数,在CONFIG_SPI_FLASH_MTD宏打开的情况下,会调用到spi_flash_mtd_register将spi_flash注册为MTD设备。函数的具体实现如下:


int spi_flash_mtd_register(struct spi_flash *flash)
{
	int ret;

	if (sf_mtd_registered) {
		ret = del_mtd_device(&sf_mtd_info); //如果已经注册,先删除MTD设备
		if (ret)
			return ret;

		sf_mtd_registered = false;
	}

	sf_mtd_registered = false;
	memset(&sf_mtd_info, 0, sizeof(sf_mtd_info));
	sprintf(sf_mtd_name, "nor%d", spi_flash_mtd_number());

    //初始化MTD设备相关的信息
	sf_mtd_info.name = sf_mtd_name;
	sf_mtd_info.type = MTD_NORFLASH;
	sf_mtd_info.flags = MTD_CAP_NORFLASH;
	sf_mtd_info.writesize = 1;
	sf_mtd_info.writebufsize = flash->page_size;

    //mtd nor flash操作过程中使用的函数
	sf_mtd_info._erase = spi_flash_mtd_erase;
	sf_mtd_info._read = spi_flash_mtd_read;
	sf_mtd_info._write = spi_flash_mtd_write;
	sf_mtd_info._sync = spi_flash_mtd_sync;

	sf_mtd_info.size = flash->size;
	sf_mtd_info.priv = flash;

	/* Only uniform flash devices for now */
	sf_mtd_info.numeraseregions = 0;
	sf_mtd_info.erasesize = flash->sector_size;

	ret = add_mtd_device(&sf_mtd_info); //注册MTD设备,为什么不用add_mtd_partitions(&sf_mtd_info,mapl138_spiflash_partition,1);
	if (!ret)
		sf_mtd_registered = true;

	return ret;
}

下面先具体函数add_mtd_device,没看明白

int add_mtd_device(struct mtd_info *mtd)
    >>> i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL);
    >>> mtd->index = i;
    >>> mtd->usecount = 0;
    >>> mtd->bitflip_threshold = mtd->ecc_strength;
    >>> mtd->erasesize_shift = ffs(mtd->erasesize) - 1;
    >>> mtd->writesize_shift = ffs(mtd->writesize) - 1;
    >>> mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1;
    >>> mtd->writesize_mask = (1 << mtd->writesize_shift) - 1;

2.2 添加环境变量

        对于u-boot而言,设置了mtdparts变量之后,可以在sf read/write/erase命令中直接使用分区的名字而不必指定分区的偏移位置。

        将上面的宏打开之后,spi flash便添加到MTD,我们就可以根据需要,对spi flash进行分区。

     SpiFlash地址               分区名                  分区大小

0x0000_0000 ~ 0x0000_FFFF     uboot_spl                  64K

0x0001_0000 ~ 0x0008_FFFF     uboot                      512K

0x0009_0000 ~ 0x0009_FFFF     Env                        64K

0x0010_0000 ~ 0x003F_0000     Kernel                     3M

0x0040_0000 ~ 0x004F_FFFF     arm_app                     1M

0x0050_0000 ~ 0x005F_FFFF     dsp_app                     1M

剩下所有余量                  rootfs

不必修改代码,只要修改两个环境变量即可完成上述分区,uboot命令行下按照顺序输入下图红线标识的命令

set mtdids nor0=639b_nor0

set mtdparts mtdparts=639b_nor0:64k@0(spl),512k@64k(uboot),64k@576k(env),3m@1m(kernel),1m@4m(arm_app),1m@5m(dsp_ubl),1m@6m(dsp_app),3m@7m(rootfs)

        首先解释下mtdids环境变量,该变量注册了一块MTD设备,该设备是norflash类型,编号为0,该MTD设备命名为“639b_nor0”。

       mtdids是对整块Flash设备进行MTD描述,那么mtdparts就是对这块MTD设备进行分区描述了,以上设置的意思是:以SPIFlash 0x0地址为参考,从第0K开始连续64k空间命名为“spl”分区,从第64K开始连续512K空间命名为“uboot”分区,从第576K开始连续64K空间命名为“env”分区,从第1M开始连续3M空间命名为“kernel”分区,从第4M开始连续1M空间命名为“arm_app”分区,从第5M开始连续1M空间命名为“dsp_ubl”分区,从第6M开始连续1M空间命名为“arm_app”分区, ,从第7M开始连续3M空间命名为“rootfs”分区。


uboot命令行下,输入“mtd”命令,分区显示如下

 需要说明的是,如果想要在命令行交互界面使用mtd命令,需要将相关的cmd使能,需要将下面的宏打开

CONFIG_CMD_MTD=y
CONFIG_SYS_LONGHELP=y

 当打开CONFIG_CMD_MTD这个宏时,Kconfig会自动的select CONFIG_MTD_PARTITIONS=y。而这2个最终会编译mtd.c及mtdparts.c 两个文件。

cmd/Makefile:105:obj-$(CONFIG_CMD_MTD) += mtd.o
cmd/Makefile:106:obj-$(CONFIG_CMD_MTDPARTS) += mtdparts.o

首先看下mtd命令

文件:mtd.c
static int do_mtd_list(struct cmd_tbl *cmdtp, int flag, int argc,
		       char *const argv[])
    >>> mtd_probe_devices();
        >>> const char *mtdparts = get_mtdparts(); //获取mtdparts分区信息
            >>> mtdparts = env_get("mtdparts"); //若环境变量中有mtdparts分区信息,直接返回此信息
            >>> mtdparts = MTDPARTS_DEFAULT; //从板级的configs/*.h中获取
            >>> mtdparts = CONFIG_MTDPARTS_DEFAULT; //从默认的配置选项中获取
            >>> env_set("mtdparts", mtdparts); //设置到环境变量
        >>> const char *mtdids = get_mtdids(); //获取mtdids信息
        >>> mtd = get_mtd_device_nm(mtd_name); //通过nor flash的名称获取mtd设备句柄,这个设备是在spi_flash_mtd_register函数中通过调用add_mtd_device函数进行分区mtd_info信息初始化的
        >>> ret = mtd_parse_partitions(mtd, &mtdparts, &parts, &nparts); //解析mtd分区
        >>> add_mtd_partitions(mtd, parts, nparts); //创建新的mtd分区
       
    >>> mtd_for_each_device(mtd) { // 轮询mtd设备,显示分区信息
        if (!mtd_is_partition(mtd))
            mtd_show_device(mtd);
        }

调试完成后,可以使用启动命令

#define CONFIG_BOOTCOMMAND   "sf probe 0; "                           \
                             "sf read 0x41800000 0x100000 0x10000; "  \
                             "sf read 0x41000000 0x110000 0x400000; " \
                             "bootz 0x41000000 - 0x41800000"

 #define CONFIG_BOOTARGS      "console=ttyS0,115200 earlyprintk panic=5 rootwait " \
                             "mtdparts=spi32766.0:1M(uboot)ro,64k(dtb)ro,4M(kernel)ro,-(rootfs) root=31:03 rw rootfstype=jffs2"

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值