
add new subcommand : mtdparts gpt <mtd-dev> [<GUID>]
extract mtd partition from GPT header present in MTD device
mtdparts gpt nand0 mtdparts gpt nor0
extract mtd partitions only for some GUID
mtdparts gpt nand0 data mtdparts gpt nor0 0FC63DAF-8483-4772-8E79-3D69D8477DE4
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com Reviewed-by: Christophe KERELLO christophe.kerello@st.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
cmd/mtdparts.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 1 deletion(-)
diff --git a/cmd/mtdparts.c b/cmd/mtdparts.c index 5f97b80..159806e 100644 --- a/cmd/mtdparts.c +++ b/cmd/mtdparts.c @@ -1894,6 +1894,111 @@ static struct part_info* mtd_part_info(struct mtd_device *dev, unsigned int part return NULL; }
+#ifdef CONFIG_EFI_PARTITION_MTD +/** + * extract MTD info from GPT information + * + * @param device string to select GPT device + * @param p_guid_filter guid for filtering add + * + * @return 0 on success, -ENODEV if no such device otherwise error + */ + +static int mtdparts_gpt(char *device, char *p_guid_filter) +{ + char tmpbuf[PART_ADD_DESC_MAXLEN]; + char size_str[17], start_str[17]; + u8 type, num, len; + struct mtdids *id; + int part_id; + struct mtd_info *mtd; + struct mtd_device *dev; + struct mtd_device *dev_tmp; + disk_partition_t info; + struct part_info *p; + int ret; + + if (mtd_id_parse(device, NULL, &type, &num) != 0) { + printf("invalid MTD device %s\n", device); + return 1; + } + + /* this may be the first run, initialize lists if needed + and make sure we are in sync with env variables */ + mtdparts_init(); + /* don't treat error (mtdparts can be empty) */ + + id = id_find(type, num); + if (id == NULL) { + printf("no such device %s defined in mtdids variable\n", + device); + return -ENODEV; + } + + if (get_mtd_info(type, num, &mtd) || (mtd == NULL)) { + printf("no such MTD device %s\n", device); + return -ENODEV; + } + + for (part_id = 1; part_id <= GPT_ENTRY_NUMBERS; part_id++) { + if (part_get_info_efi_mtd(mtd, part_id, &info)) + break; /* Stop for first non valid partition */ + +#ifdef CONFIG_PARTITION_TYPE_GUID + if (p_guid_filter && + strcmp(p_guid_filter, info.type_guid)) + continue; +#endif + sprintf(size_str, "%llx", (u64)(info.size * info.blksz)); + sprintf(start_str, "%llx", (u64)(info.start * info.blksz)); + + len = strlen(id->mtd_id) + 1; /* 'mtd_id:' */ + len += strlen(size_str) + 2; /* 0x size */ + len += strlen(start_str) + 3; /* @0x start */ + len += strlen((char *)&info.name) + 2; /* '(' name ')' */ + + if (len >= PART_ADD_DESC_MAXLEN) { + printf("too long partition description\n"); + return -EINVAL; + } + + sprintf(tmpbuf, "%s:0x%s@0x%s(%s)", + id->mtd_id, size_str, start_str, info.name); + + debug("add tmpbuf: %s\n", tmpbuf); + + ret = device_parse(tmpbuf, NULL, &dev); + if (ret) + return ret; + + debug("+ %s\t%d\t%s\n", MTD_DEV_TYPE(type), num, + id->mtd_id); + + p = list_entry(dev->parts.next, struct part_info, link); + + dev_tmp = device_find(type, num); + + if (dev_tmp == NULL) { + device_add(dev); + } else { + ret = part_add(dev_tmp, p); + if (ret) { + free(dev); + return ret; + } + } + } + + ret = generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN); + if (ret) { + printf("generated mtdparts too long, resetting to null\n"); + return ret; + } + + return 0; +} +#endif + /***************************************************/ /* U-Boot commands */ /***************************************************/ @@ -1969,6 +2074,31 @@ static int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, } }
+#ifdef CONFIG_EFI_PARTITION_MTD + /* mtdparts gpt <mtd-dev> [GUID] */ + if ((argc == 3 || argc == 4) && (strncmp(argv[1], "gpt", 3) == 0)) { +#ifdef CONFIG_PARTITION_TYPE_GUID + char guid_str[UUID_STR_LEN + 1]; + char *p_guid_filter = NULL; +#endif + + if (argc == 4) { +#ifdef CONFIG_PARTITION_TYPE_GUID + p_guid_filter = guid_str; + if (uuid_guid_parse_str(argv[3], guid_str)) { + printf("invalid type gui %s\n", argv[3]); + return 1; + } + debug("filtered type gui %s (%s)\n", argv[3], guid_str); +#else + puts("type GUI not support\n"); +#endif + } + + return mtdparts_gpt(argv[2], p_guid_filter); + } +#endif + /* make sure we are in sync with env variables */ if (mtdparts_init() != 0) return 1; @@ -2085,6 +2215,10 @@ static char mtdparts_help_text[] = "mtdparts add.spread <mtd-dev> <size>[@<offset>] [<name>] [ro]\n" " - add partition, padding size by skipping bad blocks\n" #endif +#ifdef CONFIG_EFI_PARTITION_MTD + "mtdparts gpt <mtd-dev> [<GUID>]\n" + " - add partitions for device from gpt, filtered by GUID type\n" +#endif "mtdparts default\n" " - reset partition table to defaults\n" #if defined(CONFIG_CMD_MTDPARTS_SPREAD) @@ -2114,7 +2248,11 @@ static char mtdparts_help_text[] = "<size> := standard linux memsize OR '-' to denote all remaining space\n" "<offset> := partition start offset within the device\n" "<name> := '(' NAME ')'\n" - "<ro-flag> := when set to 'ro' makes partition read-only (not used, passed to kernel)"; + "<ro-flag> := when set to 'ro' makes partition read-only (not used, passed to kernel)\n" +#ifdef CONFIG_EFI_PARTITION_MTD + "<GUID> := partition guid\n" +#endif + ; #endif
U_BOOT_CMD(