在uboot 环境变量如何进行配置分区??
在uboot源码cmd/mtdparts.c中 提供工了这样一段注释
* Three environment variables are used by the parsing routines:
*
* 'partition' - keeps current partition identifier
*
* partition := <part-id>
* <part-id> := <dev-id>,part_num
* 'mtdids' - linux kernel mtd device id <-> u-boot device id mapping
*
* mtdids=<idmap>[,<idmap>,...]
*
* <idmap> := <dev-id>=<mtd-id>
* <dev-id> := 'nand'|'nor'|'onenand'<dev-num>
* <dev-num> := mtd device number, 0...
* <mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)
*
*
* 'mtdparts' - partition list
*
* mtdparts=mtdparts=<mtd-def>[;<mtd-def>...]
*
* <mtd-def> := <mtd-id>:<part-def>[,<part-def>...]
* <mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)
* <part-def> := <size>[@<offset>][<name>][<ro-flag>]
* <size> := standard linux memsize OR '-' to denote all remaining space
* <offset> := partition start offset within the device
* <name> := '(' NAME ')'
* <ro-flag> := when set to 'ro' makes partition read-only (not used, passed to kernel)
*
* Notes:
* - each <mtd-id> used in mtdparts must albo exist in 'mtddis' mapping
* - if the above variables are not set defaults for a given target are used
*
* Examples:
*
* 1 NOR Flash, with 1 single writable partition:
* mtdids=nor0=edb7312-nor
* mtdparts=mtdparts=edb7312-nor:-
*
* 1 NOR Flash with 2 partitions, 1 NAND with one
* mtdids=nor0=edb7312-nor,nand0=edb7312-nand
* mtdparts=mtdparts=edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
这么看除了Examples: 能大概看懂其他的也没看懂啥;
给个我单板的实例看下
ubi_mtd=setenv mtdids "nor0=spi0.0";
setenv mtdparts "mtdparts=spi0.0:4M(bootloader),6M(linux.ub),6M(rootfs),10M(fpga),6M(bspom),4M(bootloader-1),6M(linux.ub-1),6M(rootfs-1),10M(fpga-1),6M(bspom-1),64M(data)"
ubi_mtd=setenv mtdids "nor0=spi0.0";setenv mtdparts "mtdparts=spi0.0:4M(bootloader),6M(linux.ub),6M(rootfs),10M(fpga),6M(bspom),4M(bootloader-1),6M(linux.ub-1),6M(rootfs-1),10M(fpga-1),6M(bspom-1),64M(data)"
上面的意思就是:
第一个步: 这只mtdids id 就是
* mtdids=<idmap>[,<idmap>,...]
<idmap> := <dev-id>=<mtd-id>
<dev-id> := 'nand'|'nor'|'onenand'<dev-num>
<dev-num> := mtd device number, 0...
<mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)
* mtdids=nor0=edb7312-nor,nand0=edb7312-nand
* mtdparts=mtdparts=edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
这就能看懂了哈, mtdids 类型 nand 或者nor flash
可以有多个flash,多个配置,需要以逗号分隔配置; 类型使用等号链接
ubi_mtd=setenv mtdids "nor0=spi0.0"; 为啥我这里配置的spi0.0因为在设备树中制定了spi0.0是norflash;
对于每个flash分区的大小和名称在 mtdparts环境变量中指定;
每个flash配置以分号分隔,每个flash项内部分区以逗号分隔;
mtdparts=mtdparts=edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
举例中这就是有两个flash :
edb7312-nor:两个分区 ARMboot 占用256k 剩下的全是 root分区的
edb7312-nand:只有一个分区 home 占用所有空间
uboot中分区初始化函数, 获取环境变量后如果为空(没有定义的话)就使用默认的环境变量;
如果定义了就解析 , 初始化全局的设备链表 设置参数;
int mtdparts_init(void)
{
static int initialized = 0;
const char *ids, *parts;
const char *current_partition;
int ids_changed;
char tmp_ep[PARTITION_MAXLEN + 1];
char tmp_parts[MTDPARTS_MAXLEN];
debug("\n---mtdparts_init---\n");
if (!initialized) {
INIT_LIST_HEAD(&mtdids);
INIT_LIST_HEAD(&devices);
memset(last_ids, 0, sizeof(last_ids));
memset(last_parts, 0, sizeof(last_parts));
memset(last_partition, 0, sizeof(last_partition));
#if defined(CONFIG_SYS_MTDPARTS_RUNTIME)
board_mtdparts_default(&mtdids_default, &mtdparts_default);
#endif
use_defaults = 1;
initialized = 1;
}
/* get variables */
ids = env_get("mtdids"); //获取环境变量 mtdids内容
parts = env_get_mtdparts(tmp_parts);
current_partition = env_get("partition"); //获取环境变量 partition内容
/* save it for later parsing, cannot rely on current partition pointer
* as 'partition' variable may be updated during init */
memset(tmp_parts, 0, sizeof(tmp_parts));
memset(tmp_ep, 0, sizeof(tmp_ep));
if (current_partition)
strncpy(tmp_ep, current_partition, PARTITION_MAXLEN);
debug("last_ids : %s\n", last_ids);
debug("env_ids : %s\n", ids);
debug("last_parts: %s\n", last_parts);
debug("env_parts : %s\n\n", parts);
debug("last_partition : %s\n", last_partition);
debug("env_partition : %s\n", current_partition);
/* if mtdids variable is empty try to use defaults */
if (!ids) {
if (mtdids_default) {
debug("mtdids variable not defined, using default\n");
ids = mtdids_default;
env_set("mtdids", (char *)ids);
} else {
printf("mtdids not defined, no default present\n");
return 1;
}
}
if (strlen(ids) > MTDIDS_MAXLEN - 1) {
printf("mtdids too long (> %d)\n", MTDIDS_MAXLEN);
return 1;
}
/* use defaults when mtdparts variable is not defined
* once mtdparts is saved environment, drop use_defaults flag */
if (!parts) {
if (mtdparts_default && use_defaults) {
parts = mtdparts_default;
if (env_set("mtdparts", (char *)parts) == 0)
use_defaults = 0;
} else
printf("mtdparts variable not set, see 'help mtdparts'\n");
}
if (parts && (strlen(parts) > MTDPARTS_MAXLEN - 1)) {
printf("mtdparts too long (> %d)\n", MTDPARTS_MAXLEN);
return 1;
}
/* check if we have already parsed those mtdids */
if ((last_ids[0] != '\0') && (strcmp(last_ids, ids) == 0)) {
ids_changed = 0;
} else {
ids_changed = 1;
if (parse_mtdids(ids) != 0) {
mtd_devices_init();
return 1;
}
/* ok it's good, save new ids */
strncpy(last_ids, ids, MTDIDS_MAXLEN);
}
/* parse partitions if either mtdparts or mtdids were updated */
if (parts && ((last_parts[0] == '\0') || ((strcmp(last_parts, parts) != 0)) || ids_changed)) {
if (parse_mtdparts(parts) != 0)
return 1;
if (list_empty(&devices)) {
printf("mtdparts_init: no valid partitions\n");
return 1;
}
/* ok it's good, save new parts */
strncpy(last_parts, parts, MTDPARTS_MAXLEN);
/* reset first partition from first dev from the list as current */
current_mtd_dev = list_entry(devices.next, struct mtd_device, link);
current_mtd_partnum = 0;
current_save();
debug("mtdparts_init: current_mtd_dev = %s%d, current_mtd_partnum = %d\n",
MTD_DEV_TYPE(current_mtd_dev->id->type),
current_mtd_dev->id->num, current_mtd_partnum);
}
/* mtdparts variable was reset to NULL, delete all devices/partitions */
if (!parts && (last_parts[0] != '\0'))
return mtd_devices_init();
/* do not process current partition if mtdparts variable is null */
if (!parts)
return 0;
/* is current partition set in environment? if so, use it */
if ((tmp_ep[0] != '\0') && (strcmp(tmp_ep, last_partition) != 0)) {
struct part_info *p;
struct mtd_device *cdev;
u8 pnum;
debug("--- getting current partition: %s\n", tmp_ep);
if (find_dev_and_part(tmp_ep, &cdev, &pnum, &p) == 0) {
current_mtd_dev = cdev;
current_mtd_partnum = pnum;
current_save();
}
} else if (env_get("partition") == NULL) {
debug("no partition variable set, setting...\n");
current_save();
}
return 0;
}