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.delau...@st.com>
Reviewed-by: Christophe KERELLO <christophe.kere...@st.com>
---

Changes in v5: None
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 796bb98..773a925 100644
--- a/cmd/mtdparts.c
+++ b/cmd/mtdparts.c
@@ -1902,6 +1902,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                                */
 /***************************************************/
@@ -1977,6 +2082,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;
@@ -2093,6 +2223,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)
@@ -2122,7 +2256,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(
-- 
1.9.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to