Quantcast

[PATCH v6 00/18] GPT over MTD

classic Classic list List threaded Threaded
27 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 00/18] GPT over MTD

Patrick DELAUNAY-2

I have a request to support GPT over MTD to have the MTD informations
without U-Boot environment(CONFIG_ENV_IS_NOWHERE is a other requirement
of my project to manage several board configuration with
the same defconfig; boot from NAND or NOR or SDCARD).

The current idea is to use the GPT header format to save the partitioning
information directly in flash device (NOR or NAND), then the U-Boot MTD
variables are rebuild from these GPT partitions and can be used by DISTRO
command to search bootable binary.

This information are directly used by BootRom to locate and load
the first bootstage.

The added code is under a new CONFIG : CONFIG_EFI_PARTITION_MTD
and in the new file "disk/part_efi_mtd.c"

For implementation details, see doc/README.gpt.mtd

TODO: full support for modified command (if needed)
      today I limit the support for the command expected
      used by DISTRO macro:
      + gpt write
      + part list

the current level is tested on sandbox with

- test/fs/gpt_mtd-test.sh

or manually with :

> make O=sandbox sandbox_defconfig
> make O=sandbox
> dd if=/dev/zero of=spi.bin bs=1M count=4
> sandbox/u-boot -d sandbox/arch/sandbox/dts/test.dtb

=> sf probe
SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB

=> setenv nor_part "name=part1,size=64KiB;name=part2,size=128KiB;\
   name=boot,type=linux,bootable,size=512KiB"
=> gpt write nor 0 $nor_part
Writing GPT: success!

=> part list nor 0
Part Start LBA End LBA Name
        Attributes
        Type GUID
        Partition GUID
  1 0x00000080 0x000000ff "part1"
        attrs: 0x0000000000000000
        type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
        type: data
        guid: d117f98e-6f2c-0040-00b2-331a19f91cb2
  2 0x00000100 0x000001ff "part2"
        attrs: 0x0000000000000000
        type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
        type: data
        guid: 25718777-d0ad-0000-8060-02cb591c9737
  3 0x00000200 0x000005ff "boot"
        attrs: 0x0000000000000004
        type: 0fc63daf-8483-4772-8e79-3d69d8477de4
        type: linux
        guid: 8a4bb8b4-e304-0040-0036-aff5c9c495b1

=> setenv mtdids "nor0=nor0"
=> setenv mtdparts "mtdparts="
=> mtdparts gpt nor0
=> mtdparts
device nor0 <nor0>, # parts = 3
 #: name size offset mask_flags
 0: part1               0x00010000 0x00010000 0
 1: part2               0x00020000 0x00020000 0
 2: boot                0x00080000 0x00040000 0

active partition: nor0,0 - (part1) 0x00010000 @ 0x00010000

defaults:
mtdids  : none
mtdparts: none

=> part list nor 0 -bootable nor_boot_part
=> printenv nor_boot_part
nor_boot_part=3

test filtering feature (can be used to mask some partitions to linux
according the GUID)
1/ only add MTD for some guid = linux
2/ then add MTD for some guid = data

=> mtdparts delall
=> setenv mtdparts "mtdparts="
=> setenv mtdids "nor0=nor0"
=> mtdparts gpt nor0 linux
=> mtdparts

device nor0 <nor0>, # parts = 1
 #: name size offset mask_flags
 0: boot                0x00080000 0x00040000 0

active partition: nor0,0 - (boot) 0x00080000 @ 0x00040000

defaults:
mtdids  : none
mtdparts: none

=> mtdparts gpt nor0 data
=> mtdparts

device nor0 <nor0>, # parts = 3
 #: name size offset mask_flags
 0: part1               0x00010000 0x00010000 0
 1: part2               0x00020000 0x00020000 0
 2: boot                0x00080000 0x00040000 0

active partition: nor0,2 - (boot) 0x00080000 @ 0x00040000

defaults:
mtdids  : none
mtdparts: none


Changes in v6:
- rebase of the top of the latest v2017.05
- add comment for function part_print_gpt and part_print_efi
- add comment for function part_get_disk_info
- add comment for function prepare_backup_gpt_header
- add export function comment in part_efi_int.h
- invalid offset my_lba in is_secondary_gpt_valid_mtd()
  the secondary GPT header wasn't detected
- add comment for functions
- add distro support for UBI volume in GPT partition in MTD device
- add sandbox test (test/fs/gpt_mtd-test.sh) for modified commands

Changes in v5:
- rebase of the top of latest u-boot master
- solve warning and error
  (dont' include linux/mtd/mtd.h in part.h)

Changes in v4:
- change RFC to PATCH
- update cover letter
- rebase on v2017.03

Changes in v3:
- solve issue in compute partition_entry_lba update :
  missing / lba_size
- rework and split patches for unrelated change after review
  from Cristophe Kerello and Simon Glass
- rebase on v2017.03-rc1

Changes in v2:
- split serie to reduce patches size
  (separate disk part and cmd impact and add precursor patch)
- split large function

Patrick Delaunay (18):
  uuid: add a function for GUID string parsing
  disk: part: refactor part_print_efi to prepare GPT over MTD
  disk: part: refactor part_get_info_efi to prepare GPT over MTD
  disk: part: prepare_backup_gpt_header rework
  disk: part: compute partition_entry_lba
  disk: part: efi: export internal function
  disk: part: add support of GPT partitioning over MTD
  cmd: gpt: remove blk_desc parameter in static function
  cmd: gpt: use error number in set_gpt_info
  cmd: gpt: add print_gpt_info_err
  cmd: gpt: update write command to support GPT over MTD
  cmd: part: update command to support GPT over MTD
  cmd: mtdparts: move PART_ADD_DESC_MAXLEN
  cmd: mtdparts: update command to support GPT over MTD
  uuid: remove dependency with io.h
  sandbox: GPT over MTD test
  distro: add boot for UBI in GPT over MTD
  tests: Add GPT over MTD test

 cmd/gpt.c                       | 152 +++++++++++---
 cmd/mtdparts.c                  | 144 ++++++++++++-
 cmd/part.c                      |  49 ++++-
 configs/sandbox_defconfig       |   3 +
 disk/Kconfig                    |  17 ++
 disk/Makefile                   |   1 +
 disk/part_efi.c                 | 152 +++++++-------
 disk/part_efi_int.h             |  70 ++++++
 disk/part_efi_mtd.c             | 456 ++++++++++++++++++++++++++++++++++++++++
 doc/README.gpt.mtd              | 187 ++++++++++++++++
 include/config_distro_bootcmd.h |  40 ++++
 include/configs/sandbox.h       |   6 +
 include/part.h                  |  42 +++-
 include/uuid.h                  |   1 +
 lib/uuid.c                      |  48 ++++-
 test/fs/gpt_mtd-test.sh         | 209 ++++++++++++++++++
 16 files changed, 1447 insertions(+), 130 deletions(-)
 create mode 100644 disk/part_efi_int.h
 create mode 100644 disk/part_efi_mtd.c
 create mode 100644 doc/README.gpt.mtd
 create mode 100755 test/fs/gpt_mtd-test.sh

--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 01/18] uuid: add a function for GUID string parsing

Patrick DELAUNAY-2
uuid_guid_parse_str parses a string provided in commands line
to found a valid GUID as valid uuid string or as shortcut
(under CONFIG_PARTITION_TYPE_GUID).

Signed-off-by: Patrick Delaunay <[hidden email]>
---

Changes in v6:
- rebase of the top of the latest v2017.05

Changes in v5:
- rebase of the top of latest u-boot master

Changes in v4:
- change RFC to PATCH
- update cover letter
- rebase on v2017.03

Changes in v3:
- solve issue in compute partition_entry_lba update :
  missing / lba_size
- rework and split patches for unrelated change after review
  from Cristophe Kerello and Simon Glass
- rebase on v2017.03-rc1

Changes in v2:
- split serie to reduce patches size
  (separate disk part and cmd impact and add precursor patch)
- split large function

 include/uuid.h |  1 +
 lib/uuid.c     | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/include/uuid.h b/include/uuid.h
index c3f423f..f444095 100644
--- a/include/uuid.h
+++ b/include/uuid.h
@@ -40,6 +40,7 @@ void uuid_bin_to_str(unsigned char *uuid_bin, char *uuid_str, int str_format);
 int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin);
 int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str);
 #endif
+int uuid_guid_parse_str(const char *str, char *guid_str);
 void gen_rand_uuid(unsigned char *uuid_bin);
 void gen_rand_uuid_str(char *uuid_str, int str_format);
 #endif
diff --git a/lib/uuid.c b/lib/uuid.c
index c8584ed..7ce822c 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -136,6 +136,41 @@ int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str)
 #endif
 
 /*
+ * uuid_guid_parse_str() - this function parses string to found a valid GUID.
+ *
+ * @param guid_str - pointer to string with partition type guid [37B]
+ *                   or GUID shorcut defined in list_guid[]
+ * @param guid_str - pointer to allocated partition type string [37B]
+ * @return 0 if OK, else -ENODEV
+ */
+int uuid_guid_parse_str(const char *str, char *guid_str)
+{
+#ifdef CONFIG_PARTITION_TYPE_GUID
+ int i;
+#endif
+
+ if (guid_str == NULL)
+ return -ENODEV;
+
+ if (uuid_str_valid(str)) {
+ memcpy(guid_str, str, UUID_STR_LEN + 1);
+ return 0;
+ }
+
+#ifdef CONFIG_PARTITION_TYPE_GUID
+ for (i = 0; i < ARRAY_SIZE(list_guid); i++) {
+ if (!strcmp(list_guid[i].string, str)) {
+ uuid_bin_to_str((unsigned char *)list_guid[i].guid.b,
+ guid_str, UUID_STR_FORMAT_GUID);
+ return 0;
+ }
+ }
+#endif
+
+ return -ENODEV;
+}
+
+/*
  * uuid_str_to_bin() - convert string UUID or GUID to big endian binary data.
  *
  * @param uuid_str - pointer to UUID or GUID string [37B] or GUID shorcut
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 02/18] disk: part: refactor part_print_efi to prepare GPT over MTD

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
split part_print_efi : create sub-functions part_print_gpt()

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Christophe KERELLO <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6:
- add comment for function part_print_gpt and part_print_efi

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 disk/part_efi.c | 63 ++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 23 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index 1b7ba27..88e925b 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -175,34 +175,18 @@ static void prepare_backup_gpt_header(gpt_header *gpt_h)
 
 #if CONFIG_IS_ENABLED(EFI_PARTITION)
 /*
- * Public Functions (include/part.h)
+ * part_print_gpt() - display GUID Partition Table information
+ *
+ * @param gpt_head - pointer to GPT header
+ * @param gpt_pte - pointer to GPT partion entry array
  */
-
-void part_print_efi(struct blk_desc *dev_desc)
+static void part_print_gpt(gpt_header *gpt_head,
+   gpt_entry *gpt_pte)
 {
- ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
- gpt_entry *gpt_pte = NULL;
  int i = 0;
  char uuid[37];
  unsigned char *uuid_bin;
 
- /* This function validates AND fills in the GPT header and PTE */
- if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
- gpt_head, &gpt_pte) != 1) {
- printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
- if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
- gpt_head, &gpt_pte) != 1) {
- printf("%s: *** ERROR: Invalid Backup GPT ***\n",
-       __func__);
- return;
- } else {
- printf("%s: ***        Using Backup GPT ***\n",
-       __func__);
- }
- }
-
- debug("%s: gpt-entry at %p\n", __func__, gpt_pte);
-
  printf("Part\tStart LBA\tEnd LBA\t\tName\n");
  printf("\tAttributes\n");
  printf("\tType GUID\n");
@@ -229,10 +213,39 @@ void part_print_efi(struct blk_desc *dev_desc)
  uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
  printf("\tguid:\t%s\n", uuid);
  }
+}
+
+/*
+ * part_print_efi() - display EFI Partition information
+ *
+ * @param dev_desc - pointer to block device descriptor
+ */
+void part_print_efi(struct blk_desc *dev_desc)
+{
+ ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
+ gpt_entry *gpt_pte = NULL;
+
+ /* This function validates AND fills in the GPT header and PTE */
+ if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
+ gpt_head, &gpt_pte) != 1) {
+ printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
+ if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
+ gpt_head, &gpt_pte) != 1) {
+ printf("%s: *** ERROR: Invalid Backup GPT ***\n",
+       __func__);
+ return;
+ } else {
+ printf("%s: ***        Using Backup GPT ***\n",
+       __func__);
+ }
+ }
+
+ debug("%s: gpt-entry at %p\n", __func__, gpt_pte);
+
+ part_print_gpt(gpt_head, gpt_pte);
 
  /* Remember to free pte */
  free(gpt_pte);
- return;
 }
 
 int part_get_info_efi(struct blk_desc *dev_desc, int part,
@@ -349,6 +362,10 @@ static int set_protective_mbr(struct blk_desc *dev_desc)
  return 0;
 }
 
+/*
+ * Public Functions (include/part.h)
+ */
+
 int write_gpt_table(struct blk_desc *dev_desc,
  gpt_header *gpt_h, gpt_entry *gpt_e)
 {
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 03/18] disk: part: refactor part_get_info_efi to prepare GPT over MTD

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
create sub-functions part_get_disk_info()

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Christophe KERELLO <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6:
- add comment for function part_get_disk_info

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 disk/part_efi.c | 57 +++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index 88e925b..16608e7 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -216,6 +216,40 @@ static void part_print_gpt(gpt_header *gpt_head,
 }
 
 /*
+ * part_get_disk_info() - extract partition information for one GPT entry
+ *
+ * @param part - index of entry in gpt_pte
+ * @param blksz - blksize
+ * @param gpt_pte - pointer to GPT partion entry array
+ * @param gpt_pte - pointer to disk partition (output)
+ */
+static void part_get_disk_info(int part, unsigned int blksz,
+       gpt_entry *gpt_pte, disk_partition_t *info)
+{
+ /* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */
+ info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba);
+ /* The ending LBA is inclusive, to calculate size, add 1 to it */
+ info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1
+     - info->start;
+ info->blksz = blksz;
+
+ sprintf((char *)info->name, "%s", print_efiname(&gpt_pte[part - 1]));
+ strcpy((char *)info->type, "U-Boot");
+ info->bootable = is_bootable(&gpt_pte[part - 1]);
+#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
+ uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid,
+ UUID_STR_FORMAT_GUID);
+#endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+ uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b,
+ info->type_guid, UUID_STR_FORMAT_GUID);
+#endif
+
+ debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__,
+      info->start, info->size, info->name);
+}
+
+/*
  * part_print_efi() - display EFI Partition information
  *
  * @param dev_desc - pointer to block device descriptor
@@ -283,28 +317,7 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part,
  return -1;
  }
 
- /* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */
- info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba);
- /* The ending LBA is inclusive, to calculate size, add 1 to it */
- info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1
-     - info->start;
- info->blksz = dev_desc->blksz;
-
- sprintf((char *)info->name, "%s",
- print_efiname(&gpt_pte[part - 1]));
- strcpy((char *)info->type, "U-Boot");
- info->bootable = is_bootable(&gpt_pte[part - 1]);
-#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
- uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid,
- UUID_STR_FORMAT_GUID);
-#endif
-#ifdef CONFIG_PARTITION_TYPE_GUID
- uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b,
- info->type_guid, UUID_STR_FORMAT_GUID);
-#endif
-
- debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__,
-      info->start, info->size, info->name);
+ part_get_disk_info(part, dev_desc->blksz, gpt_pte, info);
 
  /* Remember to free pte */
  free(gpt_pte);
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 04/18] disk: part: prepare_backup_gpt_header rework

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
inverse the order of my_lba and alternate_lba values switch value
=> alternate_lba can be used in partition entry computation

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Christophe KERELLO <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 disk/part_efi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index 16608e7..181a748 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -161,9 +161,9 @@ static void prepare_backup_gpt_header(gpt_header *gpt_h)
  uint64_t val;
 
  /* recalculate the values for the Backup GPT Header */
- val = le64_to_cpu(gpt_h->my_lba);
- gpt_h->my_lba = gpt_h->alternate_lba;
- gpt_h->alternate_lba = cpu_to_le64(val);
+ val = le64_to_cpu(gpt_h->alternate_lba);
+ gpt_h->alternate_lba = gpt_h->my_lba;
+ gpt_h->my_lba = cpu_to_le64(val);
  gpt_h->partition_entry_lba =
  cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1);
  gpt_h->header_crc32 = 0;
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 05/18] disk: part: compute partition_entry_lba

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
the value for partition_entry_lba of secondary GPT (last usable lba + 1)
is not correct with MTD support as last usable LBA need to be erase size
aligned

The correct location of partition entry is always recomputed with
the formula :
partition_entry_lba =
   alternate_lba -
   num_pte * sizeof_partition_entry / lba_size

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Christophe KERELLO <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---
the device mapping is

1/ for block case:

  last_usable_lba     -> partition_entry_lba - 1
  partition_entry_lba ->  PTE table (num * sizeof(PTE))
  alternate_lba       ->  secondary GPT
  -> end of device

2/ for MTD case : end of the last good block

  -------------

  last_usable_lba     -> last good erase block - 1
  -------------erase BLOCK aligned
  XXXXXXXXXXXXXXXXXX  -> skipped LBA for MTD case
  partition_entry_lba ->  PTE table (num * sizeof(PTE))
  alternate_lba       ->  secondary GPT
  -------------erase BLOCK aligned
  xxxxx skipping bad block
  ->end of device

Changes in v6:
- add comment for function prepare_backup_gpt_header

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 disk/part_efi.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index 181a748..23a582a 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -155,7 +155,14 @@ static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
  return 0;
 }
 
-static void prepare_backup_gpt_header(gpt_header *gpt_h)
+/*
+ * prepare_backup_gpt_header() - change primary GPT header to backup GPT header
+ *
+ * @param gpt_h - pointer to GPT header (in=primary, out=secondary)
+ * @param pte_blk_cnt - number of block for size of partition entry array (PTE)
+ */
+static void prepare_backup_gpt_header(gpt_header *gpt_h,
+      const int pte_blk_cnt)
 {
  uint32_t calc_crc32;
  uint64_t val;
@@ -164,8 +171,7 @@ static void prepare_backup_gpt_header(gpt_header *gpt_h)
  val = le64_to_cpu(gpt_h->alternate_lba);
  gpt_h->alternate_lba = gpt_h->my_lba;
  gpt_h->my_lba = cpu_to_le64(val);
- gpt_h->partition_entry_lba =
- cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1);
+ gpt_h->partition_entry_lba = cpu_to_le64(val - pte_blk_cnt);
  gpt_h->header_crc32 = 0;
 
  calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
@@ -409,7 +415,7 @@ int write_gpt_table(struct blk_desc *dev_desc,
        pte_blk_cnt, gpt_e) != pte_blk_cnt)
  goto err;
 
- prepare_backup_gpt_header(gpt_h);
+ prepare_backup_gpt_header(gpt_h, pte_blk_cnt);
 
  if (blk_dwrite(dev_desc, (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba)
        + 1, pte_blk_cnt, gpt_e) != pte_blk_cnt)
@@ -824,7 +830,7 @@ int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf)
  return 1;
  }
 
- prepare_backup_gpt_header(gpt_h);
+ prepare_backup_gpt_header(gpt_h, gpt_e_blk_cnt);
 
  /* write Backup GPT */
  lba = le64_to_cpu(gpt_h->partition_entry_lba);
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 06/18] disk: part: efi: export internal function

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
export the needed functions for GPT over MTD

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Christophe KERELLO <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6:
- add export function comment in part_efi_int.h

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 disk/part_efi.c     | 58 +++++++-------------------------------------
 disk/part_efi_int.h | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 49 deletions(-)
 create mode 100644 disk/part_efi_int.h

diff --git a/disk/part_efi.c b/disk/part_efi.c
index 23a582a..2d5072c 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -21,22 +21,11 @@
 #include <part_efi.h>
 #include <linux/compiler.h>
 #include <linux/ctype.h>
+#include "part_efi_int.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef HAVE_BLOCK_DEVICE
-/**
- * efi_crc32() - EFI version of crc32 function
- * @buf: buffer to calculate crc32 of
- * @len - length of buf
- *
- * Description: Returns EFI-style CRC32 value for @buf
- */
-static inline u32 efi_crc32(const void *buf, u32 len)
-{
- return crc32(0, buf, len);
-}
-
 /*
  * Private function prototypes
  */
@@ -47,7 +36,6 @@ static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
  gpt_header *pgpt_head, gpt_entry **pgpt_pte);
 static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
  gpt_header *pgpt_head);
-static int is_pte_valid(gpt_entry * pte);
 
 static char *print_efiname(gpt_entry *pte)
 {
@@ -72,8 +60,7 @@ static inline int is_bootable(gpt_entry *p)
  sizeof(efi_guid_t));
 }
 
-static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
- lbaint_t lastlba)
+int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba, lbaint_t lastlba)
 {
  uint32_t crc32_backup = 0;
  uint32_t calc_crc32;
@@ -135,7 +122,7 @@ static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
  return 0;
 }
 
-static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
+int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
 {
  uint32_t calc_crc32;
 
@@ -155,14 +142,8 @@ static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
  return 0;
 }
 
-/*
- * prepare_backup_gpt_header() - change primary GPT header to backup GPT header
- *
- * @param gpt_h - pointer to GPT header (in=primary, out=secondary)
- * @param pte_blk_cnt - number of block for size of partition entry array (PTE)
- */
-static void prepare_backup_gpt_header(gpt_header *gpt_h,
-      const int pte_blk_cnt)
+void prepare_backup_gpt_header(gpt_header *gpt_h,
+       const int pte_blk_cnt)
 {
  uint32_t calc_crc32;
  uint64_t val;
@@ -180,14 +161,7 @@ static void prepare_backup_gpt_header(gpt_header *gpt_h,
 }
 
 #if CONFIG_IS_ENABLED(EFI_PARTITION)
-/*
- * part_print_gpt() - display GUID Partition Table information
- *
- * @param gpt_head - pointer to GPT header
- * @param gpt_pte - pointer to GPT partion entry array
- */
-static void part_print_gpt(gpt_header *gpt_head,
-   gpt_entry *gpt_pte)
+void part_print_gpt(gpt_header *gpt_head, gpt_entry *gpt_pte)
 {
  int i = 0;
  char uuid[37];
@@ -221,16 +195,8 @@ static void part_print_gpt(gpt_header *gpt_head,
  }
 }
 
-/*
- * part_get_disk_info() - extract partition information for one GPT entry
- *
- * @param part - index of entry in gpt_pte
- * @param blksz - blksize
- * @param gpt_pte - pointer to GPT partion entry array
- * @param gpt_pte - pointer to disk partition (output)
- */
-static void part_get_disk_info(int part, unsigned int blksz,
-       gpt_entry *gpt_pte, disk_partition_t *info)
+void part_get_disk_info(int part, unsigned int blksz,
+ gpt_entry *gpt_pte, disk_partition_t *info)
 {
  /* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */
  info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba);
@@ -989,13 +955,7 @@ static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
  return pte;
 }
 
-/**
- * is_pte_valid(): validates a single Partition Table Entry
- * @gpt_entry - Pointer to a single Partition Table Entry
- *
- * Description: returns 1 if valid,  0 on error.
- */
-static int is_pte_valid(gpt_entry * pte)
+int is_pte_valid(gpt_entry *pte)
 {
  efi_guid_t unused_guid;
 
diff --git a/disk/part_efi_int.h b/disk/part_efi_int.h
new file mode 100644
index 0000000..f381ade
--- /dev/null
+++ b/disk/part_efi_int.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 STMicroelectronics .
+ * Patrick Delaunay <[hidden email]>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DISK_PART_EFI_INT_H
+#define _DISK_PART_EFI_INT_H
+
+/*
+ * efi_crc32() - EFI version of crc32 function
+ * @buf: buffer to calculate crc32 of
+ * @len - length of buf
+ *
+ * Description: Returns EFI-style CRC32 value for @buf
+ */
+static inline u32 efi_crc32(const void *buf, u32 len)
+{
+ return crc32(0, buf, len);
+}
+
+int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba, lbaint_t lastlba);
+
+/**
+ * validate_gpt_entries(): check GPT CRC information
+ * @param gpt_h - pointer to GPT header
+ * @param gpt_e - pointer to GPT partion entry array
+ *
+ * Description: returns 1 if valid,  0 on error.
+ */
+int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e);
+
+/**
+ * is_pte_valid(): validates a single Partition Table Entry
+ * @gpt_entry - Pointer to a single Partition Table Entry
+ *
+ * Description: returns 1 if valid,  0 on error.
+ */
+int is_pte_valid(gpt_entry *pte);
+
+/*
+ * prepare_backup_gpt_header() - change primary GPT header to backup GPT header
+ *
+ * @param gpt_h - pointer to GPT header (in=primary, out=secondary)
+ * @param pte_blk_cnt - number of block for size of partition entry array (PTE)
+ */
+void prepare_backup_gpt_header(gpt_header *gpt_h,
+       const int pte_blk_cnt);
+
+/*
+ * part_print_gpt() - display GUID Partition Table information
+ *
+ * @param gpt_head - pointer to GPT header
+ * @param gpt_pte - pointer to GPT partion entry array
+ */
+void part_print_gpt(gpt_header *gpt_head, gpt_entry *gpt_pte);
+
+/*
+ * part_get_disk_info() - extract partition information for one GPT entry
+ *
+ * @param part - index of entry in gpt_pte
+ * @param blksz - blksize
+ * @param gpt_pte - pointer to GPT partion entry array
+ * @param gpt_pte - pointer to disk partition (output)
+ */
+void part_get_disk_info(int part, unsigned int blksz,
+ gpt_entry *gpt_pte, disk_partition_t *info);
+
+#endif /* _DISK_PART_EFI_INT_H */
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 07/18] disk: part: add support of GPT partitioning over MTD

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Christophe KERELLO <[hidden email]>
---

Changes in v6:
- invalid offset my_lba in is_secondary_gpt_valid_mtd()
  the secondary GPT header wasn't detected
- add comment for functions

Changes in v5:
- solve warning and error
  (dont' include linux/mtd/mtd.h in part.h)

Changes in v4: None
Changes in v3: None
Changes in v2: None

 disk/Kconfig        |  17 ++
 disk/Makefile       |   1 +
 disk/part_efi_mtd.c | 456 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 doc/README.gpt.mtd  | 187 +++++++++++++++++++++
 include/part.h      |  42 ++++-
 5 files changed, 701 insertions(+), 2 deletions(-)
 create mode 100644 disk/part_efi_mtd.c
 create mode 100644 doc/README.gpt.mtd

diff --git a/disk/Kconfig b/disk/Kconfig
index 9396562..886a089 100644
--- a/disk/Kconfig
+++ b/disk/Kconfig
@@ -96,6 +96,23 @@ config SPL_EFI_PARTITION
  depends on  SPL && PARTITIONS
  default y if EFI_PARTITION
 
+config EFI_PARTITION_MTD
+ bool "Support EFI GPT over MTD"
+ depends on EFI_PARTITION
+ help
+  The GPT partition is normally defined only for block device with
+  built-in controller which manage flash translation layer
+  This option activate the GPT partition support over RAW device
+  using the MTD framework
+  - manage partition over MTD devices (as flash: NOR and NAND)
+  - extract MTD information
+  - update command gpt, mtdparts and part
+
+config SPL_EFI_PARTITION_MTD
+ bool "Enable EFI GPT over MTD for SPL"
+ depends on SPL_EFI_PARTITION
+ default y if EFI_PARTITION_MTD
+
 config PARTITION_UUIDS
  bool "Enable support of UUID for partition"
  depends on PARTITIONS
diff --git a/disk/Makefile b/disk/Makefile
index 12c0531..0d01160 100644
--- a/disk/Makefile
+++ b/disk/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_$(SPL_)DOS_PARTITION)   += part_dos.o
 obj-$(CONFIG_$(SPL_)ISO_PARTITION)   += part_iso.o
 obj-$(CONFIG_$(SPL_)AMIGA_PARTITION) += part_amiga.o
 obj-$(CONFIG_$(SPL_)EFI_PARTITION)   += part_efi.o
+obj-$(CONFIG_$(SPL_)EFI_PARTITION_MTD) += part_efi_mtd.o
diff --git a/disk/part_efi_mtd.c b/disk/part_efi_mtd.c
new file mode 100644
index 0000000..0c83f34
--- /dev/null
+++ b/disk/part_efi_mtd.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright (C) 2016 STMicroelectronics .
+ * Patrick Delaunay <[hidden email]>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/unaligned.h>
+#include <common.h>
+#include <command.h>
+#include <ide.h>
+#include <inttypes.h>
+#include <malloc.h>
+#include <memalign.h>
+#include <part_efi.h>
+#include <linux/ctype.h>
+#include <linux/mtd/mtd.h>
+#include "part_efi_int.h"
+
+static int is_primary_gpt_valid_mtd(struct mtd_info *mtd,
+    lbaint_t lba,
+    void **buf,
+    gpt_header **pgpt_head,
+    gpt_entry **pgpt_pte)
+{
+ gpt_header *gpt_h;
+ gpt_entry *gpt_e;
+ uint32_t size;
+ uint64_t offset;
+ int ret;
+ size_t retlen;
+ lbaint_t my_lba;
+ u32 gpt_e_size = PAD_SIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
+  MTD_LBA_SIZE);
+
+ size = gpt_e_size + 2 * MTD_LBA_SIZE;
+ /* skip bad block */
+ offset = 0;
+ while (mtd_block_isbad(mtd, offset)) {
+ printf("bad block at 0x%llx\n", offset);
+ offset += mtd->erasesize;
+ if (offset >= mtd->size) {
+ printf("*** ERROR: too many bad block ***\n");
+ return -1;
+ }
+ }
+
+ debug("primary offset = 0x%llx\n", offset);
+ /* Read primary GPT from device */
+ ret = mtd_read(mtd, offset, size, &retlen, *buf);
+ if (ret || (retlen != size)) {
+ printf("*** ERROR: Can't read primary GPT ***\n");
+ return -1;
+ }
+
+ /* determine start of GPT Header & Entries in the buffer */
+ gpt_h = *buf + (1 * MTD_LBA_SIZE);
+ gpt_e = *buf + (2 * MTD_LBA_SIZE);
+ my_lba = lldiv(offset, MTD_LBA_SIZE) + GPT_PRIMARY_PARTITION_TABLE_LBA;
+
+ if (!validate_gpt_header(gpt_h, my_lba, lba) &&
+    !validate_gpt_entries(gpt_h, gpt_e)) {
+ *pgpt_head = gpt_h;
+ *pgpt_pte = gpt_e;
+ return 0;
+ }
+
+ return -1;
+}
+
+static int is_secondary_gpt_valid_mtd(struct mtd_info *mtd,
+      lbaint_t lba,
+      void **buf,
+      gpt_header **pgpt_head,
+      gpt_entry **pgpt_pte)
+{
+ gpt_header *gpt_h;
+ gpt_entry *gpt_e;
+ uint32_t size;
+ uint64_t offset;
+ int ret;
+ size_t retlen;
+ lbaint_t my_lba;
+ u32 gpt_e_size = PAD_SIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
+  MTD_LBA_SIZE);
+
+ size = gpt_e_size + 2 * MTD_LBA_SIZE;
+ /* skip bad block */
+ offset = mtd->size;
+ while (mtd_block_isbad(mtd, offset - mtd->erasesize)) {
+ offset -= mtd->erasesize;
+ printf("bad block at 0x%llx\n", offset);
+ if (offset <= mtd->erasesize) {
+ printf("*** ERROR: too many bad block ***\n");
+ return -1;
+ }
+ }
+
+ /* Read backup GPT from device : end of the last valid block */
+ size = gpt_e_size + MTD_LBA_SIZE;
+
+ debug("backup offset = 0x%llx\n", offset - size);
+ ret = mtd_read(mtd, offset - size, size, &retlen, *buf);
+ if (ret || (retlen != size)) {
+ printf("*** ERROR: Can't read backup GPT ***\n");
+ return -1;
+ }
+
+ /* determine start of GPT Header & Entries in the buffer */
+ gpt_h = *buf + gpt_e_size;
+ gpt_e = *buf;
+ my_lba = lldiv(offset, MTD_LBA_SIZE) - 1;
+
+ if (!validate_gpt_header(gpt_h, my_lba, lba) &&
+    !validate_gpt_entries(gpt_h, gpt_e)) {
+ *pgpt_head = gpt_h;
+ *pgpt_pte = gpt_e;
+ return 0;
+ }
+
+ return -1;
+}
+
+static int is_gpt_valid_mtd(struct mtd_info *mtd,
+    void **buf,
+    gpt_header **pgpt_head,
+    gpt_entry **pgpt_pte)
+{
+ u32 gpt_e_size = PAD_SIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
+  MTD_LBA_SIZE);
+ lbaint_t lba;
+
+ if (!mtd || !pgpt_head || !pgpt_pte) {
+ printf("%s: Invalid Argument(s)\n", __func__);
+ return 0;
+ }
+
+ *pgpt_head = NULL;
+ *pgpt_pte = NULL;
+ *buf = malloc(gpt_e_size + 2 * MTD_LBA_SIZE);
+ if (!buf)
+ return -ENOMEM;
+
+ lba = lldiv(mtd->size, MTD_LBA_SIZE);
+ if (!is_primary_gpt_valid_mtd(mtd, lba, buf, pgpt_head, pgpt_pte))
+ return 1;
+
+ printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
+
+ if (!is_secondary_gpt_valid_mtd(mtd, lba, buf, pgpt_head, pgpt_pte)) {
+ printf("%s: *** Using Backup GPT ***\n", __func__);
+ return 1;
+ }
+ printf("%s: *** ERROR: Invalid Backup GPT ***\n", __func__);
+
+ free(*buf);
+
+ return 0;
+}
+
+static int gpt_fill_header_mtd(struct mtd_info *mtd, gpt_header *gpt_h,
+       char *str_guid, int parts_count)
+{
+ uint32_t erasesize;
+ uint64_t offset_p_gpt, offset_s_gpt;
+ __le64 my_lba;
+ __le64 alternate_lba;
+ u32 gpt_e_size = PAD_SIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
+  MTD_LBA_SIZE);
+
+ /* one mtd block is not enought for MBR and GPT */
+ if ((gpt_e_size + 2 * MTD_LBA_SIZE) > mtd->erasesize)
+ return -1;
+
+ erasesize = lldiv(mtd->erasesize, MTD_LBA_SIZE);
+
+ /* GPT location : skip bad block */
+ offset_p_gpt = 0;
+ while (mtd_block_isbad(mtd, offset_p_gpt)) {
+ printf("bad block at 0x%llx\n", offset_p_gpt);
+ offset_p_gpt += mtd->erasesize;
+ if (offset_p_gpt >= mtd->size)
+ return -1;
+ }
+ /* primary GPT : 17 first LBA of last good block */
+ my_lba = lldiv(offset_p_gpt, MTD_LBA_SIZE) + 1;
+
+ offset_s_gpt = mtd->size;
+ while (mtd_block_isbad(mtd, offset_s_gpt - mtd->erasesize)) {
+ offset_s_gpt -= mtd->erasesize;
+ printf("bad block at 0x%llx\n", offset_s_gpt);
+ if (offset_s_gpt <= mtd->erasesize)
+ return -1;
+ }
+ /* secondary GPT : 16 LBA of last good block */
+ alternate_lba = lldiv(offset_s_gpt, MTD_LBA_SIZE) - 1;
+
+ /* only one good block (primary and secondary on same block) */
+ if (offset_p_gpt == ((offset_s_gpt - mtd->erasesize)))
+ return -1;
+
+ gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
+ gpt_h->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
+ gpt_h->header_size = cpu_to_le32(sizeof(gpt_header));
+ gpt_h->my_lba = cpu_to_le64(my_lba);
+ gpt_h->alternate_lba = cpu_to_le64(alternate_lba);
+ gpt_h->first_usable_lba = cpu_to_le64(my_lba - 1 + erasesize);
+ gpt_h->last_usable_lba = cpu_to_le64(alternate_lba - erasesize);
+ gpt_h->partition_entry_lba = cpu_to_le64(my_lba + 1);
+ gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
+ gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry));
+ gpt_h->header_crc32 = 0;
+ gpt_h->partition_entry_array_crc32 = 0;
+
+ if (uuid_str_to_bin(str_guid, gpt_h->disk_guid.b, UUID_STR_FORMAT_GUID))
+ return -1;
+
+ return 0;
+}
+
+static int mtd_erase_write_block(struct mtd_info *mtd,
+ uint64_t offset,
+ void *buf,
+ size_t len)
+{
+ struct erase_info erase;
+ int ret;
+ size_t retlen;
+ u_char *verify_buf;
+
+ erase.mtd = mtd;
+ erase.len  = mtd->erasesize;
+ erase.addr = offset & ~(mtd->erasesize - 1); /* aligned erase offset */
+ erase.callback = NULL;
+
+ debug(" erase at 0x%llx\n", erase.addr);
+ ret = mtd_erase(mtd, &erase);
+ if (ret != 0) {
+ printf("** mark bad block 0x%llx on MTD device %s **\n",
+       erase.addr, mtd->name);
+ ret = mtd_block_markbad(mtd, erase.addr);
+ if (ret)
+ error("cannot mark bad at offset 0x%llx, error %d",
+      offset, ret);
+ return -1;
+ }
+
+ /* mtd write */
+ ret = mtd_write(mtd, offset, len, &retlen, buf);
+ if (ret != 0) {
+ error("Write error %d\n", ret);
+ return ret;
+ }
+
+ verify_buf = malloc(len);
+ if (!verify_buf)
+ return -ENOMEM;
+
+ ret = mtd_read(mtd, offset, len, &retlen, verify_buf);
+ if (ret) {
+ error("Read failed 0x%x, %d\n", (u32)offset, ret);
+ free(verify_buf);
+ return ret;
+ }
+
+ if (memcmp(buf, verify_buf, len)) {
+ error("Verify failed at 0x%x\n", (u32)offset);
+ return -EIO;
+ }
+
+ free(verify_buf);
+
+ return 0;
+}
+
+static void prepare_mbr_gpt_header_mtd(void *buf,
+       struct mtd_info *mtd,
+       gpt_header *gpt_h,
+       gpt_entry *gpt_e)
+{
+ legacy_mbr *p_mbr = buf;
+ u32 calc_crc32;
+
+ /* Generate CRC for the Primary GPT Header */
+ calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
+      le32_to_cpu(gpt_h->num_partition_entries) *
+      le32_to_cpu(gpt_h->sizeof_partition_entry));
+ gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32);
+
+ calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
+      le32_to_cpu(gpt_h->header_size));
+ gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
+
+ /* Setup the Protective MBR */
+ p_mbr->signature = MSDOS_MBR_SIGNATURE;
+ p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
+ p_mbr->partition_record[0].start_sect = 1;
+ p_mbr->partition_record[0].nr_sects = (u32) lldiv(mtd->size,
+      MTD_LBA_SIZE) - 1;
+}
+
+static int write_gpt_table_mtd(struct mtd_info *mtd,
+       gpt_header *gpt_h,
+       gpt_entry *gpt_e)
+{
+ const int pte_blk_cnt = PAD_COUNT((gpt_h->num_partition_entries
+   * sizeof(gpt_entry)), MTD_LBA_SIZE);
+ uint64_t offset;
+ void *buf;
+ u32 gpt_e_size = PAD_SIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
+  MTD_LBA_SIZE);
+ u32 buf_size, p_size, s_size;
+
+ p_size = gpt_e_size + 2 * MTD_LBA_SIZE;
+ s_size = roundup(gpt_e_size + MTD_LBA_SIZE, mtd->writesize);
+ buf_size = max(p_size, s_size);
+ buf = malloc(buf_size);
+ if (!buf)
+ return -ENOMEM;
+
+ memset(buf, 0x0, p_size);
+
+ prepare_mbr_gpt_header_mtd(buf, mtd, gpt_h, gpt_e);
+
+ /* GPT Header (1 block) */
+ memcpy(buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * MTD_LBA_SIZE),
+       gpt_h, sizeof(*gpt_h));
+ memcpy(buf + ((GPT_PRIMARY_PARTITION_TABLE_LBA + 1) * MTD_LBA_SIZE),
+       gpt_e, sizeof(gpt_entry) * pte_blk_cnt);
+
+ offset = ALIGN(le64_to_cpu(gpt_h->my_lba -
+   GPT_PRIMARY_PARTITION_TABLE_LBA)
+       * MTD_LBA_SIZE,
+       mtd->erasesize);
+
+ debug("primary offset = 0x%llx\n", offset);
+
+ if (mtd_erase_write_block(mtd, offset, buf, p_size))
+ goto err;
+
+ prepare_backup_gpt_header(gpt_h, pte_blk_cnt);
+
+ memset(buf, 0x0, s_size);
+
+ offset = (le64_to_cpu(gpt_h->my_lba) + 1) * MTD_LBA_SIZE - s_size;
+ memcpy(buf + s_size - MTD_LBA_SIZE, gpt_h, sizeof(*gpt_h));
+ memcpy(buf + s_size - MTD_LBA_SIZE - gpt_e_size,
+       gpt_e, sizeof(gpt_entry) * pte_blk_cnt);
+
+ debug("backup offset = 0x%llx\n", offset);
+
+ if (mtd_erase_write_block(mtd, offset, buf, s_size))
+ goto err;
+
+ free(buf);
+ debug("GPT successfully written to MTD device!\n");
+
+ return 0;
+
+ err:
+ free(buf);
+ printf("** Can't write to MTD device %s **\n", mtd->name);
+
+ return -EIO;
+}
+
+/*
+ * Public Functions (include/part.h)
+ */
+int gpt_restore_mtd(struct mtd_info *mtd, char *str_disk_guid,
+    disk_partition_t *partitions, const int parts_count)
+{
+ int ret;
+ gpt_header *gpt_h = calloc(1, PAD_SIZE(sizeof(gpt_header),
+       MTD_LBA_SIZE));
+ gpt_entry *gpt_e;
+
+ if (gpt_h == NULL) {
+ printf("%s: calloc failed!\n", __func__);
+ return -ENOMEM;
+ }
+
+ gpt_e = calloc(1, PAD_SIZE(GPT_ENTRY_NUMBERS
+   * sizeof(gpt_entry),
+   MTD_LBA_SIZE));
+ if (gpt_e == NULL) {
+ printf("%s: calloc failed!\n", __func__);
+ free(gpt_h);
+ return -ENOMEM;
+ }
+
+ /* Generate Primary GPT header (LBA1) */
+ ret = gpt_fill_header_mtd(mtd, gpt_h, str_disk_guid, parts_count);
+ if (ret)
+ goto err;
+
+ /* Generate partition entries */
+ ret = gpt_fill_pte(gpt_h, gpt_e, partitions, parts_count);
+ if (ret)
+ goto err;
+
+ /* Write GPT partition table */
+ ret = write_gpt_table_mtd(mtd, gpt_h, gpt_e);
+
+err:
+ free(gpt_e);
+ free(gpt_h);
+
+ return ret;
+}
+
+void part_print_efi_mtd(struct mtd_info *mtd)
+{
+ void *buf;
+ gpt_header *gpt_head;
+ gpt_entry *gpt_pte;
+
+ if (!is_gpt_valid_mtd(mtd, &buf, &gpt_head, &gpt_pte))
+ return;
+
+ part_print_gpt(gpt_head, gpt_pte);
+
+ /* Remember to free buffer */
+ free(buf);
+}
+
+int part_get_info_efi_mtd(struct mtd_info *mtd, int part,
+  disk_partition_t *info)
+{
+ void *buf;
+ gpt_header *gpt_head;
+ gpt_entry *gpt_pte;
+
+ if (!mtd || !info || part < 1) {
+ printf("%s: Invalid Argument(s)\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!is_gpt_valid_mtd(mtd, &buf, &gpt_head, &gpt_pte))
+ return -1;
+
+ if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
+    !is_pte_valid(&gpt_pte[part - 1])) {
+ debug("%s: *** ERROR: Invalid partition number %d ***\n",
+      __func__, part);
+ free(buf);
+ return -EINVAL;
+ }
+
+ part_get_disk_info(part, MTD_LBA_SIZE, gpt_pte, info);
+
+ /* Remember to free buffer */
+ free(buf);
+
+ return 0;
+}
diff --git a/doc/README.gpt.mtd b/doc/README.gpt.mtd
new file mode 100644
index 0000000..326b8f8
--- /dev/null
+++ b/doc/README.gpt.mtd
@@ -0,0 +1,187 @@
+#
+#
+# SPDX-License-Identifier: GPL-2.0+
+
+Glossary:
+========
+- GPT (GUID Partition Table) - it is the EFI standard part
+- MTD (Memory Technology Device) - abstraction layer for RAW flah device
+
+Introduction:
+=============
+This document describes the GPT support on MTD and usage of
+the associated command in U-Boot.
+
+The GPT is normally defined only for block device with built-in controller
+which manage flash translation layer (FTL) as MMC, SD, USB or ATA.
+
+For raw flash device, the MTD partionning are usally defined in U-Boot
+environment and provided to kernel (see mtdparts command).
+
+U-Boot support GPT for MTD device to save the partition informations of
+raw flash device directly in this device (usefull for CONFIG_ENV_IS_NOWHERE)
+and to use these informations to support MTD devices in DISTRO without
+hardcoded MTD partitioning in U-Boot environment
+
+The GPT support on top of MTD is defined under CONFIG_EFI_PARTITION_MTD.
+
+GPT on MTD brief explanation:
+=============================
+
+The GPT standard is respected (header and field meaning).
+
+The GPT header and each partition need to be eraseblock-align to allow
+individual udpate for header or partiton.
+
+The primary and the backup GPT header are located in the first and
+the last -not bad- eraseblock.
+
+We assume that one eraseblock is enought for MBR and GPT header
+(size = 17 KB for 128 entry)
+
+So it not compatible with the feature CONFIG_SPI_FLASH_USE_4K_SECTORS
+
+ Layout:
+ -------
+
+ ----------------------------------------------------------
+ LBA 0-33       |Protective MBR + Primary GPT     | 1rst eraseblock
+ --------------------------------------------------
+ LBA 34       | (not used)                      |
+ LBA N-1       |                                 |
+ ----------------------------------------------------------
+ LBA N          |Partition 1                      | 2nd eraseblock
+               |                                 | = first usable
+               -----------------------------------
+               |Partition 2                      |
+               |                                 |
+                ----------------------------------- last-1 eraseblock
+ LBA M       |Partition n                      | = last usable
+ ----------------------------------------------------------
+ LBA M+1       | (not used)                      | last eraseblock
+ LBA -35       |                                 |
+ --------------------------------------------------
+ LBA -1 to -34  |Backup GPT Header                |
+ ----------------------------------------------------------
+
+ NB: this layout change (LBA0 and LBA-1) if bad block are present
+
+ GPT header:
+ -----------
+
+ for details of GPT header, see README.gpt
+
+ "Current LBA" and "Backup LBA" give the location of the primary and
+ secondary GPT header.
+
+ All the bad block are detected and skipped when the GPT header is build.
+
+ For Primary GPT:
+
+ - Current LBA = 2nd LBA of the first good eraseblock
+
+ - Backup LBA = Last LBA of the last good block
+
+ - First usable LBA = First LBA of the first usable eraseblock
+                     i.e. the block after primary GPT one
+                     Current LBA - 1 + erase block size
+
+ - Last usable LBA = Last LBA of the last usable eraseblock
+                    i.e. the block before backup GPT one
+                    Backup LBA - erase block size
+
+ Bad Block management (NAND):
+ ---------------------------
+ As the bad blocks are skipped, Current LBA and Backup LBA give the real
+ location of primary and backup GPT header
+
+ warning: the first and the last usable LBA are not guarantee
+         to be in a good block
+
+
+ Typically, the last 4 erase blocks for NAND are used for the bad block
+ table (BBT, see bbt_options and NAND_BBT_USE_FLASH).
+ They are indicated bad by MTD framework and they are also skipped.
+ So the layout for NAND with bad :
+
+ NAND layout with bad blocks:
+ ----------------------------------------------------------
+ N * BAD (*)   |                                 | skipped bad
+ -----------------------------------------------------------
+               |Protective MBR                   | 1rst good eraseblock
+               |Primary GPT Header               |
+               |                                 |
+               -------------------------------------------
+               |                                 | = first usable
+               |                                 |
+               |  Partitions                     |
+               |                                 |
+               |                                 | = last usable
+               -------------------------------------------
+               |                                 |
+               |Backup GPT Header                | last good eraseblock
+ ----------------------------------------------------------
+ M * BAD (*)    |                                 | skipped bad
+ ----------------------------------------------------------
+ BBT => BAD (*) |                                 | skipped 4 blocks
+ ----------------------------------------------------------
+ (*) BBT and block marked bad are skipped
+
+
+Drawbacks:
+==========
+1.  2 eraseblocks are used in the device just to save the GPT headers
+    (primary and backup)
+
+2.  for device with back block (NAND), any read request can disturb the device
+    so the GPT header should be refreshed when one fixable bit-flip ECC error is
+    detected...
+    but it is not the case today
+
+3.  for gpt write the eraseblock for the primary or backup GPT header
+    (expected good) can become bad for the erase request
+
+    And then U-Boot will mark this block bad
+
+    In this case the first / last usable LBA need to change and to skip the new
+    bad block, so header need to be recomputed
+    => the requested gpt write command failed to force new request
+       PS: the next request will work (skip the new bad block)
+
+    And as the first / last usable LBA can change the same partionning after
+    the block is marked bad
+
+GPT on MTD commands:
+====================
+some command are modified to support GPT on MTD devices under CONFIG_EFI_PARTITION_MTD
+
+ Creating GPT on MTD partitions:
+ -------------------------------
+
+ 1. Define partition layout in the environment.
+     "partitions=uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
+ name=kernel,size=60MiB,uuid=...;"
+
+ 2. From U-Boot prompt type:
+   gpt write nand 0 $partitions
+   gpt write nor 0 $partitions
+
+ List GPT partition on MTD:
+ ---------------------------------
+ part list nand 0
+ part list nor 0
+
+ to find bootable partition (used for distro):
+
+ part list nand 0 -bootable nand_boot_part
+ part list nor 0 -bootable nor_boot_part
+
+ NB: bootable partition can be used with UBIFS
+
+ Generate MTD partitions from GPT:
+ ---------------------------------
+ mtdparts gpt nand0
+ mtdparts gpt nor0
+
+ Then to check mtd partition created with:
+ mtdparts
diff --git a/include/part.h b/include/part.h
index b6d1b33..8896b5c 100644
--- a/include/part.h
+++ b/include/part.h
@@ -311,7 +311,6 @@ int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
  */
 int gpt_restore(struct blk_desc *dev_desc, char *str_disk_guid,
  disk_partition_t *partitions, const int parts_count);
-
 /**
  * is_valid_gpt_buf() - Ensure that the Primary GPT information is valid
  *
@@ -366,7 +365,46 @@ int gpt_verify_headers(struct blk_desc *dev_desc, gpt_header *gpt_head,
 int gpt_verify_partitions(struct blk_desc *dev_desc,
   disk_partition_t *partitions, int parts,
   gpt_header *gpt_head, gpt_entry **gpt_pte);
-#endif
+
+#ifdef CONFIG_EFI_PARTITION_MTD
+
+struct mtd_info;
+
+#define MTD_LBA_SIZE 512
+/**
+ * gpt_restore_mtd() - Restore GPT partition table on MTD device
+ *
+ * @param mtd - mtd device descriptor
+ * @param str_disk_guid - disk GUID
+ * @param partitions - list of partitions
+ * @param parts_count - number of partitions
+ *
+ * @return - '0' on success, otherwise error
+ */
+int gpt_restore_mtd(struct mtd_info *mtd, char *str_disk_guid,
+    disk_partition_t *partitions, const int parts_count);
+
+/*
+ * part_print_efi() - display GPT Partition information for MTD device
+ *
+ * @param mtd_info - pointer to MTD device descriptor
+ */
+void part_print_efi_mtd(struct mtd_info *mtd_info);
+
+/*
+ * part_get_info_efi_mtd() - extract partition information for one GPT entry
+ *                           for a MTD device
+ *
+ * @param mtd_info - pointer to MTD device descriptor
+ * @param part - index of entry in gpt_pte
+ * @param gpt_pte - pointer to disk partition (output)
+ *
+ * @return - '0' on success, otherwise error
+ */
+int part_get_info_efi_mtd(struct mtd_info *mtd, int part,
+  disk_partition_t *info);
+#endif /* CONFIG_EFI_PARTITION_MTD */
+#endif /* CONFIG_EFI_PARTITION */
 
 #if CONFIG_IS_ENABLED(DOS_PARTITION)
 /**
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 08/18] cmd: gpt: remove blk_desc parameter in static function

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
this patch prepare GPT over MTD support
blk_desc is only available for block device but not for MTD device

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 cmd/gpt.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/cmd/gpt.c b/cmd/gpt.c
index 3e98821..5dfbce5 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -155,7 +155,8 @@ static bool found_key(const char *str, const char *key)
  * set_gpt_info(): Fill partition information from string
  * function allocates memory, remember to free!
  *
- * @param dev_desc - pointer block device descriptor
+ * @param lba - lba index
+ * @param blksz - block size for device
  * @param str_part - pointer to string with partition information
  * @param str_disk_guid - pointer to pointer to allocated string with disk guid
  * @param partitions - pointer to pointer to allocated partitions array
@@ -164,7 +165,8 @@ static bool found_key(const char *str, const char *key)
  * @return - zero on success, otherwise error
  *
  */
-static int set_gpt_info(struct blk_desc *dev_desc,
+static int set_gpt_info(unsigned int lba,
+ unsigned int blksz,
  const char *str_part,
  char **str_disk_guid,
  disk_partition_t **partitions,
@@ -179,8 +181,7 @@ static int set_gpt_info(struct blk_desc *dev_desc,
  uint64_t size_ll, start_ll;
  lbaint_t offset = 0;
 
- debug("%s:  lba num: 0x%x %d\n", __func__,
-      (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba);
+ debug("%s:  lba num: 0x%x %d\n", __func__, lba, lba);
 
  if (str_part == NULL)
  return -1;
@@ -298,7 +299,7 @@ static int set_gpt_info(struct blk_desc *dev_desc,
  parts[i].size = 0;
  } else {
  size_ll = ustrtoull(p, &p, 0);
- parts[i].size = lldiv(size_ll, dev_desc->blksz);
+ parts[i].size = lldiv(size_ll, blksz);
  }
 
  free(val);
@@ -309,7 +310,7 @@ static int set_gpt_info(struct blk_desc *dev_desc,
  if (extract_env(val, &p))
  p = val;
  start_ll = ustrtoull(p, &p, 0);
- parts[i].start = lldiv(start_ll, dev_desc->blksz);
+ parts[i].start = lldiv(start_ll, blksz);
  free(val);
  }
 
@@ -341,7 +342,7 @@ static int gpt_default(struct blk_desc *blk_dev_desc, const char *str_part)
  disk_partition_t *partitions = NULL;
 
  /* fill partitions */
- ret = set_gpt_info(blk_dev_desc, str_part,
+ ret = set_gpt_info(blk_dev_desc->lba, blk_dev_desc->blksz, str_part,
  &str_disk_guid, &partitions, &part_count);
  if (ret) {
  if (ret == -1)
@@ -372,7 +373,7 @@ static int gpt_verify(struct blk_desc *blk_dev_desc, const char *str_part)
  int ret = 0;
 
  /* fill partitions */
- ret = set_gpt_info(blk_dev_desc, str_part,
+ ret = set_gpt_info(blk_dev_desc->lba, blk_dev_desc->blksz, str_part,
  &str_disk_guid, &partitions, &part_count);
  if (ret) {
  if (ret == -1) {
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 09/18] cmd: gpt: use error number in set_gpt_info

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
-1 => -ENOENT : "No partition list provided"
-2 => -EBADF : "Missing disk guid"
-3 => -EFAULT &
-4 => -EINVAL : "Partition list incomplete"

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Christophe KERELLO <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 cmd/gpt.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/cmd/gpt.c b/cmd/gpt.c
index 5dfbce5..a36dbdf 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -184,7 +184,7 @@ static int set_gpt_info(unsigned int lba,
  debug("%s:  lba num: 0x%x %d\n", __func__, lba, lba);
 
  if (str_part == NULL)
- return -1;
+ return -ENOENT;
 
  str = strdup(str_part);
 
@@ -197,7 +197,7 @@ static int set_gpt_info(unsigned int lba,
  gen_rand_uuid_str(*str_disk_guid, UUID_STR_FORMAT_STD);
 #else
  free(str);
- return -2;
+ return -EBADF;
 #endif
  } else {
  val = strsep(&val, ";");
@@ -209,7 +209,7 @@ static int set_gpt_info(unsigned int lba,
  strsep(&s, ";");
  }
  if (strlen(s) == 0)
- return -3;
+ return -EFAULT;
 
  i = strlen(s) - 1;
  if (s[i] == ';')
@@ -240,7 +240,7 @@ static int set_gpt_info(unsigned int lba,
 #ifdef CONFIG_RANDOM_UUID
  gen_rand_uuid_str(parts[i].uuid, UUID_STR_FORMAT_STD);
 #else
- errno = -4;
+ errno = -EINVAL;
  goto err;
 #endif
  } else {
@@ -248,7 +248,7 @@ static int set_gpt_info(unsigned int lba,
  p = val;
  if (strlen(p) >= sizeof(parts[i].uuid)) {
  printf("Wrong uuid format for partition %d\n", i);
- errno = -4;
+ errno = -EINVAL;
  goto err;
  }
  strcpy((char *)parts[i].uuid, p);
@@ -264,7 +264,7 @@ static int set_gpt_info(unsigned int lba,
  if (strlen(p) >= sizeof(parts[i].type_guid)) {
  printf("Wrong type guid format for partition %d\n",
        i);
- errno = -4;
+ errno = -EINVAL;
  goto err;
  }
  strcpy((char *)parts[i].type_guid, p);
@@ -274,13 +274,13 @@ static int set_gpt_info(unsigned int lba,
  /* name */
  val = extract_val(tok, "name");
  if (!val) { /* name is mandatory */
- errno = -4;
+ errno = -EINVAL;
  goto err;
  }
  if (extract_env(val, &p))
  p = val;
  if (strlen(p) >= sizeof(parts[i].name)) {
- errno = -4;
+ errno = -EINVAL;
  goto err;
  }
  strcpy((char *)parts[i].name, p);
@@ -289,7 +289,7 @@ static int set_gpt_info(unsigned int lba,
  /* size */
  val = extract_val(tok, "size");
  if (!val) { /* 'size' is mandatory */
- errno = -4;
+ errno = -EINVAL;
  goto err;
  }
  if (extract_env(val, &p))
@@ -345,11 +345,11 @@ static int gpt_default(struct blk_desc *blk_dev_desc, const char *str_part)
  ret = set_gpt_info(blk_dev_desc->lba, blk_dev_desc->blksz, str_part,
  &str_disk_guid, &partitions, &part_count);
  if (ret) {
- if (ret == -1)
+ if (ret == -ENOENT)
  printf("No partition list provided\n");
- if (ret == -2)
+ if (ret == -EBADF)
  printf("Missing disk guid\n");
- if ((ret == -3) || (ret == -4))
+ if ((ret == -EFAULT) || (ret == -EINVAL))
  printf("Partition list incomplete\n");
  return -1;
  }
@@ -376,15 +376,15 @@ static int gpt_verify(struct blk_desc *blk_dev_desc, const char *str_part)
  ret = set_gpt_info(blk_dev_desc->lba, blk_dev_desc->blksz, str_part,
  &str_disk_guid, &partitions, &part_count);
  if (ret) {
- if (ret == -1) {
+ if (ret == -ENOENT) {
  printf("No partition list provided - only basic check\n");
  ret = gpt_verify_headers(blk_dev_desc, gpt_head,
  &gpt_pte);
  goto out;
  }
- if (ret == -2)
+ if (ret == -EBADF)
  printf("Missing disk guid\n");
- if ((ret == -3) || (ret == -4))
+ if ((ret == -EFAULT) || (ret == -EINVAL))
  printf("Partition list incomplete\n");
  return -1;
  }
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 10/18] cmd: gpt: add print_gpt_info_err

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
add a common function between gpt_default and gpt_verify
to display the error message associated to errno
the patch prepare GPT over MTD, as the same function will be reused

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Christophe KERELLO <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 cmd/gpt.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/cmd/gpt.c b/cmd/gpt.c
index a36dbdf..a634071 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -334,6 +334,21 @@ err:
  return errno;
 }
 
+/**
+ * print_gpt_info_err(): display error message for set_gpt_info()
+ *
+ * @param ret - value of the result
+ */
+static void print_gpt_info_err(int ret)
+{
+ if (ret == -ENOENT)
+ printf("No partition list provided\n");
+ if (ret == -EBADF)
+ printf("Missing disk guid\n");
+ if ((ret == -EFAULT) || (ret == -EINVAL))
+ printf("Partition list incomplete\n");
+}
+
 static int gpt_default(struct blk_desc *blk_dev_desc, const char *str_part)
 {
  int ret;
@@ -345,12 +360,7 @@ static int gpt_default(struct blk_desc *blk_dev_desc, const char *str_part)
  ret = set_gpt_info(blk_dev_desc->lba, blk_dev_desc->blksz, str_part,
  &str_disk_guid, &partitions, &part_count);
  if (ret) {
- if (ret == -ENOENT)
- printf("No partition list provided\n");
- if (ret == -EBADF)
- printf("Missing disk guid\n");
- if ((ret == -EFAULT) || (ret == -EINVAL))
- printf("Partition list incomplete\n");
+ print_gpt_info_err(ret);
  return -1;
  }
 
@@ -376,16 +386,12 @@ static int gpt_verify(struct blk_desc *blk_dev_desc, const char *str_part)
  ret = set_gpt_info(blk_dev_desc->lba, blk_dev_desc->blksz, str_part,
  &str_disk_guid, &partitions, &part_count);
  if (ret) {
+ print_gpt_info_err(ret);
  if (ret == -ENOENT) {
- printf("No partition list provided - only basic check\n");
  ret = gpt_verify_headers(blk_dev_desc, gpt_head,
  &gpt_pte);
  goto out;
  }
- if (ret == -EBADF)
- printf("Missing disk guid\n");
- if ((ret == -EFAULT) || (ret == -EINVAL))
- printf("Partition list incomplete\n");
  return -1;
  }
 
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 11/18] cmd: gpt: update write command to support GPT over MTD

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
support gpt write for MTD device
> gpt write nand 0
> gpt write nor 0

And verify is not yet supported for MTD device

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Christophe KERELLO <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 cmd/gpt.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 83 insertions(+), 4 deletions(-)

diff --git a/cmd/gpt.c b/cmd/gpt.c
index a634071..a40357a 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -19,6 +19,7 @@
 #include <linux/ctype.h>
 #include <div64.h>
 #include <memalign.h>
+#include <linux/mtd/mtd.h>
 
 /**
  * extract_env(): Expand env name from string format '&{env_name}'
@@ -405,6 +406,57 @@ static int gpt_verify(struct blk_desc *blk_dev_desc, const char *str_part)
  return ret;
 }
 
+#ifdef CONFIG_EFI_PARTITION_MTD
+/**
+ * gpt_default_mtd(): write GPT partition on MTD device
+ *
+ * @param mtd_info - pointer for MTD device descriptor
+ * @param str_part - pointer to string with partition information
+ *
+ * @return - zero on success, otherwise error
+ */
+static int gpt_default_mtd(struct mtd_info *mtd_info, const char *str_part)
+{
+ int ret;
+ char *str_disk_guid;
+ u8 part_count = 0;
+ disk_partition_t *partitions = NULL;
+ unsigned int lba = lldiv(mtd_info->size, MTD_LBA_SIZE);
+
+ if (!str_part)
+ return -1;
+
+ /* fill partitions */
+ ret = set_gpt_info(lba, MTD_LBA_SIZE, str_part,
+   &str_disk_guid, &partitions, &part_count);
+ if (ret) {
+ print_gpt_info_err(ret);
+ return -1;
+ }
+
+ /* save partitions layout to disk */
+ ret = gpt_restore_mtd(mtd_info, str_disk_guid, partitions, part_count);
+ free(str_disk_guid);
+ free(partitions);
+
+ return ret;
+}
+
+/**
+ * gpt_verify_mtd(): verify GPT partition on MTD device
+ *
+ * @param mtd_info - pointer for MTD device descriptor
+ * @param str_part - pointer to string with partition information
+ *
+ * @return - zero on success, otherwise error
+ */
+static int gpt_verify_mtd(struct mtd_info *mtd_info, const char *str_part)
+{
+ printf("Verify no yet supported for MTD device\n");
+ return CMD_RET_FAILURE;
+}
+#endif
+
 /**
  * do_gpt(): Perform GPT operations
  *
@@ -421,6 +473,10 @@ static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  int dev = 0;
  char *ep;
  struct blk_desc *blk_dev_desc = NULL;
+#ifdef CONFIG_EFI_PARTITION_MTD
+ struct mtd_info *mtd_info = NULL;
+ char mtd_dev[16];
+#endif
 
  if (argc < 4 || argc > 5)
  return CMD_RET_USAGE;
@@ -431,17 +487,40 @@ static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  return CMD_RET_USAGE;
  }
  blk_dev_desc = blk_get_dev(argv[2], dev);
- if (!blk_dev_desc) {
+ if (!blk_dev_desc)
+ ret = CMD_RET_FAILURE;
+#ifdef CONFIG_EFI_PARTITION_MTD
+ if (ret) {
+ ret = CMD_RET_SUCCESS;
+ sprintf(mtd_dev, "%s%d", argv[2], dev);
+ mtd_info = get_mtd_device_nm(mtd_dev);
+ if (IS_ERR(mtd_info))
+ ret = CMD_RET_FAILURE;
+ }
+#endif
+ if (ret) {
  printf("%s: %s dev %d NOT available\n",
        __func__, argv[2], dev);
- return CMD_RET_FAILURE;
+ return ret;
  }
 
  if ((strcmp(argv[1], "write") == 0) && (argc == 5)) {
  printf("Writing GPT: ");
- ret = gpt_default(blk_dev_desc, argv[4]);
+ ret = CMD_RET_FAILURE;
+ if (blk_dev_desc)
+ ret = gpt_default(blk_dev_desc, argv[4]);
+#ifdef CONFIG_EFI_PARTITION_MTD
+ if (mtd_info)
+ ret = gpt_default_mtd(mtd_info, argv[4]);
+#endif
  } else if ((strcmp(argv[1], "verify") == 0)) {
- ret = gpt_verify(blk_dev_desc, argv[4]);
+ ret = CMD_RET_FAILURE;
+ if (blk_dev_desc)
+ ret = gpt_verify(blk_dev_desc, argv[4]);
+#ifdef CONFIG_EFI_PARTITION_MTD
+ if (mtd_info)
+ ret = gpt_verify_mtd(mtd_info, argv[4]);
+#endif
  printf("Verify GPT: ");
  } else {
  return CMD_RET_USAGE;
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 12/18] cmd: part: update command to support GPT over MTD

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
support part list for MTD device
> part list nand 0
> part list nor 0

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 cmd/part.c | 49 +++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/cmd/part.c b/cmd/part.c
index 8ba0598..ef5d979 100644
--- a/cmd/part.c
+++ b/cmd/part.c
@@ -21,6 +21,7 @@
 #include <command.h>
 #include <part.h>
 #include <vsprintf.h>
+#include <linux/mtd/mtd.h>
 
 static int do_part_uuid(int argc, char * const argv[])
 {
@@ -48,10 +49,14 @@ static int do_part_uuid(int argc, char * const argv[])
 static int do_part_list(int argc, char * const argv[])
 {
  int ret;
- struct blk_desc *desc;
+ struct blk_desc *desc = NULL;
  char *var = NULL;
  bool bootable = false;
  int i;
+#ifdef CONFIG_EFI_PARTITION_MTD
+ struct mtd_info *mtd = NULL;
+ char mtd_dev[16];
+#endif
 
  if (argc < 2)
  return CMD_RET_USAGE;
@@ -77,10 +82,19 @@ static int do_part_list(int argc, char * const argv[])
  return CMD_RET_USAGE;
  }
 
- ret = blk_get_device_by_str(argv[0], argv[1], &desc);
- if (ret < 0)
- return 1;
-
+#ifdef CONFIG_EFI_PARTITION_MTD
+ if ((strlen(argv[0]) + strlen(argv[1])) < sizeof(mtd_dev)) {
+ sprintf(mtd_dev, "%s%s", argv[0], argv[1]);
+ mtd = get_mtd_device_nm(mtd_dev);
+ }
+ if (IS_ERR(mtd)) {
+#endif
+ ret = blk_get_device_by_str(argv[0], argv[1], &desc);
+ if (ret < 0)
+ return 1;
+#ifdef CONFIG_EFI_PARTITION_MTD
+ }
+#endif
  if (var != NULL) {
  int p;
  char str[512] = { '\0', };
@@ -88,10 +102,21 @@ static int do_part_list(int argc, char * const argv[])
 
  for (p = 1; p < 128; p++) {
  char t[5];
- int r = part_get_info(desc, p, &info);
+ int r;
 
- if (r != 0)
- continue;
+ if (desc) {
+ r = part_get_info(desc, p, &info);
+ if (r != 0)
+ continue;
+ }
+#ifdef CONFIG_EFI_PARTITION_MTD
+ else {
+ r = part_get_info_efi_mtd(mtd, p, &info);
+ /* Stop for first non valid partition */
+ if (r != 0)
+ break;
+ }
+#endif
 
  if (bootable && !info.bootable)
  continue;
@@ -100,10 +125,18 @@ static int do_part_list(int argc, char * const argv[])
  strcat(str, t);
  }
  setenv(var, str);
+
  return 0;
  }
 
+#ifndef CONFIG_EFI_PARTITION_MTD
  part_print(desc);
+#else
+ if (desc)
+ part_print(desc);
+ else
+ part_print_efi_mtd(mtd);
+#endif
 
  return 0;
 }
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 13/18] cmd: mtdparts: move PART_ADD_DESC_MAXLEN

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 cmd/mtdparts.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/cmd/mtdparts.c b/cmd/mtdparts.c
index 112bf1f..796bb98 100644
--- a/cmd/mtdparts.c
+++ b/cmd/mtdparts.c
@@ -108,6 +108,9 @@ DECLARE_GLOBAL_DATA_PTR;
  * field for read-only partitions */
 #define MTD_WRITEABLE_CMD 1
 
+/* max size for partition description */
+#define PART_ADD_DESC_MAXLEN 64
+
 /* default values for mtdids and mtdparts variables */
 #if !defined(MTDIDS_DEFAULT)
 #ifdef CONFIG_MTDIDS_DEFAULT
@@ -1985,7 +1988,6 @@ static int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc,
 
  /* mtdparts add <mtd-dev> <size>[@<offset>] <name> [ro] */
  if (((argc == 5) || (argc == 6)) && (strncmp(argv[1], "add", 3) == 0)) {
-#define PART_ADD_DESC_MAXLEN 64
  char tmpbuf[PART_ADD_DESC_MAXLEN];
 #if defined(CONFIG_CMD_MTDPARTS_SPREAD)
  struct mtd_info *mtd;
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 14/18] cmd: mtdparts: update command to support GPT over MTD

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
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 <[hidden email]>
Reviewed-by: Christophe KERELLO <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6: None
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
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 15/18] uuid: remove dependency with io.h

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
io.h is only used for CONFIG_RANDOM_UUID
- for clrsetbits_be16
- for clrsetbits_8
available only for some target (but not for SANDBOX)

Signed-off-by: Patrick Delaunay <[hidden email]>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 lib/uuid.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/lib/uuid.c b/lib/uuid.c
index 7ce822c..058b1c3 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -8,7 +8,6 @@
 #include <linux/ctype.h>
 #include <errno.h>
 #include <common.h>
-#include <asm/io.h>
 #include <part_efi.h>
 #include <malloc.h>
 
@@ -278,13 +277,13 @@ void gen_rand_uuid(unsigned char *uuid_bin)
  for (i = 0; i < sizeof(struct uuid) / sizeof(*ptr); i++)
  *(ptr + i) = cpu_to_be32(rand());
 
- clrsetbits_be16(&uuid.time_hi_and_version,
- UUID_VERSION_MASK,
- UUID_VERSION << UUID_VERSION_SHIFT);
+ /* UUID is big endian */
+ uuid.time_hi_and_version |= ~cpu_to_be16(UUID_VERSION_MASK);
+ uuid.time_hi_and_version &=
+ cpu_to_be16(UUID_VERSION << UUID_VERSION_SHIFT);
 
- clrsetbits_8(&uuid.clock_seq_hi_and_reserved,
-     UUID_VARIANT_MASK,
-     UUID_VARIANT << UUID_VARIANT_SHIFT);
+ uuid.clock_seq_hi_and_reserved |= ~UUID_VARIANT_MASK;
+ uuid.clock_seq_hi_and_reserved &= UUID_VARIANT << UUID_VARIANT_SHIFT;
 
  memcpy(uuid_bin, &uuid, sizeof(struct uuid));
 }
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 16/18] sandbox: GPT over MTD test

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
activate needed feature in sandbox to allow test GPT over MTD
- EFI_PARTITION_MTD
- SPI_FLASH_MTD
- CMD_MTDPARTS
- MTD_PARTITIONS
- MTD_DEVICE

activate 2 features usefull for test
- RANDOM_UUID
- PARTITION_TYPE_GUID

Signed-off-by: Patrick Delaunay <[hidden email]>
Reviewed-by: Simon Glass <[hidden email]>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 configs/sandbox_defconfig | 3 +++
 include/configs/sandbox.h | 6 ++++++
 2 files changed, 9 insertions(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index d3fee89..546f837 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -57,6 +57,8 @@ CONFIG_CMD_CRAMFS=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MAC_PARTITION=y
 CONFIG_AMIGA_PARTITION=y
+CONFIG_EFI_PARTITION_MTD=y
+CONFIG_PARTITION_TYPE_GUID=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_NETCONSOLE=y
@@ -110,6 +112,7 @@ CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_SST=y
 CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_DM_ETH=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 37c6132..5fe92b8 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -37,6 +37,12 @@
 #define CONFIG_EXT4_WRITE
 #define CONFIG_HOST_MAX_DEVICES 4
 
+#define CONFIG_RANDOM_UUID
+
+/* Dynamic MTD partition support */
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_MTD_DEVICE
 /*
  * Size of malloc() pool, before and after relocation
  */
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 17/18] distro: add boot for UBI in GPT over MTD

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
Now that we can expose boot for UBI partition on MTD devices
(NOR and NAND).

This patch adds the distro script to automatically
payloads from UBI volume called boot detected in a bootable partition
in GPT partition in the MTD device.

example to start from nor0 and nand0:

        func(EFIMTD, nor, 0) \
        func(EFIMTD, nand, 0)

Signed-off-by: Patrick Delaunay <[hidden email]>
---

Changes in v6:
- add distro support for UBI volume in GPT partition in MTD device

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 include/config_distro_bootcmd.h | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index 0e01e82..39584e0 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -68,6 +68,45 @@
  BOOT_TARGET_DEVICES_references_MMC_without_CONFIG_CMD_MMC
 #endif
 
+#ifdef CONFIG_EFI_PARTITION_MTD
+#define BOOTENV_SHARED_EFIMTD \
+ "scan_efi_mtd_for_ubi=" \
+ "mtdparts gpt ${mtddev}${devnum}; " \
+ "part list ${mtddev} ${devnum} -bootable devplist; " \
+ "env exists devplist || setenv devplist 1; " \
+ "for distro_bootpart in ${devplist}; do " \
+ "setexpr mtd_bootpart ${distro_bootpart} - 1;" \
+ "if ubi part ${mtddev}${devnum},${mtd_bootpart} &&" \
+ "   ubifsmount ubi0; then " \
+ "setenv devtype ubi; " \
+ "setenv distro_bootpart 0; " \
+ "run scan_dev_for_boot;" \
+ "ubi detach;" \
+ "fi;" \
+ "done\0" \
+ \
+ "nor_boot=" \
+ "if sf probe ${devnum}; then " \
+ "setenv mtddev nor;" \
+ "run scan_efi_mtd_for_ubi;" \
+ "fi\0" \
+ \
+ "nand_boot=" \
+ "if nand device ${devnum}; then " \
+ "setenv mtddev nand;" \
+ "run scan_efi_mtd_for_ubi;" \
+ "fi\0"
+
+#define BOOTENV_DEV_EFIMTD BOOTENV_DEV_BLKDEV
+#define BOOTENV_DEV_NAME_EFIMTD BOOTENV_DEV_NAME_BLKDEV
+#else
+#define BOOTENV_SHARED_EFIMTD
+#define BOOTENV_DEV_EFIMTD \
+ BOOT_TARGET_DEVICES_references_EFIMTD_without_CONFIG_EFI_PARTITION_MTD
+#define BOOTENV_DEV_NAME_EFIMTD \
+ BOOT_TARGET_DEVICES_references_EFIMTD_without_CONFIG_EFI_PARTITION_MTD
+#endif
+
 #ifdef CONFIG_CMD_UBIFS
 #define BOOTENV_SHARED_UBIFS \
  "ubifs_boot=" \
@@ -322,6 +361,7 @@
  BOOTENV_SHARED_IDE \
  BOOTENV_SHARED_UBIFS \
  BOOTENV_SHARED_EFI \
+ BOOTENV_SHARED_EFIMTD \
  "boot_prefixes=/ /boot/\0" \
  "boot_scripts=boot.scr.uimg boot.scr\0" \
  "boot_script_dhcp=boot.scr.uimg\0" \
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v6 18/18] tests: Add GPT over MTD test

Patrick DELAUNAY-2
In reply to this post by Patrick DELAUNAY-2
test/fs/gpt_mtd-test.sh
today only test for SF device (nor0)

Signed-off-by: Patrick Delaunay <[hidden email]>
---

Changes in v6:
- add sandbox test (test/fs/gpt_mtd-test.sh) for modified commands

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 test/fs/gpt_mtd-test.sh | 209 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 209 insertions(+)
 create mode 100755 test/fs/gpt_mtd-test.sh

diff --git a/test/fs/gpt_mtd-test.sh b/test/fs/gpt_mtd-test.sh
new file mode 100755
index 0000000..6cb2994
--- /dev/null
+++ b/test/fs/gpt_mtd-test.sh
@@ -0,0 +1,209 @@
+#!/bin/bash
+#
+# (C) Copyright 2017 Patrick Delaunay
+#
+#  SPDX-License-Identifier: GPL-2.0+
+#
+
+# Invoke this test script from U-Boot base directory as
+#      ./test/fs/gpt_mtd-test.sh
+# It currently tests the gpt over mtd support
+# Expected results are as follows:
+# Total Summary: TOTAL PASS: 7 TOTAL FAIL: 0
+
+# pre-requisite binaries list.
+PREREQ_BINS="dd "
+
+# Location of generated sandbox u-boot
+SANDBOX_DIR="sandbox"
+UBOOT="$SANDBOX_DIR/u-boot"
+
+# All generated output files from this test will be in $OUT_DIR
+# Hence everything is sandboxed.
+OUT_DIR="$SANDBOX_DIR/test/fs"
+
+# $OUT shall be the prefix of the test output. Their suffix will be .out
+OUT="${OUT_DIR}/fs-test"
+
+# DTB file to use
+DTB="$SANDBOX_DIR/arch/sandbox/dts/test.dtb"
+
+# ************************
+# * Functions start here *
+# ************************
+
+# Check if the prereq binaries exist, or exit
+function check_prereq() {
+ for prereq in $PREREQ_BINS; do
+ if [ ! -x "`which $prereq`" ]; then
+ echo "Missing $prereq binary. Exiting!"
+ exit
+ fi
+ done
+}
+
+# If 1st param is "clean", then clean out the generated files and exit
+function check_clean() {
+ if [ "$1" = "clean" ]; then
+ rm -rf "$OUT_DIR"
+ echo "Cleaned up generated files. Exiting"
+ exit
+ fi
+}
+
+# Generate sandbox U-Boot - gleaned from /test/dm/test-dm.sh
+function compile_sandbox() {
+ unset CROSS_COMPILE
+ NUM_CPUS=$(cat /proc/cpuinfo |grep -c processor)
+ make O=$SANDBOX_DIR sandbox_config
+ make O=$SANDBOX_DIR -s -j${NUM_CPUS}
+
+ # Check if U-Boot exists
+ if [ ! -x "$UBOOT" ]; then
+ echo "$UBOOT does not exist or is not executable"
+ echo "Build error?"
+ echo "Please run this script as ./test/fs/`basename $0`"
+ exit
+ fi
+}
+
+# Clean out all generated files other than the file system images
+# We save time by not deleting and recreating the file system images
+function prepare_env() {
+ dd if=/dev/zero of=spi.bin bs=1M count=4
+ mkdir -p ${OUT_DIR}
+}
+
+
+function test_gpt_mtd_nor() {
+
+ $UBOOT -d $DTB << EOF
+sf probe
+#
+# Test Case 1 - gpt write
+gpt write nor 0 "name=part1,size=64KiB;name=part2,type=system,size=128KiB;\
+name=boot,type=linux,bootable,size=512KiB"
+#
+# Test Case 2 - part list
+part list nor 0
+#
+# Test Case 3 - mtdparts
+setenv mtdids "nor0=nor0"
+setenv mtdparts "mtdparts="
+mtdparts gpt nor0
+mtdparts
+#
+# Test Case 4 - part list
+part list nor 0 -bootable boot_part
+printenv boot_part
+#
+# Test Case 5 - test filtering feature
+mtdparts delall
+setenv mtdparts "mtdparts="
+setenv mtdids "nor0=nor0"
+#
+# Test Case 5.1 - only add MTD for some guid = linux
+mtdparts gpt nor0 linux
+mtdparts
+#
+# Test Case 5.2 - then add MTD for some guid = data
+mtdparts gpt nor0 data
+mtdparts
+#
+# Test Case 5.3 - then add MTD for some guid = system
+mtdparts gpt nor0 system
+mtdparts
+#
+# Test Case 6.1 - check backup GPT header
+sf erase 0 0x10000
+part list nor 0
+# Test Case 6.2 - check backup GPT header
+sf erase 0x1F0000 0x10000
+part list nor 0
+#
+reset
+
+EOF
+}
+
+# 1st parameter is the text to print
+# if $? is 0 its a pass, else a fail
+# As a side effect it shall update env variable PASS and FAIL
+function pass_fail() {
+ if [ $? -eq 0 ]; then
+ echo pass - "$1"
+ PASS=$((PASS + 1))
+ else
+ echo FAIL - "$1"
+ FAIL=$((FAIL + 1))
+ fi
+}
+
+
+# 1st parameter is the name of the output file to check
+function check_results() {
+ echo "** Start $1"
+
+ PASS=0
+ FAIL=0
+
+ grep -A2 "Test Case 1 " "$1" | egrep -q "Writing GPT: success!"
+ pass_fail "TC1: gpt write"
+
+ grep -A6 "Test Case 2 " "$1" | egrep -q "part1"
+ pass_fail "TC2: part list"
+
+ grep -A7 "Test Case 3 " "$1" | egrep -q "parts = 3"
+ pass_fail "TC3: mtdparts"
+
+ grep -A4 "Test Case 4 " "$1" | egrep -q "boot_part=2 3"
+ pass_fail "TC4: part list"
+
+ grep -A4 "Test Case 5.1 " "$1" | egrep -q "parts = 1"
+ pass_fail "TC5.1: mtdparts gpt for linux"
+
+ grep -A4 "Test Case 5.2 " "$1" | egrep -q "parts = 2"
+ pass_fail "TC5.2: mtdparts gpt for data"
+
+ grep -A4 "Test Case 5.3 " "$1" | egrep -q "parts = 3"
+ pass_fail "TC5.2: mtdparts gpt for system"
+
+ grep -A6 "Test Case 6.1 " "$1" | egrep -q "Using Backup GPT"
+ pass_fail "TC6.1: check backup GPT use"
+
+ grep -A8 "Test Case 6.2 " "$1" | egrep -q "Invalid Backup GPT"
+ pass_fail "TC6.2: check backup GPT erase"
+
+ echo "** End $1"
+}
+
+# ********************
+# * End of functions *
+# ********************
+
+check_clean "$1"
+check_prereq
+compile_sandbox
+prepare_env
+
+# Track TOTAL_FAIL and TOTAL_PASS
+TOTAL_FAIL=0
+TOTAL_PASS=0
+
+OUT_FILE="${OUT}.sb.gpt_mtd_nor.out"
+test_gpt_mtd_nor > ${OUT_FILE} 2>&1
+
+check_results $OUT_FILE
+TOTAL_FAIL=$((TOTAL_FAIL + FAIL))
+TOTAL_PASS=$((TOTAL_PASS + PASS))
+
+
+echo "Total Summary: TOTAL PASS: $TOTAL_PASS TOTAL FAIL: $TOTAL_FAIL"
+echo "--------------------------------------------"
+if [ $TOTAL_FAIL -eq 0 ]; then
+ echo "PASSED"
+ exit 0
+else
+ echo "FAILED"
+ exit 1
+fi
--
1.9.1

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH v6 00/18] GPT over MTD

Maxime Ripard
In reply to this post by Patrick DELAUNAY-2
Hi,

On Thu, May 11, 2017 at 09:51:50AM +0200, Patrick Delaunay wrote:
> I have a request to support GPT over MTD to have the MTD informations
> without U-Boot environment(CONFIG_ENV_IS_NOWHERE is a other requirement
> of my project to manage several board configuration with
> the same defconfig; boot from NAND or NOR or SDCARD).

What would happen if you have a bad block in the middle of the primary
or secondary GPT headers (or both)?

Maxime

--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

_______________________________________________
U-Boot mailing list
[hidden email]
https://lists.denx.de/listinfo/u-boot

signature.asc (817 bytes) Download Attachment
12
Loading...