All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration
@ 2012-08-24  8:13 Lukasz Majewski
  2012-08-24  8:13 ` [U-Boot] [PATCH 1/6] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
                   ` (11 more replies)
  0 siblings, 12 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-08-24  8:13 UTC (permalink / raw)
  To: u-boot

This patch series provides a new command - "gpt" for eMMC partition table
(in the GPT format) restoration and display.

As a pre-work, some cleanup at the part_efi.c file was performed to 
remove custom macros and make GPT related structures more readable. 

The GPT detailed description has been written to README.gpt file.

Tested at:
	- Exynos4210 rev.1 - TRATS Samsung development board

Lukasz Majewski (6):
  gpt:doc: GPT (GUID Partition Table) documentation
  gpt: Replace the leXX_to_int() calls with ones defined at
    <compiler.h>
  gpt: Replacement of GPT structures members with ones indicating
    endianness and size
  gpt: Support for GPT (GUID Partition Table) restoration
  gpt: Support for new "gpt" command
  gpt: Enable support for GPT partition table restoration at Samsung's
    Trats

 common/Makefile         |    1 +
 common/cmd_gpt.c        |  182 ++++++++++++++++++++++++++
 disk/part_efi.c         |  334 +++++++++++++++++++++++++++++++++++++----------
 disk/part_efi.h         |   85 ++++++------
 doc/README.gpt          |  199 ++++++++++++++++++++++++++++
 include/configs/trats.h |   23 +++-
 include/part.h          |    2 +
 7 files changed, 715 insertions(+), 111 deletions(-)
 create mode 100644 common/cmd_gpt.c
 create mode 100644 doc/README.gpt

-- 
1.7.2.3

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot]  [PATCH 1/6] gpt:doc: GPT (GUID Partition Table) documentation
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
@ 2012-08-24  8:13 ` Lukasz Majewski
  2012-09-05 19:31   ` Stephen Warren
  2012-08-24  8:13 ` [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h> Lukasz Majewski
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-08-24  8:13 UTC (permalink / raw)
  To: u-boot

Documentation of the GPT table format.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 doc/README.gpt |  199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 199 insertions(+), 0 deletions(-)
 create mode 100644 doc/README.gpt

diff --git a/doc/README.gpt b/doc/README.gpt
new file mode 100644
index 0000000..0bdacf3
--- /dev/null
+++ b/doc/README.gpt
@@ -0,0 +1,199 @@
+#
+#  Copyright (C) 2012 Samsung Electronics
+#
+#  Lukasz Majewski <l.majewski@samsung.com>
+#
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+
+
+Glossary:
+========
+- UUID -(Universally Unique Identifier)
+- GUID - (Globally Unique ID)
+- EFI - (Extensible Firmware Interface)
+- UEFI - (Unified EFI) - EFI evolution
+- GPT (GUID Page Table) - it is the EFI standard part
+- partitions - lists of availavle partitions (defined at u-boot):
+  ./include/configs/{target}.h
+
+Introduction:
+=============
+This document describes the GPT partition table format when used with u-boot.
+
+
+UUID introduction[5]:
+====================
+
+GPT for marking disks/partitions is using the UUID. It is supposed to be a
+globally unique value. A UUID is a 16-byte (128-bit) number. The number of
+theoretically possible UUIDs is therefore about 3 ? 10^38.
+More often UUID is stored as 32 hexadecimal digits, displayed in 5 groups
+separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters
+(32 digits and 4 hyphens)
+
+For instance, GUID of Linux data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
+For u-boot GPT hyphens are omitted.
+
+Historically there are 5 methods to generate this number. The oldest one is
+combining machine's MAC address and timer (epoch) value.
+
+Successive versions are using MD5 hash, random numbers and SHA-1 hash. All major
+OSes and programming languages are providing libraries to compute UUID.
+
+However it costs in terms of the computational power and memory footprint.
+Therefore u-boot uses the crc32 with reading random block (512B) from MMC
+storage device to generate UUID/GUID.
+
+
+GUID brief explanation:
+======================
+
+	Layout:
+	-------
+
+	--------------------------------------------------
+	LBA 0          |Protective MBR                   |
+	----------------------------------------------------------
+	LBA 1          |Primary GPT Header               | Primary
+	-------------------------------------------------- GPT
+	LBA 2          |Entry 1|Entry 2| Entry 3| Entry 4|
+	--------------------------------------------------
+	LBA 3          |Entries 5 - 128                  |
+		       |                                 |
+		       |                                 |
+       -----------------------------------------------------------
+       LBA 34          |Partition 1                      |
+		       |                                 |
+		       -----------------------------------
+		       |Partition 2                      |
+		       |                                 |
+		       -----------------------------------
+		       |Partition n                      |
+		       |                                 |
+       -----------------------------------------------------------
+       LBA -34         |Entry 1|Entry 2| Entry 3| Entry 4| Secondary
+       --------------------------------------------------- (bkp)
+       LBA 34          |Partition 1                      |
+		       |                                 |
+		       -----------------------------------
+		       |Partition 2                      |
+		       |                                 |
+		       -----------------------------------
+		       |Partition n                      |
+		       |                                 |
+       -----------------------------------------------------------
+       LBA -34         |Entry 1|Entry 2| Entry 3| Entry 4| Secondary
+       --------------------------------------------------- (bkp)
+       LBA -33         |Entries 5 - 128                  | GPT
+		       |                                 |
+		       |                                 |
+       LBA -2          |                                 |
+       ---------------------------------------------------
+       LBA -1          |Secondary GPT Header             |
+       -----------------------------------------------------------
+
+
+For a legacy reasons, GPT's LBA 0 sector has a MBR structure. It is called
+"protective MBR".
+Its first partition entry ID has 0xEE value, and disk software, which is not
+handling the GPT sees it as a storage device without free space.
+
+It is possible to define 128 lineary placed partition entries.
+
+"LBA -1" means the last addressable block (in the mmc subsystem:
+"dev_desc->lba - 1")
+
+Primary/Secondary GPT header:
+----------------------------
+Offset  Size    Description
+
+0       8 B     Signature ("EFI PART", 45 46 49 20 50 41 52 54)
+8       4 B     Revision (For version 1.0, the value is 00 00 01 00)
+12      4 B     Header size (in bytes, usually 5C 00 00 00 meaning 92 bytes)
+16      4 B     CRC32 of header (0 to header size), with this field zeroed
+		during calculation
+20      4 B     Reserved (ZERO);
+24      8 B     Current LBA (location of this header copy)
+32      8 B     Backup LBA (location of the other header copy)
+40      8 B     First usable LBA for partitions (primary partition table last
+		LBA + 1)
+48      8 B     Last usable LBA (secondary partition table first LBA - 1)
+56      16 B    Disk GUID (also referred as UUID on UNIXes)
+72      8 B     Partition entries starting LBA (always 2 in primary copy)
+80      4 B     Number of partition entries
+84      4 B     Size of a partition entry (usually 128)
+88      4 B     CRC32 of partition array
+92      *       Reserved; must be ZERO (420 bytes for a 512-byte LBA)
+
+TOTAL: 512 B
+
+
+
+IMPORTANT:
+
+GPT headers and partition entries are protected by CRC32 (the POSIX CRC32).
+
+Primary GPT header and Secondary GPT header have swapped values of "Current LBA"
+and "Backup LBA" and therefore different CRC32 check-sum.
+
+CRC32 for GPT headers (field "CRC of header") are calculated up till
+"Header size" (92), NOT 512 bytes.
+
+CRC32 for partition entries (field "CRC32 of partition array") is calculated for
+the whole array entry ( Number_of_partition_entries *
+sizeof(partition_entry_size (usually 128)))
+
+Observe, how Secondary GPT is placed in the memory. It is NOT a mirror reflect
+of the Primary.
+
+
+	   Partition Entry Format:
+	   ----------------------
+	   Offset  Size    Description
+
+	   0       16 B    Partition type GUID
+	   16      16 B    Unique partition GUID
+	   32      8  B    First LBA (Little Endian)
+	   40      8  B    Last LBA (inclusive)
+	   48      8  B    Attribute flags [+]
+	   56      72 B    Partition name (text)
+
+	   Attribute flags (Don't used at u-boot):
+	   Bit 0  - System partition
+	   Bit 60 - Read-only
+	   Bit 62 - Hidden
+	   Bit 63 - Not mount
+
+
+
+Useful info:
+============
+
+Two programs, namely: 'fdisk' and 'parted' are recommended to work with GPT
+recovery. Parted is able to handle GUID partitions. Unfortunately the 'fdisk'
+hasn't got such ability.
+Please, pay attention at -l switch for parted.
+
+
+Problems with current implementation:
+====================================
+
+1. Entropy of the u-boot's current GUID generation is only sufficient for an
+emergency situations.
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h>
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
  2012-08-24  8:13 ` [U-Boot] [PATCH 1/6] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
@ 2012-08-24  8:13 ` Lukasz Majewski
  2012-09-05 19:35   ` Stephen Warren
  2012-09-05 19:45   ` Stephen Warren
  2012-08-24  8:13 ` [U-Boot] [PATCH 3/6] gpt: Replacement of GPT structures members with ones indicating endianness and size Lukasz Majewski
                   ` (9 subsequent siblings)
  11 siblings, 2 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-08-24  8:13 UTC (permalink / raw)
  To: u-boot

Custom definitions of le_XX_to_int functions have been replaced with
standard ones, defined at <compiler.h>

Signed-off-by: Chang Hyun Park <chchch.park@samsung.com>
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 disk/part_efi.c |  109 ++++++++++++++++++++-----------------------------------
 1 files changed, 40 insertions(+), 69 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index 02927a0..86e7f33 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -44,34 +44,6 @@
     defined(CONFIG_MMC) || \
     defined(CONFIG_SYSTEMACE)
 
-/* Convert char[2] in little endian format to the host format integer
- */
-static inline unsigned short le16_to_int(unsigned char *le16)
-{
-	return ((le16[1] << 8) + le16[0]);
-}
-
-/* Convert char[4] in little endian format to the host format integer
- */
-static inline unsigned long le32_to_int(unsigned char *le32)
-{
-	return ((le32[3] << 24) + (le32[2] << 16) + (le32[1] << 8) + le32[0]);
-}
-
-/* Convert char[8] in little endian format to the host format integer
- */
-static inline unsigned long long le64_to_int(unsigned char *le64)
-{
-	return (((unsigned long long)le64[7] << 56) +
-		((unsigned long long)le64[6] << 48) +
-		((unsigned long long)le64[5] << 40) +
-		((unsigned long long)le64[4] << 32) +
-		((unsigned long long)le64[3] << 24) +
-		((unsigned long long)le64[2] << 16) +
-		((unsigned long long)le64[1] << 8) +
-		(unsigned long long)le64[0]);
-}
-
 /**
  * efi_crc32() - EFI version of crc32 function
  * @buf: buffer to calculate crc32 of
@@ -79,7 +51,7 @@ static inline unsigned long long le64_to_int(unsigned char *le64)
  *
  * Description: Returns EFI-style CRC32 value for @buf
  */
-static inline unsigned long efi_crc32(const void *buf, unsigned long len)
+static inline u32 efi_crc32(const void *buf, u32 len)
 {
 	return crc32(0, buf, len);
 }
@@ -137,13 +109,13 @@ void print_part_efi(block_dev_desc_t * dev_desc)
 	debug("%s: gpt-entry@%p\n", __func__, gpt_pte);
 
 	printf("Part\tName\t\t\tStart LBA\tEnd LBA\n");
-	for (i = 0; i < le32_to_int(gpt_head->num_partition_entries); i++) {
+	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
 
 		if (is_pte_valid(&gpt_pte[i])) {
 			printf("%3d\t%-18s\t0x%08llX\t0x%08llX\n", (i + 1),
 				print_efiname(&gpt_pte[i]),
-				le64_to_int(gpt_pte[i].starting_lba),
-				le64_to_int(gpt_pte[i].ending_lba));
+			       (u64) le64_to_cpu(gpt_pte[i].starting_lba),
+			       (u64) le64_to_cpu(gpt_pte[i].ending_lba));
 		} else {
 			break;	/* Stop at the first non valid PTE */
 		}
@@ -174,9 +146,9 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 	}
 
 	/* The ulong casting limits the maximum disk size to 2 TB */
-	info->start = (ulong) le64_to_int(gpt_pte[part - 1].starting_lba);
+	info->start = (u64) le64_to_cpu(gpt_pte[part - 1].starting_lba);
 	/* The ending LBA is inclusive, to calculate size, add 1 to it */
-	info->size = ((ulong)le64_to_int(gpt_pte[part - 1].ending_lba) + 1)
+	info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
 		     - info->start;
 	info->blksz = GPT_BLOCK_SIZE;
 
@@ -215,7 +187,7 @@ int test_part_efi(block_dev_desc_t * dev_desc)
 static int pmbr_part_valid(struct partition *part)
 {
 	if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
-		le32_to_int(part->start_sect) == 1UL) {
+		le32_to_cpu(part->start_sect) == 1UL) {
 		return 1;
 	}
 
@@ -234,9 +206,8 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 {
 	int i = 0;
 
-	if (!mbr || le16_to_int(mbr->signature) != MSDOS_MBR_SIGNATURE) {
+	if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
 		return 0;
-	}
 
 	for (i = 0; i < 4; i++) {
 		if (pmbr_part_valid(&mbr->partition_record[i])) {
@@ -259,8 +230,8 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 			gpt_header * pgpt_head, gpt_entry ** pgpt_pte)
 {
-	unsigned char crc32_backup[4] = { 0 };
-	unsigned long calc_crc32;
+	u32 crc32_backup = 0;
+	u32 calc_crc32;
 	unsigned long long lastlba;
 
 	if (!dev_desc || !pgpt_head) {
@@ -275,54 +246,54 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 	}
 
 	/* Check the GPT header signature */
-	if (le64_to_int(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
+	if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
 		printf("GUID Partition Table Header signature is wrong:"
 			"0x%llX != 0x%llX\n",
-			(unsigned long long)le64_to_int(pgpt_head->signature),
-			(unsigned long long)GPT_HEADER_SIGNATURE);
+			(u64) le64_to_cpu(pgpt_head->signature),
+			(u64) GPT_HEADER_SIGNATURE);
 		return 0;
 	}
 
 	/* Check the GUID Partition Table CRC */
-	memcpy(crc32_backup, pgpt_head->header_crc32, sizeof(crc32_backup));
-	memset(pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
+	memcpy(&crc32_backup, &pgpt_head->header_crc32, sizeof(crc32_backup));
+	memset(&pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
 
 	calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
-		le32_to_int(pgpt_head->header_size));
+		le32_to_cpu(pgpt_head->header_size));
 
-	memcpy(pgpt_head->header_crc32, crc32_backup, sizeof(crc32_backup));
+	memcpy(&pgpt_head->header_crc32, &crc32_backup, sizeof(crc32_backup));
 
-	if (calc_crc32 != le32_to_int(crc32_backup)) {
+	if (calc_crc32 != le32_to_cpu(crc32_backup)) {
 		printf("GUID Partition Table Header CRC is wrong:"
-			"0x%08lX != 0x%08lX\n",
-			le32_to_int(crc32_backup), calc_crc32);
+			"0x%x != 0x%x\n",
+		       (u32) le32_to_cpu(crc32_backup), calc_crc32);
 		return 0;
 	}
 
 	/* Check that the my_lba entry points to the LBA that contains the GPT */
-	if (le64_to_int(pgpt_head->my_lba) != lba) {
+	if (le64_to_cpu(pgpt_head->my_lba) != lba) {
 		printf("GPT: my_lba incorrect: %llX != %llX\n",
-			(unsigned long long)le64_to_int(pgpt_head->my_lba),
-			(unsigned long long)lba);
+			(u64)le64_to_cpu(pgpt_head->my_lba),
+			(u64)lba);
 		return 0;
 	}
 
 	/* Check the first_usable_lba and last_usable_lba are within the disk. */
 	lastlba = (unsigned long long)dev_desc->lba;
-	if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
+	if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) {
 		printf("GPT: first_usable_lba incorrect: %llX > %llX\n",
-			le64_to_int(pgpt_head->first_usable_lba), lastlba);
+		       (u64) le64_to_cpu(pgpt_head->first_usable_lba), lastlba);
 		return 0;
 	}
-	if (le64_to_int(pgpt_head->last_usable_lba) > lastlba) {
+	if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) {
 		printf("GPT: last_usable_lba incorrect: %llX > %llX\n",
-			le64_to_int(pgpt_head->last_usable_lba), lastlba);
+		       (u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 		return 0;
 	}
 
 	debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n",
-		le64_to_int(pgpt_head->first_usable_lba),
-		le64_to_int(pgpt_head->last_usable_lba), lastlba);
+	      (u64) le64_to_cpu(pgpt_head->first_usable_lba),
+	      (u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 
 	/* Read and allocate Partition Table Entries */
 	*pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
@@ -333,13 +304,13 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 
 	/* Check the GUID Partition Table Entry Array CRC */
 	calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
-		le32_to_int(pgpt_head->num_partition_entries) *
-		le32_to_int(pgpt_head->sizeof_partition_entry));
+		le32_to_cpu(pgpt_head->num_partition_entries) *
+		le32_to_cpu(pgpt_head->sizeof_partition_entry));
 
-	if (calc_crc32 != le32_to_int(pgpt_head->partition_entry_array_crc32)) {
+	if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) {
 		printf("GUID Partition Table Entry Array CRC is wrong:"
-			"0x%08lX != 0x%08lX\n",
-			le32_to_int(pgpt_head->partition_entry_array_crc32),
+			"0x%x != 0x%x\n",
+		       (u32)le32_to_cpu(pgpt_head->partition_entry_array_crc32),
 			calc_crc32);
 
 		free(*pgpt_pte);
@@ -370,12 +341,12 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 		return NULL;
 	}
 
-	count = le32_to_int(pgpt_head->num_partition_entries) *
-		le32_to_int(pgpt_head->sizeof_partition_entry);
+	count = le32_to_cpu(pgpt_head->num_partition_entries) *
+		le32_to_cpu(pgpt_head->sizeof_partition_entry);
 
-	debug("%s: count = %lu * %lu = %u\n", __func__,
-		le32_to_int(pgpt_head->num_partition_entries),
-		le32_to_int(pgpt_head->sizeof_partition_entry), count);
+	debug("%s: count = %u * %u = %u\n", __func__,
+	      (u32) le32_to_cpu(pgpt_head->num_partition_entries),
+	      (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), count);
 
 	/* Allocate memory for PTE, remember to FREE */
 	if (count != 0) {
@@ -390,7 +361,7 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 
 	/* Read GPT Entries from device */
 	if (dev_desc->block_read (dev_desc->dev,
-		(unsigned long)le64_to_int(pgpt_head->partition_entry_lba),
+		(u64) le64_to_cpu(pgpt_head->partition_entry_lba),
 		(lbaint_t) (count / GPT_BLOCK_SIZE), pte)
 		!= (count / GPT_BLOCK_SIZE)) {
 
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 3/6] gpt: Replacement of GPT structures members with ones indicating endianness and size
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
  2012-08-24  8:13 ` [U-Boot] [PATCH 1/6] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
  2012-08-24  8:13 ` [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h> Lukasz Majewski
@ 2012-08-24  8:13 ` Lukasz Majewski
  2012-09-05 19:41   ` Stephen Warren
  2012-08-24  8:13 ` [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-08-24  8:13 UTC (permalink / raw)
  To: u-boot

Replacement of several GPT related structures members with ones
indicating its endianness and proper size.

Signed-off-by: Chang Hyun Park <chchch.park@samsung.com>
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 disk/part_efi.h |   85 ++++++++++++++++++++++++++++--------------------------
 1 files changed, 44 insertions(+), 41 deletions(-)

diff --git a/disk/part_efi.h b/disk/part_efi.h
index 5903e7c..85692fb 100644
--- a/disk/part_efi.h
+++ b/disk/part_efi.h
@@ -29,6 +29,8 @@
  * http://developer.intel.com/technology/efi/efi.htm
 */
 
+#include <linux/compiler.h>
+
 #ifndef _DISK_PART_EFI_H
 #define _DISK_PART_EFI_H
 
@@ -41,6 +43,8 @@
 #define GPT_HEADER_REVISION_V1 0x00010000
 #define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
 #define GPT_ENTRY_NAME "gpt"
+#define GPT_ENTRY_NUMBERS		128
+#define GPT_ENTRY_SIZE			128
 
 #define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
 	((efi_guid_t) \
@@ -72,68 +76,67 @@
 		0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
 
 /* linux/include/efi.h */
-typedef unsigned short efi_char16_t;
+typedef u16 efi_char16_t;
 
 typedef struct {
-	unsigned char b[16];
+	u8 b[16];
 } efi_guid_t;
 
 /* based on linux/include/genhd.h */
 struct partition {
-	unsigned char boot_ind;		/* 0x80 - active */
-	unsigned char head;		/* starting head */
-	unsigned char sector;		/* starting sector */
-	unsigned char cyl;		/* starting cylinder */
-	unsigned char sys_ind;		/* What partition type */
-	unsigned char end_head;		/* end head */
-	unsigned char end_sector;	/* end sector */
-	unsigned char end_cyl;		/* end cylinder */
-	unsigned char start_sect[4];	/* starting sector counting from 0 */
-	unsigned char nr_sects[4];	/* nr of sectors in partition */
-} __attribute__ ((packed));
+	u8 boot_ind;		/* 0x80 - active */
+	u8 head;		/* starting head */
+	u8 sector;		/* starting sector */
+	u8 cyl;		/* starting cylinder */
+	u8 sys_ind;		/* What partition type */
+	u8 end_head;		/* end head */
+	u8 end_sector;	/* end sector */
+	u8 end_cyl;		/* end cylinder */
+	__le32 start_sect;	/* starting sector counting from 0 */
+	__le32 nr_sects;	/* nr of sectors in partition */
+} __packed;
 
 /* based on linux/fs/partitions/efi.h */
 typedef struct _gpt_header {
-	unsigned char signature[8];
-	unsigned char revision[4];
-	unsigned char header_size[4];
-	unsigned char header_crc32[4];
-	unsigned char reserved1[4];
-	unsigned char my_lba[8];
-	unsigned char alternate_lba[8];
-	unsigned char first_usable_lba[8];
-	unsigned char last_usable_lba[8];
+	__le64 signature;
+	__le32 revision;
+	__le32 header_size;
+	__le32 header_crc32;
+	__le32 reserved1;
+	__le64 my_lba;
+	__le64 alternate_lba;
+	__le64 first_usable_lba;
+	__le64 last_usable_lba;
 	efi_guid_t disk_guid;
-	unsigned char partition_entry_lba[8];
-	unsigned char num_partition_entries[4];
-	unsigned char sizeof_partition_entry[4];
-	unsigned char partition_entry_array_crc32[4];
-	unsigned char reserved2[GPT_BLOCK_SIZE - 92];
-} __attribute__ ((packed)) gpt_header;
+	__le64 partition_entry_lba;
+	__le32 num_partition_entries;
+	__le32 sizeof_partition_entry;
+	__le32 partition_entry_array_crc32;
+	u8 reserved2[GPT_BLOCK_SIZE - 92];
+} __packed gpt_header;
 
 typedef struct _gpt_entry_attributes {
-	unsigned long long required_to_function:1;
-	unsigned long long reserved:47;
-	unsigned long long type_guid_specific:16;
-} __attribute__ ((packed)) gpt_entry_attributes;
+	u64 required_to_function:1;
+	u64 reserved:47;
+	u64 type_guid_specific:16;
+} __packed gpt_entry_attributes;
 
 #define PARTNAME_SZ	(72 / sizeof(efi_char16_t))
 typedef struct _gpt_entry {
 	efi_guid_t partition_type_guid;
 	efi_guid_t unique_partition_guid;
-	unsigned char starting_lba[8];
-	unsigned char ending_lba[8];
+	__le64 starting_lba;
+	__le64 ending_lba;
 	gpt_entry_attributes attributes;
 	efi_char16_t partition_name[PARTNAME_SZ];
-}
-__attribute__ ((packed)) gpt_entry;
+} __packed gpt_entry;
 
 typedef struct _legacy_mbr {
-	unsigned char boot_code[440];
-	unsigned char unique_mbr_signature[4];
-	unsigned char unknown[2];
+	u8 boot_code[440];
+	__le32 unique_mbr_signature;
+	__le16 unknown;
 	struct partition partition_record[4];
-	unsigned char signature[2];
-} __attribute__ ((packed)) legacy_mbr;
+	__le16 signature;
+} __packed legacy_mbr;
 
 #endif	/* _DISK_PART_EFI_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
                   ` (2 preceding siblings ...)
  2012-08-24  8:13 ` [U-Boot] [PATCH 3/6] gpt: Replacement of GPT structures members with ones indicating endianness and size Lukasz Majewski
@ 2012-08-24  8:13 ` Lukasz Majewski
  2012-09-05 19:49   ` Stephen Warren
                     ` (2 more replies)
  2012-08-24  8:13 ` [U-Boot] [PATCH 5/6] gpt: Support for new "gpt" command Lukasz Majewski
                   ` (7 subsequent siblings)
  11 siblings, 3 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-08-24  8:13 UTC (permalink / raw)
  To: u-boot

The restoration of GPT table (both primary and secondary) is now possible.
Simple GUID generation is supported.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 disk/part_efi.c |  225 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/part.h  |    2 +
 2 files changed, 227 insertions(+), 0 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index 86e7f33..c1e8d54 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -403,4 +403,229 @@ static int is_pte_valid(gpt_entry * pte)
 		return 1;
 	}
 }
+
+/**
+ * guid_gen(): Generate UUID
+ *
+ * @param dev_desc - block device descriptor
+ *
+ * @return - generated UUID table
+ *
+ * NOTE: The entrophy of this function is small
+ */
+static u8 *guid_gen(block_dev_desc_t * dev_desc)
+{
+	int k = 0;
+	static int i = 1;
+	static u8 __aligned(CONFIG_SYS_CACHELINE_SIZE) guid[16];
+	static u8 __aligned(CONFIG_SYS_CACHELINE_SIZE) ent_pool[512];
+	u32 *ptr = (u32 *) guid;
+
+	/* Entrophy initialization - read random content of one SD sector */
+	if (i == 1) {
+		debug("Init entropy:%x\n", (u32)(dev_desc->lba >> 14));
+
+		if (dev_desc->block_read(dev_desc->dev, (dev_desc->lba >> 14),
+					 1, (u32 *) ent_pool) != 1) {
+			printf("** Can't read from device %d **\n",
+			       dev_desc->dev);
+		}
+	}
+
+	for (k = 0; k < 4; k++) {
+		*(ptr + k) = efi_crc32((const void *) ent_pool,
+				       sizeof(ent_pool));
+		ent_pool[511 - k] = *(ptr + k);
+	}
+
+	ent_pool[0] = ((u8) i) & 0xff;
+
+	debug("GUID: ");
+	for (k = 0; k < sizeof(guid); k++)
+		debug(" %x ", guid[k]);
+
+	debug("     i:%d,\n", i);
+
+	i++;
+	return guid;
+}
+
+/**
+ * set_protective_mbr(): Set the EFI protective MBR
+ * @param dev_desc - block device descriptor
+ *
+ * @return - zero on success, otherwise error
+ */
+static int set_protective_mbr(block_dev_desc_t *dev_desc)
+{
+	legacy_mbr p_mbr;
+
+	/* Setup the Protective MBR */
+	memset((u32 *) &p_mbr, 0x00, sizeof(p_mbr));
+	/* Append signature */
+	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) dev_desc->lba;
+
+	/* Write MBR sector to the MMC device */
+	if (dev_desc->block_write(dev_desc->dev, 0, 1, &p_mbr) != 1) {
+		printf("** Can't write to device %d **\n",
+			dev_desc->dev);
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * fill_pte(): Fill the GPT partition table entry
+ *
+ * @param dev_desc - block device descriptor
+ * @param gpt_h - GPT header representation
+ * @param gpt_e - GPT partition table entries
+ * @param parts - number of partitions
+ * @param size - size of each partition
+ * @param name - name of each partition
+ */
+static void fill_pte(block_dev_desc_t *dev_desc, gpt_header *gpt_h,
+		     gpt_entry *gpt_e, int parts, unsigned int *size,
+		     char *name[])
+{
+	u32 offset = (u32) gpt_h->first_usable_lba;
+	char p[PARTNAME_SZ];
+	int i, k, j;
+	char *s;
+
+	for (i = 0; i < parts; i++) {
+		memcpy(gpt_e[i].partition_type_guid.b,
+		       &PARTITION_BASIC_DATA_GUID, 16);
+		memcpy(gpt_e[i].unique_partition_guid.b,
+		       guid_gen(dev_desc),
+		       sizeof(gpt_e[i].unique_partition_guid.b));
+
+		s = name[i];
+
+		memset(p, 0x00, sizeof(p));
+		for (k = 0, j = 0; k < strlen(s); k++, j += 2) {
+			p[j] = *(s + k);
+			p[j + 1] = '.';
+		}
+
+		memcpy(gpt_e[i].partition_name,
+		       p, strlen(p));
+
+		gpt_e[i].starting_lba = cpu_to_le32(offset);
+
+		/* allocate remaining memory in last partition */
+		if (i != parts - 1) {
+			gpt_e[i].ending_lba =
+				cpu_to_le64(offset + size[i] - 1);
+		} else {
+			gpt_e[i].ending_lba = gpt_h->last_usable_lba;
+		}
+
+		memset(&gpt_e[i].attributes, 0,
+		       sizeof(gpt_entry_attributes));
+
+		offset += size[i];
+		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%x\n",
+		      __func__, name[i], i, offset, i, size[i]);
+	}
+}
+
+/**
+ * set_gpt_table() - Restore the GUID Partition Table
+ *
+ * @param dev_desc - block device descriptor
+ * @param parts - number of partitions
+ * @param size - pointer to array with each partition size
+ * @param name - pointer to array with each partition name
+ *
+ * @return - zero on success, otherwise error
+ */
+int set_gpt_table(block_dev_desc_t *dev_desc,
+		   int parts, unsigned int *size, char *name[])
+{
+	const int pte_blk_num = (GPT_ENTRY_NUMBERS * sizeof(gpt_entry)) /
+		dev_desc->blksz;
+	gpt_entry gpt_e[GPT_ENTRY_NUMBERS];
+	gpt_header gpt_h;
+	u32 calc_crc32;
+	u64 val;
+
+	debug("max lba: %x\n", (u32) dev_desc->lba);
+
+	/* Setup the Protective MBR */
+	if (set_protective_mbr(dev_desc) < 0)
+		goto err;
+
+	memset((u32 *) &gpt_h, 0x00, sizeof(gpt_h));
+
+	/* Generate Primary GPT header (LBA1) */
+	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(1);
+	gpt_h.alternate_lba = cpu_to_le64(dev_desc->lba - 1);
+	gpt_h.first_usable_lba = cpu_to_le64(34);
+	gpt_h.last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
+	gpt_h.partition_entry_lba = cpu_to_le64(2);
+	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;
+	memcpy(gpt_h.disk_guid.b, guid_gen(dev_desc),
+	       sizeof(gpt_h.disk_guid.b));
+
+	memset((u32 *) gpt_e, 0x00, sizeof(gpt_e));
+
+	fill_pte(dev_desc, &gpt_h, gpt_e, parts, size, name);
+
+	/* 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);
+
+	/* Write the First GPT to the block right after the Legacy MBR */
+	if (dev_desc->block_write(dev_desc->dev, 1, 1, &gpt_h) != 1)
+		goto err;
+
+	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e)
+	    != pte_blk_num)
+		goto err;
+
+	/* recalculate the values for the Second 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);
+	gpt_h.header_crc32 = 0;
+
+	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);
+
+	/* Write the Second GPT that is located at the end of the disk */
+	if (dev_desc->block_write(dev_desc->dev,
+				  le32_to_cpu(gpt_h.last_usable_lba + 1),
+				  pte_blk_num, gpt_e) != pte_blk_num)
+		goto err;
+
+	if (dev_desc->block_write(dev_desc->dev,
+				  le32_to_cpu(gpt_h.my_lba), 1, &gpt_h) != 1)
+		goto err;
+
+	printf("GPT successfully written to block device!\n");
+	return 0;
+
+ err:
+	printf("** Can't write to device %d **\n",
+	       dev_desc->dev);
+	return -1;
+}
 #endif
diff --git a/include/part.h b/include/part.h
index e1478f4..e12c10f 100644
--- a/include/part.h
+++ b/include/part.h
@@ -161,6 +161,8 @@ int   test_part_amiga (block_dev_desc_t *dev_desc);
 int get_partition_info_efi (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
 void print_part_efi (block_dev_desc_t *dev_desc);
 int   test_part_efi (block_dev_desc_t *dev_desc);
+int set_gpt_table(block_dev_desc_t *dev_desc,
+		   int parts, unsigned int *blocks, char *name[]);
 #endif
 
 #endif /* _PART_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 5/6] gpt: Support for new "gpt" command
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
                   ` (3 preceding siblings ...)
  2012-08-24  8:13 ` [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
@ 2012-08-24  8:13 ` Lukasz Majewski
  2012-09-05 20:08   ` Stephen Warren
  2012-08-24  8:13 ` [U-Boot] [PATCH 6/6] gpt: Enable support for GPT partition table restoration at Samsung's Trats Lukasz Majewski
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-08-24  8:13 UTC (permalink / raw)
  To: u-boot

New command - "gpt" is now supported. It shows and restores the GPT partition
table.
It looks into the "partitions" environment variable for partitions definition.
It can be enabled at target configuration file with CONFIG_CMD_GPT.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 common/Makefile  |    1 +
 common/cmd_gpt.c |  182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 183 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_gpt.c

diff --git a/common/Makefile b/common/Makefile
index 49df751..438d36c 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -185,6 +185,7 @@ COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
 COBJS-$(CONFIG_UPDATE_TFTP) += update.o
 COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
 COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o
+COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o
 endif
 
 ifdef CONFIG_SPL_BUILD
diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
new file mode 100644
index 0000000..06d7c5f
--- /dev/null
+++ b/common/cmd_gpt.c
@@ -0,0 +1,182 @@
+/*
+ * cmd_gpt.c -- GPT (GUID Partition Table) handling command
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * author: Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <command.h>
+#include <mmc.h>
+
+static unsigned int gpt_parts;
+static int gpt_dev;
+
+static unsigned long memsize_to_blocks(const char *const ptr,
+				       const char **retptr)
+{
+	unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);
+	int shift = 0;
+
+	switch (**retptr) {
+	case 'G':
+	case 'g':
+		shift += 10;
+	case 'M':
+	case 'm':
+		shift += 10;
+	case 'K':
+	case 'k':
+		shift += 10;
+	(*retptr)++;
+	default:
+		shift -= 9;
+		break;
+	}
+
+	if (shift > 0)
+		ret <<= shift;
+	else
+		ret >>= shift;
+
+	return ret;
+}
+
+int set_gpt_info(block_dev_desc_t *dev_desc)
+{
+	char *ps[GPT_PARTS_NUM], *name[GPT_PARTS_NUM];
+	unsigned int size[GPT_PARTS_NUM];
+	char *tok, *t, *p, *s, *ss;
+	int i, ret;
+
+	s = getenv("partitions");
+	if (s == NULL) {
+		printf("%s: \"partitions\" env variable not defined!\n",
+		       __func__);
+		return -1;
+	}
+
+	ss = calloc(strlen(s) + 1, 1);
+	if (ss == NULL) {
+		printf("%s: calloc failed!\n", __func__);
+		return -1;
+	}
+	memcpy(ss, s, strlen(s) + 1);
+
+	for (i = 0, p = ss; ; i++) {
+		tok = strsep(&p, ",");
+		if (tok == NULL)
+			break;
+
+		t = strsep(&tok, "(");
+		ps[i] = calloc(strlen(t) + 1, 1);
+		if (ps[i] == NULL) {
+			printf("%s: calloc failed!\n", __func__);
+			ret = -1;
+			goto err;
+		}
+		strcpy(ps[i], t);
+
+		t = strsep(&tok, ")");
+		name[i] = calloc(strlen(t) + 1, 1);
+		if (name[i] == NULL) {
+			printf("%s: calloc failed!\n", __func__);
+			ret = -1;
+			goto err;
+		}
+		strcpy(name[i], t);
+	}
+
+	gpt_parts = i;
+	printf("found %d partitions\n", gpt_parts);
+
+	for (i = 0; i < gpt_parts; i++) {
+		p = ps[i];
+		size[i] = memsize_to_blocks(p, (const char **)&p);
+	}
+
+	puts("save the GPT Table...\n");
+	ret = set_gpt_table(dev_desc, gpt_parts, size, name);
+
+	i = gpt_parts;
+ err:
+	for (i--; i >= 0; i--) {
+		free(name[i]);
+		free(ps[i]);
+	}
+
+	free(ss);
+	return ret;
+}
+
+static void set_gpt_dev(int dev)
+{
+	gpt_dev = dev;
+}
+
+static void gpt_show(void)
+{
+	struct mmc *mmc = find_mmc_device(gpt_dev);
+
+	print_part_efi(&mmc->block_dev);
+}
+
+static int gpt_default(void)
+{
+	struct mmc *mmc = find_mmc_device(gpt_dev);
+
+	if (mmc == NULL) {
+		printf("%s: mmc dev %d NOT available\n", __func__, gpt_dev);
+		return CMD_RET_FAILURE;
+	}
+
+	puts("Using default GPT UUID\n");
+
+	return set_gpt_info(&mmc->block_dev);
+}
+
+static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int ret = CMD_RET_SUCCESS;
+
+	switch (argc) {
+	case 2:
+		if (strncmp(argv[1], "show", 4) == 0)
+			gpt_show();
+		else if (strncmp(argv[1], "restore", 7) == 0)
+			if (gpt_default())
+				return CMD_RET_FAILURE;
+		break;
+	case 3:
+		if (strncmp(argv[1], "dev", 3) == 0)
+			set_gpt_dev(simple_strtoul(argv[2], NULL, 10));
+		break;
+	default:
+		ret = CMD_RET_USAGE;
+	}
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	gpt,	CONFIG_SYS_MAXARGS,	1, do_gpt,
+	"GUID Partition Table",
+	"show - show GPT\n"
+	"gpt restore - reset GPT partition to defaults\n"
+	"gpt dev #num - set device number\n"
+);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 6/6] gpt: Enable support for GPT partition table restoration at Samsung's Trats
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
                   ` (4 preceding siblings ...)
  2012-08-24  8:13 ` [U-Boot] [PATCH 5/6] gpt: Support for new "gpt" command Lukasz Majewski
@ 2012-08-24  8:13 ` Lukasz Majewski
  2012-08-24  8:48 ` [U-Boot] gpt: GUID/UUID - GPT restoration - open questions Lukasz Majewski
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-08-24  8:13 UTC (permalink / raw)
  To: u-boot

Enable support for GPT partition table restoration at Samsung's Trats
development board.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 include/configs/trats.h |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/include/configs/trats.h b/include/configs/trats.h
index 08aa65b..c6fb2e0 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -98,6 +98,7 @@
 #undef CONFIG_CMD_MTDPARTS
 #define CONFIG_CMD_MMC
 #define CONFIG_CMD_DFU
+#define CONFIG_CMD_GPT
 
 /* FAT */
 #define CONFIG_CMD_FAT
@@ -122,6 +123,24 @@
 #define CONFIG_BOOTBLOCK		"10"
 #define CONFIG_ENV_COMMON_BOOT		"${console} ${meminfo}"
 
+/* Tizen - partitions definitions */
+#define PARTS_CSA		"csa-mmc"
+#define PARTS_BOOTLOADER	"u-boot"
+#define PARTS_KERNEL		"kernel"
+#define PARTS_ROOT		"platform"
+#define PARTS_DATA		"data"
+#define PARTS_CSC		"csc"
+#define PARTS_UMS		"ums"
+
+#define PARTS_DEFAULT	"8M("PARTS_CSA")"\
+			",60M("PARTS_BOOTLOADER")"\
+			",60M("PARTS_KERNEL")"\
+			",1G("PARTS_ROOT")"\
+			",3G("PARTS_DATA")"\
+			",150M("PARTS_CSC")"\
+			",-("PARTS_UMS")\0"
+#define GPT_PARTS_NUM 7
+
 #define CONFIG_DFU_ALT \
 	"dfu_alt_info=" \
 	"u-boot mmc 80 400;" \
@@ -171,7 +190,8 @@
 	"mmcbootpart=2\0" \
 	"mmcrootpart=3\0" \
 	"opts=always_resume=1\0" \
-	CONFIG_DFU_ALT
+	"partitions=" PARTS_DEFAULT \
+	CONFIG_DFU_ALT \
 
 /* Miscellaneous configurable options */
 #define CONFIG_SYS_LONGHELP		/* undef to save memory */
@@ -210,6 +230,7 @@
 #define CONFIG_ENV_OFFSET		((32 - 4) << 10) /* 32KiB - 4KiB */
 
 #define CONFIG_DOS_PARTITION
+#define CONFIG_EFI_PARTITION
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE)
 #define CONFIG_SYS_CACHELINE_SIZE       32
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] gpt: GUID/UUID - GPT restoration - open questions
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
                   ` (5 preceding siblings ...)
  2012-08-24  8:13 ` [U-Boot] [PATCH 6/6] gpt: Enable support for GPT partition table restoration at Samsung's Trats Lukasz Majewski
@ 2012-08-24  8:48 ` Lukasz Majewski
  2012-09-05 20:21   ` Stephen Warren
  2012-09-06 12:27   ` Rob Herring
  2012-09-03  9:28 ` [U-Boot] gpt: GUID/UUID - GPT restoration - open questions - RESEND Lukasz Majewski
                   ` (4 subsequent siblings)
  11 siblings, 2 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-08-24  8:48 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

I'm writing to you, since I've posted a patch series regarding GPT
support for Samsung Trats board (you were on the CC).

e.g. http://patchwork.ozlabs.org/patch/179785/

I think, that we can cooperate to provide better EFI/GPT support.

In mine implementation the "gpt" command (with several sub commands) has
been proposed
- we can discuss if this is a correct way to go.

Moreover, at this patch series a "weak" GUID generator is implemented.
For now it is "good enough", since I consider the restoration as an
emergency situation.
However,I wonder how can we provide better GUID (and in general random
numbers pool) generator for u-boot.


Maybe md5sum command can be used with some running clock (WDT, or
system clock from u-boot start up) data to provide better entropy?

Any ideas?

Regards,
Lukasz

> This patch series provides a new command - "gpt" for eMMC partition
> table (in the GPT format) restoration and display.
> 
> As a pre-work, some cleanup at the part_efi.c file was performed to 
> remove custom macros and make GPT related structures more readable. 
> 
> The GPT detailed description has been written to README.gpt file.
> 
> Tested at:
> 	- Exynos4210 rev.1 - TRATS Samsung development board
> 
> Lukasz Majewski (6):
>   gpt:doc: GPT (GUID Partition Table) documentation
>   gpt: Replace the leXX_to_int() calls with ones defined at
>     <compiler.h>
>   gpt: Replacement of GPT structures members with ones indicating
>     endianness and size
>   gpt: Support for GPT (GUID Partition Table) restoration
>   gpt: Support for new "gpt" command
>   gpt: Enable support for GPT partition table restoration at Samsung's
>     Trats
> 
>  common/Makefile         |    1 +
>  common/cmd_gpt.c        |  182 ++++++++++++++++++++++++++
>  disk/part_efi.c         |  334
> +++++++++++++++++++++++++++++++++++++----------
> disk/part_efi.h         |   85 ++++++------ doc/README.gpt
> |  199 ++++++++++++++++++++++++++++ include/configs/trats.h |   23
> +++- include/part.h          |    2 +
>  7 files changed, 715 insertions(+), 111 deletions(-)
>  create mode 100644 common/cmd_gpt.c
>  create mode 100644 doc/README.gpt
> 

-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] gpt: GUID/UUID - GPT restoration - open questions - RESEND
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
                   ` (6 preceding siblings ...)
  2012-08-24  8:48 ` [U-Boot] gpt: GUID/UUID - GPT restoration - open questions Lukasz Majewski
@ 2012-09-03  9:28 ` Lukasz Majewski
  2012-10-02 13:46   ` Simon Glass
  2012-09-03  9:30 ` [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-03  9:28 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

I'm writing to you, since I've posted a patch series regarding GPT
support for Samsung Trats board (you were on the CC).

e.g. http://patchwork.ozlabs.org/patch/179785/

I think, that we can cooperate to provide better EFI/GPT support.

In mine implementation the "gpt" command (with several sub commands) has
been proposed
- we can discuss if this is a correct way to go.

Moreover, at this patch series a "weak" GUID generator is implemented.
For now it is "good enough", since I consider the restoration as an
emergency situation.
However,I wonder how can we provide better GUID (and in general random
numbers pool) generator for u-boot.


Maybe md5sum command can be used with some running clock (WDT, or
system clock from u-boot start up) data to provide better entropy?

Any ideas?

Regards,
Lukasz

p.s. I'm resending this patch, so please do not regard it as a spam.

> This patch series provides a new command - "gpt" for eMMC partition
> table (in the GPT format) restoration and display.
> 
> As a pre-work, some cleanup at the part_efi.c file was performed to 
> remove custom macros and make GPT related structures more readable. 
> 
> The GPT detailed description has been written to README.gpt file.
> 
> Tested at:
> 	- Exynos4210 rev.1 - TRATS Samsung development board
> 
> Lukasz Majewski (6):
>   gpt:doc: GPT (GUID Partition Table) documentation
>   gpt: Replace the leXX_to_int() calls with ones defined at
>     <compiler.h>
>   gpt: Replacement of GPT structures members with ones indicating
>     endianness and size
>   gpt: Support for GPT (GUID Partition Table) restoration
>   gpt: Support for new "gpt" command
>   gpt: Enable support for GPT partition table restoration at Samsung's
>     Trats
> 
>  common/Makefile         |    1 +
>  common/cmd_gpt.c        |  182 ++++++++++++++++++++++++++
>  disk/part_efi.c         |  334
> +++++++++++++++++++++++++++++++++++++----------
> disk/part_efi.h         |   85 ++++++------ doc/README.gpt
> |  199 ++++++++++++++++++++++++++++ include/configs/trats.h |   23
> +++- include/part.h          |    2 +
>  7 files changed, 715 insertions(+), 111 deletions(-)
>  create mode 100644 common/cmd_gpt.c
>  create mode 100644 doc/README.gpt
> 

-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
                   ` (7 preceding siblings ...)
  2012-09-03  9:28 ` [U-Boot] gpt: GUID/UUID - GPT restoration - open questions - RESEND Lukasz Majewski
@ 2012-09-03  9:30 ` Lukasz Majewski
  2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-03  9:30 UTC (permalink / raw)
  To: u-boot

Dear All,

> This patch series provides a new command - "gpt" for eMMC partition
> table (in the GPT format) restoration and display.
> 
> As a pre-work, some cleanup at the part_efi.c file was performed to 
> remove custom macros and make GPT related structures more readable. 
> 
> The GPT detailed description has been written to README.gpt file.
> 
> Tested at:
> 	- Exynos4210 rev.1 - TRATS Samsung development board
> 
> Lukasz Majewski (6):
>   gpt:doc: GPT (GUID Partition Table) documentation
>   gpt: Replace the leXX_to_int() calls with ones defined at
>     <compiler.h>
>   gpt: Replacement of GPT structures members with ones indicating
>     endianness and size
>   gpt: Support for GPT (GUID Partition Table) restoration
>   gpt: Support for new "gpt" command
>   gpt: Enable support for GPT partition table restoration at Samsung's
>     Trats
> 

Any ideas/comments ?

-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 1/6] gpt:doc: GPT (GUID Partition Table) documentation
  2012-08-24  8:13 ` [U-Boot] [PATCH 1/6] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
@ 2012-09-05 19:31   ` Stephen Warren
  2012-09-06  9:22     ` Lukasz Majewski
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-05 19:31 UTC (permalink / raw)
  To: u-boot

On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> Documentation of the GPT table format.

> +++ b/doc/README.gpt

> +Glossary:
> +========
> +- UUID -(Universally Unique Identifier)
> +- GUID - (Globally Unique ID)
> +- EFI - (Extensible Firmware Interface)
> +- UEFI - (Unified EFI) - EFI evolution
> +- GPT (GUID Page Table) - it is the EFI standard part

GUID Partition Table, not Page.

> +- partitions - lists of availavle partitions (defined at u-boot):
> +  ./include/configs/{target}.h
> +
> +Introduction:
> +=============
> +This document describes the GPT partition table format when used with u-boot.
> +
> +
> +UUID introduction[5]:
> +====================

What is "[5]"?

> +For instance, GUID of Linux data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
> +For u-boot GPT hyphens are omitted.

I don't think U-Boot should omit any of the hyphens; it makes the UUIDs
far more readable, and the strings can then be cut/paste to/from other
applications that use/print UUIDs, without any manual conversion.

> +Historically there are 5 methods to generate this number. The oldest one is
> +combining machine's MAC address and timer (epoch) value.
> +
> +Successive versions are using MD5 hash, random numbers and SHA-1 hash. All major
> +OSes and programming languages are providing libraries to compute UUID.
> +
> +However it costs in terms of the computational power and memory footprint.
> +Therefore u-boot uses the crc32 with reading random block (512B) from MMC
> +storage device to generate UUID/GUID.

That doesn't seem particularly relevant to general documentation about
GPT; it's an implementation detail of the GPT creation command in a
later patch, and could easily be changed.

In fact, I wonder why not require the user to concoct UUIDs and pass
them to your GPT creation command, rather than forming them using some
non-standard process.

> +GUID brief explanation:

Not "GUID", but "GPT".

> +======================
> +
> +	Layout:
> +	-------
> +
> +	--------------------------------------------------
> +	LBA 0          |Protective MBR                   |
> +	----------------------------------------------------------
> +	LBA 1          |Primary GPT Header               | Primary
> +	-------------------------------------------------- GPT
> +	LBA 2          |Entry 1|Entry 2| Entry 3| Entry 4|
> +	--------------------------------------------------
> +	LBA 3          |Entries 5 - 128                  |
> +		       |                                 |
> +		       |                                 |
> +       -----------------------------------------------------------
> +       LBA 34          |Partition 1                      |

The indentation looks inconsistent in this diagram

> +		       |                                 |
> +		       -----------------------------------
> +		       |Partition 2                      |
> +		       |                                 |
> +		       -----------------------------------
> +		       |Partition n                      |
> +		       |                                 |

> +       -----------------------------------------------------------
> +       LBA -34         |Entry 1|Entry 2| Entry 3| Entry 4| Secondary
> +       --------------------------------------------------- (bkp)
> +       LBA 34          |Partition 1                      |
> +		       |                                 |
> +		       -----------------------------------
> +		       |Partition 2                      |
> +		       |                                 |
> +		       -----------------------------------
> +		       |Partition n                      |
> +		       |                                 |

That part of the diagram appears duplicated.

> +       -----------------------------------------------------------
> +       LBA -34         |Entry 1|Entry 2| Entry 3| Entry 4| Secondary
> +       --------------------------------------------------- (bkp)
> +       LBA -33         |Entries 5 - 128                  | GPT
> +		       |                                 |
> +		       |                                 |
> +       LBA -2          |                                 |
> +       ---------------------------------------------------
> +       LBA -1          |Secondary GPT Header             |
> +       -----------------------------------------------------------
> +

> +	   Attribute flags (Don't used at u-boot):

I wouldn't write "Don't used at u-boot" since that's potentially subject
to change. For example, I'm expecting to send a patch to use the "Legacy
BIOS bootable" attribute soon.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h>
  2012-08-24  8:13 ` [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h> Lukasz Majewski
@ 2012-09-05 19:35   ` Stephen Warren
  2012-09-06 10:20     ` Lukasz Majewski
  2012-09-05 19:45   ` Stephen Warren
  1 sibling, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-05 19:35 UTC (permalink / raw)
  To: u-boot

On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> Custom definitions of le_XX_to_int functions have been replaced with
> standard ones, defined at <compiler.h>
> 
> Signed-off-by: Chang Hyun Park <chchch.park@samsung.com>
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

Did Chang Hyun Park write this? If so, shouldn't git have generated a
"From" header for him, to reflect his authorship upstream. I'm not sure
how Kyungmin Park's S-o-b plays into this, since he's not sending the patch.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 3/6] gpt: Replacement of GPT structures members with ones indicating endianness and size
  2012-08-24  8:13 ` [U-Boot] [PATCH 3/6] gpt: Replacement of GPT structures members with ones indicating endianness and size Lukasz Majewski
@ 2012-09-05 19:41   ` Stephen Warren
  2012-09-06 10:24     ` Lukasz Majewski
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-05 19:41 UTC (permalink / raw)
  To: u-boot

On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> Replacement of several GPT related structures members with ones
> indicating its endianness and proper size.

This patch seems reasonable to me, but I'm surprised it doesn't require
/any/ changes to the code that uses these structures in order to avoid
warnings/errors. Is git bisect maintained by this series?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h>
  2012-08-24  8:13 ` [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h> Lukasz Majewski
  2012-09-05 19:35   ` Stephen Warren
@ 2012-09-05 19:45   ` Stephen Warren
  2012-09-06 10:15     ` Lukasz Majewski
  1 sibling, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-05 19:45 UTC (permalink / raw)
  To: u-boot

On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> Custom definitions of le_XX_to_int functions have been replaced with
> standard ones, defined at <compiler.h>

> diff --git a/disk/part_efi.c b/disk/part_efi.c

> -/* Convert char[8] in little endian format to the host format integer
> - */
> -static inline unsigned long long le64_to_int(unsigned char *le64)
> -{

So this original function takes a pointer to the value ...

>  	/* Check the first_usable_lba and last_usable_lba are within the disk. */
>  	lastlba = (unsigned long long)dev_desc->lba;
> -	if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
> +	if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) {

At this point in the series, first_usable_lba is a char[8], so this is
passing the address of the first byte to both the original function
le64_to_int(), and the replacement function le64_to_cpu(). However,
le64_to_cpu() expects to receive the 64-bit value to swap, not a pointer
to it - from compiler.h:

#define _uswap_64(x, sfx) \
        ((((x) & 0xff00000000000000##sfx) >> 56) | \
...
# define uswap_64(x) _uswap_64(x, ull)

le:
# define le64_to_cpu(x)         (x)
be:
# define le64_to_cpu(x)         uswap_64(x)

So I think this patch breaks the code, and then the next patch fixes it,
since it changes the type of first_usable_lba from char[8] to __le64?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration
  2012-08-24  8:13 ` [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
@ 2012-09-05 19:49   ` Stephen Warren
  2012-09-06 11:19     ` Lukasz Majewski
  2012-09-05 20:19   ` Stephen Warren
  2012-10-03 23:00   ` [U-Boot] [U-Boot, " Tom Rini
  2 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-05 19:49 UTC (permalink / raw)
  To: u-boot

On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> The restoration of GPT table (both primary and secondary) is now possible.
> Simple GUID generation is supported.

> diff --git a/include/part.h b/include/part.h

> +int set_gpt_table(block_dev_desc_t *dev_desc,
> +		   int parts, unsigned int *blocks, char *name[]);

That interface seems very limiting; what if you want to select specific
type UUIDs, set the partition attributes, leave gaps between the
partitions, have the physical order of partitions (their block numbers)
be different to the partition table ordering, etc.

I wonder if it wouldn't be better to take an array of structures here,
and have each entry define all the properties of the partition. That
would allow fields to be added to the structure to describe more
information as we add more functionality.

I didn't review the implementation.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 5/6] gpt: Support for new "gpt" command
  2012-08-24  8:13 ` [U-Boot] [PATCH 5/6] gpt: Support for new "gpt" command Lukasz Majewski
@ 2012-09-05 20:08   ` Stephen Warren
  2012-09-06 14:01     ` Lukasz Majewski
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-05 20:08 UTC (permalink / raw)
  To: u-boot

On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> New command - "gpt" is now supported. It shows and restores the GPT partition
> table.
> It looks into the "partitions" environment variable for partitions definition.
> It can be enabled at target configuration file with CONFIG_CMD_GPT.

> diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c

> +int set_gpt_info(block_dev_desc_t *dev_desc)
> +{
> +	char *ps[GPT_PARTS_NUM], *name[GPT_PARTS_NUM];
> +	unsigned int size[GPT_PARTS_NUM];
> +	char *tok, *t, *p, *s, *ss;
> +	int i, ret;
> +
> +	s = getenv("partitions");
> +	if (s == NULL) {
> +		printf("%s: \"partitions\" env variable not defined!\n",
> +		       __func__);
> +		return -1;
> +	}

It'd be nice to be able to pass the partition definition on the
command-line instead of (or perhaps as an alternative to) reading an
environment variable.

Some documentation of the expected format of the partitions variable
would be useful. From the following patch, the format appears to be:

8M(csa-mmc),60M(u-boot),60M(kernel),...

That's not particularly extensible (think about allowing partition type
UUID to or attributes to be specified), and the brackets are a bit
painful. Can we use key/value for defining the values, and have a simple
separate separator between fields and partitions, e.g. something like:

size=8M,name=csa-mmc;size=60M,name=u-boot;size=60M,name=kernel;...

That would allow us to very easily allow new fields to be specified per
partition in the future, e.g.:

uuid=XXXXX,size=512M,name=boot,type=21686148-6449-6E6F-744E-656564454649,attrs=2;uuid=YYYYY,size=7000M,name=root,type=0FC63DAF-8483-4772-8E79-3D69D8477DE4,attrs=0;...

> +U_BOOT_CMD(
> +	gpt,	CONFIG_SYS_MAXARGS,	1, do_gpt,
> +	"GUID Partition Table",
...
> +	"gpt restore - reset GPT partition to defaults\n"
> +	"gpt dev #num - set device number\n"
...
> +static void set_gpt_dev(int dev)
> +{
> +	gpt_dev = dev;
> +}
> +

Hmmm. I think it'd be better to specify the device each time the gpt
command was invoked. That would be simpler to use, more flexible, and
more consistent with how other commands such as "ext2load" operate.

In other words, I would get rid of "gpt dev" completely, and instead of
implementing "gpt restore", implement "gpt restore mmc 0".

I'm not sure "restore" is the correct name, given that the command can
write arbitrary new partition layouts, rather than just restoring some
specific hard-coded table from e.g. a backup image.

I'm not sure that "gpt" is even the best command name; it'd be nice if
this were generic and could be extended to work with e.g. FAT in the
future - something like:

part write usb 1 gpt uuid=XXXXX,size=512M,name=boot,...
part write mmc 0 fat size=512M,attrs=0x80;...

> +U_BOOT_CMD(
> +	gpt,	CONFIG_SYS_MAXARGS,	1, do_gpt,
> +	"GUID Partition Table",
> +	"show - show GPT\n"

s/show/gpt show/

> +static void gpt_show(void)
> +{
> +	struct mmc *mmc = find_mmc_device(gpt_dev);
> +
> +	print_part_efi(&mmc->block_dev);
> +}

Do we really need another way of showing partition tables; "mmc part",
"usb part", ... already exist. I think if we want another way, it'd be
better to add this functionality to my proposed "part" command, i.e.
"part show mmc 0".

> +static int gpt_default(void)
> +{
> +	struct mmc *mmc = find_mmc_device(gpt_dev);
> +
> +	if (mmc == NULL) {
> +		printf("%s: mmc dev %d NOT available\n", __func__, gpt_dev);
> +		return CMD_RET_FAILURE;
> +	}

Why only allow mmc devices; what about USB for example? Other commands
such as ext2load allow arbitrary device types to be used. Rob Herring
recently posted some patches to unify how commands such as ext2load,
ext2ls, fatload, fatls, ... all obtain a device/partition handle from
their command-line - this patch should probably build on top of those
patches.

> +	puts("Using default GPT UUID\n");
> +
> +	return set_gpt_info(&mmc->block_dev);
> +}

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration
  2012-08-24  8:13 ` [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
  2012-09-05 19:49   ` Stephen Warren
@ 2012-09-05 20:19   ` Stephen Warren
  2012-10-03 23:00   ` [U-Boot] [U-Boot, " Tom Rini
  2 siblings, 0 replies; 95+ messages in thread
From: Stephen Warren @ 2012-09-05 20:19 UTC (permalink / raw)
  To: u-boot

On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> The restoration of GPT table (both primary and secondary) is now possible.
> Simple GUID generation is supported.

> +/**
> + * guid_gen(): Generate UUID
> + *
> + * @param dev_desc - block device descriptor
> + *
> + * @return - generated UUID table
> + *
> + * NOTE: The entrophy of this function is small
> + */
> +static u8 *guid_gen(block_dev_desc_t * dev_desc)
> +{
> +	int k = 0;
> +	static int i = 1;
> +	static u8 __aligned(CONFIG_SYS_CACHELINE_SIZE) guid[16];

Hmmm. Wouldn't it be better to take a pointer to the GUID as a parameter
rather than returning a pointer to the same static over and over again.
That way, the caller won't cause problems if they call this function 4
times, and cache the pointer each time.

> +	static u8 __aligned(CONFIG_SYS_CACHELINE_SIZE) ent_pool[512];
> +	u32 *ptr = (u32 *) guid;
> +
> +	/* Entrophy initialization - read random content of one SD sector */
> +	if (i == 1) {
> +		debug("Init entropy:%x\n", (u32)(dev_desc->lba >> 14));
> +
> +		if (dev_desc->block_read(dev_desc->dev, (dev_desc->lba >> 14),
> +					 1, (u32 *) ent_pool) != 1) {

I imagine you might get more entropy out of just reading sector 0, or 1
(or both) than some random sector in the middle of the disk, which quite
possibly won't ever have been written to.

Is there any particular reason why ">> 14" rather than any other shift?

> +			printf("** Can't read from device %d **\n",
> +			       dev_desc->dev);
> +		}
> +	}
> +
> +	for (k = 0; k < 4; k++) {
> +		*(ptr + k) = efi_crc32((const void *) ent_pool,
> +				       sizeof(ent_pool));
> +		ent_pool[511 - k] = *(ptr + k);
> +	}
> +
> +	ent_pool[0] = ((u8) i) & 0xff;

That doesn't quite implement a fully compliant UUID. According to:

http://en.wikipedia.org/wiki/Universally_unique_identifier

the "variant" (UUID) and "version" (4; random) should be encoded into a
few specific bits of the final UUID value.

> +	debug("GUID: ");
> +	for (k = 0; k < sizeof(guid); k++)
> +		debug(" %x ", guid[k]);

I think inventing (stealing from Linux) a proper UUID formatting
function would be useful; that way it could be shared by
print_part_efi() if that function was ever enhanced to print the
partition UUID and partition type UUID.

> +	debug("     i:%d,\n", i);
> +
> +	i++;
> +	return guid;
> +}

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] gpt: GUID/UUID - GPT restoration - open questions
  2012-08-24  8:48 ` [U-Boot] gpt: GUID/UUID - GPT restoration - open questions Lukasz Majewski
@ 2012-09-05 20:21   ` Stephen Warren
  2012-09-06 11:27     ` Lukasz Majewski
  2012-09-06 12:27   ` Rob Herring
  1 sibling, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-05 20:21 UTC (permalink / raw)
  To: u-boot

On 08/24/2012 02:48 AM, Lukasz Majewski wrote:
> Hi Stephen,
> 
> I'm writing to you, since I've posted a patch series regarding GPT
> support for Samsung Trats board (you were on the CC).
> 
> e.g. http://patchwork.ozlabs.org/patch/179785/
> 
> I think, that we can cooperate to provide better EFI/GPT support.
> 
> In mine implementation the "gpt" command (with several sub commands) has
> been proposed
> - we can discuss if this is a correct way to go.
> 
> Moreover, at this patch series a "weak" GUID generator is implemented.
> For now it is "good enough", since I consider the restoration as an
> emergency situation.

I think that (perhaps optionally) allowing the user to specify their own
UUIDs would be a good idea; whatever was generating the script being
executed might have access to a better entropy source.

> However,I wonder how can we provide better GUID (and in general random
> numbers pool) generator for u-boot.
> 
> Maybe md5sum command can be used with some running clock (WDT, or
> system clock from u-boot start up) data to provide better entropy?

If there's a standard way of retrieving wall-clock, MAC address, ...
it'd definitely be a good idea to include those entropy sources.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 1/6] gpt:doc: GPT (GUID Partition Table) documentation
  2012-09-05 19:31   ` Stephen Warren
@ 2012-09-06  9:22     ` Lukasz Majewski
  0 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-06  9:22 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> > Documentation of the GPT table format.
> 
> > +++ b/doc/README.gpt
> 
> > +Glossary:
> > +========
> > +- UUID -(Universally Unique Identifier)
> > +- GUID - (Globally Unique ID)
> > +- EFI - (Extensible Firmware Interface)
> > +- UEFI - (Unified EFI) - EFI evolution
> > +- GPT (GUID Page Table) - it is the EFI standard part
> 
> GUID Partition Table, not Page.
> 
> > +- partitions - lists of availavle partitions (defined at u-boot):
> > +  ./include/configs/{target}.h
> > +
> > +Introduction:
> > +=============
> > +This document describes the GPT partition table format when used
> > with u-boot. +
> > +
> > +UUID introduction[5]:
> > +====================
> 
> What is "[5]"?
> 
> > +For instance, GUID of Linux data partition:
> > EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 +For u-boot GPT hyphens are
> > omitted.
> 
> I don't think U-Boot should omit any of the hyphens; it makes the
> UUIDs far more readable, and the strings can then be cut/paste
> to/from other applications that use/print UUIDs, without any manual
> conversion.
> 
> > +Historically there are 5 methods to generate this number. The
> > oldest one is +combining machine's MAC address and timer (epoch)
> > value. +
> > +Successive versions are using MD5 hash, random numbers and SHA-1
> > hash. All major +OSes and programming languages are providing
> > libraries to compute UUID. +
> > +However it costs in terms of the computational power and memory
> > footprint. +Therefore u-boot uses the crc32 with reading random
> > block (512B) from MMC +storage device to generate UUID/GUID.
> 
> That doesn't seem particularly relevant to general documentation about
> GPT; it's an implementation detail of the GPT creation command in a
> later patch, and could easily be changed.
> 
> In fact, I wonder why not require the user to concoct UUIDs and pass
> them to your GPT creation command, rather than forming them using some
> non-standard process.

I think that it is a good idea. User can use standard uuid command and
store its output as an environment variable.

> 
> > +GUID brief explanation:
> 
> Not "GUID", but "GPT".
> 
> > +======================
> > +
> > +	Layout:
> > +	-------
> > +
> > +	--------------------------------------------------
> > +	LBA 0          |Protective MBR                   |
> > +	----------------------------------------------------------
> > +	LBA 1          |Primary GPT Header               | Primary
> > +	-------------------------------------------------- GPT
> > +	LBA 2          |Entry 1|Entry 2| Entry 3| Entry 4|
> > +	--------------------------------------------------
> > +	LBA 3          |Entries 5 - 128                  |
> > +		       |                                 |
> > +		       |                                 |
> > +       -----------------------------------------------------------
> > +       LBA 34          |Partition 1                      |
> 
> The indentation looks inconsistent in this diagram

Strange, my emacs shows it correctly. I'll investigate the issue.
> 
> > +		       |                                 |
> > +		       -----------------------------------
> > +		       |Partition 2                      |
> > +		       |                                 |
> > +		       -----------------------------------
> > +		       |Partition n                      |
> > +		       |                                 |
> 
> > +       -----------------------------------------------------------
> > +       LBA -34         |Entry 1|Entry 2| Entry 3| Entry 4|
> > Secondary
> > +       --------------------------------------------------- (bkp)
> > +       LBA 34          |Partition 1                      |
> > +		       |                                 |
> > +		       -----------------------------------
> > +		       |Partition 2                      |
> > +		       |                                 |
> > +		       -----------------------------------
> > +		       |Partition n                      |
> > +		       |                                 |
> 
> That part of the diagram appears duplicated.
> 
> > +       -----------------------------------------------------------
> > +       LBA -34         |Entry 1|Entry 2| Entry 3| Entry 4|
> > Secondary
> > +       --------------------------------------------------- (bkp)
> > +       LBA -33         |Entries 5 - 128                  | GPT
> > +		       |                                 |
> > +		       |                                 |
> > +       LBA -2          |                                 |
> > +       ---------------------------------------------------
> > +       LBA -1          |Secondary GPT Header             |
> > +       -----------------------------------------------------------
> > +
> 
> > +	   Attribute flags (Don't used at u-boot):
> 
> I wouldn't write "Don't used at u-boot" since that's potentially
> subject to change. For example, I'm expecting to send a patch to use
> the "Legacy BIOS bootable" attribute soon.

Ok, I will correct this.

-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h>
  2012-09-05 19:45   ` Stephen Warren
@ 2012-09-06 10:15     ` Lukasz Majewski
  0 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-06 10:15 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> > Custom definitions of le_XX_to_int functions have been replaced with
> > standard ones, defined at <compiler.h>
> 
> > diff --git a/disk/part_efi.c b/disk/part_efi.c
> 
> > -/* Convert char[8] in little endian format to the host format
> > integer
> > - */
> > -static inline unsigned long long le64_to_int(unsigned char *le64)
> > -{
> 
> So this original function takes a pointer to the value ...
> 
> >  	/* Check the first_usable_lba and last_usable_lba are
> > within the disk. */ lastlba = (unsigned long long)dev_desc->lba;
> > -	if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
> > +	if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) {
> 
> At this point in the series, first_usable_lba is a char[8], so this is
> passing the address of the first byte to both the original function
> le64_to_int(), and the replacement function le64_to_cpu(). However,
> le64_to_cpu() expects to receive the 64-bit value to swap, not a
> pointer to it - from compiler.h:
> 
> #define _uswap_64(x, sfx) \
>         ((((x) & 0xff00000000000000##sfx) >> 56) | \
> ...
> # define uswap_64(x) _uswap_64(x, ull)
> 
> le:
> # define le64_to_cpu(x)         (x)
> be:
> # define le64_to_cpu(x)         uswap_64(x)
> 
> So I think this patch breaks the code, and then the next patch fixes
> it, since it changes the type of first_usable_lba from char[8] to
> __le64?

First of all, thanks for very thorough review. 

You are right, my fault. Patch 2/6 and 3/6 shall be squashed together.
When squashed, no errors and warnings appear.

I've unnecessary separated them to show this two step change. For the
sake of bisecting - those shall be squashed. 


-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h>
  2012-09-05 19:35   ` Stephen Warren
@ 2012-09-06 10:20     ` Lukasz Majewski
  2012-09-06 18:53       ` Stephen Warren
  0 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-06 10:20 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> > Custom definitions of le_XX_to_int functions have been replaced with
> > standard ones, defined at <compiler.h>
> > 
> > Signed-off-by: Chang Hyun Park <chchch.park@samsung.com>
> > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> 
> Did Chang Hyun Park write this? If so, shouldn't git have generated a
> "From" header for him, to reflect his authorship upstream. I'm not
> sure how Kyungmin Park's S-o-b plays into this, since he's not
> sending the patch.

My work (for those patches) was based on Mr. Chang Hyum Park patches.
However I had to modify his work for patches submission.

Therefore I've added Mr. Chang in a first place to credit his effort to
this patch series creation.

Shall I do it in a different way?

-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 3/6] gpt: Replacement of GPT structures members with ones indicating endianness and size
  2012-09-05 19:41   ` Stephen Warren
@ 2012-09-06 10:24     ` Lukasz Majewski
  0 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-06 10:24 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> > Replacement of several GPT related structures members with ones
> > indicating its endianness and proper size.
> 
> This patch seems reasonable to me, but I'm surprised it doesn't
> require /any/ changes to the code that uses these structures in order
> to avoid warnings/errors. Is git bisect maintained by this series?

As I've written for Patch 2/6, this patch will be merged with patch 2/6 

-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration
  2012-09-05 19:49   ` Stephen Warren
@ 2012-09-06 11:19     ` Lukasz Majewski
  2012-09-06 18:55       ` Stephen Warren
  0 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-06 11:19 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> > The restoration of GPT table (both primary and secondary) is now
> > possible. Simple GUID generation is supported.
> 
> > diff --git a/include/part.h b/include/part.h
> 
> > +int set_gpt_table(block_dev_desc_t *dev_desc,
> > +		   int parts, unsigned int *blocks, char *name[]);
> 
> That interface seems very limiting; what if you want to select
> specific type UUIDs, set the partition attributes, leave gaps between
> the partitions, have the physical order of partitions (their block
> numbers) be different to the partition table ordering, etc.
> 
> I wonder if it wouldn't be better to take an array of structures here,
> and have each entry define all the properties of the partition. That
> would allow fields to be added to the structure to describe more
> information as we add more functionality.

I agree.

I'd propose following approach:

- set_gpt_table will receive a table with pointers to partition entries
  (up to 128 entries in this table). In this way one can easily define
  partition properties (which can be different for different
  commands/boards).

- I think, that Legacy MBR, and Primary/Secondary GPT shall be
  generated in the set_gpt_table function. However I expect a problem
  with one Primary/Secondary GPT field
  - the Disk GUID. We can read it from environment, generate it or
  hardcode it at ./include/boards/{target}.h


What is your opinion?

> 
> I didn't review the implementation.


-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] gpt: GUID/UUID - GPT restoration - open questions
  2012-09-05 20:21   ` Stephen Warren
@ 2012-09-06 11:27     ` Lukasz Majewski
  0 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-06 11:27 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> On 08/24/2012 02:48 AM, Lukasz Majewski wrote:
> > Hi Stephen,
> > 
> > I'm writing to you, since I've posted a patch series regarding GPT
> > support for Samsung Trats board (you were on the CC).
> > 
> > e.g. http://patchwork.ozlabs.org/patch/179785/
> > 
> > I think, that we can cooperate to provide better EFI/GPT support.
> > 
> > In mine implementation the "gpt" command (with several sub
> > commands) has been proposed
> > - we can discuss if this is a correct way to go.
> > 
> > Moreover, at this patch series a "weak" GUID generator is
> > implemented. For now it is "good enough", since I consider the
> > restoration as an emergency situation.
> 
> I think that (perhaps optionally) allowing the user to specify their
> own UUIDs would be a good idea; whatever was generating the script
> being executed might have access to a better entropy source.

I think, that passing UUID as the command argument would be a better
option than inventing own GUID generator, especially when tools like
uuid were available.

> 
> > However,I wonder how can we provide better GUID (and in general
> > random numbers pool) generator for u-boot.
> > 
> > Maybe md5sum command can be used with some running clock (WDT, or
> > system clock from u-boot start up) data to provide better entropy?
> 
> If there's a standard way of retrieving wall-clock, MAC address, ...
> it'd definitely be a good idea to include those entropy sources.
> 

-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] gpt: GUID/UUID - GPT restoration - open questions
  2012-08-24  8:48 ` [U-Boot] gpt: GUID/UUID - GPT restoration - open questions Lukasz Majewski
  2012-09-05 20:21   ` Stephen Warren
@ 2012-09-06 12:27   ` Rob Herring
  2012-09-06 14:14     ` Lukasz Majewski
  1 sibling, 1 reply; 95+ messages in thread
From: Rob Herring @ 2012-09-06 12:27 UTC (permalink / raw)
  To: u-boot

On 08/24/2012 03:48 AM, Lukasz Majewski wrote:
> Hi Stephen,
> 
> I'm writing to you, since I've posted a patch series regarding GPT
> support for Samsung Trats board (you were on the CC).
> 
> e.g. http://patchwork.ozlabs.org/patch/179785/
> 
> I think, that we can cooperate to provide better EFI/GPT support.
> 
> In mine implementation the "gpt" command (with several sub commands) has
> been proposed
> - we can discuss if this is a correct way to go.
> 
> Moreover, at this patch series a "weak" GUID generator is implemented.
> For now it is "good enough", since I consider the restoration as an
> emergency situation.
> However,I wonder how can we provide better GUID (and in general random
> numbers pool) generator for u-boot.
> 
> 
> Maybe md5sum command can be used with some running clock (WDT, or
> system clock from u-boot start up) data to provide better entropy?
> 
> Any ideas?

The question I'm asking is why we need partition creation support in
u-boot in the first place? Next you need filesystem creation too?

Rob

> 
> Regards,
> Lukasz
> 
>> This patch series provides a new command - "gpt" for eMMC partition
>> table (in the GPT format) restoration and display.
>>
>> As a pre-work, some cleanup at the part_efi.c file was performed to 
>> remove custom macros and make GPT related structures more readable. 
>>
>> The GPT detailed description has been written to README.gpt file.
>>
>> Tested at:
>> 	- Exynos4210 rev.1 - TRATS Samsung development board
>>
>> Lukasz Majewski (6):
>>   gpt:doc: GPT (GUID Partition Table) documentation
>>   gpt: Replace the leXX_to_int() calls with ones defined at
>>     <compiler.h>
>>   gpt: Replacement of GPT structures members with ones indicating
>>     endianness and size
>>   gpt: Support for GPT (GUID Partition Table) restoration
>>   gpt: Support for new "gpt" command
>>   gpt: Enable support for GPT partition table restoration at Samsung's
>>     Trats
>>
>>  common/Makefile         |    1 +
>>  common/cmd_gpt.c        |  182 ++++++++++++++++++++++++++
>>  disk/part_efi.c         |  334
>> +++++++++++++++++++++++++++++++++++++----------
>> disk/part_efi.h         |   85 ++++++------ doc/README.gpt
>> |  199 ++++++++++++++++++++++++++++ include/configs/trats.h |   23
>> +++- include/part.h          |    2 +
>>  7 files changed, 715 insertions(+), 111 deletions(-)
>>  create mode 100644 common/cmd_gpt.c
>>  create mode 100644 doc/README.gpt
>>
> 

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 5/6] gpt: Support for new "gpt" command
  2012-09-05 20:08   ` Stephen Warren
@ 2012-09-06 14:01     ` Lukasz Majewski
  0 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-06 14:01 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
> > New command - "gpt" is now supported. It shows and restores the GPT
> > partition table.
> > It looks into the "partitions" environment variable for partitions
> > definition. It can be enabled at target configuration file with
> > CONFIG_CMD_GPT.
> 
> > diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
> 
> > +int set_gpt_info(block_dev_desc_t *dev_desc)
> > +{
> > +	char *ps[GPT_PARTS_NUM], *name[GPT_PARTS_NUM];
> > +	unsigned int size[GPT_PARTS_NUM];
> > +	char *tok, *t, *p, *s, *ss;
> > +	int i, ret;
> > +
> > +	s = getenv("partitions");
> > +	if (s == NULL) {
> > +		printf("%s: \"partitions\" env variable not
> > defined!\n",
> > +		       __func__);
> > +		return -1;
> > +	}
> 
> It'd be nice to be able to pass the partition definition on the
> command-line instead of (or perhaps as an alternative to) reading an
> environment variable.
> 
> Some documentation of the expected format of the partitions variable
> would be useful. From the following patch, the format appears to be:
> 
> 8M(csa-mmc),60M(u-boot),60M(kernel),...
> 
> That's not particularly extensible (think about allowing partition
> type UUID to or attributes to be specified), and the brackets are a
> bit painful. Can we use key/value for defining the values, and have a
> simple separate separator between fields and partitions, e.g.
> something like:
> 
> size=8M,name=csa-mmc;size=60M,name=u-boot;size=60M,name=kernel;...
This approach looks reasonable, but...

> 
> That would allow us to very easily allow new fields to be specified
> per partition in the future, e.g.:
> 
> uuid=XXXXX,size=512M,name=boot,type=21686148-6449-6E6F-744E-656564454649,attrs=2;uuid=YYYYY,size=7000M,name=root,type=0FC63DAF-8483-4772-8E79-3D69D8477DE4,attrs=0;...

it would be a pain to paste so long string to u-boot command line.
Suppose we have 8 partitions to define. Then the definition string grows
considerable.

For default restoration, it would be good to define the environment
variable (like "partitions") to perform quick default restoration.

However there is a problem with passing UUID - size, name and
attributes can be defined at ./include/config/{board}.h
(partitions=size=8M,name=csa-mmc;size=60M,name=u-boot;size=60M,name=kernel)
, but UUID shall be passed by user via command line or generated
internally at u-boot (as it is proposed in this patch).

When passing from user it would look like:

gpt default uuid1 uuid2 .... uuid8

But we shall also think about using guid_gen() function (reimplemented)
for handy and quick gpt restoration.


> 
> > +U_BOOT_CMD(
> > +	gpt,	CONFIG_SYS_MAXARGS,	1, do_gpt,
> > +	"GUID Partition Table",
> ...
> > +	"gpt restore - reset GPT partition to defaults\n"
> > +	"gpt dev #num - set device number\n"
> ...
> > +static void set_gpt_dev(int dev)
> > +{
> > +	gpt_dev = dev;
> > +}
> > +
> 
> Hmmm. I think it'd be better to specify the device each time the gpt
> command was invoked. That would be simpler to use, more flexible, and
> more consistent with how other commands such as "ext2load" operate.
> 
> In other words, I would get rid of "gpt dev" completely, and instead
> of implementing "gpt restore", implement "gpt restore mmc 0".

Agree - the same approach is in dfu.

> 
> I'm not sure "restore" is the correct name, given that the command can
> write arbitrary new partition layouts, rather than just restoring some
> specific hard-coded table from e.g. a backup image.
> 
> I'm not sure that "gpt" is even the best command name; it'd be nice if
> this were generic and could be extended to work with e.g. FAT in the
> future - something like:
> 
> part write usb 1 gpt uuid=XXXXX,size=512M,name=boot,...
> part write mmc 0 fat size=512M,attrs=0x80;...

I'm open for discussion. Since part command is not yet finished, I will
use the gpt command for version 2 of this patch series. When we agree
with rest of GPT implementation we can decide if gpt or part command
will be used. OK?
> 
> > +U_BOOT_CMD(
> > +	gpt,	CONFIG_SYS_MAXARGS,	1, do_gpt,
> > +	"GUID Partition Table",
> > +	"show - show GPT\n"
> 
> s/show/gpt show/
> 
> > +static void gpt_show(void)
> > +{
> > +	struct mmc *mmc = find_mmc_device(gpt_dev);
> > +
> > +	print_part_efi(&mmc->block_dev);
> > +}
> 
> Do we really need another way of showing partition tables; "mmc part",
> "usb part", ... already exist. I think if we want another way, it'd be
> better to add this functionality to my proposed "part" command, i.e.
> "part show mmc 0".

I agree that "gpt show" is not needed. Instead "mmc part" can be used.
> 
> > +static int gpt_default(void)
> > +{
> > +	struct mmc *mmc = find_mmc_device(gpt_dev);
> > +
> > +	if (mmc == NULL) {
> > +		printf("%s: mmc dev %d NOT available\n", __func__,
> > gpt_dev);
> > +		return CMD_RET_FAILURE;
> > +	}
> 
> Why only allow mmc devices; what about USB for example? Other commands
> such as ext2load allow arbitrary device types to be used. Rob Herring
> recently posted some patches to unify how commands such as ext2load,
> ext2ls, fatload, fatls, ... all obtain a device/partition handle from
> their command-line - this patch should probably build on top of those
> patches.

Yes, but Rob's patches are not yet accepted to mainline. I'd prefer to
not use patches which aren't accepted as a base for development. 

> 
> > +	puts("Using default GPT UUID\n");
> > +
> > +	return set_gpt_info(&mmc->block_dev);
> > +}
> 


I think, that most important change is to pass table with pointers to
partition entries to set_gpt_table. Second thing is to fix guid_gen()
function and change the format of "partitions" to be key=value pairs.


-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] gpt: GUID/UUID - GPT restoration - open questions
  2012-09-06 12:27   ` Rob Herring
@ 2012-09-06 14:14     ` Lukasz Majewski
  2012-09-06 18:57       ` Stephen Warren
  0 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-06 14:14 UTC (permalink / raw)
  To: u-boot

Hi Rob,

> The question I'm asking is why we need partition creation support in
> u-boot in the first place? 

Please consider following scenarios:

1. eMMC content is exported to the user (via UMS USB Mass Storage). Then
user by chance or on purpose will corrupt MBR/GPT.

2. misuse of "mmc" command - user by chance writes mmc erase 0.

To unbrick the device one would simply use "gpt/part restore" command
with already defined at ./include/config/{target}.h default settings
for partitions.

> Next you need filesystem creation too?

I can use UMS to export eMMC to host PC (with restored partitions) and
then use mkfs.* to create proper file system.


-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h>
  2012-09-06 10:20     ` Lukasz Majewski
@ 2012-09-06 18:53       ` Stephen Warren
       [not found]         ` <SNT002-W181FE3CE14BE68990CDF80CCB920@phx.gbl>
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-06 18:53 UTC (permalink / raw)
  To: u-boot

On 09/06/2012 04:20 AM, Lukasz Majewski wrote:
> Hi Stephen,
> 
>> On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
>>> Custom definitions of le_XX_to_int functions have been replaced with
>>> standard ones, defined at <compiler.h>
>>>
>>> Signed-off-by: Chang Hyun Park <chchch.park@samsung.com>
>>> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
>>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>>
>> Did Chang Hyun Park write this? If so, shouldn't git have generated a
>> "From" header for him, to reflect his authorship upstream. I'm not
>> sure how Kyungmin Park's S-o-b plays into this, since he's not
>> sending the patch.
> 
> My work (for those patches) was based on Mr. Chang Hyum Park patches.
> However I had to modify his work for patches submission.
> 
> Therefore I've added Mr. Chang in a first place to credit his effort to
> this patch series creation.
> 
> Shall I do it in a different way?

To be honest, I'm not really sure. When I've done this, I've kept the
original author in the git "author" field to show this, and then listed
what I changed in the commit description. Whether that's the right way
to go perhaps depends on the size of your changes. If your changes are
so large that it doesn't make sense to do that, perhaps his S-o-b should
be removed and replaced with a simple note "based on work by Chang Hyun
Park <chchch.park@samsung.com>"?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration
  2012-09-06 11:19     ` Lukasz Majewski
@ 2012-09-06 18:55       ` Stephen Warren
  0 siblings, 0 replies; 95+ messages in thread
From: Stephen Warren @ 2012-09-06 18:55 UTC (permalink / raw)
  To: u-boot

On 09/06/2012 05:19 AM, Lukasz Majewski wrote:
> Hi Stephen,
> 
>> On 08/24/2012 02:13 AM, Lukasz Majewski wrote:
>>> The restoration of GPT table (both primary and secondary) is now
>>> possible. Simple GUID generation is supported.
>>
>>> diff --git a/include/part.h b/include/part.h
>>
>>> +int set_gpt_table(block_dev_desc_t *dev_desc,
>>> +		   int parts, unsigned int *blocks, char *name[]);
>>
>> That interface seems very limiting; what if you want to select
>> specific type UUIDs, set the partition attributes, leave gaps between
>> the partitions, have the physical order of partitions (their block
>> numbers) be different to the partition table ordering, etc.
>>
>> I wonder if it wouldn't be better to take an array of structures here,
>> and have each entry define all the properties of the partition. That
>> would allow fields to be added to the structure to describe more
>> information as we add more functionality.
> 
> I agree.
> 
> I'd propose following approach:
> 
> - set_gpt_table will receive a table with pointers to partition entries
>   (up to 128 entries in this table). In this way one can easily define
>   partition properties (which can be different for different
>   commands/boards).
> 
> - I think, that Legacy MBR, and Primary/Secondary GPT shall be
>   generated in the set_gpt_table function. However I expect a problem
>   with one Primary/Secondary GPT field
>   - the Disk GUID. We can read it from environment, generate it or
>   hardcode it at ./include/boards/{target}.h
> 
> 
> What is your opinion?

Perhaps rather than /just/ taking a pointer to a table of partitions,
take a pointer to a struct, which can hold both global properties and a
pointer to the list of partitions?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] gpt: GUID/UUID - GPT restoration - open questions
  2012-09-06 14:14     ` Lukasz Majewski
@ 2012-09-06 18:57       ` Stephen Warren
  2012-09-07  6:45         ` Lukasz Majewski
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-06 18:57 UTC (permalink / raw)
  To: u-boot

On 09/06/2012 08:14 AM, Lukasz Majewski wrote:
> Hi Rob,
> 
>> The question I'm asking is why we need partition creation support in
>> u-boot in the first place? 
> 
> Please consider following scenarios:
> 
> 1. eMMC content is exported to the user (via UMS USB Mass Storage). Then
> user by chance or on purpose will corrupt MBR/GPT.
> 
> 2. misuse of "mmc" command - user by chance writes mmc erase 0.
> 
> To unbrick the device one would simply use "gpt/part restore" command
> with already defined at ./include/config/{target}.h default settings
> for partitions.
> 
>> Next you need filesystem creation too?
> 
> I can use UMS to export eMMC to host PC (with restored partitions) and
> then use mkfs.* to create proper file system.

In that case, wouldn't you be exposing the entire eMMC device over UMS,
and hence the user could just run fdisk/parted/... on the host, just
like you're proposing they run mkfs on the host?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] gpt: GUID/UUID - GPT restoration - open questions
  2012-09-06 18:57       ` Stephen Warren
@ 2012-09-07  6:45         ` Lukasz Majewski
  0 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-07  6:45 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> On 09/06/2012 08:14 AM, Lukasz Majewski wrote:
> > Hi Rob,
> > 
> >> The question I'm asking is why we need partition creation support
> >> in u-boot in the first place? 
> > 
> > Please consider following scenarios:
> > 
> > 1. eMMC content is exported to the user (via UMS USB Mass Storage).
> > Then user by chance or on purpose will corrupt MBR/GPT.
> > 
> > 2. misuse of "mmc" command - user by chance writes mmc erase 0.
> > 
> > To unbrick the device one would simply use "gpt/part restore"
> > command with already defined at ./include/config/{target}.h default
> > settings for partitions.
> > 
> >> Next you need filesystem creation too?
> > 
> > I can use UMS to export eMMC to host PC (with restored partitions)
> > and then use mkfs.* to create proper file system.
> 
> In that case, wouldn't you be exposing the entire eMMC device over
> UMS, and hence the user could just run fdisk/parted/... on the host,
> just like you're proposing they run mkfs on the host?

This would be one option for restoring GPT table.

However, I believe, that there also should be a separate gpt command to
do the trick and restore default GPT (with default partitions) only
from u-boot (with no UMS interaction).

Additionally it is far more user friendly, when one type "gpt default"
and default partitions are restored for a particular board (stored
at ./include/configs/{board}.h .

-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h>
       [not found]         ` <SNT002-W181FE3CE14BE68990CDF80CCB920@phx.gbl>
@ 2012-09-12 14:42           ` Lukasz Majewski
  0 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-12 14:42 UTC (permalink / raw)
  To: u-boot

Hi Chang Hyun,

> Hello Lukasz, Stephen, 
> I see there has been quite a few mails going back and forth on the
> mailing list on the "gpt: Replace the leXX_to_int() calls with ones
> defined at <compiler.h>"I haven't been receiving the e-mails because
> my samsung e-mail account has expired.(Internship expired)(I just
> happened to run into the mails from a google search) Is there
> anything I should catch up on? Anything I should be doing?And on
> which fork is this commit being pushed onto? Thank you.
> 

I've changed you as an author of the commit. I will also add your
"private" e-mail to CC when I send gpt v2, so stay tunned :-)


-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 0/7] gpt: GUID Partition Table (GPT) restoration
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
                   ` (8 preceding siblings ...)
  2012-09-03  9:30 ` [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
@ 2012-09-12 14:50 ` Lukasz Majewski
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 1/7] vsprintf:fix: Change type returned by ustrtoul Lukasz Majewski
                     ` (7 more replies)
  2012-09-13  8:09 ` [U-Boot] [PATCH v3 " Lukasz Majewski
  2012-11-09  9:22 ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Piotr Wilczek
  11 siblings, 8 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-12 14:50 UTC (permalink / raw)
  To: u-boot

This patch series provides a new command - "gpt" for eMMC partition table
(in the GPT format) restoration.

As a pre-work, some cleanup at the part_efi.c file was performed to
remove custom macros and make GPT related structures more readable.

Moreover the part_efi.h file has been moved to ./include directory to
be easily available from other subsystems.

The GPT detailed description has been written to README.gpt file.

Tested at:
        - Exynos4210 rev.1 - TRATS Samsung development board


Chang Hyun Park (1):
  gpt: The leXX_to_int() calls replaced with ones defined at
    <compiler.h>

Lukasz Majewski (6):
  vsprintf:fix: Change type returned by ustrtoul
  part:efi: Move part_efi.h file to ./include
  gpt:doc: GPT (GUID Partition Table) documentation
  gpt: Support for GPT (GUID Partition Table) restoration
  gpt: Support for new "gpt" command
  gpt: Enable support for GPT partition table restoration at Samsung's
    Trats

 common/Makefile         |    1 +
 common/cmd_gpt.c        |  405 +++++++++++++++++++++++++++++++++++++++++++++++
 disk/part_efi.c         |  210 ++++++++++++++++--------
 disk/part_efi.h         |  139 ----------------
 doc/README.gpt          |  207 ++++++++++++++++++++++++
 include/configs/trats.h |   23 +++-
 include/exports.h       |    2 +-
 include/part.h          |    3 +
 include/part_efi.h      |  143 +++++++++++++++++
 lib/vsprintf.c          |    2 +-
 10 files changed, 923 insertions(+), 212 deletions(-)
 create mode 100644 common/cmd_gpt.c
 delete mode 100644 disk/part_efi.h
 create mode 100644 doc/README.gpt
 create mode 100644 include/part_efi.h

-- 
1.7.2.3

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 1/7] vsprintf:fix: Change type returned by ustrtoul
  2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
@ 2012-09-12 14:50   ` Lukasz Majewski
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 2/7] part:efi: Move part_efi.h file to ./include Lukasz Majewski
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-12 14:50 UTC (permalink / raw)
  To: u-boot

The ustrtoul shall convert string defined size (e.g. 1GiB) to unsigned
long type (as its name implies).

Up till now it had returned int, which might cause problems with large
numbers (GiB range), when interpreted as U2 signed numbers.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 include/exports.h |    2 +-
 lib/vsprintf.c    |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/exports.h b/include/exports.h
index 63aa4b2..6cf31aa 100644
--- a/include/exports.h
+++ b/include/exports.h
@@ -23,7 +23,7 @@ char *getenv (const char *name);
 int setenv (const char *varname, const char *varvalue);
 long simple_strtol(const char *cp,char **endp,unsigned int base);
 int strcmp(const char * cs,const char * ct);
-int ustrtoul(const char *cp, char **endp, unsigned int base);
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
 #if defined(CONFIG_CMD_I2C)
 int i2c_write (uchar, uint, int , uchar* , int);
 int i2c_read (uchar, uint, int , uchar* , int);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index e38a4b7..27cb836 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -98,7 +98,7 @@ long simple_strtol(const char *cp,char **endp,unsigned int base)
 	return simple_strtoul(cp,endp,base);
 }
 
-int ustrtoul(const char *cp, char **endp, unsigned int base)
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
 {
 	unsigned long result = simple_strtoul(cp, endp, base);
 	switch (**endp) {
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 2/7] part:efi: Move part_efi.h file to ./include
  2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 1/7] vsprintf:fix: Change type returned by ustrtoul Lukasz Majewski
@ 2012-09-12 14:50   ` Lukasz Majewski
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 3/7] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-12 14:50 UTC (permalink / raw)
  To: u-boot

This move is necessary to export gpt header and GPT partition entries to be
used with other commands or subsystems (like DFU in the future)
Additionally the part_efi.h file has been cleaned-up to supress checkpatch's
warnings.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 disk/part_efi.c    |    2 +-
 disk/part_efi.h    |  139 ---------------------------------------------------
 include/part_efi.h |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 141 insertions(+), 140 deletions(-)
 delete mode 100644 disk/part_efi.h
 create mode 100644 include/part_efi.h

diff --git a/disk/part_efi.c b/disk/part_efi.c
index 02927a0..b2233da 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -34,7 +34,7 @@
 #include <command.h>
 #include <ide.h>
 #include <malloc.h>
-#include "part_efi.h"
+#include <part_efi.h>
 #include <linux/ctype.h>
 
 #if defined(CONFIG_CMD_IDE) || \
diff --git a/disk/part_efi.h b/disk/part_efi.h
deleted file mode 100644
index 5903e7c..0000000
--- a/disk/part_efi.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2008 RuggedCom, Inc.
- * Richard Retanubun <RichardRetanubun@RuggedCom.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * See also linux/fs/partitions/efi.h
- *
- * EFI GUID Partition Table
- * Per Intel EFI Specification v1.02
- * http://developer.intel.com/technology/efi/efi.htm
-*/
-
-#ifndef _DISK_PART_EFI_H
-#define _DISK_PART_EFI_H
-
-#define MSDOS_MBR_SIGNATURE 0xAA55
-#define EFI_PMBR_OSTYPE_EFI 0xEF
-#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
-
-#define GPT_BLOCK_SIZE 512
-#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
-#define GPT_HEADER_REVISION_V1 0x00010000
-#define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
-#define GPT_ENTRY_NAME "gpt"
-
-#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-	((efi_guid_t) \
-	{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
-		(b) & 0xff, ((b) >> 8) & 0xff, \
-		(c) & 0xff, ((c) >> 8) & 0xff, \
-		(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
-
-#define PARTITION_SYSTEM_GUID \
-	EFI_GUID( 0xC12A7328, 0xF81F, 0x11d2, \
-		0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B)
-#define LEGACY_MBR_PARTITION_GUID \
-	EFI_GUID( 0x024DEE41, 0x33E7, 0x11d3, \
-		0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F)
-#define PARTITION_MSFT_RESERVED_GUID \
-	EFI_GUID( 0xE3C9E316, 0x0B5C, 0x4DB8, \
-		0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE)
-#define PARTITION_BASIC_DATA_GUID \
-	EFI_GUID( 0xEBD0A0A2, 0xB9E5, 0x4433, \
-		0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7)
-#define PARTITION_LINUX_RAID_GUID \
-	EFI_GUID( 0xa19d880f, 0x05fc, 0x4d3b, \
-		0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e)
-#define PARTITION_LINUX_SWAP_GUID \
-	EFI_GUID( 0x0657fd6d, 0xa4ab, 0x43c4, \
-		0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f)
-#define PARTITION_LINUX_LVM_GUID \
-	EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
-		0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
-
-/* linux/include/efi.h */
-typedef unsigned short efi_char16_t;
-
-typedef struct {
-	unsigned char b[16];
-} efi_guid_t;
-
-/* based on linux/include/genhd.h */
-struct partition {
-	unsigned char boot_ind;		/* 0x80 - active */
-	unsigned char head;		/* starting head */
-	unsigned char sector;		/* starting sector */
-	unsigned char cyl;		/* starting cylinder */
-	unsigned char sys_ind;		/* What partition type */
-	unsigned char end_head;		/* end head */
-	unsigned char end_sector;	/* end sector */
-	unsigned char end_cyl;		/* end cylinder */
-	unsigned char start_sect[4];	/* starting sector counting from 0 */
-	unsigned char nr_sects[4];	/* nr of sectors in partition */
-} __attribute__ ((packed));
-
-/* based on linux/fs/partitions/efi.h */
-typedef struct _gpt_header {
-	unsigned char signature[8];
-	unsigned char revision[4];
-	unsigned char header_size[4];
-	unsigned char header_crc32[4];
-	unsigned char reserved1[4];
-	unsigned char my_lba[8];
-	unsigned char alternate_lba[8];
-	unsigned char first_usable_lba[8];
-	unsigned char last_usable_lba[8];
-	efi_guid_t disk_guid;
-	unsigned char partition_entry_lba[8];
-	unsigned char num_partition_entries[4];
-	unsigned char sizeof_partition_entry[4];
-	unsigned char partition_entry_array_crc32[4];
-	unsigned char reserved2[GPT_BLOCK_SIZE - 92];
-} __attribute__ ((packed)) gpt_header;
-
-typedef struct _gpt_entry_attributes {
-	unsigned long long required_to_function:1;
-	unsigned long long reserved:47;
-	unsigned long long type_guid_specific:16;
-} __attribute__ ((packed)) gpt_entry_attributes;
-
-#define PARTNAME_SZ	(72 / sizeof(efi_char16_t))
-typedef struct _gpt_entry {
-	efi_guid_t partition_type_guid;
-	efi_guid_t unique_partition_guid;
-	unsigned char starting_lba[8];
-	unsigned char ending_lba[8];
-	gpt_entry_attributes attributes;
-	efi_char16_t partition_name[PARTNAME_SZ];
-}
-__attribute__ ((packed)) gpt_entry;
-
-typedef struct _legacy_mbr {
-	unsigned char boot_code[440];
-	unsigned char unique_mbr_signature[4];
-	unsigned char unknown[2];
-	struct partition partition_record[4];
-	unsigned char signature[2];
-} __attribute__ ((packed)) legacy_mbr;
-
-#endif	/* _DISK_PART_EFI_H */
diff --git a/include/part_efi.h b/include/part_efi.h
new file mode 100644
index 0000000..a9d4399
--- /dev/null
+++ b/include/part_efi.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2008 RuggedCom, Inc.
+ * Richard Retanubun <RichardRetanubun@RuggedCom.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * See also linux/fs/partitions/efi.h
+ *
+ * EFI GUID Partition Table
+ * Per Intel EFI Specification v1.02
+ * http://developer.intel.com/technology/efi/efi.htm
+*/
+
+#ifndef _DISK_PART_EFI_H
+#define _DISK_PART_EFI_H
+
+#define MSDOS_MBR_SIGNATURE 0xAA55
+#define EFI_PMBR_OSTYPE_EFI 0xEF
+#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
+
+#define GPT_BLOCK_SIZE 512
+#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
+#define GPT_HEADER_REVISION_V1 0x00010000
+#define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
+#define GPT_ENTRY_NAME "gpt"
+
+#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
+	((efi_guid_t) \
+	{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, \
+		((a) >> 24) & 0xff, \
+		(b) & 0xff, ((b) >> 8) & 0xff, \
+		(c) & 0xff, ((c) >> 8) & 0xff, \
+		(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
+
+#define PARTITION_SYSTEM_GUID \
+	EFI_GUID(0xC12A7328, 0xF81F, 0x11d2, \
+		0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B)
+#define LEGACY_MBR_PARTITION_GUID \
+	EFI_GUID(0x024DEE41, 0x33E7, 0x11d3, \
+		0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F)
+#define PARTITION_MSFT_RESERVED_GUID \
+	EFI_GUID(0xE3C9E316, 0x0B5C, 0x4DB8, \
+		0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE)
+#define PARTITION_BASIC_DATA_GUID \
+	EFI_GUID(0xEBD0A0A2, 0xB9E5, 0x4433, \
+		0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7)
+#define PARTITION_LINUX_RAID_GUID \
+	EFI_GUID(0xa19d880f, 0x05fc, 0x4d3b, \
+		0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e)
+#define PARTITION_LINUX_SWAP_GUID \
+	EFI_GUID(0x0657fd6d, 0xa4ab, 0x43c4, \
+		0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f)
+#define PARTITION_LINUX_LVM_GUID \
+	EFI_GUID(0xe6d6d379, 0xf507, 0x44c2, \
+		0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
+
+/* linux/include/efi.h */
+typedef unsigned short efi_char16_t;
+
+typedef struct {
+	unsigned char b[16];
+} efi_guid_t;
+
+/* based on linux/include/genhd.h */
+struct partition {
+	unsigned char boot_ind;		/* 0x80 - active */
+	unsigned char head;		/* starting head */
+	unsigned char sector;		/* starting sector */
+	unsigned char cyl;		/* starting cylinder */
+	unsigned char sys_ind;		/* What partition type */
+	unsigned char end_head;		/* end head */
+	unsigned char end_sector;	/* end sector */
+	unsigned char end_cyl;		/* end cylinder */
+	unsigned char start_sect[4];	/* starting sector counting from 0 */
+	unsigned char nr_sects[4];	/* nr of sectors in partition */
+} __attribute__ ((packed));
+
+/* based on linux/fs/partitions/efi.h */
+typedef struct _gpt_header {
+	unsigned char signature[8];
+	unsigned char revision[4];
+	unsigned char header_size[4];
+	unsigned char header_crc32[4];
+	unsigned char reserved1[4];
+	unsigned char my_lba[8];
+	unsigned char alternate_lba[8];
+	unsigned char first_usable_lba[8];
+	unsigned char last_usable_lba[8];
+	efi_guid_t disk_guid;
+	unsigned char partition_entry_lba[8];
+	unsigned char num_partition_entries[4];
+	unsigned char sizeof_partition_entry[4];
+	unsigned char partition_entry_array_crc32[4];
+	unsigned char reserved2[GPT_BLOCK_SIZE - 92];
+} __attribute__ ((packed)) gpt_header;
+
+typedef struct _gpt_entry_attributes {
+	unsigned long long required_to_function:1;
+	unsigned long long reserved:47;
+	unsigned long long type_guid_specific:16;
+} __attribute__ ((packed)) gpt_entry_attributes;
+
+#define PARTNAME_SZ	(72 / sizeof(efi_char16_t))
+typedef struct _gpt_entry {
+	efi_guid_t partition_type_guid;
+	efi_guid_t unique_partition_guid;
+	unsigned char starting_lba[8];
+	unsigned char ending_lba[8];
+	gpt_entry_attributes attributes;
+	efi_char16_t partition_name[PARTNAME_SZ];
+}
+__attribute__ ((packed)) gpt_entry;
+
+typedef struct _legacy_mbr {
+	unsigned char boot_code[440];
+	unsigned char unique_mbr_signature[4];
+	unsigned char unknown[2];
+	struct partition partition_record[4];
+	unsigned char signature[2];
+} __attribute__ ((packed)) legacy_mbr;
+
+#endif	/* _DISK_PART_EFI_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot]  [PATCH v2 3/7] gpt:doc: GPT (GUID Partition Table) documentation
  2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 1/7] vsprintf:fix: Change type returned by ustrtoul Lukasz Majewski
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 2/7] part:efi: Move part_efi.h file to ./include Lukasz Majewski
@ 2012-09-12 14:50   ` Lukasz Majewski
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Lukasz Majewski
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-12 14:50 UTC (permalink / raw)
  To: u-boot

Documentation of the GPT format.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v2:
- Typos correction.
- Adding guidlines about GPT restoration.
- Adding information about GUID generator
---
 doc/README.gpt |  207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 207 insertions(+), 0 deletions(-)
 create mode 100644 doc/README.gpt

diff --git a/doc/README.gpt b/doc/README.gpt
new file mode 100644
index 0000000..ec56005
--- /dev/null
+++ b/doc/README.gpt
@@ -0,0 +1,207 @@
+#
+#  Copyright (C) 2012 Samsung Electronics
+#
+#  Lukasz Majewski <l.majewski@samsung.com>
+#
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+
+
+Glossary:
+========
+- UUID -(Universally Unique Identifier)
+- GUID - (Globally Unique ID)
+- EFI - (Extensible Firmware Interface)
+- UEFI - (Unified EFI) - EFI evolution
+- GPT (GUID Partition Table) - it is the EFI standard part
+- partitions - lists of available partitions (defined at u-boot):
+  ./include/configs/{target}.h
+
+Introduction:
+=============
+This document describes the GPT partition table format when used with u-boot.
+
+
+UUID introduction:
+====================
+
+GPT for marking disks/partitions is using the UUID. It is supposed to be a
+globally unique value. A UUID is a 16-byte (128-bit) number. The number of
+theoretically possible UUIDs is therefore about 3 ? 10^38.
+More often UUID is stored as 32 hexadecimal digits, displayed in 5 groups
+separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters
+(32 digits and 4 hyphens)
+
+For instance, GUID of Linux data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
+
+Historically there are 5 methods to generate this number. The oldest one is
+combining machine's MAC address and timer (epoch) value.
+
+Successive versions are using MD5 hash, random numbers and SHA-1 hash. All major
+OSes and programming languages are providing libraries to compute UUID (e.g.
+uuid command line tool).
+
+GPT brief explanation:
+======================
+
+	Layout:
+	-------
+
+	--------------------------------------------------
+	LBA 0          |Protective MBR                   |
+	----------------------------------------------------------
+	LBA 1          |Primary GPT Header               | Primary
+	-------------------------------------------------- GPT
+	LBA 2          |Entry 1|Entry 2| Entry 3| Entry 4|
+	--------------------------------------------------
+	LBA 3          |Entries 5 - 128                  |
+		       |                                 |
+		       |                                 |
+	----------------------------------------------------------
+	LBA 34         |Partition 1                      |
+		       |                                 |
+		       -----------------------------------
+		       |Partition 2                      |
+		       |                                 |
+		       -----------------------------------
+		       |Partition n                      |
+		       |                                 |
+	----------------------------------------------------------
+	LBA -34        |Entry 1|Entry 2| Entry 3| Entry 4| Secondary
+	-------------------------------------------------- (bkp)
+	LBA -33        |Entries 5 - 128                  | GPT
+		       |                                 |
+		       |                                 |
+	LBA -2         |                                 |
+	--------------------------------------------------
+	LBA -1         |Secondary GPT Header             |
+	----------------------------------------------------------
+
+
+For a legacy reasons, GPT's LBA 0 sector has a MBR structure. It is called
+"protective MBR".
+Its first partition entry ID has 0xEE value, and disk software, which is not
+handling the GPT sees it as a storage device without free space.
+
+It is possible to define 128 linearly placed partition entries.
+
+"LBA -1" means the last addressable block (in the mmc subsystem:
+"dev_desc->lba - 1")
+
+Primary/Secondary GPT header:
+----------------------------
+Offset  Size    Description
+
+0       8 B     Signature ("EFI PART", 45 46 49 20 50 41 52 54)
+8       4 B     Revision (For version 1.0, the value is 00 00 01 00)
+12      4 B     Header size (in bytes, usually 5C 00 00 00 meaning 92 bytes)
+16      4 B     CRC32 of header (0 to header size), with this field zeroed
+		during calculation
+20      4 B     Reserved (ZERO);
+24      8 B     Current LBA (location of this header copy)
+32      8 B     Backup LBA (location of the other header copy)
+40      8 B     First usable LBA for partitions (primary partition table last
+		LBA + 1)
+48      8 B     Last usable LBA (secondary partition table first LBA - 1)
+56      16 B    Disk GUID (also referred as UUID on UNIXes)
+72      8 B     Partition entries starting LBA (always 2 in primary copy)
+80      4 B     Number of partition entries
+84      4 B     Size of a partition entry (usually 128)
+88      4 B     CRC32 of partition array
+92      *       Reserved; must be ZERO (420 bytes for a 512-byte LBA)
+
+TOTAL: 512 B
+
+
+
+IMPORTANT:
+
+GPT headers and partition entries are protected by CRC32 (the POSIX CRC32).
+
+Primary GPT header and Secondary GPT header have swapped values of "Current LBA"
+and "Backup LBA" and therefore different CRC32 check-sum.
+
+CRC32 for GPT headers (field "CRC of header") are calculated up till
+"Header size" (92), NOT 512 bytes.
+
+CRC32 for partition entries (field "CRC32 of partition array") is calculated for
+the whole array entry ( Number_of_partition_entries *
+sizeof(partition_entry_size (usually 128)))
+
+Observe, how Secondary GPT is placed in the memory. It is NOT a mirror reflect
+of the Primary.
+
+
+	   Partition Entry Format:
+	   ----------------------
+	   Offset  Size    Description
+
+	   0       16 B    Partition type GUID
+	   16      16 B    Unique partition GUID
+	   32      8  B    First LBA (Little Endian)
+	   40      8  B    Last LBA (inclusive)
+	   48      8  B    Attribute flags [+]
+	   56      72 B    Partition name (text)
+
+	   Attribute flags:
+	   Bit 0  - System partition
+	   Bit 60 - Read-only
+	   Bit 62 - Hidden
+	   Bit 63 - Not mount
+
+
+Example usage:
+==============
+
+To restore GUID partition table one needs to:
+1. at ./include/configs/{board}.h
+   - define "partitions=" environment variable with format:
+     "name=u-boot,size=60M;name=kernel,size=60M;name=platform,size=1G;"
+   - define GPT_PARTS_NUM with actual number of partitions (as defined above)
+   - #define CONFIG_EFI_PARTITION and #define CONFIG_CMD_GPT
+
+2. From u-boot prompt type:
+   gpt mmc 0 uuid_disk=ec2cddf2-fbf5-11e1-af3a-001fd09285c0, \
+   uuid1=ed09c4b0-fbf5-11e1-9a95-001fd09285c0, \
+   uuid2=edd6d93c-fbf5-11e1-875a-001fd09285c0, \
+   uuid3=f0485114-fbf5-11e1-a3ae-001fd09285c0 ...
+
+   UUIDs shall be defined up to GPT_PARTS_NUM. Smaller number is acceptable.
+   When UUIDs are NOT provided, internal (rather weak) GUID generator will be
+   used instead
+
+Internal GUID generator:
+=======================
+
+For "emergency" usage (or when list of UUIDs cannot be provided)  the internal
+GUID generator shall be used. It uses gd->start_addr_sp as a primary source of
+UUID generator (16B).
+
+
+Useful info:
+============
+
+Two programs, namely: 'fdisk' and 'parted' are recommended to work with GPT
+recovery. Parted is able to handle GUID partitions. Unfortunately the 'fdisk'
+hasn't got such ability.
+Please, pay attention at -l switch for parted.
+
+"uuid" program is recommended to generate UUID string. Moreover it can decode
+(-d switch) passed in UUID string. It can be used to generate partitions UUID
+passed to u-boot environment variables.
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h>
  2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
                     ` (2 preceding siblings ...)
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 3/7] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
@ 2012-09-12 14:50   ` Lukasz Majewski
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 5/7] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-12 14:50 UTC (permalink / raw)
  To: u-boot

From: Chang Hyun Park <chchch.park@samsung.com>

Custom definitions of le_XX_to_int functions have been replaced with
standard ones, defined at <compiler.h>

Replacement of several GPT related structures members with ones
indicating its endianness and proper size.

Signed-off-by: Chang Hyun Park <chchch.park@samsung.com>
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v2:
- Combining two commits regarding part_efi.{h|c}
---
 disk/part_efi.c    |  109 +++++++++++++++++++---------------------------------
 include/part_efi.h |   85 +++++++++++++++++++++-------------------
 2 files changed, 84 insertions(+), 110 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index b2233da..d4c61d2 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -44,34 +44,6 @@
     defined(CONFIG_MMC) || \
     defined(CONFIG_SYSTEMACE)
 
-/* Convert char[2] in little endian format to the host format integer
- */
-static inline unsigned short le16_to_int(unsigned char *le16)
-{
-	return ((le16[1] << 8) + le16[0]);
-}
-
-/* Convert char[4] in little endian format to the host format integer
- */
-static inline unsigned long le32_to_int(unsigned char *le32)
-{
-	return ((le32[3] << 24) + (le32[2] << 16) + (le32[1] << 8) + le32[0]);
-}
-
-/* Convert char[8] in little endian format to the host format integer
- */
-static inline unsigned long long le64_to_int(unsigned char *le64)
-{
-	return (((unsigned long long)le64[7] << 56) +
-		((unsigned long long)le64[6] << 48) +
-		((unsigned long long)le64[5] << 40) +
-		((unsigned long long)le64[4] << 32) +
-		((unsigned long long)le64[3] << 24) +
-		((unsigned long long)le64[2] << 16) +
-		((unsigned long long)le64[1] << 8) +
-		(unsigned long long)le64[0]);
-}
-
 /**
  * efi_crc32() - EFI version of crc32 function
  * @buf: buffer to calculate crc32 of
@@ -79,7 +51,7 @@ static inline unsigned long long le64_to_int(unsigned char *le64)
  *
  * Description: Returns EFI-style CRC32 value for @buf
  */
-static inline unsigned long efi_crc32(const void *buf, unsigned long len)
+static inline u32 efi_crc32(const void *buf, u32 len)
 {
 	return crc32(0, buf, len);
 }
@@ -137,13 +109,13 @@ void print_part_efi(block_dev_desc_t * dev_desc)
 	debug("%s: gpt-entry@%p\n", __func__, gpt_pte);
 
 	printf("Part\tName\t\t\tStart LBA\tEnd LBA\n");
-	for (i = 0; i < le32_to_int(gpt_head->num_partition_entries); i++) {
+	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
 
 		if (is_pte_valid(&gpt_pte[i])) {
 			printf("%3d\t%-18s\t0x%08llX\t0x%08llX\n", (i + 1),
 				print_efiname(&gpt_pte[i]),
-				le64_to_int(gpt_pte[i].starting_lba),
-				le64_to_int(gpt_pte[i].ending_lba));
+			       (u64) le64_to_cpu(gpt_pte[i].starting_lba),
+			       (u64) le64_to_cpu(gpt_pte[i].ending_lba));
 		} else {
 			break;	/* Stop at the first non valid PTE */
 		}
@@ -174,9 +146,9 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 	}
 
 	/* The ulong casting limits the maximum disk size to 2 TB */
-	info->start = (ulong) le64_to_int(gpt_pte[part - 1].starting_lba);
+	info->start = (u64) le64_to_cpu(gpt_pte[part - 1].starting_lba);
 	/* The ending LBA is inclusive, to calculate size, add 1 to it */
-	info->size = ((ulong)le64_to_int(gpt_pte[part - 1].ending_lba) + 1)
+	info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
 		     - info->start;
 	info->blksz = GPT_BLOCK_SIZE;
 
@@ -215,7 +187,7 @@ int test_part_efi(block_dev_desc_t * dev_desc)
 static int pmbr_part_valid(struct partition *part)
 {
 	if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
-		le32_to_int(part->start_sect) == 1UL) {
+		le32_to_cpu(part->start_sect) == 1UL) {
 		return 1;
 	}
 
@@ -234,9 +206,8 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 {
 	int i = 0;
 
-	if (!mbr || le16_to_int(mbr->signature) != MSDOS_MBR_SIGNATURE) {
+	if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
 		return 0;
-	}
 
 	for (i = 0; i < 4; i++) {
 		if (pmbr_part_valid(&mbr->partition_record[i])) {
@@ -259,8 +230,8 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 			gpt_header * pgpt_head, gpt_entry ** pgpt_pte)
 {
-	unsigned char crc32_backup[4] = { 0 };
-	unsigned long calc_crc32;
+	u32 crc32_backup = 0;
+	u32 calc_crc32;
 	unsigned long long lastlba;
 
 	if (!dev_desc || !pgpt_head) {
@@ -275,54 +246,54 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 	}
 
 	/* Check the GPT header signature */
-	if (le64_to_int(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
+	if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
 		printf("GUID Partition Table Header signature is wrong:"
 			"0x%llX != 0x%llX\n",
-			(unsigned long long)le64_to_int(pgpt_head->signature),
-			(unsigned long long)GPT_HEADER_SIGNATURE);
+			(u64) le64_to_cpu(pgpt_head->signature),
+			(u64) GPT_HEADER_SIGNATURE);
 		return 0;
 	}
 
 	/* Check the GUID Partition Table CRC */
-	memcpy(crc32_backup, pgpt_head->header_crc32, sizeof(crc32_backup));
-	memset(pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
+	memcpy(&crc32_backup, &pgpt_head->header_crc32, sizeof(crc32_backup));
+	memset(&pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
 
 	calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
-		le32_to_int(pgpt_head->header_size));
+		le32_to_cpu(pgpt_head->header_size));
 
-	memcpy(pgpt_head->header_crc32, crc32_backup, sizeof(crc32_backup));
+	memcpy(&pgpt_head->header_crc32, &crc32_backup, sizeof(crc32_backup));
 
-	if (calc_crc32 != le32_to_int(crc32_backup)) {
+	if (calc_crc32 != le32_to_cpu(crc32_backup)) {
 		printf("GUID Partition Table Header CRC is wrong:"
-			"0x%08lX != 0x%08lX\n",
-			le32_to_int(crc32_backup), calc_crc32);
+			"0x%x != 0x%x\n",
+		       (u32) le32_to_cpu(crc32_backup), calc_crc32);
 		return 0;
 	}
 
 	/* Check that the my_lba entry points to the LBA that contains the GPT */
-	if (le64_to_int(pgpt_head->my_lba) != lba) {
+	if (le64_to_cpu(pgpt_head->my_lba) != lba) {
 		printf("GPT: my_lba incorrect: %llX != %llX\n",
-			(unsigned long long)le64_to_int(pgpt_head->my_lba),
-			(unsigned long long)lba);
+			(u64)le64_to_cpu(pgpt_head->my_lba),
+			(u64)lba);
 		return 0;
 	}
 
 	/* Check the first_usable_lba and last_usable_lba are within the disk. */
 	lastlba = (unsigned long long)dev_desc->lba;
-	if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
+	if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) {
 		printf("GPT: first_usable_lba incorrect: %llX > %llX\n",
-			le64_to_int(pgpt_head->first_usable_lba), lastlba);
+		       (u64) le64_to_cpu(pgpt_head->first_usable_lba), lastlba);
 		return 0;
 	}
-	if (le64_to_int(pgpt_head->last_usable_lba) > lastlba) {
+	if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) {
 		printf("GPT: last_usable_lba incorrect: %llX > %llX\n",
-			le64_to_int(pgpt_head->last_usable_lba), lastlba);
+		       (u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 		return 0;
 	}
 
 	debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n",
-		le64_to_int(pgpt_head->first_usable_lba),
-		le64_to_int(pgpt_head->last_usable_lba), lastlba);
+	      (u64) le64_to_cpu(pgpt_head->first_usable_lba),
+	      (u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 
 	/* Read and allocate Partition Table Entries */
 	*pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
@@ -333,13 +304,13 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 
 	/* Check the GUID Partition Table Entry Array CRC */
 	calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
-		le32_to_int(pgpt_head->num_partition_entries) *
-		le32_to_int(pgpt_head->sizeof_partition_entry));
+		le32_to_cpu(pgpt_head->num_partition_entries) *
+		le32_to_cpu(pgpt_head->sizeof_partition_entry));
 
-	if (calc_crc32 != le32_to_int(pgpt_head->partition_entry_array_crc32)) {
+	if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) {
 		printf("GUID Partition Table Entry Array CRC is wrong:"
-			"0x%08lX != 0x%08lX\n",
-			le32_to_int(pgpt_head->partition_entry_array_crc32),
+			"0x%x != 0x%x\n",
+		       (u32)le32_to_cpu(pgpt_head->partition_entry_array_crc32),
 			calc_crc32);
 
 		free(*pgpt_pte);
@@ -370,12 +341,12 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 		return NULL;
 	}
 
-	count = le32_to_int(pgpt_head->num_partition_entries) *
-		le32_to_int(pgpt_head->sizeof_partition_entry);
+	count = le32_to_cpu(pgpt_head->num_partition_entries) *
+		le32_to_cpu(pgpt_head->sizeof_partition_entry);
 
-	debug("%s: count = %lu * %lu = %u\n", __func__,
-		le32_to_int(pgpt_head->num_partition_entries),
-		le32_to_int(pgpt_head->sizeof_partition_entry), count);
+	debug("%s: count = %u * %u = %u\n", __func__,
+	      (u32) le32_to_cpu(pgpt_head->num_partition_entries),
+	      (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), count);
 
 	/* Allocate memory for PTE, remember to FREE */
 	if (count != 0) {
@@ -390,7 +361,7 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 
 	/* Read GPT Entries from device */
 	if (dev_desc->block_read (dev_desc->dev,
-		(unsigned long)le64_to_int(pgpt_head->partition_entry_lba),
+		(u64) le64_to_cpu(pgpt_head->partition_entry_lba),
 		(lbaint_t) (count / GPT_BLOCK_SIZE), pte)
 		!= (count / GPT_BLOCK_SIZE)) {
 
diff --git a/include/part_efi.h b/include/part_efi.h
index a9d4399..11d995c 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -29,6 +29,8 @@
  * http://developer.intel.com/technology/efi/efi.htm
 */
 
+#include <linux/compiler.h>
+
 #ifndef _DISK_PART_EFI_H
 #define _DISK_PART_EFI_H
 
@@ -41,6 +43,8 @@
 #define GPT_HEADER_REVISION_V1 0x00010000
 #define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
 #define GPT_ENTRY_NAME "gpt"
+#define GPT_ENTRY_NUMBERS		128
+#define GPT_ENTRY_SIZE			128
 
 #define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
 	((efi_guid_t) \
@@ -73,68 +77,67 @@
 		0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
 
 /* linux/include/efi.h */
-typedef unsigned short efi_char16_t;
+typedef u16 efi_char16_t;
 
 typedef struct {
-	unsigned char b[16];
+	u8 b[16];
 } efi_guid_t;
 
 /* based on linux/include/genhd.h */
 struct partition {
-	unsigned char boot_ind;		/* 0x80 - active */
-	unsigned char head;		/* starting head */
-	unsigned char sector;		/* starting sector */
-	unsigned char cyl;		/* starting cylinder */
-	unsigned char sys_ind;		/* What partition type */
-	unsigned char end_head;		/* end head */
-	unsigned char end_sector;	/* end sector */
-	unsigned char end_cyl;		/* end cylinder */
-	unsigned char start_sect[4];	/* starting sector counting from 0 */
-	unsigned char nr_sects[4];	/* nr of sectors in partition */
-} __attribute__ ((packed));
+	u8 boot_ind;		/* 0x80 - active */
+	u8 head;		/* starting head */
+	u8 sector;		/* starting sector */
+	u8 cyl;		/* starting cylinder */
+	u8 sys_ind;		/* What partition type */
+	u8 end_head;		/* end head */
+	u8 end_sector;	/* end sector */
+	u8 end_cyl;		/* end cylinder */
+	__le32 start_sect;	/* starting sector counting from 0 */
+	__le32 nr_sects;	/* nr of sectors in partition */
+} __packed;
 
 /* based on linux/fs/partitions/efi.h */
 typedef struct _gpt_header {
-	unsigned char signature[8];
-	unsigned char revision[4];
-	unsigned char header_size[4];
-	unsigned char header_crc32[4];
-	unsigned char reserved1[4];
-	unsigned char my_lba[8];
-	unsigned char alternate_lba[8];
-	unsigned char first_usable_lba[8];
-	unsigned char last_usable_lba[8];
+	__le64 signature;
+	__le32 revision;
+	__le32 header_size;
+	__le32 header_crc32;
+	__le32 reserved1;
+	__le64 my_lba;
+	__le64 alternate_lba;
+	__le64 first_usable_lba;
+	__le64 last_usable_lba;
 	efi_guid_t disk_guid;
-	unsigned char partition_entry_lba[8];
-	unsigned char num_partition_entries[4];
-	unsigned char sizeof_partition_entry[4];
-	unsigned char partition_entry_array_crc32[4];
-	unsigned char reserved2[GPT_BLOCK_SIZE - 92];
-} __attribute__ ((packed)) gpt_header;
+	__le64 partition_entry_lba;
+	__le32 num_partition_entries;
+	__le32 sizeof_partition_entry;
+	__le32 partition_entry_array_crc32;
+	u8 reserved2[GPT_BLOCK_SIZE - 92];
+} __packed gpt_header;
 
 typedef struct _gpt_entry_attributes {
-	unsigned long long required_to_function:1;
-	unsigned long long reserved:47;
-	unsigned long long type_guid_specific:16;
-} __attribute__ ((packed)) gpt_entry_attributes;
+	u64 required_to_function:1;
+	u64 reserved:47;
+	u64 type_guid_specific:16;
+} __packed gpt_entry_attributes;
 
 #define PARTNAME_SZ	(72 / sizeof(efi_char16_t))
 typedef struct _gpt_entry {
 	efi_guid_t partition_type_guid;
 	efi_guid_t unique_partition_guid;
-	unsigned char starting_lba[8];
-	unsigned char ending_lba[8];
+	__le64 starting_lba;
+	__le64 ending_lba;
 	gpt_entry_attributes attributes;
 	efi_char16_t partition_name[PARTNAME_SZ];
-}
-__attribute__ ((packed)) gpt_entry;
+} __packed gpt_entry;
 
 typedef struct _legacy_mbr {
-	unsigned char boot_code[440];
-	unsigned char unique_mbr_signature[4];
-	unsigned char unknown[2];
+	u8 boot_code[440];
+	__le32 unique_mbr_signature;
+	__le16 unknown;
 	struct partition partition_record[4];
-	unsigned char signature[2];
-} __attribute__ ((packed)) legacy_mbr;
+	__le16 signature;
+} __packed legacy_mbr;
 
 #endif	/* _DISK_PART_EFI_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
                     ` (3 preceding siblings ...)
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Lukasz Majewski
@ 2012-09-12 14:50   ` Lukasz Majewski
  2012-09-12 17:22     ` Tom Rini
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 6/7] gpt: Support for new "gpt" command Lukasz Majewski
                     ` (2 subsequent siblings)
  7 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-12 14:50 UTC (permalink / raw)
  To: u-boot

The restoration of GPT table (both primary and secondary) is now possible.
Simple GUID generation is supported.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v2:
- Move GPT Header and Page Table Entries generation code to cmd_gpt.c
- Provide clean API to use set_gpt_table function for GPT restoration on
  a block device
---
 disk/part_efi.c |   99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/part.h  |    3 ++
 2 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index d4c61d2..531c7ad 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -403,4 +403,103 @@ static int is_pte_valid(gpt_entry * pte)
 		return 1;
 	}
 }
+
+/**
+ * set_protective_mbr(): Set the EFI protective MBR
+ * @param dev_desc - block device descriptor
+ *
+ * @return - zero on success, otherwise error
+ */
+static int set_protective_mbr(block_dev_desc_t *dev_desc)
+{
+	legacy_mbr p_mbr;
+
+	/* Setup the Protective MBR */
+	memset((u32 *) &p_mbr, 0x00, sizeof(p_mbr));
+	/* Append signature */
+	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) dev_desc->lba;
+
+	/* Write MBR sector to the MMC device */
+	if (dev_desc->block_write(dev_desc->dev, 0, 1, &p_mbr) != 1) {
+		printf("** Can't write to device %d **\n",
+			dev_desc->dev);
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * set_gpt_table() - Restore the GUID Partition Table
+ *
+ * @param dev_desc - block device descriptor
+ * @param parts - number of partitions
+ * @param size - pointer to array with each partition size
+ * @param name - pointer to array with each partition name
+ *
+ * @return - zero on success, otherwise error
+ */
+int set_gpt_table(block_dev_desc_t *dev_desc,
+		  gpt_header *gpt_h, gpt_entry *gpt_e)
+{
+	const int pte_blk_num = (GPT_ENTRY_NUMBERS * sizeof(gpt_entry)) /
+		dev_desc->blksz;
+	u32 calc_crc32;
+	u64 val;
+
+	debug("max lba: %x\n", (u32) dev_desc->lba);
+
+	/* Setup the Protective MBR */
+	if (set_protective_mbr(dev_desc) < 0)
+		goto err;
+
+	/* 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);
+
+	/* Write the First GPT to the block right after the Legacy MBR */
+	if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1)
+		goto err;
+
+	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e)
+	    != pte_blk_num)
+		goto err;
+
+	/* recalculate the values for the Second 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);
+	gpt_h->header_crc32 = 0;
+
+	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);
+
+	/* Write the Second GPT that is located at the end of the disk */
+	if (dev_desc->block_write(dev_desc->dev,
+				  le32_to_cpu(gpt_h->last_usable_lba + 1),
+				  pte_blk_num, gpt_e) != pte_blk_num)
+		goto err;
+
+	if (dev_desc->block_write(dev_desc->dev,
+				  le32_to_cpu(gpt_h->my_lba), 1, gpt_h) != 1)
+		goto err;
+
+	printf("GPT successfully written to block device!\n");
+	return 0;
+
+ err:
+	printf("** Can't write to device %d **\n",
+	       dev_desc->dev);
+	return -1;
+}
 #endif
diff --git a/include/part.h b/include/part.h
index e1478f4..fc34ed2 100644
--- a/include/part.h
+++ b/include/part.h
@@ -157,10 +157,13 @@ int   test_part_amiga (block_dev_desc_t *dev_desc);
 #endif
 
 #ifdef CONFIG_EFI_PARTITION
+#include <part_efi.h>
 /* disk/part_efi.c */
 int get_partition_info_efi (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
 void print_part_efi (block_dev_desc_t *dev_desc);
 int   test_part_efi (block_dev_desc_t *dev_desc);
+int set_gpt_table(block_dev_desc_t *dev_desc,
+		  gpt_header *gpt_h, gpt_entry *gpt_e);
 #endif
 
 #endif /* _PART_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 6/7] gpt: Support for new "gpt" command
  2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
                     ` (4 preceding siblings ...)
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 5/7] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
@ 2012-09-12 14:50   ` Lukasz Majewski
  2012-09-12 17:21     ` Tom Rini
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats Lukasz Majewski
  2012-09-12 17:23   ` [U-Boot] [PATCH v2 0/7] gpt: GUID Partition Table (GPT) restoration Tom Rini
  7 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-12 14:50 UTC (permalink / raw)
  To: u-boot

New command - "gpt" is supported. It restores the GPT partition table.
It looks into the "partitions" environment variable for partitions definition.
It can be enabled at target configuration file with CONFIG_CMD_GPT.
Simple UUID generator has been implemented. It uses the the gd->start_addr_sp
for entrophy pool. Moreover the pool address is used as crc32 seed.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v2:
- gpt command now accepts device medium and its number (e.g. gpt mmc 0)
- UUIDs can be passed via u-boot prompt when used with gpt command
- Format of restored GPT has been changed - now key=value pairs are used
  'name="PARTS_CSA",size=8MiB;\ '
  'name="PARTS_BOOTLOADER",size=60MiB; \'
- guid_gen now accepts "pool" pointer and guid pointer
- gd->start_addr_sp is used as a primary source of entrophy
- static buffers definitions have been removed
- remove memsize_to_blocks function with call to standard ustrtoul
- doxygen comments for functions added
---
 common/Makefile  |    1 +
 common/cmd_gpt.c |  405 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 406 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_gpt.c

diff --git a/common/Makefile b/common/Makefile
index 49df751..438d36c 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -185,6 +185,7 @@ COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
 COBJS-$(CONFIG_UPDATE_TFTP) += update.o
 COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
 COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o
+COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o
 endif
 
 ifdef CONFIG_SPL_BUILD
diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
new file mode 100644
index 0000000..bb62b05
--- /dev/null
+++ b/common/cmd_gpt.c
@@ -0,0 +1,405 @@
+/*
+ * cmd_gpt.c -- GPT (GUID Partition Table) handling command
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * author: Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <command.h>
+#include <mmc.h>
+#include <part_efi.h>
+#include <exports.h>
+
+gpt_entry *gpt_e;
+gpt_header *gpt_h;
+DECLARE_GLOBAL_DATA_PTR;
+static unsigned int gpt_parts;
+
+#ifdef DEBUG
+/**
+ * guid_dump(): Dump guid content
+ *
+ * @param guid - pinter to guid
+ * @param i - number of bytes to dump
+ */
+static void guid_dump(u8 *guid, int i)
+{
+	int k;
+
+	debug("GUID: ");
+	for (k = 0; k < i; k++, guid++)
+		debug(" %x ", *guid);
+	debug("\n");
+}
+#else
+static void guid_dump(u8 *guid, int i) {}
+#endif
+
+/**
+ * guid_gen(): Generate UUID
+ *
+ * @param pool - pointer to pseudo random data (e.g. SP)
+ * @param guid - pointer to guid table
+ *
+ * @return - generated UUID table
+ *
+ * NOTE: The entrophy of this function is small
+ */
+static void guid_gen(const u32 *pool, u8 *guid)
+{
+	int k = 0;
+	u32 *ptr = (u32 *) guid;
+
+	debug("%s: pool: 0x%p guid: 0x%p\n", __func__, pool, guid);
+	for (k = 0; k < 4; k++)
+		*(ptr + k) = crc32((u32) pool, (const void *) (pool - k), 512);
+
+	guid_dump(guid, sizeof(efi_guid_t));
+}
+
+/**
+ * convert_uuid(); Convert UUID stored as string to bytes
+ *
+ * @param uuid - UUID represented as string
+ * @param dst - GUID buffer
+ *
+ * @return
+ */
+static int convert_uuid(char *uuid, u8 *dst)
+{
+	efi_guid_t guid;
+	u16 b, c, d;
+	char *t;
+	u64 e;
+	u32 a;
+	u8 *p;
+
+	debug("%s: uuid: %s\n", __func__, uuid);
+	t = strsep(&uuid, "-");
+	a = (u32)simple_strtoul(t, NULL, 16);
+	t = strsep(&uuid, "-");
+	b = (u16)simple_strtoul(t, NULL, 16);
+	t = strsep(&uuid, "-");
+	c = (u16)simple_strtoul(t, NULL, 16);
+	t = strsep(&uuid, "-");
+	d = (u16)simple_strtoul(t, NULL, 16);
+	e = (u64)simple_strtoull(uuid, NULL, 16);
+
+	p = (u8 *) &e;
+	guid = EFI_GUID(a, b, c, d >> 8, d & 0xFF,
+			*(p + 5), *(p + 4), *(p + 3),
+			*(p + 2), *(p + 1) , *p);
+
+	guid_dump(guid.b, sizeof(efi_guid_t));
+	memcpy(dst, guid.b, sizeof(efi_guid_t));
+
+	return 0;
+}
+
+/**
+ * fill_pte(): Fill the GPT partition table entry
+ *
+ * @param dev_desc - block device descriptor
+ * @param gpt_h - GPT header representation
+ * @param gpt_e - GPT partition table entries
+ * @param parts - number of partitions
+ * @param size - size of each partition
+ * @param name - name of each partition
+ */
+static void gpt_fill_pte(block_dev_desc_t *dev_desc, gpt_header *gpt_h,
+		     gpt_entry *gpt_e, int parts, unsigned int *size,
+		     char *name[], char *uuid[])
+{
+	u32 offset = (u32) gpt_h->first_usable_lba;
+	u8 guid[sizeof(efi_guid_t)];
+	char p[PARTNAME_SZ];
+	int i, k, j;
+	char *s;
+
+	for (i = 0; i < parts; i++) {
+		memcpy(gpt_e[i].partition_type_guid.b,
+		       &PARTITION_BASIC_DATA_GUID, 16);
+
+		if (uuid[i])
+			convert_uuid(uuid[i], gpt_e[i].unique_partition_guid.b);
+		else {
+			guid_gen((((u32 *) gd->start_addr_sp) - i - 1), guid);
+			memcpy(gpt_e[i].unique_partition_guid.b, guid,
+			       sizeof(efi_guid_t));
+
+		}
+		s = name[i];
+
+		memset(p, 0x00, sizeof(p));
+		for (k = 0, j = 0; k < strlen(s); k++, j += 2) {
+			p[j] = *(s + k);
+			p[j + 1] = '.';
+		}
+
+		memcpy(gpt_e[i].partition_name,
+		       p, strlen(p));
+
+		gpt_e[i].starting_lba = cpu_to_le32(offset);
+
+		/* allocate remaining memory in last partition */
+		if (i != parts - 1) {
+			gpt_e[i].ending_lba =
+				cpu_to_le64(offset + size[i] - 1);
+		} else {
+			gpt_e[i].ending_lba = gpt_h->last_usable_lba;
+		}
+
+		memset(&gpt_e[i].attributes, 0,
+		       sizeof(gpt_entry_attributes));
+
+		offset += size[i];
+		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%x\n",
+		      __func__, name[i], i, offset, i, size[i]);
+	}
+}
+
+/**
+ * extract_val(): Extract value from a key=value pair
+ *
+ * @param p - pointer to string
+ * @param tab - table to store extracted value
+ * @param i - actual tab element to work on
+ *
+ * @return - zero on success; otherwise error
+ */
+static int extract_val(char **p, char *tab[], int i)
+{
+	char *t, *tok = *p;
+
+	t = strsep(&tok, ",");
+	strsep(&t, "=");
+	tab[i] = calloc(strlen(t) + 1, 1);
+	if (tab[i] == NULL) {
+		printf("%s: calloc failed!\n", __func__);
+		return -1;
+	}
+	strcpy(tab[i], t);
+	*p = tok;
+
+	return 0;
+}
+
+/**
+ * extract_uuid(); Extract UUIDs from a string
+ *
+ * @param uuid - string to uuid representation
+ * @param tab - place to store separated items
+ *
+ * @return - zero on success; otherwise error
+ */
+static int extract_uuid(char *uuid, char *tab[])
+{
+	char *tok = uuid;
+	int i;
+
+	for (i = 0; tok && i < (GPT_PARTS_NUM + 1); i++) {
+		if (extract_val(&tok, tab, i)) {
+			for (i--; i >= 0; i--)
+				free(tab[i]);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * set_gpt_info(): Fill gpt information for GPT header and partition entries
+ *
+ * @param dev_desc - block device descriptor
+ * @param str_uuid - string uuid representation
+ *
+ * @return - zero on success; otherwise error
+ *
+ * NOTE - uuid table is bigger than GPT_PARTS_NUM to support disk UUID
+ *
+ */
+static int set_gpt_info(block_dev_desc_t *dev_desc, char *str_uuid)
+{
+	char *ps[GPT_PARTS_NUM], *name[GPT_PARTS_NUM];
+	char *uuid[GPT_PARTS_NUM + 1]; /* extra space to store disk uuid */
+	u8 guid[sizeof(gpt_h->disk_guid.b)];
+	unsigned int size[GPT_PARTS_NUM];
+	char *tok, *p, *s, *ss;
+	int i, ret;
+
+	debug("%s: MMC lba num: 0x%x %d\n", __func__,
+	      (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba);
+
+	for (i = 0; i <= GPT_PARTS_NUM; i++)
+		uuid[i] = NULL;
+
+	s = getenv("partitions");
+	if (s == NULL) {
+		printf("%s: \"partitions\" env variable not defined!\n",
+		       __func__);
+		return -1;
+	}
+
+	if (str_uuid)
+		extract_uuid(str_uuid, uuid);
+
+	ss = calloc(strlen(s) + 1, 1);
+	if (ss == NULL) {
+		printf("%s: calloc failed!\n", __func__);
+		return -1;
+	}
+	memcpy(ss, s, strlen(s) + 1);
+
+	for (i = 0, p = ss; i < GPT_PARTS_NUM; i++) {
+		tok = strsep(&p, ";");
+		if (tok == NULL)
+			break;
+
+		if (extract_val(&tok, name, i)) {
+			ret = -1;
+			goto err;
+		}
+
+		if (extract_val(&tok, ps, i)) {
+			ret = -1;
+			free(name[i]);
+			goto err;
+		}
+	}
+
+	gpt_parts = i;
+
+	printf("found %d partitions\n", gpt_parts);
+
+	for (i = 0; i < gpt_parts; i++) {
+		p = ps[i];
+		size[i] = ustrtoul(p, &p, 0);
+		size[i] /= dev_desc->blksz;
+	}
+
+	gpt_h = calloc(sizeof(gpt_header), 1);
+	gpt_e = calloc(sizeof(gpt_entry), GPT_ENTRY_NUMBERS);
+
+	/* Generate Primary GPT header (LBA1) */
+	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(1);
+	gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1);
+	gpt_h->first_usable_lba = cpu_to_le64(34);
+	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
+	gpt_h->partition_entry_lba = cpu_to_le64(2);
+	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[0])
+		convert_uuid(uuid[0], gpt_h->disk_guid.b);
+	else {
+		guid_gen((u32 *)gd->start_addr_sp, guid);
+		memcpy(gpt_h->disk_guid.b, guid, sizeof(efi_guid_t));
+	}
+	gpt_fill_pte(dev_desc, gpt_h, gpt_e, gpt_parts, size, name, &uuid[1]);
+
+	puts("save the GPT ...\n");
+	ret = set_gpt_table(dev_desc, gpt_h, gpt_e);
+
+	free(gpt_e);
+	free(gpt_h);
+
+	i = gpt_parts;
+ err:
+	for (i--; i >= 0; i--) {
+		free(name[i]);
+		free(ps[i]);
+	}
+
+	free(ss);
+	return ret;
+}
+
+/**
+ * gpt_mmc_default(): Restore default GPT on a MMC device
+ *
+ * @param dev - number of MMC device
+ * @param str_uuid - string representation of UUIDs
+ *
+ * @return zero on success; otherwise error
+ */
+static int gpt_mmc_default(int dev, char *str_uuid)
+{
+	struct mmc *mmc = find_mmc_device(dev);
+
+	if (mmc == NULL) {
+		printf("%s: mmc dev %d NOT available\n", __func__, dev);
+		return CMD_RET_FAILURE;
+	}
+
+	puts("Using default GPT UUID\n");
+	return set_gpt_info(&mmc->block_dev, str_uuid);
+}
+
+/**
+ * do_gpt(): Perform GPT operations
+ *
+ * @param cmdtp - command name
+ * @param flag
+ * @param argc
+ * @param argv
+ *
+ * @return zero on success; otherwise error
+ */
+static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int ret = CMD_RET_SUCCESS;
+	char *str_uuid = NULL;
+	int dev = 0;
+
+	if (argc < 3)
+		return CMD_RET_USAGE;
+
+	if (argc == 4) {
+		str_uuid = strdup(argv[3]);
+		if (!str_uuid) {
+			printf("%s: malloc failed!\n", __func__);
+			return CMD_RET_FAILURE;
+		}
+	}
+
+	if (strcmp(argv[1], "mmc") == 0) {
+		dev = (int)simple_strtoul(argv[2], NULL, 10);
+		if (gpt_mmc_default(dev, str_uuid))
+			return CMD_RET_FAILURE;
+	}
+
+	if (argc == 4)
+		free(str_uuid);
+
+	return ret;
+}
+
+U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
+	"GUID Partition Table",
+	"<interface> <dev> [uuid1=, uuid2=, ..., uuidN=]\n"
+	" - GUID partition table restoration\n"
+	" Restore GPT information on a device connected\n"
+	" to interface\n"
+);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats
  2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
                     ` (5 preceding siblings ...)
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 6/7] gpt: Support for new "gpt" command Lukasz Majewski
@ 2012-09-12 14:50   ` Lukasz Majewski
  2012-09-12 17:23   ` [U-Boot] [PATCH v2 0/7] gpt: GUID Partition Table (GPT) restoration Tom Rini
  7 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-12 14:50 UTC (permalink / raw)
  To: u-boot

Enable support for GPT partition table restoration at Samsung's Trats
development board.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v2:
- New format for default GPT partitions (key=value pairs)
- replace size definitions with more readable description(1GiB instead of 1G)
---
 include/configs/trats.h |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/include/configs/trats.h b/include/configs/trats.h
index 08aa65b..f1ba9e7 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -98,6 +98,7 @@
 #undef CONFIG_CMD_MTDPARTS
 #define CONFIG_CMD_MMC
 #define CONFIG_CMD_DFU
+#define CONFIG_CMD_GPT
 
 /* FAT */
 #define CONFIG_CMD_FAT
@@ -122,6 +123,24 @@
 #define CONFIG_BOOTBLOCK		"10"
 #define CONFIG_ENV_COMMON_BOOT		"${console} ${meminfo}"
 
+/* Tizen - partitions definitions */
+#define PARTS_CSA		"csa-mmc"
+#define PARTS_BOOTLOADER	"u-boot"
+#define PARTS_KERNEL		"kernel"
+#define PARTS_ROOT		"platform"
+#define PARTS_DATA		"data"
+#define PARTS_CSC		"csc"
+#define PARTS_UMS		"ums"
+
+#define PARTS_DEFAULT	"name="PARTS_CSA",size=8MiB;"\
+			"name="PARTS_BOOTLOADER",size=60MiB;"\
+			"name="PARTS_KERNEL",size=60MiB;"\
+			"name="PARTS_ROOT",size=1GiB;"\
+			"name="PARTS_DATA",size=3GiB;"\
+			"name="PARTS_CSC",size=150MiB;"\
+			"name="PARTS_UMS",size=-\0"
+#define GPT_PARTS_NUM 7
+
 #define CONFIG_DFU_ALT \
 	"dfu_alt_info=" \
 	"u-boot mmc 80 400;" \
@@ -171,7 +190,8 @@
 	"mmcbootpart=2\0" \
 	"mmcrootpart=3\0" \
 	"opts=always_resume=1\0" \
-	CONFIG_DFU_ALT
+	"partitions=" PARTS_DEFAULT \
+	CONFIG_DFU_ALT \
 
 /* Miscellaneous configurable options */
 #define CONFIG_SYS_LONGHELP		/* undef to save memory */
@@ -210,6 +230,7 @@
 #define CONFIG_ENV_OFFSET		((32 - 4) << 10) /* 32KiB - 4KiB */
 
 #define CONFIG_DOS_PARTITION
+#define CONFIG_EFI_PARTITION
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE)
 #define CONFIG_SYS_CACHELINE_SIZE       32
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 6/7] gpt: Support for new "gpt" command
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 6/7] gpt: Support for new "gpt" command Lukasz Majewski
@ 2012-09-12 17:21     ` Tom Rini
  0 siblings, 0 replies; 95+ messages in thread
From: Tom Rini @ 2012-09-12 17:21 UTC (permalink / raw)
  To: u-boot

On 09/12/2012 07:50 AM, Lukasz Majewski wrote:
> New command - "gpt" is supported. It restores the GPT partition table.
> It looks into the "partitions" environment variable for partitions definition.
> It can be enabled at target configuration file with CONFIG_CMD_GPT.
> Simple UUID generator has been implemented. It uses the the gd->start_addr_sp
> for entrophy pool. Moreover the pool address is used as crc32 seed.
> 
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
[snip]
> +		/* allocate remaining memory in last partition */
> +		if (i != parts - 1) {
> +			gpt_e[i].ending_lba =
> +				cpu_to_le64(offset + size[i] - 1);
> +		} else {
> +			gpt_e[i].ending_lba = gpt_h->last_usable_lba;
> +		}

Extra curly braces.  That's all I've seen in this patch however, so
getting close :)

-- 
Tom

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 5/7] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
@ 2012-09-12 17:22     ` Tom Rini
  0 siblings, 0 replies; 95+ messages in thread
From: Tom Rini @ 2012-09-12 17:22 UTC (permalink / raw)
  To: u-boot

On 09/12/2012 07:50 AM, Lukasz Majewski wrote:
> The restoration of GPT table (both primary and secondary) is now possible.
> Simple GUID generation is supported.
> 
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
[sinp]
> +
> +	printf("GPT successfully written to block device!\n");

puts() please.  Thanks!

-- 
Tom

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 0/7] gpt: GUID Partition Table (GPT) restoration
  2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
                     ` (6 preceding siblings ...)
  2012-09-12 14:50   ` [U-Boot] [PATCH v2 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats Lukasz Majewski
@ 2012-09-12 17:23   ` Tom Rini
  2012-09-13  6:20     ` Lukasz Majewski
  7 siblings, 1 reply; 95+ messages in thread
From: Tom Rini @ 2012-09-12 17:23 UTC (permalink / raw)
  To: u-boot

On 09/12/2012 07:50 AM, Lukasz Majewski wrote:
> This patch series provides a new command - "gpt" for eMMC partition table
> (in the GPT format) restoration.
> 
> As a pre-work, some cleanup at the part_efi.c file was performed to
> remove custom macros and make GPT related structures more readable.
> 
> Moreover the part_efi.h file has been moved to ./include directory to
> be easily available from other subsystems.
> 
> The GPT detailed description has been written to README.gpt file.
> 
> Tested at:
>         - Exynos4210 rev.1 - TRATS Samsung development board

I had two very minor comments.  Aside from that, please make sure the
series is checkpatch clean (I haven't checked).  Thanks!

-- 
Tom

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 0/7] gpt: GUID Partition Table (GPT) restoration
  2012-09-12 17:23   ` [U-Boot] [PATCH v2 0/7] gpt: GUID Partition Table (GPT) restoration Tom Rini
@ 2012-09-13  6:20     ` Lukasz Majewski
  2012-09-13 17:39       ` Tom Rini
  0 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-13  6:20 UTC (permalink / raw)
  To: u-boot

Hi Tom,

Thanks for review. 

> On 09/12/2012 07:50 AM, Lukasz Majewski wrote:
> > This patch series provides a new command - "gpt" for eMMC partition
> > table (in the GPT format) restoration.
> > 
> > As a pre-work, some cleanup at the part_efi.c file was performed to
> > remove custom macros and make GPT related structures more readable.
> > 
> > Moreover the part_efi.h file has been moved to ./include directory
> > to be easily available from other subsystems.
> > 
> > The GPT detailed description has been written to README.gpt file.
> > 
> > Tested at:
> >         - Exynos4210 rev.1 - TRATS Samsung development board
> 
> I had two very minor comments.  Aside from that, please make sure the
> series is checkpatch clean (I haven't checked).  Thanks!

There is one little problem with the checkpatch:

The patch:
[PATCH v2 2/7] part:efi: Move part_efi.h file to ./include

"touches" some legacy code, and checkpatch complaints about e.g.:

WARNING: do not add new typedefs
#281: FILE: include/part_efi.h:97:
+typedef struct _gpt_header {

which I don't want to change in this patch series.

Moreover it complaints about:
WARNING: __packed is preferred over __attribute__((packed))
#303: FILE: include/part_efi.h:119:
+} __attribute__ ((packed)) gpt_entry_attributes;
 which was changed at further patch (which I believe is a better place
 to do so):
[PATCH v2 4/7] gpt: The leXX_to_int() calls replaced with ones defined
at <compiler.h>

To sum up - some checkpatch warnings appears since I've moved a legacy
code to a new place.
Rest of those patches is checkpatch "clean".


-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 0/7] gpt: GUID Partition Table (GPT) restoration
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
                   ` (9 preceding siblings ...)
  2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
@ 2012-09-13  8:09 ` Lukasz Majewski
  2012-09-13  8:09   ` [U-Boot] [PATCH v3 1/7] vsprintf:fix: Change type returned by ustrtoul Lukasz Majewski
                     ` (6 more replies)
  2012-11-09  9:22 ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Piotr Wilczek
  11 siblings, 7 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-13  8:09 UTC (permalink / raw)
  To: u-boot

This patch series provides a new command - "gpt" for eMMC partition table
(in the GPT format) restoration.

As a pre-work, some cleanup at the part_efi.c file was performed to
remove custom macros and make GPT related structures more readable.

Moreover the part_efi.h file has been moved to ./include directory to
be easily available from other subsystems.

The GPT detailed description has been written to README.gpt file.

Tested at:
        - Exynos4210 rev.1 - TRATS Samsung development board


Chang Hyun Park (1):
  gpt: The leXX_to_int() calls replaced with ones defined at
    <compiler.h>

Lukasz Majewski (6):
  vsprintf:fix: Change type returned by ustrtoul
  part:efi: Move part_efi.h file to ./include
  gpt:doc: GPT (GUID Partition Table) documentation
  gpt: Support for GPT (GUID Partition Table) restoration
  gpt: Support for new "gpt" command
  gpt: Enable support for GPT partition table restoration at Samsung's
    Trats

 common/Makefile         |    1 +
 common/cmd_gpt.c        |  404 +++++++++++++++++++++++++++++++++++++++++++++++
 disk/part_efi.c         |  210 ++++++++++++++++--------
 disk/part_efi.h         |  139 ----------------
 doc/README.gpt          |  207 ++++++++++++++++++++++++
 include/configs/trats.h |   23 +++-
 include/exports.h       |    2 +-
 include/part.h          |    3 +
 include/part_efi.h      |  143 +++++++++++++++++
 lib/vsprintf.c          |    2 +-
 10 files changed, 922 insertions(+), 212 deletions(-)
 create mode 100644 common/cmd_gpt.c
 delete mode 100644 disk/part_efi.h
 create mode 100644 doc/README.gpt
 create mode 100644 include/part_efi.h

-- 
1.7.2.3

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 1/7] vsprintf:fix: Change type returned by ustrtoul
  2012-09-13  8:09 ` [U-Boot] [PATCH v3 " Lukasz Majewski
@ 2012-09-13  8:09   ` Lukasz Majewski
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 2/7] part:efi: Move part_efi.h file to ./include Lukasz Majewski
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-13  8:09 UTC (permalink / raw)
  To: u-boot

The ustrtoul shall convert string defined size (e.g. 1GiB) to unsigned
long type (as its name implies).

Up till now it had returned int, which might cause problems with large
numbers (GiB range), when interpreted as U2 signed numbers.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v3:
- None
---
 include/exports.h |    2 +-
 lib/vsprintf.c    |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/exports.h b/include/exports.h
index 63aa4b2..6cf31aa 100644
--- a/include/exports.h
+++ b/include/exports.h
@@ -23,7 +23,7 @@ char *getenv (const char *name);
 int setenv (const char *varname, const char *varvalue);
 long simple_strtol(const char *cp,char **endp,unsigned int base);
 int strcmp(const char * cs,const char * ct);
-int ustrtoul(const char *cp, char **endp, unsigned int base);
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
 #if defined(CONFIG_CMD_I2C)
 int i2c_write (uchar, uint, int , uchar* , int);
 int i2c_read (uchar, uint, int , uchar* , int);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index e38a4b7..27cb836 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -98,7 +98,7 @@ long simple_strtol(const char *cp,char **endp,unsigned int base)
 	return simple_strtoul(cp,endp,base);
 }
 
-int ustrtoul(const char *cp, char **endp, unsigned int base)
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
 {
 	unsigned long result = simple_strtoul(cp, endp, base);
 	switch (**endp) {
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 2/7] part:efi: Move part_efi.h file to ./include
  2012-09-13  8:09 ` [U-Boot] [PATCH v3 " Lukasz Majewski
  2012-09-13  8:09   ` [U-Boot] [PATCH v3 1/7] vsprintf:fix: Change type returned by ustrtoul Lukasz Majewski
@ 2012-09-13  8:10   ` Lukasz Majewski
  2012-09-13 18:54     ` Kim Phillips
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 3/7] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
                     ` (4 subsequent siblings)
  6 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-13  8:10 UTC (permalink / raw)
  To: u-boot

This move is necessary to export gpt header and GPT partition entries to be
used with other commands or subsystems (like DFU in the future)
Additionally the part_efi.h file has been cleaned-up to supress checkpatch's
warnings.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v3:
- None
---
 disk/part_efi.c    |    2 +-
 disk/part_efi.h    |  139 ---------------------------------------------------
 include/part_efi.h |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 141 insertions(+), 140 deletions(-)
 delete mode 100644 disk/part_efi.h
 create mode 100644 include/part_efi.h

diff --git a/disk/part_efi.c b/disk/part_efi.c
index 02927a0..b2233da 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -34,7 +34,7 @@
 #include <command.h>
 #include <ide.h>
 #include <malloc.h>
-#include "part_efi.h"
+#include <part_efi.h>
 #include <linux/ctype.h>
 
 #if defined(CONFIG_CMD_IDE) || \
diff --git a/disk/part_efi.h b/disk/part_efi.h
deleted file mode 100644
index 5903e7c..0000000
--- a/disk/part_efi.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2008 RuggedCom, Inc.
- * Richard Retanubun <RichardRetanubun@RuggedCom.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * See also linux/fs/partitions/efi.h
- *
- * EFI GUID Partition Table
- * Per Intel EFI Specification v1.02
- * http://developer.intel.com/technology/efi/efi.htm
-*/
-
-#ifndef _DISK_PART_EFI_H
-#define _DISK_PART_EFI_H
-
-#define MSDOS_MBR_SIGNATURE 0xAA55
-#define EFI_PMBR_OSTYPE_EFI 0xEF
-#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
-
-#define GPT_BLOCK_SIZE 512
-#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
-#define GPT_HEADER_REVISION_V1 0x00010000
-#define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
-#define GPT_ENTRY_NAME "gpt"
-
-#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-	((efi_guid_t) \
-	{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
-		(b) & 0xff, ((b) >> 8) & 0xff, \
-		(c) & 0xff, ((c) >> 8) & 0xff, \
-		(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
-
-#define PARTITION_SYSTEM_GUID \
-	EFI_GUID( 0xC12A7328, 0xF81F, 0x11d2, \
-		0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B)
-#define LEGACY_MBR_PARTITION_GUID \
-	EFI_GUID( 0x024DEE41, 0x33E7, 0x11d3, \
-		0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F)
-#define PARTITION_MSFT_RESERVED_GUID \
-	EFI_GUID( 0xE3C9E316, 0x0B5C, 0x4DB8, \
-		0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE)
-#define PARTITION_BASIC_DATA_GUID \
-	EFI_GUID( 0xEBD0A0A2, 0xB9E5, 0x4433, \
-		0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7)
-#define PARTITION_LINUX_RAID_GUID \
-	EFI_GUID( 0xa19d880f, 0x05fc, 0x4d3b, \
-		0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e)
-#define PARTITION_LINUX_SWAP_GUID \
-	EFI_GUID( 0x0657fd6d, 0xa4ab, 0x43c4, \
-		0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f)
-#define PARTITION_LINUX_LVM_GUID \
-	EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
-		0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
-
-/* linux/include/efi.h */
-typedef unsigned short efi_char16_t;
-
-typedef struct {
-	unsigned char b[16];
-} efi_guid_t;
-
-/* based on linux/include/genhd.h */
-struct partition {
-	unsigned char boot_ind;		/* 0x80 - active */
-	unsigned char head;		/* starting head */
-	unsigned char sector;		/* starting sector */
-	unsigned char cyl;		/* starting cylinder */
-	unsigned char sys_ind;		/* What partition type */
-	unsigned char end_head;		/* end head */
-	unsigned char end_sector;	/* end sector */
-	unsigned char end_cyl;		/* end cylinder */
-	unsigned char start_sect[4];	/* starting sector counting from 0 */
-	unsigned char nr_sects[4];	/* nr of sectors in partition */
-} __attribute__ ((packed));
-
-/* based on linux/fs/partitions/efi.h */
-typedef struct _gpt_header {
-	unsigned char signature[8];
-	unsigned char revision[4];
-	unsigned char header_size[4];
-	unsigned char header_crc32[4];
-	unsigned char reserved1[4];
-	unsigned char my_lba[8];
-	unsigned char alternate_lba[8];
-	unsigned char first_usable_lba[8];
-	unsigned char last_usable_lba[8];
-	efi_guid_t disk_guid;
-	unsigned char partition_entry_lba[8];
-	unsigned char num_partition_entries[4];
-	unsigned char sizeof_partition_entry[4];
-	unsigned char partition_entry_array_crc32[4];
-	unsigned char reserved2[GPT_BLOCK_SIZE - 92];
-} __attribute__ ((packed)) gpt_header;
-
-typedef struct _gpt_entry_attributes {
-	unsigned long long required_to_function:1;
-	unsigned long long reserved:47;
-	unsigned long long type_guid_specific:16;
-} __attribute__ ((packed)) gpt_entry_attributes;
-
-#define PARTNAME_SZ	(72 / sizeof(efi_char16_t))
-typedef struct _gpt_entry {
-	efi_guid_t partition_type_guid;
-	efi_guid_t unique_partition_guid;
-	unsigned char starting_lba[8];
-	unsigned char ending_lba[8];
-	gpt_entry_attributes attributes;
-	efi_char16_t partition_name[PARTNAME_SZ];
-}
-__attribute__ ((packed)) gpt_entry;
-
-typedef struct _legacy_mbr {
-	unsigned char boot_code[440];
-	unsigned char unique_mbr_signature[4];
-	unsigned char unknown[2];
-	struct partition partition_record[4];
-	unsigned char signature[2];
-} __attribute__ ((packed)) legacy_mbr;
-
-#endif	/* _DISK_PART_EFI_H */
diff --git a/include/part_efi.h b/include/part_efi.h
new file mode 100644
index 0000000..a9d4399
--- /dev/null
+++ b/include/part_efi.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2008 RuggedCom, Inc.
+ * Richard Retanubun <RichardRetanubun@RuggedCom.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * See also linux/fs/partitions/efi.h
+ *
+ * EFI GUID Partition Table
+ * Per Intel EFI Specification v1.02
+ * http://developer.intel.com/technology/efi/efi.htm
+*/
+
+#ifndef _DISK_PART_EFI_H
+#define _DISK_PART_EFI_H
+
+#define MSDOS_MBR_SIGNATURE 0xAA55
+#define EFI_PMBR_OSTYPE_EFI 0xEF
+#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
+
+#define GPT_BLOCK_SIZE 512
+#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
+#define GPT_HEADER_REVISION_V1 0x00010000
+#define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
+#define GPT_ENTRY_NAME "gpt"
+
+#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
+	((efi_guid_t) \
+	{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, \
+		((a) >> 24) & 0xff, \
+		(b) & 0xff, ((b) >> 8) & 0xff, \
+		(c) & 0xff, ((c) >> 8) & 0xff, \
+		(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
+
+#define PARTITION_SYSTEM_GUID \
+	EFI_GUID(0xC12A7328, 0xF81F, 0x11d2, \
+		0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B)
+#define LEGACY_MBR_PARTITION_GUID \
+	EFI_GUID(0x024DEE41, 0x33E7, 0x11d3, \
+		0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F)
+#define PARTITION_MSFT_RESERVED_GUID \
+	EFI_GUID(0xE3C9E316, 0x0B5C, 0x4DB8, \
+		0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE)
+#define PARTITION_BASIC_DATA_GUID \
+	EFI_GUID(0xEBD0A0A2, 0xB9E5, 0x4433, \
+		0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7)
+#define PARTITION_LINUX_RAID_GUID \
+	EFI_GUID(0xa19d880f, 0x05fc, 0x4d3b, \
+		0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e)
+#define PARTITION_LINUX_SWAP_GUID \
+	EFI_GUID(0x0657fd6d, 0xa4ab, 0x43c4, \
+		0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f)
+#define PARTITION_LINUX_LVM_GUID \
+	EFI_GUID(0xe6d6d379, 0xf507, 0x44c2, \
+		0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
+
+/* linux/include/efi.h */
+typedef unsigned short efi_char16_t;
+
+typedef struct {
+	unsigned char b[16];
+} efi_guid_t;
+
+/* based on linux/include/genhd.h */
+struct partition {
+	unsigned char boot_ind;		/* 0x80 - active */
+	unsigned char head;		/* starting head */
+	unsigned char sector;		/* starting sector */
+	unsigned char cyl;		/* starting cylinder */
+	unsigned char sys_ind;		/* What partition type */
+	unsigned char end_head;		/* end head */
+	unsigned char end_sector;	/* end sector */
+	unsigned char end_cyl;		/* end cylinder */
+	unsigned char start_sect[4];	/* starting sector counting from 0 */
+	unsigned char nr_sects[4];	/* nr of sectors in partition */
+} __attribute__ ((packed));
+
+/* based on linux/fs/partitions/efi.h */
+typedef struct _gpt_header {
+	unsigned char signature[8];
+	unsigned char revision[4];
+	unsigned char header_size[4];
+	unsigned char header_crc32[4];
+	unsigned char reserved1[4];
+	unsigned char my_lba[8];
+	unsigned char alternate_lba[8];
+	unsigned char first_usable_lba[8];
+	unsigned char last_usable_lba[8];
+	efi_guid_t disk_guid;
+	unsigned char partition_entry_lba[8];
+	unsigned char num_partition_entries[4];
+	unsigned char sizeof_partition_entry[4];
+	unsigned char partition_entry_array_crc32[4];
+	unsigned char reserved2[GPT_BLOCK_SIZE - 92];
+} __attribute__ ((packed)) gpt_header;
+
+typedef struct _gpt_entry_attributes {
+	unsigned long long required_to_function:1;
+	unsigned long long reserved:47;
+	unsigned long long type_guid_specific:16;
+} __attribute__ ((packed)) gpt_entry_attributes;
+
+#define PARTNAME_SZ	(72 / sizeof(efi_char16_t))
+typedef struct _gpt_entry {
+	efi_guid_t partition_type_guid;
+	efi_guid_t unique_partition_guid;
+	unsigned char starting_lba[8];
+	unsigned char ending_lba[8];
+	gpt_entry_attributes attributes;
+	efi_char16_t partition_name[PARTNAME_SZ];
+}
+__attribute__ ((packed)) gpt_entry;
+
+typedef struct _legacy_mbr {
+	unsigned char boot_code[440];
+	unsigned char unique_mbr_signature[4];
+	unsigned char unknown[2];
+	struct partition partition_record[4];
+	unsigned char signature[2];
+} __attribute__ ((packed)) legacy_mbr;
+
+#endif	/* _DISK_PART_EFI_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot]  [PATCH v3 3/7] gpt:doc: GPT (GUID Partition Table) documentation
  2012-09-13  8:09 ` [U-Boot] [PATCH v3 " Lukasz Majewski
  2012-09-13  8:09   ` [U-Boot] [PATCH v3 1/7] vsprintf:fix: Change type returned by ustrtoul Lukasz Majewski
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 2/7] part:efi: Move part_efi.h file to ./include Lukasz Majewski
@ 2012-09-13  8:10   ` Lukasz Majewski
  2012-09-17 17:58     ` Stephen Warren
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Lukasz Majewski
                     ` (3 subsequent siblings)
  6 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-13  8:10 UTC (permalink / raw)
  To: u-boot

Documentation of the GPT format.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v2:
- Typos correction.
- Adding guidlines about GPT restoration.
- Adding information about GUID generator

Changes for v3:
- None
---
 doc/README.gpt |  207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 207 insertions(+), 0 deletions(-)
 create mode 100644 doc/README.gpt

diff --git a/doc/README.gpt b/doc/README.gpt
new file mode 100644
index 0000000..ec56005
--- /dev/null
+++ b/doc/README.gpt
@@ -0,0 +1,207 @@
+#
+#  Copyright (C) 2012 Samsung Electronics
+#
+#  Lukasz Majewski <l.majewski@samsung.com>
+#
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+
+
+Glossary:
+========
+- UUID -(Universally Unique Identifier)
+- GUID - (Globally Unique ID)
+- EFI - (Extensible Firmware Interface)
+- UEFI - (Unified EFI) - EFI evolution
+- GPT (GUID Partition Table) - it is the EFI standard part
+- partitions - lists of available partitions (defined at u-boot):
+  ./include/configs/{target}.h
+
+Introduction:
+=============
+This document describes the GPT partition table format when used with u-boot.
+
+
+UUID introduction:
+====================
+
+GPT for marking disks/partitions is using the UUID. It is supposed to be a
+globally unique value. A UUID is a 16-byte (128-bit) number. The number of
+theoretically possible UUIDs is therefore about 3 ? 10^38.
+More often UUID is stored as 32 hexadecimal digits, displayed in 5 groups
+separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters
+(32 digits and 4 hyphens)
+
+For instance, GUID of Linux data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
+
+Historically there are 5 methods to generate this number. The oldest one is
+combining machine's MAC address and timer (epoch) value.
+
+Successive versions are using MD5 hash, random numbers and SHA-1 hash. All major
+OSes and programming languages are providing libraries to compute UUID (e.g.
+uuid command line tool).
+
+GPT brief explanation:
+======================
+
+	Layout:
+	-------
+
+	--------------------------------------------------
+	LBA 0          |Protective MBR                   |
+	----------------------------------------------------------
+	LBA 1          |Primary GPT Header               | Primary
+	-------------------------------------------------- GPT
+	LBA 2          |Entry 1|Entry 2| Entry 3| Entry 4|
+	--------------------------------------------------
+	LBA 3          |Entries 5 - 128                  |
+		       |                                 |
+		       |                                 |
+	----------------------------------------------------------
+	LBA 34         |Partition 1                      |
+		       |                                 |
+		       -----------------------------------
+		       |Partition 2                      |
+		       |                                 |
+		       -----------------------------------
+		       |Partition n                      |
+		       |                                 |
+	----------------------------------------------------------
+	LBA -34        |Entry 1|Entry 2| Entry 3| Entry 4| Secondary
+	-------------------------------------------------- (bkp)
+	LBA -33        |Entries 5 - 128                  | GPT
+		       |                                 |
+		       |                                 |
+	LBA -2         |                                 |
+	--------------------------------------------------
+	LBA -1         |Secondary GPT Header             |
+	----------------------------------------------------------
+
+
+For a legacy reasons, GPT's LBA 0 sector has a MBR structure. It is called
+"protective MBR".
+Its first partition entry ID has 0xEE value, and disk software, which is not
+handling the GPT sees it as a storage device without free space.
+
+It is possible to define 128 linearly placed partition entries.
+
+"LBA -1" means the last addressable block (in the mmc subsystem:
+"dev_desc->lba - 1")
+
+Primary/Secondary GPT header:
+----------------------------
+Offset  Size    Description
+
+0       8 B     Signature ("EFI PART", 45 46 49 20 50 41 52 54)
+8       4 B     Revision (For version 1.0, the value is 00 00 01 00)
+12      4 B     Header size (in bytes, usually 5C 00 00 00 meaning 92 bytes)
+16      4 B     CRC32 of header (0 to header size), with this field zeroed
+		during calculation
+20      4 B     Reserved (ZERO);
+24      8 B     Current LBA (location of this header copy)
+32      8 B     Backup LBA (location of the other header copy)
+40      8 B     First usable LBA for partitions (primary partition table last
+		LBA + 1)
+48      8 B     Last usable LBA (secondary partition table first LBA - 1)
+56      16 B    Disk GUID (also referred as UUID on UNIXes)
+72      8 B     Partition entries starting LBA (always 2 in primary copy)
+80      4 B     Number of partition entries
+84      4 B     Size of a partition entry (usually 128)
+88      4 B     CRC32 of partition array
+92      *       Reserved; must be ZERO (420 bytes for a 512-byte LBA)
+
+TOTAL: 512 B
+
+
+
+IMPORTANT:
+
+GPT headers and partition entries are protected by CRC32 (the POSIX CRC32).
+
+Primary GPT header and Secondary GPT header have swapped values of "Current LBA"
+and "Backup LBA" and therefore different CRC32 check-sum.
+
+CRC32 for GPT headers (field "CRC of header") are calculated up till
+"Header size" (92), NOT 512 bytes.
+
+CRC32 for partition entries (field "CRC32 of partition array") is calculated for
+the whole array entry ( Number_of_partition_entries *
+sizeof(partition_entry_size (usually 128)))
+
+Observe, how Secondary GPT is placed in the memory. It is NOT a mirror reflect
+of the Primary.
+
+
+	   Partition Entry Format:
+	   ----------------------
+	   Offset  Size    Description
+
+	   0       16 B    Partition type GUID
+	   16      16 B    Unique partition GUID
+	   32      8  B    First LBA (Little Endian)
+	   40      8  B    Last LBA (inclusive)
+	   48      8  B    Attribute flags [+]
+	   56      72 B    Partition name (text)
+
+	   Attribute flags:
+	   Bit 0  - System partition
+	   Bit 60 - Read-only
+	   Bit 62 - Hidden
+	   Bit 63 - Not mount
+
+
+Example usage:
+==============
+
+To restore GUID partition table one needs to:
+1. at ./include/configs/{board}.h
+   - define "partitions=" environment variable with format:
+     "name=u-boot,size=60M;name=kernel,size=60M;name=platform,size=1G;"
+   - define GPT_PARTS_NUM with actual number of partitions (as defined above)
+   - #define CONFIG_EFI_PARTITION and #define CONFIG_CMD_GPT
+
+2. From u-boot prompt type:
+   gpt mmc 0 uuid_disk=ec2cddf2-fbf5-11e1-af3a-001fd09285c0, \
+   uuid1=ed09c4b0-fbf5-11e1-9a95-001fd09285c0, \
+   uuid2=edd6d93c-fbf5-11e1-875a-001fd09285c0, \
+   uuid3=f0485114-fbf5-11e1-a3ae-001fd09285c0 ...
+
+   UUIDs shall be defined up to GPT_PARTS_NUM. Smaller number is acceptable.
+   When UUIDs are NOT provided, internal (rather weak) GUID generator will be
+   used instead
+
+Internal GUID generator:
+=======================
+
+For "emergency" usage (or when list of UUIDs cannot be provided)  the internal
+GUID generator shall be used. It uses gd->start_addr_sp as a primary source of
+UUID generator (16B).
+
+
+Useful info:
+============
+
+Two programs, namely: 'fdisk' and 'parted' are recommended to work with GPT
+recovery. Parted is able to handle GUID partitions. Unfortunately the 'fdisk'
+hasn't got such ability.
+Please, pay attention at -l switch for parted.
+
+"uuid" program is recommended to generate UUID string. Moreover it can decode
+(-d switch) passed in UUID string. It can be used to generate partitions UUID
+passed to u-boot environment variables.
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h>
  2012-09-13  8:09 ` [U-Boot] [PATCH v3 " Lukasz Majewski
                     ` (2 preceding siblings ...)
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 3/7] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
@ 2012-09-13  8:10   ` Lukasz Majewski
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 5/7] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-13  8:10 UTC (permalink / raw)
  To: u-boot

From: Chang Hyun Park <chchch.park@samsung.com>

Custom definitions of le_XX_to_int functions have been replaced with
standard ones, defined at <compiler.h>

Replacement of several GPT related structures members with ones
indicating its endianness and proper size.

Signed-off-by: Chang Hyun Park <chchch.park@samsung.com>
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v2:
- Combining two commits regarding part_efi.{h|c}

Changes for v3:
- None
---
 disk/part_efi.c    |  109 +++++++++++++++++++---------------------------------
 include/part_efi.h |   85 +++++++++++++++++++++-------------------
 2 files changed, 84 insertions(+), 110 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index b2233da..d4c61d2 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -44,34 +44,6 @@
     defined(CONFIG_MMC) || \
     defined(CONFIG_SYSTEMACE)
 
-/* Convert char[2] in little endian format to the host format integer
- */
-static inline unsigned short le16_to_int(unsigned char *le16)
-{
-	return ((le16[1] << 8) + le16[0]);
-}
-
-/* Convert char[4] in little endian format to the host format integer
- */
-static inline unsigned long le32_to_int(unsigned char *le32)
-{
-	return ((le32[3] << 24) + (le32[2] << 16) + (le32[1] << 8) + le32[0]);
-}
-
-/* Convert char[8] in little endian format to the host format integer
- */
-static inline unsigned long long le64_to_int(unsigned char *le64)
-{
-	return (((unsigned long long)le64[7] << 56) +
-		((unsigned long long)le64[6] << 48) +
-		((unsigned long long)le64[5] << 40) +
-		((unsigned long long)le64[4] << 32) +
-		((unsigned long long)le64[3] << 24) +
-		((unsigned long long)le64[2] << 16) +
-		((unsigned long long)le64[1] << 8) +
-		(unsigned long long)le64[0]);
-}
-
 /**
  * efi_crc32() - EFI version of crc32 function
  * @buf: buffer to calculate crc32 of
@@ -79,7 +51,7 @@ static inline unsigned long long le64_to_int(unsigned char *le64)
  *
  * Description: Returns EFI-style CRC32 value for @buf
  */
-static inline unsigned long efi_crc32(const void *buf, unsigned long len)
+static inline u32 efi_crc32(const void *buf, u32 len)
 {
 	return crc32(0, buf, len);
 }
@@ -137,13 +109,13 @@ void print_part_efi(block_dev_desc_t * dev_desc)
 	debug("%s: gpt-entry@%p\n", __func__, gpt_pte);
 
 	printf("Part\tName\t\t\tStart LBA\tEnd LBA\n");
-	for (i = 0; i < le32_to_int(gpt_head->num_partition_entries); i++) {
+	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
 
 		if (is_pte_valid(&gpt_pte[i])) {
 			printf("%3d\t%-18s\t0x%08llX\t0x%08llX\n", (i + 1),
 				print_efiname(&gpt_pte[i]),
-				le64_to_int(gpt_pte[i].starting_lba),
-				le64_to_int(gpt_pte[i].ending_lba));
+			       (u64) le64_to_cpu(gpt_pte[i].starting_lba),
+			       (u64) le64_to_cpu(gpt_pte[i].ending_lba));
 		} else {
 			break;	/* Stop at the first non valid PTE */
 		}
@@ -174,9 +146,9 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 	}
 
 	/* The ulong casting limits the maximum disk size to 2 TB */
-	info->start = (ulong) le64_to_int(gpt_pte[part - 1].starting_lba);
+	info->start = (u64) le64_to_cpu(gpt_pte[part - 1].starting_lba);
 	/* The ending LBA is inclusive, to calculate size, add 1 to it */
-	info->size = ((ulong)le64_to_int(gpt_pte[part - 1].ending_lba) + 1)
+	info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
 		     - info->start;
 	info->blksz = GPT_BLOCK_SIZE;
 
@@ -215,7 +187,7 @@ int test_part_efi(block_dev_desc_t * dev_desc)
 static int pmbr_part_valid(struct partition *part)
 {
 	if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
-		le32_to_int(part->start_sect) == 1UL) {
+		le32_to_cpu(part->start_sect) == 1UL) {
 		return 1;
 	}
 
@@ -234,9 +206,8 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 {
 	int i = 0;
 
-	if (!mbr || le16_to_int(mbr->signature) != MSDOS_MBR_SIGNATURE) {
+	if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
 		return 0;
-	}
 
 	for (i = 0; i < 4; i++) {
 		if (pmbr_part_valid(&mbr->partition_record[i])) {
@@ -259,8 +230,8 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 			gpt_header * pgpt_head, gpt_entry ** pgpt_pte)
 {
-	unsigned char crc32_backup[4] = { 0 };
-	unsigned long calc_crc32;
+	u32 crc32_backup = 0;
+	u32 calc_crc32;
 	unsigned long long lastlba;
 
 	if (!dev_desc || !pgpt_head) {
@@ -275,54 +246,54 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 	}
 
 	/* Check the GPT header signature */
-	if (le64_to_int(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
+	if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
 		printf("GUID Partition Table Header signature is wrong:"
 			"0x%llX != 0x%llX\n",
-			(unsigned long long)le64_to_int(pgpt_head->signature),
-			(unsigned long long)GPT_HEADER_SIGNATURE);
+			(u64) le64_to_cpu(pgpt_head->signature),
+			(u64) GPT_HEADER_SIGNATURE);
 		return 0;
 	}
 
 	/* Check the GUID Partition Table CRC */
-	memcpy(crc32_backup, pgpt_head->header_crc32, sizeof(crc32_backup));
-	memset(pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
+	memcpy(&crc32_backup, &pgpt_head->header_crc32, sizeof(crc32_backup));
+	memset(&pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
 
 	calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
-		le32_to_int(pgpt_head->header_size));
+		le32_to_cpu(pgpt_head->header_size));
 
-	memcpy(pgpt_head->header_crc32, crc32_backup, sizeof(crc32_backup));
+	memcpy(&pgpt_head->header_crc32, &crc32_backup, sizeof(crc32_backup));
 
-	if (calc_crc32 != le32_to_int(crc32_backup)) {
+	if (calc_crc32 != le32_to_cpu(crc32_backup)) {
 		printf("GUID Partition Table Header CRC is wrong:"
-			"0x%08lX != 0x%08lX\n",
-			le32_to_int(crc32_backup), calc_crc32);
+			"0x%x != 0x%x\n",
+		       (u32) le32_to_cpu(crc32_backup), calc_crc32);
 		return 0;
 	}
 
 	/* Check that the my_lba entry points to the LBA that contains the GPT */
-	if (le64_to_int(pgpt_head->my_lba) != lba) {
+	if (le64_to_cpu(pgpt_head->my_lba) != lba) {
 		printf("GPT: my_lba incorrect: %llX != %llX\n",
-			(unsigned long long)le64_to_int(pgpt_head->my_lba),
-			(unsigned long long)lba);
+			(u64)le64_to_cpu(pgpt_head->my_lba),
+			(u64)lba);
 		return 0;
 	}
 
 	/* Check the first_usable_lba and last_usable_lba are within the disk. */
 	lastlba = (unsigned long long)dev_desc->lba;
-	if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
+	if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) {
 		printf("GPT: first_usable_lba incorrect: %llX > %llX\n",
-			le64_to_int(pgpt_head->first_usable_lba), lastlba);
+		       (u64) le64_to_cpu(pgpt_head->first_usable_lba), lastlba);
 		return 0;
 	}
-	if (le64_to_int(pgpt_head->last_usable_lba) > lastlba) {
+	if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) {
 		printf("GPT: last_usable_lba incorrect: %llX > %llX\n",
-			le64_to_int(pgpt_head->last_usable_lba), lastlba);
+		       (u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 		return 0;
 	}
 
 	debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n",
-		le64_to_int(pgpt_head->first_usable_lba),
-		le64_to_int(pgpt_head->last_usable_lba), lastlba);
+	      (u64) le64_to_cpu(pgpt_head->first_usable_lba),
+	      (u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 
 	/* Read and allocate Partition Table Entries */
 	*pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
@@ -333,13 +304,13 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 
 	/* Check the GUID Partition Table Entry Array CRC */
 	calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
-		le32_to_int(pgpt_head->num_partition_entries) *
-		le32_to_int(pgpt_head->sizeof_partition_entry));
+		le32_to_cpu(pgpt_head->num_partition_entries) *
+		le32_to_cpu(pgpt_head->sizeof_partition_entry));
 
-	if (calc_crc32 != le32_to_int(pgpt_head->partition_entry_array_crc32)) {
+	if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) {
 		printf("GUID Partition Table Entry Array CRC is wrong:"
-			"0x%08lX != 0x%08lX\n",
-			le32_to_int(pgpt_head->partition_entry_array_crc32),
+			"0x%x != 0x%x\n",
+		       (u32)le32_to_cpu(pgpt_head->partition_entry_array_crc32),
 			calc_crc32);
 
 		free(*pgpt_pte);
@@ -370,12 +341,12 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 		return NULL;
 	}
 
-	count = le32_to_int(pgpt_head->num_partition_entries) *
-		le32_to_int(pgpt_head->sizeof_partition_entry);
+	count = le32_to_cpu(pgpt_head->num_partition_entries) *
+		le32_to_cpu(pgpt_head->sizeof_partition_entry);
 
-	debug("%s: count = %lu * %lu = %u\n", __func__,
-		le32_to_int(pgpt_head->num_partition_entries),
-		le32_to_int(pgpt_head->sizeof_partition_entry), count);
+	debug("%s: count = %u * %u = %u\n", __func__,
+	      (u32) le32_to_cpu(pgpt_head->num_partition_entries),
+	      (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), count);
 
 	/* Allocate memory for PTE, remember to FREE */
 	if (count != 0) {
@@ -390,7 +361,7 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 
 	/* Read GPT Entries from device */
 	if (dev_desc->block_read (dev_desc->dev,
-		(unsigned long)le64_to_int(pgpt_head->partition_entry_lba),
+		(u64) le64_to_cpu(pgpt_head->partition_entry_lba),
 		(lbaint_t) (count / GPT_BLOCK_SIZE), pte)
 		!= (count / GPT_BLOCK_SIZE)) {
 
diff --git a/include/part_efi.h b/include/part_efi.h
index a9d4399..11d995c 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -29,6 +29,8 @@
  * http://developer.intel.com/technology/efi/efi.htm
 */
 
+#include <linux/compiler.h>
+
 #ifndef _DISK_PART_EFI_H
 #define _DISK_PART_EFI_H
 
@@ -41,6 +43,8 @@
 #define GPT_HEADER_REVISION_V1 0x00010000
 #define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
 #define GPT_ENTRY_NAME "gpt"
+#define GPT_ENTRY_NUMBERS		128
+#define GPT_ENTRY_SIZE			128
 
 #define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
 	((efi_guid_t) \
@@ -73,68 +77,67 @@
 		0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
 
 /* linux/include/efi.h */
-typedef unsigned short efi_char16_t;
+typedef u16 efi_char16_t;
 
 typedef struct {
-	unsigned char b[16];
+	u8 b[16];
 } efi_guid_t;
 
 /* based on linux/include/genhd.h */
 struct partition {
-	unsigned char boot_ind;		/* 0x80 - active */
-	unsigned char head;		/* starting head */
-	unsigned char sector;		/* starting sector */
-	unsigned char cyl;		/* starting cylinder */
-	unsigned char sys_ind;		/* What partition type */
-	unsigned char end_head;		/* end head */
-	unsigned char end_sector;	/* end sector */
-	unsigned char end_cyl;		/* end cylinder */
-	unsigned char start_sect[4];	/* starting sector counting from 0 */
-	unsigned char nr_sects[4];	/* nr of sectors in partition */
-} __attribute__ ((packed));
+	u8 boot_ind;		/* 0x80 - active */
+	u8 head;		/* starting head */
+	u8 sector;		/* starting sector */
+	u8 cyl;		/* starting cylinder */
+	u8 sys_ind;		/* What partition type */
+	u8 end_head;		/* end head */
+	u8 end_sector;	/* end sector */
+	u8 end_cyl;		/* end cylinder */
+	__le32 start_sect;	/* starting sector counting from 0 */
+	__le32 nr_sects;	/* nr of sectors in partition */
+} __packed;
 
 /* based on linux/fs/partitions/efi.h */
 typedef struct _gpt_header {
-	unsigned char signature[8];
-	unsigned char revision[4];
-	unsigned char header_size[4];
-	unsigned char header_crc32[4];
-	unsigned char reserved1[4];
-	unsigned char my_lba[8];
-	unsigned char alternate_lba[8];
-	unsigned char first_usable_lba[8];
-	unsigned char last_usable_lba[8];
+	__le64 signature;
+	__le32 revision;
+	__le32 header_size;
+	__le32 header_crc32;
+	__le32 reserved1;
+	__le64 my_lba;
+	__le64 alternate_lba;
+	__le64 first_usable_lba;
+	__le64 last_usable_lba;
 	efi_guid_t disk_guid;
-	unsigned char partition_entry_lba[8];
-	unsigned char num_partition_entries[4];
-	unsigned char sizeof_partition_entry[4];
-	unsigned char partition_entry_array_crc32[4];
-	unsigned char reserved2[GPT_BLOCK_SIZE - 92];
-} __attribute__ ((packed)) gpt_header;
+	__le64 partition_entry_lba;
+	__le32 num_partition_entries;
+	__le32 sizeof_partition_entry;
+	__le32 partition_entry_array_crc32;
+	u8 reserved2[GPT_BLOCK_SIZE - 92];
+} __packed gpt_header;
 
 typedef struct _gpt_entry_attributes {
-	unsigned long long required_to_function:1;
-	unsigned long long reserved:47;
-	unsigned long long type_guid_specific:16;
-} __attribute__ ((packed)) gpt_entry_attributes;
+	u64 required_to_function:1;
+	u64 reserved:47;
+	u64 type_guid_specific:16;
+} __packed gpt_entry_attributes;
 
 #define PARTNAME_SZ	(72 / sizeof(efi_char16_t))
 typedef struct _gpt_entry {
 	efi_guid_t partition_type_guid;
 	efi_guid_t unique_partition_guid;
-	unsigned char starting_lba[8];
-	unsigned char ending_lba[8];
+	__le64 starting_lba;
+	__le64 ending_lba;
 	gpt_entry_attributes attributes;
 	efi_char16_t partition_name[PARTNAME_SZ];
-}
-__attribute__ ((packed)) gpt_entry;
+} __packed gpt_entry;
 
 typedef struct _legacy_mbr {
-	unsigned char boot_code[440];
-	unsigned char unique_mbr_signature[4];
-	unsigned char unknown[2];
+	u8 boot_code[440];
+	__le32 unique_mbr_signature;
+	__le16 unknown;
 	struct partition partition_record[4];
-	unsigned char signature[2];
-} __attribute__ ((packed)) legacy_mbr;
+	__le16 signature;
+} __packed legacy_mbr;
 
 #endif	/* _DISK_PART_EFI_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-09-13  8:09 ` [U-Boot] [PATCH v3 " Lukasz Majewski
                     ` (3 preceding siblings ...)
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Lukasz Majewski
@ 2012-09-13  8:10   ` Lukasz Majewski
  2012-09-17 18:07     ` Stephen Warren
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 6/7] gpt: Support for new "gpt" command Lukasz Majewski
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats Lukasz Majewski
  6 siblings, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-13  8:10 UTC (permalink / raw)
  To: u-boot

The restoration of GPT table (both primary and secondary) is now possible.
Simple GUID generation is supported.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v2:
- Move GPT Header and Page Table Entries generation code to cmd_gpt.c
- Provide clean API to use set_gpt_table function for GPT restoration on
  a block device

Changes for v3:
- Replace printf with puts
---
 disk/part_efi.c |   99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/part.h  |    3 ++
 2 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index d4c61d2..19821f3 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -403,4 +403,103 @@ static int is_pte_valid(gpt_entry * pte)
 		return 1;
 	}
 }
+
+/**
+ * set_protective_mbr(): Set the EFI protective MBR
+ * @param dev_desc - block device descriptor
+ *
+ * @return - zero on success, otherwise error
+ */
+static int set_protective_mbr(block_dev_desc_t *dev_desc)
+{
+	legacy_mbr p_mbr;
+
+	/* Setup the Protective MBR */
+	memset((u32 *) &p_mbr, 0x00, sizeof(p_mbr));
+	/* Append signature */
+	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) dev_desc->lba;
+
+	/* Write MBR sector to the MMC device */
+	if (dev_desc->block_write(dev_desc->dev, 0, 1, &p_mbr) != 1) {
+		printf("** Can't write to device %d **\n",
+			dev_desc->dev);
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * set_gpt_table() - Restore the GUID Partition Table
+ *
+ * @param dev_desc - block device descriptor
+ * @param parts - number of partitions
+ * @param size - pointer to array with each partition size
+ * @param name - pointer to array with each partition name
+ *
+ * @return - zero on success, otherwise error
+ */
+int set_gpt_table(block_dev_desc_t *dev_desc,
+		  gpt_header *gpt_h, gpt_entry *gpt_e)
+{
+	const int pte_blk_num = (GPT_ENTRY_NUMBERS * sizeof(gpt_entry)) /
+		dev_desc->blksz;
+	u32 calc_crc32;
+	u64 val;
+
+	debug("max lba: %x\n", (u32) dev_desc->lba);
+
+	/* Setup the Protective MBR */
+	if (set_protective_mbr(dev_desc) < 0)
+		goto err;
+
+	/* 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);
+
+	/* Write the First GPT to the block right after the Legacy MBR */
+	if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1)
+		goto err;
+
+	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e)
+	    != pte_blk_num)
+		goto err;
+
+	/* recalculate the values for the Second 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);
+	gpt_h->header_crc32 = 0;
+
+	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);
+
+	/* Write the Second GPT that is located at the end of the disk */
+	if (dev_desc->block_write(dev_desc->dev,
+				  le32_to_cpu(gpt_h->last_usable_lba + 1),
+				  pte_blk_num, gpt_e) != pte_blk_num)
+		goto err;
+
+	if (dev_desc->block_write(dev_desc->dev,
+				  le32_to_cpu(gpt_h->my_lba), 1, gpt_h) != 1)
+		goto err;
+
+	puts("GPT successfully written to block device!\n");
+	return 0;
+
+ err:
+	printf("** Can't write to device %d **\n",
+	       dev_desc->dev);
+	return -1;
+}
 #endif
diff --git a/include/part.h b/include/part.h
index e1478f4..fc34ed2 100644
--- a/include/part.h
+++ b/include/part.h
@@ -157,10 +157,13 @@ int   test_part_amiga (block_dev_desc_t *dev_desc);
 #endif
 
 #ifdef CONFIG_EFI_PARTITION
+#include <part_efi.h>
 /* disk/part_efi.c */
 int get_partition_info_efi (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
 void print_part_efi (block_dev_desc_t *dev_desc);
 int   test_part_efi (block_dev_desc_t *dev_desc);
+int set_gpt_table(block_dev_desc_t *dev_desc,
+		  gpt_header *gpt_h, gpt_entry *gpt_e);
 #endif
 
 #endif /* _PART_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 6/7] gpt: Support for new "gpt" command
  2012-09-13  8:09 ` [U-Boot] [PATCH v3 " Lukasz Majewski
                     ` (4 preceding siblings ...)
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 5/7] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
@ 2012-09-13  8:10   ` Lukasz Majewski
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats Lukasz Majewski
  6 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-13  8:10 UTC (permalink / raw)
  To: u-boot

New command - "gpt" is supported. It restores the GPT partition table.
It looks into the "partitions" environment variable for partitions definition.
It can be enabled at target configuration file with CONFIG_CMD_GPT.
Simple UUID generator has been implemented. It uses the the gd->start_addr_sp
for entrophy pool. Moreover the pool address is used as crc32 seed.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v2:
- gpt command now accepts device medium and its number (e.g. gpt mmc 0)
- UUIDs can be passed via u-boot prompt when used with gpt command
- Format of restored GPT has been changed - now key=value pairs are used
  'name="PARTS_CSA",size=8MiB;\ '
  'name="PARTS_BOOTLOADER",size=60MiB; \'
- guid_gen now accepts "pool" pointer and guid pointer
- gd->start_addr_sp is used as a primary source of entrophy
- static buffers definitions have been removed
- remove memsize_to_blocks function with call to standard ustrtoul
- doxygen comments for functions added

Changes for v3:
- Remove unnecessary braces
---
 common/Makefile  |    1 +
 common/cmd_gpt.c |  404 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 405 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_gpt.c

diff --git a/common/Makefile b/common/Makefile
index 57da76f..39247c5 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -185,6 +185,7 @@ COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
 COBJS-$(CONFIG_UPDATE_TFTP) += update.o
 COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
 COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o
+COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o
 endif
 
 ifdef CONFIG_SPL_BUILD
diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
new file mode 100644
index 0000000..2460573
--- /dev/null
+++ b/common/cmd_gpt.c
@@ -0,0 +1,404 @@
+/*
+ * cmd_gpt.c -- GPT (GUID Partition Table) handling command
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * author: Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <command.h>
+#include <mmc.h>
+#include <part_efi.h>
+#include <exports.h>
+
+gpt_entry *gpt_e;
+gpt_header *gpt_h;
+DECLARE_GLOBAL_DATA_PTR;
+static unsigned int gpt_parts;
+
+#ifdef DEBUG
+/**
+ * guid_dump(): Dump guid content
+ *
+ * @param guid - pinter to guid
+ * @param i - number of bytes to dump
+ */
+static void guid_dump(u8 *guid, int i)
+{
+	int k;
+
+	debug("GUID: ");
+	for (k = 0; k < i; k++, guid++)
+		debug(" %x ", *guid);
+	debug("\n");
+}
+#else
+static void guid_dump(u8 *guid, int i) {}
+#endif
+
+/**
+ * guid_gen(): Generate UUID
+ *
+ * @param pool - pointer to pseudo random data (e.g. SP)
+ * @param guid - pointer to guid table
+ *
+ * @return - generated UUID table
+ *
+ * NOTE: The entrophy of this function is small
+ */
+static void guid_gen(const u32 *pool, u8 *guid)
+{
+	int k = 0;
+	u32 *ptr = (u32 *) guid;
+
+	debug("%s: pool: 0x%p guid: 0x%p\n", __func__, pool, guid);
+	for (k = 0; k < 4; k++)
+		*(ptr + k) = crc32((u32) pool, (const void *) (pool - k), 512);
+
+	guid_dump(guid, sizeof(efi_guid_t));
+}
+
+/**
+ * convert_uuid(); Convert UUID stored as string to bytes
+ *
+ * @param uuid - UUID represented as string
+ * @param dst - GUID buffer
+ *
+ * @return
+ */
+static int convert_uuid(char *uuid, u8 *dst)
+{
+	efi_guid_t guid;
+	u16 b, c, d;
+	char *t;
+	u64 e;
+	u32 a;
+	u8 *p;
+
+	debug("%s: uuid: %s\n", __func__, uuid);
+	t = strsep(&uuid, "-");
+	a = (u32)simple_strtoul(t, NULL, 16);
+	t = strsep(&uuid, "-");
+	b = (u16)simple_strtoul(t, NULL, 16);
+	t = strsep(&uuid, "-");
+	c = (u16)simple_strtoul(t, NULL, 16);
+	t = strsep(&uuid, "-");
+	d = (u16)simple_strtoul(t, NULL, 16);
+	e = (u64)simple_strtoull(uuid, NULL, 16);
+
+	p = (u8 *) &e;
+	guid = EFI_GUID(a, b, c, d >> 8, d & 0xFF,
+			*(p + 5), *(p + 4), *(p + 3),
+			*(p + 2), *(p + 1) , *p);
+
+	guid_dump(guid.b, sizeof(efi_guid_t));
+	memcpy(dst, guid.b, sizeof(efi_guid_t));
+
+	return 0;
+}
+
+/**
+ * fill_pte(): Fill the GPT partition table entry
+ *
+ * @param dev_desc - block device descriptor
+ * @param gpt_h - GPT header representation
+ * @param gpt_e - GPT partition table entries
+ * @param parts - number of partitions
+ * @param size - size of each partition
+ * @param name - name of each partition
+ */
+static void gpt_fill_pte(block_dev_desc_t *dev_desc, gpt_header *gpt_h,
+		     gpt_entry *gpt_e, int parts, unsigned int *size,
+		     char *name[], char *uuid[])
+{
+	u32 offset = (u32) gpt_h->first_usable_lba;
+	u8 guid[sizeof(efi_guid_t)];
+	char p[PARTNAME_SZ];
+	int i, k, j;
+	char *s;
+
+	for (i = 0; i < parts; i++) {
+		memcpy(gpt_e[i].partition_type_guid.b,
+		       &PARTITION_BASIC_DATA_GUID, 16);
+
+		if (uuid[i])
+			convert_uuid(uuid[i], gpt_e[i].unique_partition_guid.b);
+		else {
+			guid_gen((((u32 *) gd->start_addr_sp) - i - 1), guid);
+			memcpy(gpt_e[i].unique_partition_guid.b, guid,
+			       sizeof(efi_guid_t));
+
+		}
+		s = name[i];
+
+		memset(p, 0x00, sizeof(p));
+		for (k = 0, j = 0; k < strlen(s); k++, j += 2) {
+			p[j] = *(s + k);
+			p[j + 1] = '.';
+		}
+
+		memcpy(gpt_e[i].partition_name,
+		       p, strlen(p));
+
+		gpt_e[i].starting_lba = cpu_to_le32(offset);
+
+		/* allocate remaining memory in last partition */
+		if (i != parts - 1)
+			gpt_e[i].ending_lba =
+				cpu_to_le64(offset + size[i] - 1);
+		else
+			gpt_e[i].ending_lba = gpt_h->last_usable_lba;
+
+		memset(&gpt_e[i].attributes, 0,
+		       sizeof(gpt_entry_attributes));
+
+		offset += size[i];
+		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%x\n",
+		      __func__, name[i], i, offset, i, size[i]);
+	}
+}
+
+/**
+ * extract_val(): Extract value from a key=value pair
+ *
+ * @param p - pointer to string
+ * @param tab - table to store extracted value
+ * @param i - actual tab element to work on
+ *
+ * @return - zero on success; otherwise error
+ */
+static int extract_val(char **p, char *tab[], int i)
+{
+	char *t, *tok = *p;
+
+	t = strsep(&tok, ",");
+	strsep(&t, "=");
+	tab[i] = calloc(strlen(t) + 1, 1);
+	if (tab[i] == NULL) {
+		printf("%s: calloc failed!\n", __func__);
+		return -1;
+	}
+	strcpy(tab[i], t);
+	*p = tok;
+
+	return 0;
+}
+
+/**
+ * extract_uuid(); Extract UUIDs from a string
+ *
+ * @param uuid - string to uuid representation
+ * @param tab - place to store separated items
+ *
+ * @return - zero on success; otherwise error
+ */
+static int extract_uuid(char *uuid, char *tab[])
+{
+	char *tok = uuid;
+	int i;
+
+	for (i = 0; tok && i < (GPT_PARTS_NUM + 1); i++) {
+		if (extract_val(&tok, tab, i)) {
+			for (i--; i >= 0; i--)
+				free(tab[i]);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * set_gpt_info(): Fill gpt information for GPT header and partition entries
+ *
+ * @param dev_desc - block device descriptor
+ * @param str_uuid - string uuid representation
+ *
+ * @return - zero on success; otherwise error
+ *
+ * NOTE - uuid table is bigger than GPT_PARTS_NUM to support disk UUID
+ *
+ */
+static int set_gpt_info(block_dev_desc_t *dev_desc, char *str_uuid)
+{
+	char *ps[GPT_PARTS_NUM], *name[GPT_PARTS_NUM];
+	char *uuid[GPT_PARTS_NUM + 1]; /* extra space to store disk uuid */
+	u8 guid[sizeof(gpt_h->disk_guid.b)];
+	unsigned int size[GPT_PARTS_NUM];
+	char *tok, *p, *s, *ss;
+	int i, ret;
+
+	debug("%s: MMC lba num: 0x%x %d\n", __func__,
+	      (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba);
+
+	for (i = 0; i <= GPT_PARTS_NUM; i++)
+		uuid[i] = NULL;
+
+	s = getenv("partitions");
+	if (s == NULL) {
+		printf("%s: \"partitions\" env variable not defined!\n",
+		       __func__);
+		return -1;
+	}
+
+	if (str_uuid)
+		extract_uuid(str_uuid, uuid);
+
+	ss = calloc(strlen(s) + 1, 1);
+	if (ss == NULL) {
+		printf("%s: calloc failed!\n", __func__);
+		return -1;
+	}
+	memcpy(ss, s, strlen(s) + 1);
+
+	for (i = 0, p = ss; i < GPT_PARTS_NUM; i++) {
+		tok = strsep(&p, ";");
+		if (tok == NULL)
+			break;
+
+		if (extract_val(&tok, name, i)) {
+			ret = -1;
+			goto err;
+		}
+
+		if (extract_val(&tok, ps, i)) {
+			ret = -1;
+			free(name[i]);
+			goto err;
+		}
+	}
+
+	gpt_parts = i;
+
+	printf("found %d partitions\n", gpt_parts);
+
+	for (i = 0; i < gpt_parts; i++) {
+		p = ps[i];
+		size[i] = ustrtoul(p, &p, 0);
+		size[i] /= dev_desc->blksz;
+	}
+
+	gpt_h = calloc(sizeof(gpt_header), 1);
+	gpt_e = calloc(sizeof(gpt_entry), GPT_ENTRY_NUMBERS);
+
+	/* Generate Primary GPT header (LBA1) */
+	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(1);
+	gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1);
+	gpt_h->first_usable_lba = cpu_to_le64(34);
+	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
+	gpt_h->partition_entry_lba = cpu_to_le64(2);
+	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[0])
+		convert_uuid(uuid[0], gpt_h->disk_guid.b);
+	else {
+		guid_gen((u32 *)gd->start_addr_sp, guid);
+		memcpy(gpt_h->disk_guid.b, guid, sizeof(efi_guid_t));
+	}
+	gpt_fill_pte(dev_desc, gpt_h, gpt_e, gpt_parts, size, name, &uuid[1]);
+
+	puts("save the GPT ...\n");
+	ret = set_gpt_table(dev_desc, gpt_h, gpt_e);
+
+	free(gpt_e);
+	free(gpt_h);
+
+	i = gpt_parts;
+ err:
+	for (i--; i >= 0; i--) {
+		free(name[i]);
+		free(ps[i]);
+	}
+
+	free(ss);
+	return ret;
+}
+
+/**
+ * gpt_mmc_default(): Restore default GPT on a MMC device
+ *
+ * @param dev - number of MMC device
+ * @param str_uuid - string representation of UUIDs
+ *
+ * @return zero on success; otherwise error
+ */
+static int gpt_mmc_default(int dev, char *str_uuid)
+{
+	struct mmc *mmc = find_mmc_device(dev);
+
+	if (mmc == NULL) {
+		printf("%s: mmc dev %d NOT available\n", __func__, dev);
+		return CMD_RET_FAILURE;
+	}
+
+	puts("Using default GPT UUID\n");
+	return set_gpt_info(&mmc->block_dev, str_uuid);
+}
+
+/**
+ * do_gpt(): Perform GPT operations
+ *
+ * @param cmdtp - command name
+ * @param flag
+ * @param argc
+ * @param argv
+ *
+ * @return zero on success; otherwise error
+ */
+static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int ret = CMD_RET_SUCCESS;
+	char *str_uuid = NULL;
+	int dev = 0;
+
+	if (argc < 3)
+		return CMD_RET_USAGE;
+
+	if (argc == 4) {
+		str_uuid = strdup(argv[3]);
+		if (!str_uuid) {
+			printf("%s: malloc failed!\n", __func__);
+			return CMD_RET_FAILURE;
+		}
+	}
+
+	if (strcmp(argv[1], "mmc") == 0) {
+		dev = (int)simple_strtoul(argv[2], NULL, 10);
+		if (gpt_mmc_default(dev, str_uuid))
+			return CMD_RET_FAILURE;
+	}
+
+	if (argc == 4)
+		free(str_uuid);
+
+	return ret;
+}
+
+U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
+	"GUID Partition Table",
+	"<interface> <dev> [uuid1=, uuid2=, ..., uuidN=]\n"
+	" - GUID partition table restoration\n"
+	" Restore GPT information on a device connected\n"
+	" to interface\n"
+);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats
  2012-09-13  8:09 ` [U-Boot] [PATCH v3 " Lukasz Majewski
                     ` (5 preceding siblings ...)
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 6/7] gpt: Support for new "gpt" command Lukasz Majewski
@ 2012-09-13  8:10   ` Lukasz Majewski
  6 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-09-13  8:10 UTC (permalink / raw)
  To: u-boot

Enable support for GPT partition table restoration at Samsung's Trats
development board.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
Changes for v2:
- New format for default GPT partitions (key=value pairs)
- replace size definitions with more readable description(1GiB instead of 1G)

Changes for v3:
- None
---
 include/configs/trats.h |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/include/configs/trats.h b/include/configs/trats.h
index f8da9c0..e595b5e 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -98,6 +98,7 @@
 #undef CONFIG_CMD_MTDPARTS
 #define CONFIG_CMD_MMC
 #define CONFIG_CMD_DFU
+#define CONFIG_CMD_GPT
 
 /* FAT */
 #define CONFIG_CMD_FAT
@@ -122,6 +123,24 @@
 #define CONFIG_BOOTBLOCK		"10"
 #define CONFIG_ENV_COMMON_BOOT		"${console} ${meminfo}"
 
+/* Tizen - partitions definitions */
+#define PARTS_CSA		"csa-mmc"
+#define PARTS_BOOTLOADER	"u-boot"
+#define PARTS_KERNEL		"kernel"
+#define PARTS_ROOT		"platform"
+#define PARTS_DATA		"data"
+#define PARTS_CSC		"csc"
+#define PARTS_UMS		"ums"
+
+#define PARTS_DEFAULT	"name="PARTS_CSA",size=8MiB;"\
+			"name="PARTS_BOOTLOADER",size=60MiB;"\
+			"name="PARTS_KERNEL",size=60MiB;"\
+			"name="PARTS_ROOT",size=1GiB;"\
+			"name="PARTS_DATA",size=3GiB;"\
+			"name="PARTS_CSC",size=150MiB;"\
+			"name="PARTS_UMS",size=-\0"
+#define GPT_PARTS_NUM 7
+
 #define CONFIG_DFU_ALT \
 	"dfu_alt_info=" \
 	"u-boot mmc 80 400;" \
@@ -171,7 +190,8 @@
 	"mmcbootpart=2\0" \
 	"mmcrootpart=3\0" \
 	"opts=always_resume=1\0" \
-	CONFIG_DFU_ALT
+	"partitions=" PARTS_DEFAULT \
+	CONFIG_DFU_ALT \
 
 /* Miscellaneous configurable options */
 #define CONFIG_SYS_LONGHELP		/* undef to save memory */
@@ -207,6 +227,7 @@
 #define CONFIG_ENV_OFFSET		((32 - 4) << 10) /* 32KiB - 4KiB */
 
 #define CONFIG_DOS_PARTITION
+#define CONFIG_EFI_PARTITION
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE)
 #define CONFIG_SYS_CACHELINE_SIZE       32
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v2 0/7] gpt: GUID Partition Table (GPT) restoration
  2012-09-13  6:20     ` Lukasz Majewski
@ 2012-09-13 17:39       ` Tom Rini
  0 siblings, 0 replies; 95+ messages in thread
From: Tom Rini @ 2012-09-13 17:39 UTC (permalink / raw)
  To: u-boot

On Thu, Sep 13, 2012 at 08:20:16AM +0200, Lukasz Majewski wrote:
> Hi Tom,
> 
> Thanks for review. 
> 
> > On 09/12/2012 07:50 AM, Lukasz Majewski wrote:
> > > This patch series provides a new command - "gpt" for eMMC partition
> > > table (in the GPT format) restoration.
> > > 
> > > As a pre-work, some cleanup at the part_efi.c file was performed to
> > > remove custom macros and make GPT related structures more readable.
> > > 
> > > Moreover the part_efi.h file has been moved to ./include directory
> > > to be easily available from other subsystems.
> > > 
> > > The GPT detailed description has been written to README.gpt file.
> > > 
> > > Tested at:
> > >         - Exynos4210 rev.1 - TRATS Samsung development board
> > 
> > I had two very minor comments.  Aside from that, please make sure the
> > series is checkpatch clean (I haven't checked).  Thanks!
> 
> There is one little problem with the checkpatch:
> 
> The patch:
> [PATCH v2 2/7] part:efi: Move part_efi.h file to ./include
> 
> "touches" some legacy code, and checkpatch complaints about e.g.:
> 
> WARNING: do not add new typedefs
> #281: FILE: include/part_efi.h:97:
> +typedef struct _gpt_header {
> 
> which I don't want to change in this patch series.
> 
> Moreover it complaints about:
> WARNING: __packed is preferred over __attribute__((packed))
> #303: FILE: include/part_efi.h:119:
> +} __attribute__ ((packed)) gpt_entry_attributes;
>  which was changed at further patch (which I believe is a better place
>  to do so):
> [PATCH v2 4/7] gpt: The leXX_to_int() calls replaced with ones defined
> at <compiler.h>
> 
> To sum up - some checkpatch warnings appears since I've moved a legacy
> code to a new place.
> Rest of those patches is checkpatch "clean".

Sounds good to me, thanks for the explanation.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120913/a2f34f6d/attachment.pgp>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 2/7] part:efi: Move part_efi.h file to ./include
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 2/7] part:efi: Move part_efi.h file to ./include Lukasz Majewski
@ 2012-09-13 18:54     ` Kim Phillips
  0 siblings, 0 replies; 95+ messages in thread
From: Kim Phillips @ 2012-09-13 18:54 UTC (permalink / raw)
  To: u-boot

On Thu, 13 Sep 2012 10:10:00 +0200
Lukasz Majewski <l.majewski@samsung.com> wrote:

> This move is necessary to export gpt header and GPT partition entries to be
> used with other commands or subsystems (like DFU in the future)
> Additionally the part_efi.h file has been cleaned-up to supress checkpatch's
> warnings.
> 
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> 
> ---
> Changes for v3:
> - None
> ---
>  disk/part_efi.c    |    2 +-
>  disk/part_efi.h    |  139 ---------------------------------------------------
>  include/part_efi.h |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 141 insertions(+), 140 deletions(-)
>  delete mode 100644 disk/part_efi.h
>  create mode 100644 include/part_efi.h

use git format-patch's -M/-C flags when posting code
movement/copying patches.

Kim

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 3/7] gpt:doc: GPT (GUID Partition Table) documentation
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 3/7] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
@ 2012-09-17 17:58     ` Stephen Warren
  2012-10-05 10:35       ` Lukasz Majewski
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-17 17:58 UTC (permalink / raw)
  To: u-boot

On 09/13/2012 02:10 AM, Lukasz Majewski wrote:
> Documentation of the GPT format.

> diff --git a/doc/README.gpt b/doc/README.gpt

> +Example usage:
> +==============
> +
> +To restore GUID partition table one needs to:
> +1. at ./include/configs/{board}.h
> +   - define "partitions=" environment variable with format:
> +     "name=u-boot,size=60M;name=kernel,size=60M;name=platform,size=1G;"
> +   - define GPT_PARTS_NUM with actual number of partitions (as defined above)

That seems unfortunate; the partitions variable and GPT_PARTS_NUM define
could easily become out-of-sync (what if the user edited the variable in
order to create an alternative disk layout, or what if a developer
simply forgot to update GPT_PARTS_NUM when editing the hard-coded value?).

Instead, can't GPT_PARTS_NUM be removed, and the code simply count the
number of entries in the partitions variable?

> +   - #define CONFIG_EFI_PARTITION and #define CONFIG_CMD_GPT
> +
> +2. From u-boot prompt type:
> +   gpt mmc 0 uuid_disk=ec2cddf2-fbf5-11e1-af3a-001fd09285c0, \
> +   uuid1=ed09c4b0-fbf5-11e1-9a95-001fd09285c0, \
> +   uuid2=edd6d93c-fbf5-11e1-875a-001fd09285c0, \
> +   uuid3=f0485114-fbf5-11e1-a3ae-001fd09285c0 ...
> +
> +   UUIDs shall be defined up to GPT_PARTS_NUM. Smaller number is acceptable.
> +   When UUIDs are NOT provided, internal (rather weak) GUID generator will be
> +   used instead

Hmmm. It's a little unfortunate to provide the partitions list through
one mechanism (environment variable with a hard-coded name), and the
UUIDs through a different mechanism (command-line). Surely these two
mechanisms can be combined; rather than the command reading an
environment variable, you could at least require the user to pass the
appropriate data on the command-line, and optionally have them pass the
environment variable if they want to use the pre-defined layout, e.g.:

pre-defined:
gpt mmc 0 ${partitions}

manual/custom layout:
gpt mmc 0 name=u-boot,size=60M;name=kernel,size=60M;...

Then, I wonder if you couldn't define the partitions environment
variable as:

partitions=\
name=u-boot,size=60M,uuid=${uuid_gpt_u_boot};\
name=kernel,size=60M,uuid=${uuid_gpt_kernel};...

and have the environment variables expanded as in:

setenv uuid_gpt_u_boot=ed09c4b0-fbf5-11e1-9a95-001fd09285c0
setenv uuid_gpt_kernel=...
gpt mmc 0 ${partitions}

That way, the gpt command would read everything from the command-line,
yet the partition layout and UUID names could be specified separately,
so as to allow the user to define them at different times or places.

The implementation of "gpt" would have to scan all the variables it
extracted from the command-line, and expand any environment variable
references in them for this to work, since I assume the shell doesn't do
recursive variable expansions like make does.

Oh, and don't you want the "gpt" command to take a sub-command like
"create", so that "gpt" could do different things in the future, e.g.
take an existing GPT layout, and edit, say, one partition's name:

gpt create mmc 0 ${partitions}
gpt set-name mmc 0 ${partition-id} ${new-name}

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-09-13  8:10   ` [U-Boot] [PATCH v3 5/7] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
@ 2012-09-17 18:07     ` Stephen Warren
  2012-10-05 10:50       ` Lukasz Majewski
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-09-17 18:07 UTC (permalink / raw)
  To: u-boot

On 09/13/2012 02:10 AM, Lukasz Majewski wrote:
> The restoration of GPT table (both primary and secondary) is now possible.
> Simple GUID generation is supported.

> diff --git a/include/part.h b/include/part.h

> +int set_gpt_table(block_dev_desc_t *dev_desc,
> +		  gpt_header *gpt_h, gpt_entry *gpt_e);

The API here isn't very generic; it requires the caller to have
formatted the GPT entirely by itself, which means having complete
knowledge of how to lay out a GPT header and partition table entry.
Right now, all that knowledge is contained inside the implementation of
the "gpt" command - what if some other unrelated code wanted to write a
GPT; it'd have to duplicate everything.

I was thinking of a much more generic interface, where each partition is
described using abstract structs, and the creation of the actual on-disk
layout is handling inside the set_gpt_table() function. That would
presumably allow the same abstract structs to be passed to e.g.
set_mbr_partition_table() and a generic "ptable create" command to be
created.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] gpt: GUID/UUID - GPT restoration - open questions - RESEND
  2012-09-03  9:28 ` [U-Boot] gpt: GUID/UUID - GPT restoration - open questions - RESEND Lukasz Majewski
@ 2012-10-02 13:46   ` Simon Glass
  2012-10-02 16:39     ` Lukasz Majewski
  0 siblings, 1 reply; 95+ messages in thread
From: Simon Glass @ 2012-10-02 13:46 UTC (permalink / raw)
  To: u-boot

Hi Lukasz,

On Mon, Sep 3, 2012 at 2:28 AM, Lukasz Majewski <l.majewski@samsung.com> wrote:
> Hi Stephen,
>
> I'm writing to you, since I've posted a patch series regarding GPT
> support for Samsung Trats board (you were on the CC).

I'm not sure if Stephen got that - try "Stephen Warren" <swarren@wwwdotorg.org>.

Regards,
Simon

>
> e.g. http://patchwork.ozlabs.org/patch/179785/
>
> I think, that we can cooperate to provide better EFI/GPT support.
>
> In mine implementation the "gpt" command (with several sub commands) has
> been proposed
> - we can discuss if this is a correct way to go.
>
> Moreover, at this patch series a "weak" GUID generator is implemented.
> For now it is "good enough", since I consider the restoration as an
> emergency situation.
> However,I wonder how can we provide better GUID (and in general random
> numbers pool) generator for u-boot.
>
>
> Maybe md5sum command can be used with some running clock (WDT, or
> system clock from u-boot start up) data to provide better entropy?
>
> Any ideas?
>
> Regards,
> Lukasz
>
> p.s. I'm resending this patch, so please do not regard it as a spam.
>
>> This patch series provides a new command - "gpt" for eMMC partition
>> table (in the GPT format) restoration and display.
>>
>> As a pre-work, some cleanup at the part_efi.c file was performed to
>> remove custom macros and make GPT related structures more readable.
>>
>> The GPT detailed description has been written to README.gpt file.
>>
>> Tested at:
>>       - Exynos4210 rev.1 - TRATS Samsung development board
>>
>> Lukasz Majewski (6):
>>   gpt:doc: GPT (GUID Partition Table) documentation
>>   gpt: Replace the leXX_to_int() calls with ones defined at
>>     <compiler.h>
>>   gpt: Replacement of GPT structures members with ones indicating
>>     endianness and size
>>   gpt: Support for GPT (GUID Partition Table) restoration
>>   gpt: Support for new "gpt" command
>>   gpt: Enable support for GPT partition table restoration at Samsung's
>>     Trats
>>
>>  common/Makefile         |    1 +
>>  common/cmd_gpt.c        |  182 ++++++++++++++++++++++++++
>>  disk/part_efi.c         |  334
>> +++++++++++++++++++++++++++++++++++++----------
>> disk/part_efi.h         |   85 ++++++------ doc/README.gpt
>> |  199 ++++++++++++++++++++++++++++ include/configs/trats.h |   23
>> +++- include/part.h          |    2 +
>>  7 files changed, 715 insertions(+), 111 deletions(-)
>>  create mode 100644 common/cmd_gpt.c
>>  create mode 100644 doc/README.gpt
>>
>
> --
> Best regards,
>
> Lukasz Majewski
>
> Samsung Poland R&D Center | Linux Platform Group
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] gpt: GUID/UUID - GPT restoration - open questions - RESEND
  2012-10-02 13:46   ` Simon Glass
@ 2012-10-02 16:39     ` Lukasz Majewski
  0 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-10-02 16:39 UTC (permalink / raw)
  To: u-boot

Hi Simon,

> Hi Lukasz,
> 
> On Mon, Sep 3, 2012 at 2:28 AM, Lukasz Majewski
> <l.majewski@samsung.com> wrote:
> > Hi Stephen,
> >
> > I'm writing to you, since I've posted a patch series regarding GPT
> > support for Samsung Trats board (you were on the CC).
> 
> I'm not sure if Stephen got that - try "Stephen Warren"
> <swarren@wwwdotorg.org>.
> 

I've already received some some comments from Stephen.

I'm going to correct this patch series and provide version 2.

In short the GPT restoration needs some more work, especially at adding
more abstraction to provide the code more useful. 


-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [U-Boot, 4/6] gpt: Support for GPT (GUID Partition Table) restoration
  2012-08-24  8:13 ` [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
  2012-09-05 19:49   ` Stephen Warren
  2012-09-05 20:19   ` Stephen Warren
@ 2012-10-03 23:00   ` Tom Rini
  2012-10-04  7:18     ` [U-Boot] [u-boot] Adding missing CONFIG_SYS_CACHELINE_SIZE to boards definitions Lukasz Majewski
  2 siblings, 1 reply; 95+ messages in thread
From: Tom Rini @ 2012-10-03 23:00 UTC (permalink / raw)
  To: u-boot

On Thu, Aug 23, 2012 at 10:13:13PM -0000, Lukasz Majewski wrote:

> The restoration of GPT table (both primary and secondary) is now possible.
> Simple GUID generation is supported.
> 
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

While the changes are fine, tt01 and eb_cpux9k2 use CONFIG_PART_EFI and
do not set CONFIG_SYS_CACHELINE_SIZE and so fail to build after this
patch.  tt01 is easily fixable (it relies on a non-exported define
elsewhere to 32) but the eb_cpu9k2 please contact the listed board
maintainer to get the define added.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20121003/8df6c985/attachment.pgp>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [u-boot] Adding missing CONFIG_SYS_CACHELINE_SIZE to boards definitions
  2012-10-03 23:00   ` [U-Boot] [U-Boot, " Tom Rini
@ 2012-10-04  7:18     ` Lukasz Majewski
  2012-10-04  8:28       ` esw
  2012-10-04  9:02       ` Helmut Raiger
  0 siblings, 2 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-10-04  7:18 UTC (permalink / raw)
  To: u-boot

Hi Jens and Helmut,

> On Thu, Aug 23, 2012 at 10:13:13PM -0000, Lukasz Majewski wrote:
> 
> > The restoration of GPT table (both primary and secondary) is now
> > possible. Simple GUID generation is supported.
> > 
> > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> 
> While the changes are fine, tt01 and eb_cpux9k2 use CONFIG_PART_EFI
> and do not set CONFIG_SYS_CACHELINE_SIZE and so fail to build after
> this patch.  tt01 is easily fixable (it relies on a non-exported
> define elsewhere to 32) but the eb_cpu9k2 please contact the listed
> board maintainer to get the define added.
> 

Would it be possible to add the CONFIG_SYS_CACHELINE_SIZE
definition to ./include/configs/{tty01|eb_cpux9k2} boards definition?

It would help improving cache alignment and GPT development. 

Thanks in advance
-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [u-boot] Adding missing CONFIG_SYS_CACHELINE_SIZE to boards definitions
  2012-10-04  7:18     ` [U-Boot] [u-boot] Adding missing CONFIG_SYS_CACHELINE_SIZE to boards definitions Lukasz Majewski
@ 2012-10-04  8:28       ` esw
  2012-10-18 18:48         ` Albert ARIBAUD
  2012-10-04  9:02       ` Helmut Raiger
  1 sibling, 1 reply; 95+ messages in thread
From: esw @ 2012-10-04  8:28 UTC (permalink / raw)
  To: u-boot

Dear Lukasz,

> Hi Jens and Helmut,
> 
>> On Thu, Aug 23, 2012 at 10:13:13PM -0000, Lukasz Majewski wrote:
>>
>>> The restoration of GPT table (both primary and secondary) is now
>>> possible. Simple GUID generation is supported.
>>>
>>> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
>>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>>
>> While the changes are fine, tt01 and eb_cpux9k2 use CONFIG_PART_EFI
>> and do not set CONFIG_SYS_CACHELINE_SIZE and so fail to build after
>> this patch.  tt01 is easily fixable (it relies on a non-exported
>> define elsewhere to 32) but the eb_cpu9k2 please contact the listed
>> board maintainer to get the define added.
>>
> 
> Would it be possible to add the CONFIG_SYS_CACHELINE_SIZE
> definition to ./include/configs/{tty01|eb_cpux9k2} boards definition?
> 
The eb_cpux9k2 board based on at91rm9200 soc. This soc has currently no cache implementation. So I think your run in this error.

The attached patch sets the define to the soc default.

We can also set #define CONFIG_SYS_DCACHE_OFF

regards Jens

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [u-boot] Adding missing CONFIG_SYS_CACHELINE_SIZE to boards definitions
  2012-10-04  7:18     ` [U-Boot] [u-boot] Adding missing CONFIG_SYS_CACHELINE_SIZE to boards definitions Lukasz Majewski
  2012-10-04  8:28       ` esw
@ 2012-10-04  9:02       ` Helmut Raiger
  1 sibling, 0 replies; 95+ messages in thread
From: Helmut Raiger @ 2012-10-04  9:02 UTC (permalink / raw)
  To: u-boot

On 10/04/2012 09:18 AM, Lukasz Majewski wrote:
> Hi Jens and Helmut,
>
>> On Thu, Aug 23, 2012 at 10:13:13PM -0000, Lukasz Majewski wrote:
>>
>>> The restoration of GPT table (both primary and secondary) is now
>>> possible. Simple GUID generation is supported.
>>>
>>> Signed-off-by: Lukasz Majewski<l.majewski@samsung.com>
>>> Signed-off-by: Kyungmin Park<kyungmin.park@samsung.com>
>> While the changes are fine, tt01 and eb_cpux9k2 use CONFIG_PART_EFI
>> and do not set CONFIG_SYS_CACHELINE_SIZE and so fail to build after
>> this patch.  tt01 is easily fixable (it relies on a non-exported
>> define elsewhere to 32) but the eb_cpu9k2 please contact the listed
>> board maintainer to get the define added.
>>
> Would it be possible to add the CONFIG_SYS_CACHELINE_SIZE
> definition to ./include/configs/{tty01|eb_cpux9k2} boards definition?
>
> It would help improving cache alignment and GPT development.
>
> Thanks in advance

Hi Lukasz,

   feel free to do the appropriate changes in the TT-01 platform code 
(explicitly setting CACHELINE_SIZE), I'm currently too busy to do any 
rebasing and testing on the board, we'll have to give it a time slice in 
the near future (to have a few platform things changed) anyway.

Helmut


--
Scanned by MailScanner.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 3/7] gpt:doc: GPT (GUID Partition Table) documentation
  2012-09-17 17:58     ` Stephen Warren
@ 2012-10-05 10:35       ` Lukasz Majewski
  2012-10-05 15:19         ` Lukasz Majewski
  2012-10-05 16:05         ` Stephen Warren
  0 siblings, 2 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-10-05 10:35 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> On 09/13/2012 02:10 AM, Lukasz Majewski wrote:
> > Documentation of the GPT format.
> 
> > diff --git a/doc/README.gpt b/doc/README.gpt
> 
> > +Example usage:
> > +==============
> > +
> > +To restore GUID partition table one needs to:
> > +1. at ./include/configs/{board}.h
> > +   - define "partitions=" environment variable with format:
> > +
> > "name=u-boot,size=60M;name=kernel,size=60M;name=platform,size=1G;"
> > +   - define GPT_PARTS_NUM with actual number of partitions (as
> > defined above)
> 
> That seems unfortunate; the partitions variable and GPT_PARTS_NUM
> define could easily become out-of-sync (what if the user edited the
> variable in order to create an alternative disk layout, or what if a
> developer simply forgot to update GPT_PARTS_NUM when editing the
> hard-coded value?).
> 
> Instead, can't GPT_PARTS_NUM be removed, and the code simply count the
> number of entries in the partitions variable?

Yes, the GPT_PARTS_NUM can (and shall be replaced) with a runtime
detection of the number of available partitions. This can be done in a
similar way as it is done at DFU code.

> 
> > +   - #define CONFIG_EFI_PARTITION and #define CONFIG_CMD_GPT
> > +
> > +2. From u-boot prompt type:
> > +   gpt mmc 0 uuid_disk=ec2cddf2-fbf5-11e1-af3a-001fd09285c0, \
> > +   uuid1=ed09c4b0-fbf5-11e1-9a95-001fd09285c0, \
> > +   uuid2=edd6d93c-fbf5-11e1-875a-001fd09285c0, \
> > +   uuid3=f0485114-fbf5-11e1-a3ae-001fd09285c0 ...
> > +
> > +   UUIDs shall be defined up to GPT_PARTS_NUM. Smaller number is
> > acceptable.
> > +   When UUIDs are NOT provided, internal (rather weak) GUID
> > generator will be
> > +   used instead
> 
> Hmmm. It's a little unfortunate to provide the partitions list through
> one mechanism (environment variable with a hard-coded name), and the
> UUIDs through a different mechanism (command-line). Surely these two
> mechanisms can be combined; rather than the command reading an
> environment variable, you could at least require the user to pass the
> appropriate data on the command-line, and optionally have them pass
> the environment variable if they want to use the pre-defined layout,
> e.g.:
> 
> pre-defined:
> gpt mmc 0 ${partitions}
> 
> manual/custom layout:
> gpt mmc 0 name=u-boot,size=60M;name=kernel,size=60M;...
> 
> Then, I wonder if you couldn't define the partitions environment
> variable as:
> 
> partitions=\
> name=u-boot,size=60M,uuid=${uuid_gpt_u_boot};\
> name=kernel,size=60M,uuid=${uuid_gpt_kernel};...
> 
> and have the environment variables expanded as in:
> 
> setenv uuid_gpt_u_boot=ed09c4b0-fbf5-11e1-9a95-001fd09285c0
> setenv uuid_gpt_kernel=...

This is a good idea to allow uuid_gpt_u_boot= to be set via setenv.
Moreover I think, that "editing" of "partitions" names, uuid and other
parameters shall be done via setenv (as you proposed).

> gpt mmc 0 ${partitions}

Moreover I think, that parsing ${partitions} as a list of argv[n] is
not the best option to proceed.

I think that it would be easier to:
1. Prepare predefined "partitions=" variable
at ./include/configs/trats.h (when no one is available on the platform)
2. Edit relevant env variables (uuid_gpt_u_boot=, etc) via setenv and
saveenv.
3. restore it with gpt mmc 0 partitions (- the name of the stored and
prepared env variable)

I'd like to emphasis, that I strive to avoid parsing possibly (very)
long list of GPT partition definition via gpt command's argv[n].

If user wants to edit something, then one can use setenv to do that.

> 
> That way, the gpt command would read everything from the command-line,
> yet the partition layout and UUID names could be specified separately,
> so as to allow the user to define them at different times or places.
> 
> The implementation of "gpt" would have to scan all the variables it
> extracted from the command-line, and expand any environment variable
> references in them for this to work, since I assume the shell doesn't
> do recursive variable expansions like make does.
> 
> Oh, and don't you want the "gpt" command to take a sub-command like
> "create", so that "gpt" could do different things in the future, e.g.
> take an existing GPT layout, and edit, say, one partition's name:
> 

This is a nice idea to divide the gpt commands to subcommands. However
I now focus on gpt restoration (done in a correct and agreed way :-) ).
I will prepare the gpt command to be easily dividable to sub-commands.

> gpt create mmc 0 ${partitions}
> gpt set-name mmc 0 ${partition-id} ${new-name}



-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-09-17 18:07     ` Stephen Warren
@ 2012-10-05 10:50       ` Lukasz Majewski
  0 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-10-05 10:50 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> On 09/13/2012 02:10 AM, Lukasz Majewski wrote:
> > The restoration of GPT table (both primary and secondary) is now
> > possible. Simple GUID generation is supported.
> 
> > diff --git a/include/part.h b/include/part.h
> 
> > +int set_gpt_table(block_dev_desc_t *dev_desc,
> > +		  gpt_header *gpt_h, gpt_entry *gpt_e);
> 
> The API here isn't very generic; it requires the caller to have
> formatted the GPT entirely by itself, which means having complete
> knowledge of how to lay out a GPT header and partition table entry.
> Right now, all that knowledge is contained inside the implementation
> of the "gpt" command - what if some other unrelated code wanted to
> write a GPT; it'd have to duplicate everything.

I must admit, that you are correct here.

> 
> I was thinking of a much more generic interface, where each partition
> is described using abstract structs, and the creation of the actual
> on-disk layout is handling inside the set_gpt_table() function. That
> would presumably allow the same abstract structs to be passed to e.g.
> set_mbr_partition_table() and a generic "ptable create" command to be
> created.

If I understood you correctly, you propose to devise an abstraction
layer to store information about each partition - e.g.

struct partition {
	char *name,
	size_t size,
	size_t start,
	...
}

then 

struct disk {
	struct partition p1,
	struct partition p2,
	...
}

And then pass this struct disk to set_gpt_table() function.

This would "clean" the partition related code and be a good starting
point for further abstracting (if needed).


-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 3/7] gpt:doc: GPT (GUID Partition Table) documentation
  2012-10-05 10:35       ` Lukasz Majewski
@ 2012-10-05 15:19         ` Lukasz Majewski
  2012-10-05 16:05         ` Stephen Warren
  1 sibling, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-10-05 15:19 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

> 
> > On 09/13/2012 02:10 AM, Lukasz Majewski wrote:
> > > Documentation of the GPT format.
> > 
> > > diff --git a/doc/README.gpt b/doc/README.gpt
> > 
> > > +Example usage:
> > > +==============
> > > +
> > > +To restore GUID partition table one needs to:
> > > +1. at ./include/configs/{board}.h
> > > +   - define "partitions=" environment variable with format:
> > > +
> > > "name=u-boot,size=60M;name=kernel,size=60M;name=platform,size=1G;"
> > > +   - define GPT_PARTS_NUM with actual number of partitions (as
> > > defined above)
> > 
> > That seems unfortunate; the partitions variable and GPT_PARTS_NUM
> > define could easily become out-of-sync (what if the user edited the
> > variable in order to create an alternative disk layout, or what if a
> > developer simply forgot to update GPT_PARTS_NUM when editing the
> > hard-coded value?).
> > 
> > Instead, can't GPT_PARTS_NUM be removed, and the code simply count
> > the number of entries in the partitions variable?
> 
> Yes, the GPT_PARTS_NUM can (and shall be replaced) with a runtime
> detection of the number of available partitions. This can be done in a
> similar way as it is done at DFU code.
> 
> > 
> > > +   - #define CONFIG_EFI_PARTITION and #define CONFIG_CMD_GPT
> > > +
> > > +2. From u-boot prompt type:
> > > +   gpt mmc 0 uuid_disk=ec2cddf2-fbf5-11e1-af3a-001fd09285c0, \
> > > +   uuid1=ed09c4b0-fbf5-11e1-9a95-001fd09285c0, \
> > > +   uuid2=edd6d93c-fbf5-11e1-875a-001fd09285c0, \
> > > +   uuid3=f0485114-fbf5-11e1-a3ae-001fd09285c0 ...
> > > +
> > > +   UUIDs shall be defined up to GPT_PARTS_NUM. Smaller number is
> > > acceptable.
> > > +   When UUIDs are NOT provided, internal (rather weak) GUID
> > > generator will be
> > > +   used instead
> > 
> > Hmmm. It's a little unfortunate to provide the partitions list
> > through one mechanism (environment variable with a hard-coded
> > name), and the UUIDs through a different mechanism (command-line).
> > Surely these two mechanisms can be combined; rather than the
> > command reading an environment variable, you could at least require
> > the user to pass the appropriate data on the command-line, and
> > optionally have them pass the environment variable if they want to
> > use the pre-defined layout, e.g.:
> > 
> > pre-defined:
> > gpt mmc 0 ${partitions}
> > 
> > manual/custom layout:
> > gpt mmc 0 name=u-boot,size=60M;name=kernel,size=60M;...
> > 
> > Then, I wonder if you couldn't define the partitions environment
> > variable as:
> > 
> > partitions=\
> > name=u-boot,size=60M,uuid=${uuid_gpt_u_boot};\
> > name=kernel,size=60M,uuid=${uuid_gpt_kernel};...
> > 
> > and have the environment variables expanded as in:
> > 
> > setenv uuid_gpt_u_boot=ed09c4b0-fbf5-11e1-9a95-001fd09285c0
> > setenv uuid_gpt_kernel=...
> 
> This is a good idea to allow uuid_gpt_u_boot= to be set via setenv.
> Moreover I think, that "editing" of "partitions" names, uuid and other
> parameters shall be done via setenv (as you proposed).
> 
> > gpt mmc 0 ${partitions}
> 
> Moreover I think, that parsing ${partitions} as a list of argv[n] is
> not the best option to proceed.
> 
> I think that it would be easier to:
> 1. Prepare predefined "partitions=" variable
> at ./include/configs/trats.h (when no one is available on the
> platform) 2. Edit relevant env variables (uuid_gpt_u_boot=, etc) via
> setenv and saveenv.
> 3. restore it with gpt mmc 0 partitions (- the name of the stored and
> prepared env variable)
> 
> I'd like to emphasis, that I strive to avoid parsing possibly (very)
> long list of GPT partition definition via gpt command's argv[n].
> 
> If user wants to edit something, then one can use setenv to do that.
> 

I must correct myself here. 

After some research I will give a shoot to the 
gpt mmc 0 ${partitions} approach.

As you pointed out, the depth of u-boot's shell variable expanding is
one. 
Due to this the string passed to gpt command needs to be parsed and
expanded in the gpt command:

name=csa-mmc,size=8MiB,uuid=${uuid_gpt_csa-mmc}

the ${uuid_gpt_csa-mmc} needs to be expanded during runtime.


> > 
> > That way, the gpt command would read everything from the
> > command-line, yet the partition layout and UUID names could be
> > specified separately, so as to allow the user to define them at
> > different times or places.

You are right, this approach (even when taking into account the extra
complexity of gpt command's run-time variables expanding) is most
universal. 

I will prepare patches with this approach.

> > 
> > The implementation of "gpt" would have to scan all the variables it
> > extracted from the command-line, and expand any environment variable
> > references in them for this to work, since I assume the shell
> > doesn't do recursive variable expansions like make does.
> > 
> > Oh, and don't you want the "gpt" command to take a sub-command like
> > "create", so that "gpt" could do different things in the future,
> > e.g. take an existing GPT layout, and edit, say, one partition's
> > name:
> > 
> 
> This is a nice idea to divide the gpt commands to subcommands. However
> I now focus on gpt restoration (done in a correct and agreed
> way :-) ). I will prepare the gpt command to be easily dividable to
> sub-commands.
> 
> > gpt create mmc 0 ${partitions}
> > gpt set-name mmc 0 ${partition-id} ${new-name}
> 
> 
> 



-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v3 3/7] gpt:doc: GPT (GUID Partition Table) documentation
  2012-10-05 10:35       ` Lukasz Majewski
  2012-10-05 15:19         ` Lukasz Majewski
@ 2012-10-05 16:05         ` Stephen Warren
  1 sibling, 0 replies; 95+ messages in thread
From: Stephen Warren @ 2012-10-05 16:05 UTC (permalink / raw)
  To: u-boot

On 10/05/2012 04:35 AM, Lukasz Majewski wrote:
> Hi Stephen,
> 
>> On 09/13/2012 02:10 AM, Lukasz Majewski wrote:
... [patch to implement GPT creation]
>> Then, I wonder if you couldn't define the partitions environment
>> variable as:
>>
>> partitions=\
>> name=u-boot,size=60M,uuid=${uuid_gpt_u_boot};\
>> name=kernel,size=60M,uuid=${uuid_gpt_kernel};...
>>
>> and have the environment variables expanded as in:
>>
>> setenv uuid_gpt_u_boot=ed09c4b0-fbf5-11e1-9a95-001fd09285c0
>> setenv uuid_gpt_kernel=...
> 
> This is a good idea to allow uuid_gpt_u_boot= to be set via setenv.
> Moreover I think, that "editing" of "partitions" names, uuid and other
> parameters shall be done via setenv (as you proposed).
> 
>> gpt mmc 0 ${partitions}
> 
> Moreover I think, that parsing ${partitions} as a list of argv[n] is
> not the best option to proceed.
> 
> I think that it would be easier to:
> 1. Prepare predefined "partitions=" variable
> at ./include/configs/trats.h (when no one is available on the platform)
> 2. Edit relevant env variables (uuid_gpt_u_boot=, etc) via setenv and
> saveenv.
> 3. restore it with gpt mmc 0 partitions (- the name of the stored and
> prepared env variable)
> 
> I'd like to emphasis, that I strive to avoid parsing possibly (very)
> long list of GPT partition definition via gpt command's argv[n].
> 
> If user wants to edit something, then one can use setenv to do that.

This forces the user to put the partition layout into an environment
variable. I don't like that idea. What if the user is running some
script on a recovery boot media to create the partition layout, rather
then restoring some partition layout defined in the default environment
in the board's U-Boot configuration file? Why should we force them to write:

setenv foo <<partition_layout>>
gpt create mmc 0 ${foo}

rather than simply:

gpt create mmc 0 <<partition_layout>>

The amount of work the command itself has to do for parsing is identical
or in fact slightly less; it just has to go to argv[4] and interpret it
as a partition list, rather than go to argv[4], read an environment
variable of that name and then interpret it as a partition list.
Admittedly, the command-shell has to do (very marginally) more work
since it has to scan more characters for the spaces that delimit
arguments, but I imagine that overhead is irrelevant compared to the
actual disk IO required to write the new partition tables, or even the
CPU calculations to calculate a UUID.

...
>> Oh, and don't you want the "gpt" command to take a sub-command like
>> "create", so that "gpt" could do different things in the future, e.g.
>> take an existing GPT layout, and edit, say, one partition's name:
>>
> 
> This is a nice idea to divide the gpt commands to subcommands. However
> I now focus on gpt restoration (done in a correct and agreed way :-) ).
> I will prepare the gpt command to be easily dividable to sub-commands.

I certainly agree that the other sub-commands can be implemented later;
I just wanted to make sure that the command syntax was extensible in a
backwards compatible manner.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [u-boot] Adding missing CONFIG_SYS_CACHELINE_SIZE to boards definitions
  2012-10-04  8:28       ` esw
@ 2012-10-18 18:48         ` Albert ARIBAUD
  0 siblings, 0 replies; 95+ messages in thread
From: Albert ARIBAUD @ 2012-10-18 18:48 UTC (permalink / raw)
  To: u-boot

Hi esw,

(resending as it was erroneously posted on gmane; sorry for any dupes)

On Thu, 4 Oct 2012 10:28:48 +0200, esw <esw@bus-elektronik.de> wrote:

> Dear Lukasz,
> 
> > Hi Jens and Helmut,
> > 
> >> On Thu, Aug 23, 2012 at 10:13:13PM -0000, Lukasz Majewski wrote:
> >>
> >>> The restoration of GPT table (both primary and secondary) is now
> >>> possible. Simple GUID generation is supported.
> >>>
> >>> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> >>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> >>
> >> While the changes are fine, tt01 and eb_cpux9k2 use CONFIG_PART_EFI
> >> and do not set CONFIG_SYS_CACHELINE_SIZE and so fail to build after
> >> this patch.  tt01 is easily fixable (it relies on a non-exported
> >> define elsewhere to 32) but the eb_cpu9k2 please contact the listed
> >> board maintainer to get the define added.
> >>
> > 
> > Would it be possible to add the CONFIG_SYS_CACHELINE_SIZE
> > definition to ./include/configs/{tty01|eb_cpux9k2} boards definition?
> > 
> The eb_cpux9k2 board based on at91rm9200 soc. This soc has currently no cache implementation. So I think your run in this error.
> 
> The attached patch sets the define to the soc default.
> 
> We can also set #define CONFIG_SYS_DCACHE_OFF
> 
> regards Jens

If this is to be considered an actual patch submission, then please
submit via git format-patch/git send-email or patman, and copy the at91
custodian. This patch has been marked as "changes requested" in PW.

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration
  2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
                   ` (10 preceding siblings ...)
  2012-09-13  8:09 ` [U-Boot] [PATCH v3 " Lukasz Majewski
@ 2012-11-09  9:22 ` Piotr Wilczek
  2012-11-09  9:22   ` [U-Boot] [PATCH v4 1/7] vsprintf:fix: Change type returned by ustrtoul Piotr Wilczek
                     ` (5 more replies)
  11 siblings, 6 replies; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-09  9:22 UTC (permalink / raw)
  To: u-boot

This patch series provides a new command - "gpt" for eMMC partition table
(in the GPT format) restoration.

As a pre-work, some cleanup at the part_efi.c file was performed to
remove custom macros and make GPT related structures more readable.

Moreover the part_efi.h file has been moved to ./include directory to
be easily available from other subsystems.

The GPT detailed description has been written to README.gpt file.

Tested at:
        - Exynos4210 rev.1 - TRATS Samsung development board

Chang Hyun Park (1):
  gpt: The leXX_to_int() calls replaced with ones defined at
    <compiler.h>

Lukasz Majewski (5):
  vsprintf:fix: Change type returned by ustrtoul
  part:efi: Move part_efi.h file to ./include
  gpt:doc: GPT (GUID Partition Table) documentation
  gpt: Support for GPT (GUID Partition Table) restoration
  gpt: Enable support for GPT partition table restoration at Samsung's
    Trats

Piotr Wilczek (1):
  gpt: Support for new "gpt" command

 common/Makefile              |    1 +
 common/cmd_gpt.c             |  300 ++++++++++++++++++++++++++++
 disk/part_efi.c              |  455 +++++++++++++++++++++++++++++++++++-------
 doc/README.gpt               |  209 +++++++++++++++++++
 include/configs/trats.h      |   29 +++-
 include/part.h               |    8 +
 {disk => include}/part_efi.h |   89 +++++----
 lib/vsprintf.c               |    2 +-
 8 files changed, 977 insertions(+), 116 deletions(-)
 create mode 100644 common/cmd_gpt.c
 create mode 100644 doc/README.gpt
 rename {disk => include}/part_efi.h (66%)

-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 1/7] vsprintf:fix: Change type returned by ustrtoul
  2012-11-09  9:22 ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Piotr Wilczek
@ 2012-11-09  9:22   ` Piotr Wilczek
  2012-11-19 19:19     ` Stephen Warren
  2012-11-09  9:22   ` [U-Boot] [PATCH v4 2/7] part:efi: Move part_efi.h file to ./include Piotr Wilczek
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-09  9:22 UTC (permalink / raw)
  To: u-boot

From: Lukasz Majewski <l.majewski@samsung.com>

The ustrtoul shall convert string defined size (e.g. 1GiB) to unsigned
long type (as its name implies).

Up till now it had returned int, which might cause problems with large
numbers (GiB range), when interpreted as U2 signed numbers.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v3:
- None
Changes for v4:
- None
---
 lib/vsprintf.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index b7a79c0..3c432f8 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -103,7 +103,7 @@ long simple_strtol(const char *cp, char **endp, unsigned int base)
 	return simple_strtoul(cp, endp, base);
 }
 
-int ustrtoul(const char *cp, char **endp, unsigned int base)
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
 {
 	unsigned long result = simple_strtoul(cp, endp, base);
 	switch (**endp) {
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 2/7] part:efi: Move part_efi.h file to ./include
  2012-11-09  9:22 ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Piotr Wilczek
  2012-11-09  9:22   ` [U-Boot] [PATCH v4 1/7] vsprintf:fix: Change type returned by ustrtoul Piotr Wilczek
@ 2012-11-09  9:22   ` Piotr Wilczek
  2012-11-19 19:30     ` Stephen Warren
  2012-11-09  9:22   ` [U-Boot] [PATCH v4 3/7] gpt:doc: GPT (GUID Partition Table) documentation Piotr Wilczek
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-09  9:22 UTC (permalink / raw)
  To: u-boot

From: Lukasz Majewski <l.majewski@samsung.com>

This move is necessary to export gpt header and GPT partition entries to be
used with other commands or subsystems (like DFU in the future)
Additionally the part_efi.h file has been cleaned-up to supress checkpatch's
warnings.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v3:
- None
Changes for v4:
- None
---
 {disk => include}/part_efi.h |    0
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename {disk => include}/part_efi.h (100%)

diff --git a/disk/part_efi.h b/include/part_efi.h
similarity index 100%
rename from disk/part_efi.h
rename to include/part_efi.h
-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot]  [PATCH v4 3/7] gpt:doc: GPT (GUID Partition Table) documentation
  2012-11-09  9:22 ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Piotr Wilczek
  2012-11-09  9:22   ` [U-Boot] [PATCH v4 1/7] vsprintf:fix: Change type returned by ustrtoul Piotr Wilczek
  2012-11-09  9:22   ` [U-Boot] [PATCH v4 2/7] part:efi: Move part_efi.h file to ./include Piotr Wilczek
@ 2012-11-09  9:22   ` Piotr Wilczek
  2012-11-19 19:28     ` Stephen Warren
  2012-11-09 10:48   ` [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Piotr Wilczek
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-09  9:22 UTC (permalink / raw)
  To: u-boot

From: Lukasz Majewski <l.majewski@samsung.com>

Documentation of the GPT format.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v2:
- Typos correction.
- Adding guidlines about GPT restoration.
- Adding information about GUID generator

Changes for v3:
- None

Changes for v4:
- Updated documentation
---
 doc/README.gpt |  209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 209 insertions(+), 0 deletions(-)
 create mode 100644 doc/README.gpt

diff --git a/doc/README.gpt b/doc/README.gpt
new file mode 100644
index 0000000..543c9ef
--- /dev/null
+++ b/doc/README.gpt
@@ -0,0 +1,209 @@
+#
+#  Copyright (C) 2012 Samsung Electronics
+#
+#  Lukasz Majewski <l.majewski@samsung.com>
+#
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+
+
+Glossary:
+========
+- UUID -(Universally Unique Identifier)
+- GUID - (Globally Unique ID)
+- EFI - (Extensible Firmware Interface)
+- UEFI - (Unified EFI) - EFI evolution
+- GPT (GUID Partition Table) - it is the EFI standard part
+- partitions - lists of available partitions (defined at u-boot):
+  ./include/configs/{target}.h
+
+Introduction:
+=============
+This document describes the GPT partition table format when used with u-boot.
+
+
+UUID introduction:
+====================
+
+GPT for marking disks/partitions is using the UUID. It is supposed to be a
+globally unique value. A UUID is a 16-byte (128-bit) number. The number of
+theoretically possible UUIDs is therefore about 3 ? 10^38.
+More often UUID is stored as 32 hexadecimal digits, displayed in 5 groups
+separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters
+(32 digits and 4 hyphens)
+
+For instance, GUID of Linux data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
+
+Historically there are 5 methods to generate this number. The oldest one is
+combining machine's MAC address and timer (epoch) value.
+
+Successive versions are using MD5 hash, random numbers and SHA-1 hash. All major
+OSes and programming languages are providing libraries to compute UUID (e.g.
+uuid command line tool).
+
+GPT brief explanation:
+======================
+
+	Layout:
+	-------
+
+	--------------------------------------------------
+	LBA 0          |Protective MBR                   |
+	----------------------------------------------------------
+	LBA 1          |Primary GPT Header               | Primary
+	-------------------------------------------------- GPT
+	LBA 2          |Entry 1|Entry 2| Entry 3| Entry 4|
+	--------------------------------------------------
+	LBA 3          |Entries 5 - 128                  |
+		       |                                 |
+		       |                                 |
+	----------------------------------------------------------
+	LBA 34         |Partition 1                      |
+		       |                                 |
+		       -----------------------------------
+		       |Partition 2                      |
+		       |                                 |
+		       -----------------------------------
+		       |Partition n                      |
+		       |                                 |
+	----------------------------------------------------------
+	LBA -34        |Entry 1|Entry 2| Entry 3| Entry 4| Secondary
+	-------------------------------------------------- (bkp)
+	LBA -33        |Entries 5 - 128                  | GPT
+		       |                                 |
+		       |                                 |
+	LBA -2         |                                 |
+	--------------------------------------------------
+	LBA -1         |Secondary GPT Header             |
+	----------------------------------------------------------
+
+
+For a legacy reasons, GPT's LBA 0 sector has a MBR structure. It is called
+"protective MBR".
+Its first partition entry ID has 0xEE value, and disk software, which is not
+handling the GPT sees it as a storage device without free space.
+
+It is possible to define 128 linearly placed partition entries.
+
+"LBA -1" means the last addressable block (in the mmc subsystem:
+"dev_desc->lba - 1")
+
+Primary/Secondary GPT header:
+----------------------------
+Offset  Size    Description
+
+0       8 B     Signature ("EFI PART", 45 46 49 20 50 41 52 54)
+8       4 B     Revision (For version 1.0, the value is 00 00 01 00)
+12      4 B     Header size (in bytes, usually 5C 00 00 00 meaning 92 bytes)
+16      4 B     CRC32 of header (0 to header size), with this field zeroed
+		during calculation
+20      4 B     Reserved (ZERO);
+24      8 B     Current LBA (location of this header copy)
+32      8 B     Backup LBA (location of the other header copy)
+40      8 B     First usable LBA for partitions (primary partition table last
+		LBA + 1)
+48      8 B     Last usable LBA (secondary partition table first LBA - 1)
+56      16 B    Disk GUID (also referred as UUID on UNIXes)
+72      8 B     Partition entries starting LBA (always 2 in primary copy)
+80      4 B     Number of partition entries
+84      4 B     Size of a partition entry (usually 128)
+88      4 B     CRC32 of partition array
+92      *       Reserved; must be ZERO (420 bytes for a 512-byte LBA)
+
+TOTAL: 512 B
+
+
+
+IMPORTANT:
+
+GPT headers and partition entries are protected by CRC32 (the POSIX CRC32).
+
+Primary GPT header and Secondary GPT header have swapped values of "Current LBA"
+and "Backup LBA" and therefore different CRC32 check-sum.
+
+CRC32 for GPT headers (field "CRC of header") are calculated up till
+"Header size" (92), NOT 512 bytes.
+
+CRC32 for partition entries (field "CRC32 of partition array") is calculated for
+the whole array entry ( Number_of_partition_entries *
+sizeof(partition_entry_size (usually 128)))
+
+Observe, how Secondary GPT is placed in the memory. It is NOT a mirror reflect
+of the Primary.
+
+
+	   Partition Entry Format:
+	   ----------------------
+	   Offset  Size    Description
+
+	   0       16 B    Partition type GUID
+	   16      16 B    Unique partition GUID
+	   32      8  B    First LBA (Little Endian)
+	   40      8  B    Last LBA (inclusive)
+	   48      8  B    Attribute flags [+]
+	   56      72 B    Partition name (text)
+
+	   Attribute flags:
+	   Bit 0  - System partition
+	   Bit 60 - Read-only
+	   Bit 62 - Hidden
+	   Bit 63 - Not mount
+
+
+Example usage:
+==============
+
+To restore GUID partition table one needs to:
+1. at ./include/configs/{board}.h
+   - define "partitions=" environment variable with format:
+     "name=..,size=..,uuid=..;..."
+     values for every key can be passed as text or environment variable
+     examples:
+     "name=u-boot,size=60M;name=kernel,size=60M;name=platform,size=1G;"
+     "name=${uboot_name},size=${uboot_size},uuid=${uboot_uuid};..."
+
+2. From u-boot prompt type:
+   gpt mmc 0
+   or
+   gpt mmc 0 partitions
+   or pass partitions list as text:
+   gpt mmc 0 "name=u-boot,size=60M;name=kernel,size=60M;name=platform,size=1G;"
+
+   When UUIDs are NOT provided, internal (rather weak) GUID generator will be
+   used instead
+
+Internal GUID generator:
+=======================
+
+For "emergency" usage (or when list of UUIDs cannot be provided)  the internal
+GUID generator shall be used. It uses gd->start_addr_sp as a primary source of
+UUID generator (16B).
+
+
+Useful info:
+============
+
+Two programs, namely: 'fdisk' and 'parted' are recommended to work with GPT
+recovery. Parted is able to handle GUID partitions. Unfortunately the 'fdisk'
+hasn't got such ability.
+Please, pay attention at -l switch for parted.
+
+"uuid" program is recommended to generate UUID string. Moreover it can decode
+(-d switch) passed in UUID string. It can be used to generate partitions UUID
+passed to u-boot environment variables.
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h>
  2012-11-09  9:22 ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Piotr Wilczek
                     ` (2 preceding siblings ...)
  2012-11-09  9:22   ` [U-Boot] [PATCH v4 3/7] gpt:doc: GPT (GUID Partition Table) documentation Piotr Wilczek
@ 2012-11-09 10:48   ` Piotr Wilczek
  2012-11-09 10:48     ` [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration Piotr Wilczek
                       ` (3 more replies)
  2012-11-19 20:43   ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Tom Rini
  2012-12-06 20:40   ` Tom Rini
  5 siblings, 4 replies; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-09 10:48 UTC (permalink / raw)
  To: u-boot

From: Chang Hyun Park <heartinpiece@outlook.com>

Custom definitions of le_XX_to_int functions have been replaced with
standard ones, defined at <compiler.h>

Replacement of several GPT related structures members with ones
indicating its endianness and proper size.

Signed-off-by: Chang Hyun Park <heartinpiece@outlook.com>
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v2:
- Combining two commits regarding part_efi.{h|c}

Changes for v3:
- None

changes for v4:
- None
---
 disk/part_efi.c    |  113 +++++++++++++++++++--------------------------------
 include/part_efi.h |   89 +++++++++++++++++++++--------------------
 2 files changed, 88 insertions(+), 114 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index a3873ce..bacb40a 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -34,7 +34,7 @@
 #include <command.h>
 #include <ide.h>
 #include <malloc.h>
-#include "part_efi.h"
+#include <part_efi.h>
 #include <linux/ctype.h>
 
 #if defined(CONFIG_CMD_IDE) || \
@@ -44,34 +44,6 @@
     defined(CONFIG_MMC) || \
     defined(CONFIG_SYSTEMACE)
 
-/* Convert char[2] in little endian format to the host format integer
- */
-static inline unsigned short le16_to_int(unsigned char *le16)
-{
-	return ((le16[1] << 8) + le16[0]);
-}
-
-/* Convert char[4] in little endian format to the host format integer
- */
-static inline unsigned long le32_to_int(unsigned char *le32)
-{
-	return ((le32[3] << 24) + (le32[2] << 16) + (le32[1] << 8) + le32[0]);
-}
-
-/* Convert char[8] in little endian format to the host format integer
- */
-static inline unsigned long long le64_to_int(unsigned char *le64)
-{
-	return (((unsigned long long)le64[7] << 56) +
-		((unsigned long long)le64[6] << 48) +
-		((unsigned long long)le64[5] << 40) +
-		((unsigned long long)le64[4] << 32) +
-		((unsigned long long)le64[3] << 24) +
-		((unsigned long long)le64[2] << 16) +
-		((unsigned long long)le64[1] << 8) +
-		(unsigned long long)le64[0]);
-}
-
 /**
  * efi_crc32() - EFI version of crc32 function
  * @buf: buffer to calculate crc32 of
@@ -79,7 +51,7 @@ static inline unsigned long long le64_to_int(unsigned char *le64)
  *
  * Description: Returns EFI-style CRC32 value for @buf
  */
-static inline unsigned long efi_crc32(const void *buf, unsigned long len)
+static inline u32 efi_crc32(const void *buf, u32 len)
 {
 	return crc32(0, buf, len);
 }
@@ -171,14 +143,14 @@ void print_part_efi(block_dev_desc_t * dev_desc)
 	printf("\tType UUID\n");
 	printf("\tPartition UUID\n");
 
-	for (i = 0; i < le32_to_int(gpt_head->num_partition_entries); i++) {
+	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
 		/* Stop at the first non valid PTE */
 		if (!is_pte_valid(&gpt_pte[i]))
 			break;
 
 		printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1),
-			le64_to_int(gpt_pte[i].starting_lba),
-			le64_to_int(gpt_pte[i].ending_lba),
+			(u64) le64_to_cpu(gpt_pte[i].starting_lba),
+			(u64) le64_to_cpu(gpt_pte[i].ending_lba),
 			print_efiname(&gpt_pte[i]));
 		printf("\tattrs:\t0x%016llx\n", gpt_pte[i].attributes.raw);
 		uuid_string(gpt_pte[i].partition_type_guid.b, uuid);
@@ -211,7 +183,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 		return -1;
 	}
 
-	if (part > le32_to_int(gpt_head->num_partition_entries) ||
+	if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
 	    !is_pte_valid(&gpt_pte[part - 1])) {
 		printf("%s: *** ERROR: Invalid partition number %d ***\n",
 			__func__, part);
@@ -219,9 +191,9 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 	}
 
 	/* The ulong casting limits the maximum disk size to 2 TB */
-	info->start = (ulong) le64_to_int(gpt_pte[part - 1].starting_lba);
+	info->start = (u64) le64_to_cpu(gpt_pte[part - 1].starting_lba);
 	/* The ending LBA is inclusive, to calculate size, add 1 to it */
-	info->size = ((ulong)le64_to_int(gpt_pte[part - 1].ending_lba) + 1)
+	info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
 		     - info->start;
 	info->blksz = GPT_BLOCK_SIZE;
 
@@ -264,7 +236,7 @@ int test_part_efi(block_dev_desc_t * dev_desc)
 static int pmbr_part_valid(struct partition *part)
 {
 	if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
-		le32_to_int(part->start_sect) == 1UL) {
+		le32_to_cpu(part->start_sect) == 1UL) {
 		return 1;
 	}
 
@@ -283,9 +255,8 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 {
 	int i = 0;
 
-	if (!mbr || le16_to_int(mbr->signature) != MSDOS_MBR_SIGNATURE) {
+	if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
 		return 0;
-	}
 
 	for (i = 0; i < 4; i++) {
 		if (pmbr_part_valid(&mbr->partition_record[i])) {
@@ -308,8 +279,8 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 			gpt_header * pgpt_head, gpt_entry ** pgpt_pte)
 {
-	unsigned char crc32_backup[4] = { 0 };
-	unsigned long calc_crc32;
+	u32 crc32_backup = 0;
+	u32 calc_crc32;
 	unsigned long long lastlba;
 
 	if (!dev_desc || !pgpt_head) {
@@ -324,54 +295,54 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 	}
 
 	/* Check the GPT header signature */
-	if (le64_to_int(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
+	if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
 		printf("GUID Partition Table Header signature is wrong:"
 			"0x%llX != 0x%llX\n",
-			(unsigned long long)le64_to_int(pgpt_head->signature),
-			(unsigned long long)GPT_HEADER_SIGNATURE);
+			(u64) le64_to_cpu(pgpt_head->signature),
+			(u64) GPT_HEADER_SIGNATURE);
 		return 0;
 	}
 
 	/* Check the GUID Partition Table CRC */
-	memcpy(crc32_backup, pgpt_head->header_crc32, sizeof(crc32_backup));
-	memset(pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
+	memcpy(&crc32_backup, &pgpt_head->header_crc32, sizeof(crc32_backup));
+	memset(&pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
 
 	calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
-		le32_to_int(pgpt_head->header_size));
+		le32_to_cpu(pgpt_head->header_size));
 
-	memcpy(pgpt_head->header_crc32, crc32_backup, sizeof(crc32_backup));
+	memcpy(&pgpt_head->header_crc32, &crc32_backup, sizeof(crc32_backup));
 
-	if (calc_crc32 != le32_to_int(crc32_backup)) {
+	if (calc_crc32 != le32_to_cpu(crc32_backup)) {
 		printf("GUID Partition Table Header CRC is wrong:"
-			"0x%08lX != 0x%08lX\n",
-			le32_to_int(crc32_backup), calc_crc32);
+			"0x%x != 0x%x\n",
+		       (u32) le32_to_cpu(crc32_backup), calc_crc32);
 		return 0;
 	}
 
 	/* Check that the my_lba entry points to the LBA that contains the GPT */
-	if (le64_to_int(pgpt_head->my_lba) != lba) {
+	if (le64_to_cpu(pgpt_head->my_lba) != lba) {
 		printf("GPT: my_lba incorrect: %llX != %llX\n",
-			(unsigned long long)le64_to_int(pgpt_head->my_lba),
-			(unsigned long long)lba);
+			(u64)le64_to_cpu(pgpt_head->my_lba),
+			(u64)lba);
 		return 0;
 	}
 
 	/* Check the first_usable_lba and last_usable_lba are within the disk. */
 	lastlba = (unsigned long long)dev_desc->lba;
-	if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
+	if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) {
 		printf("GPT: first_usable_lba incorrect: %llX > %llX\n",
-			le64_to_int(pgpt_head->first_usable_lba), lastlba);
+			le64_to_cpu(pgpt_head->first_usable_lba), lastlba);
 		return 0;
 	}
-	if (le64_to_int(pgpt_head->last_usable_lba) > lastlba) {
+	if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) {
 		printf("GPT: last_usable_lba incorrect: %llX > %llX\n",
-			le64_to_int(pgpt_head->last_usable_lba), lastlba);
+			(u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 		return 0;
 	}
 
 	debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n",
-		le64_to_int(pgpt_head->first_usable_lba),
-		le64_to_int(pgpt_head->last_usable_lba), lastlba);
+	      (u64) le64_to_cpu(pgpt_head->first_usable_lba),
+	      (u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 
 	/* Read and allocate Partition Table Entries */
 	*pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
@@ -382,13 +353,13 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 
 	/* Check the GUID Partition Table Entry Array CRC */
 	calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
-		le32_to_int(pgpt_head->num_partition_entries) *
-		le32_to_int(pgpt_head->sizeof_partition_entry));
+		le32_to_cpu(pgpt_head->num_partition_entries) *
+		le32_to_cpu(pgpt_head->sizeof_partition_entry));
 
-	if (calc_crc32 != le32_to_int(pgpt_head->partition_entry_array_crc32)) {
+	if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) {
 		printf("GUID Partition Table Entry Array CRC is wrong:"
-			"0x%08lX != 0x%08lX\n",
-			le32_to_int(pgpt_head->partition_entry_array_crc32),
+			"0x%x != 0x%x\n",
+		       (u32)le32_to_cpu(pgpt_head->partition_entry_array_crc32),
 			calc_crc32);
 
 		free(*pgpt_pte);
@@ -419,12 +390,12 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 		return NULL;
 	}
 
-	count = le32_to_int(pgpt_head->num_partition_entries) *
-		le32_to_int(pgpt_head->sizeof_partition_entry);
+	count = le32_to_cpu(pgpt_head->num_partition_entries) *
+		le32_to_cpu(pgpt_head->sizeof_partition_entry);
 
-	debug("%s: count = %lu * %lu = %zu\n", __func__,
-		le32_to_int(pgpt_head->num_partition_entries),
-		le32_to_int(pgpt_head->sizeof_partition_entry), count);
+	debug("%s: count = %u * %u = %zu\n", __func__,
+	      (u32) le32_to_cpu(pgpt_head->num_partition_entries),
+	      (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), count);
 
 	/* Allocate memory for PTE, remember to FREE */
 	if (count != 0) {
@@ -440,7 +411,7 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 
 	/* Read GPT Entries from device */
 	if (dev_desc->block_read (dev_desc->dev,
-		(unsigned long)le64_to_int(pgpt_head->partition_entry_lba),
+		(u64) le64_to_cpu(pgpt_head->partition_entry_lba),
 		(lbaint_t) (count / GPT_BLOCK_SIZE), pte)
 		!= (count / GPT_BLOCK_SIZE)) {
 
diff --git a/include/part_efi.h b/include/part_efi.h
index 4e28d1d..6de0a32 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -29,6 +29,8 @@
  * http://developer.intel.com/technology/efi/efi.htm
 */
 
+#include <linux/compiler.h>
+
 #ifndef _DISK_PART_EFI_H
 #define _DISK_PART_EFI_H
 
@@ -41,6 +43,8 @@
 #define GPT_HEADER_REVISION_V1 0x00010000
 #define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
 #define GPT_ENTRY_NAME "gpt"
+#define GPT_ENTRY_NUMBERS		128
+#define GPT_ENTRY_SIZE			128
 
 #define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
 	((efi_guid_t) \
@@ -72,73 +76,72 @@
 		0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
 
 /* linux/include/efi.h */
-typedef unsigned short efi_char16_t;
+typedef u16 efi_char16_t;
 
 typedef struct {
-	unsigned char b[16];
+	u8 b[16];
 } efi_guid_t;
 
 /* based on linux/include/genhd.h */
 struct partition {
-	unsigned char boot_ind;		/* 0x80 - active */
-	unsigned char head;		/* starting head */
-	unsigned char sector;		/* starting sector */
-	unsigned char cyl;		/* starting cylinder */
-	unsigned char sys_ind;		/* What partition type */
-	unsigned char end_head;		/* end head */
-	unsigned char end_sector;	/* end sector */
-	unsigned char end_cyl;		/* end cylinder */
-	unsigned char start_sect[4];	/* starting sector counting from 0 */
-	unsigned char nr_sects[4];	/* nr of sectors in partition */
-} __attribute__ ((packed));
+	u8 boot_ind;		/* 0x80 - active */
+	u8 head;		/* starting head */
+	u8 sector;		/* starting sector */
+	u8 cyl;			/* starting cylinder */
+	u8 sys_ind;		/* What partition type */
+	u8 end_head;		/* end head */
+	u8 end_sector;		/* end sector */
+	u8 end_cyl;		/* end cylinder */
+	__le32 start_sect;	/* starting sector counting from 0 */
+	__le32 nr_sects;	/* nr of sectors in partition */
+} __packed;
 
 /* based on linux/fs/partitions/efi.h */
 typedef struct _gpt_header {
-	unsigned char signature[8];
-	unsigned char revision[4];
-	unsigned char header_size[4];
-	unsigned char header_crc32[4];
-	unsigned char reserved1[4];
-	unsigned char my_lba[8];
-	unsigned char alternate_lba[8];
-	unsigned char first_usable_lba[8];
-	unsigned char last_usable_lba[8];
+	__le64 signature;
+	__le32 revision;
+	__le32 header_size;
+	__le32 header_crc32;
+	__le32 reserved1;
+	__le64 my_lba;
+	__le64 alternate_lba;
+	__le64 first_usable_lba;
+	__le64 last_usable_lba;
 	efi_guid_t disk_guid;
-	unsigned char partition_entry_lba[8];
-	unsigned char num_partition_entries[4];
-	unsigned char sizeof_partition_entry[4];
-	unsigned char partition_entry_array_crc32[4];
-	unsigned char reserved2[GPT_BLOCK_SIZE - 92];
-} __attribute__ ((packed)) gpt_header;
+	__le64 partition_entry_lba;
+	__le32 num_partition_entries;
+	__le32 sizeof_partition_entry;
+	__le32 partition_entry_array_crc32;
+	u8 reserved2[GPT_BLOCK_SIZE - 92];
+} __packed gpt_header;
 
 typedef union _gpt_entry_attributes {
 	struct {
-		unsigned long long required_to_function:1;
-		unsigned long long no_block_io_protocol:1;
-		unsigned long long legacy_bios_bootable:1;
-		unsigned long long reserved:45;
-		unsigned long long type_guid_specific:16;
+		u64 required_to_function:1;
+		u64 no_block_io_protocol:1;
+		u64 legacy_bios_bootable:1;
+		u64 reserved:45;
+		u64 type_guid_specific:16;
 	} fields;
 	unsigned long long raw;
-} __attribute__ ((packed)) gpt_entry_attributes;
+} __packed gpt_entry_attributes;
 
 #define PARTNAME_SZ	(72 / sizeof(efi_char16_t))
 typedef struct _gpt_entry {
 	efi_guid_t partition_type_guid;
 	efi_guid_t unique_partition_guid;
-	unsigned char starting_lba[8];
-	unsigned char ending_lba[8];
+	__le64 starting_lba;
+	__le64 ending_lba;
 	gpt_entry_attributes attributes;
 	efi_char16_t partition_name[PARTNAME_SZ];
-}
-__attribute__ ((packed)) gpt_entry;
+} __packed gpt_entry;
 
 typedef struct _legacy_mbr {
-	unsigned char boot_code[440];
-	unsigned char unique_mbr_signature[4];
-	unsigned char unknown[2];
+	u8 boot_code[440];
+	__le32 unique_mbr_signature;
+	__le16 unknown;
 	struct partition partition_record[4];
-	unsigned char signature[2];
-} __attribute__ ((packed)) legacy_mbr;
+	__le16 signature;
+} __packed legacy_mbr;
 
 #endif	/* _DISK_PART_EFI_H */
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-11-09 10:48   ` [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Piotr Wilczek
@ 2012-11-09 10:48     ` Piotr Wilczek
  2012-11-19 20:16       ` Stephen Warren
  2012-11-09 10:48     ` [U-Boot] [PATCH v4 6/7] gpt: Support for new "gpt" command Piotr Wilczek
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-09 10:48 UTC (permalink / raw)
  To: u-boot

From: Lukasz Majewski <l.majewski@samsung.com>

The restoration of GPT table (both primary and secondary) is now possible.
Simple GUID generation is supported.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Piotr Wilczek <p.wilczek@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v2:
- Move GPT Header and Page Table Entries generation code to cmd_gpt.c
- Provide clean API to use set_gpt_table function for GPT restoration on
  a block device

Changes for v3:
- Replace printf with puts

Changes for v4:
- Add public functions for fill gpt header and entries
- Add public function for fill and save gpt tables on the basis of
  simple partions list information
---
 disk/part_efi.c |  342 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/part.h  |    8 ++
 2 files changed, 350 insertions(+), 0 deletions(-)

diff --git a/disk/part_efi.c b/disk/part_efi.c
index bacb40a..e501ac1 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -37,6 +37,8 @@
 #include <part_efi.h>
 #include <linux/ctype.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #if defined(CONFIG_CMD_IDE) || \
     defined(CONFIG_CMD_SATA) || \
     defined(CONFIG_CMD_SCSI) || \
@@ -71,6 +73,16 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 
 static int is_pte_valid(gpt_entry * pte);
 
+static int set_protective_mbr(block_dev_desc_t *dev_desc);
+
+static void guid_dump(u8 *guid, int i);
+
+static void guid_gen(const u32 *pool, u8 *guid);
+
+static int convert_uuid(char *uuid, u8 *dst);
+
+static void set_part_name(efi_char16_t *part_name, char *name);
+
 static char *print_efiname(gpt_entry *pte)
 {
 	static char name[PARTNAME_SZ + 1];
@@ -225,6 +237,197 @@ int test_part_efi(block_dev_desc_t * dev_desc)
 	return 0;
 }
 
+/**
+ * set_gpt_table() - Restore the GUID Partition Table
+ *
+ * @param dev_desc - block device descriptor
+ * @param parts - number of partitions
+ * @param size - pointer to array with each partition size
+ * @param name - pointer to array with each partition name
+ *
+ * @return - zero on success, otherwise error
+ */
+int set_gpt_table(block_dev_desc_t *dev_desc,
+		  gpt_header *gpt_h, gpt_entry *gpt_e)
+{
+	const int pte_blk_num = (GPT_ENTRY_NUMBERS * sizeof(gpt_entry)) /
+		dev_desc->blksz;
+	u32 calc_crc32;
+	u64 val;
+
+	debug("max lba: %x\n", (u32) dev_desc->lba);
+	/* Setup the Protective MBR */
+	if (set_protective_mbr(dev_desc) < 0)
+		goto err;
+
+	/* 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);
+
+	/* Write the First GPT to the block right after the Legacy MBR */
+	if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1)
+		goto err;
+
+	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e)
+	    != pte_blk_num)
+		goto err;
+
+	/* recalculate the values for the Second 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);
+	gpt_h->header_crc32 = 0;
+
+	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);
+
+	if (dev_desc->block_write(dev_desc->dev,
+				  le32_to_cpu(gpt_h->last_usable_lba + 1),
+				  pte_blk_num, gpt_e) != pte_blk_num)
+		goto err;
+
+	if (dev_desc->block_write(dev_desc->dev,
+				  le32_to_cpu(gpt_h->my_lba), 1, gpt_h) != 1)
+		goto err;
+
+	puts("GPT successfully written to block device!\n");
+	return 0;
+
+ err:
+	printf("** Can't write to device %d **\n",
+	       dev_desc->dev);
+	return -1;
+}
+
+/**
+ * gpt_fill_pte(): Fill the GPT partition table entry
+ *
+ * @param gpt_h - GPT header representation
+ * @param gpt_e - GPT partition table entries
+ * @param partitions - list of partitions
+ * @param parts - number of partitions
+ */
+void gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
+		disk_partition_t *partitions[], int parts)
+{
+	u32 offset = (u32) le32_to_cpu(gpt_h->first_usable_lba);
+	u8 guid[sizeof(efi_guid_t)];
+	char *str_uuid;
+	ulong start;
+	int i;
+
+	for (i = 0; i < parts; i++) {
+		/* partition starting lba */
+		start = partitions[i]->start;
+		if (start && (offset <= start))
+			gpt_e[i].starting_lba = cpu_to_le32(start);
+		else
+			gpt_e[i].starting_lba = cpu_to_le32(offset);
+
+		offset = le32_to_cpu(gpt_e[i].starting_lba)
+			+ partitions[i]->size;
+		if (offset >= gpt_h->last_usable_lba) {
+			printf("Partitions layout excedds disk size\n");
+			return;
+		}
+		/* partition ending lba */
+		if (i != parts - 1)
+			gpt_e[i].ending_lba =
+				cpu_to_le64(offset - 1);
+		else
+			gpt_e[i].ending_lba = gpt_h->last_usable_lba;
+
+		/* partition type GUID*/
+		memcpy(gpt_e[i].partition_type_guid.b,
+			&PARTITION_BASIC_DATA_GUID, 16);
+
+		str_uuid = NULL;
+#ifdef CONFIG_PARTITION_UUIDS
+		str_uuid = partitions[i]->uuid;
+#endif
+		if (convert_uuid(str_uuid, gpt_e[i].unique_partition_guid.b)) {
+			guid_gen((((u32 *) gd->start_addr_sp) - i - 1),
+				guid);
+			memcpy(gpt_e[i].unique_partition_guid.b, guid,
+			       sizeof(efi_guid_t));
+		}
+
+		/* partition attributes */
+		memset(&gpt_e[i].attributes, 0,
+		       sizeof(gpt_entry_attributes));
+
+		/* partition name */
+		set_part_name(gpt_e[i].partition_name,
+			(char *)partitions[i]->name);
+
+		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%lx\n",
+		      __func__, partitions[i]->name, i,
+		      offset, i, partitions[i]->size);
+	}
+}
+
+/**
+ * gpt_fill_header(): Fill the GPT header
+ *
+ * @param dev_desc - block device descriptor
+ * @param gpt_h - GPT header representation
+ */
+void gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h)
+{
+	u8 guid[sizeof(gpt_h->disk_guid.b)];
+	char *s;
+
+	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(1);
+	gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1);
+	gpt_h->first_usable_lba = cpu_to_le64(34);
+	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
+	gpt_h->partition_entry_lba = cpu_to_le64(2);
+	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;
+
+	s = getenv("uuid_gpt_disk");
+	if (!convert_uuid(s, gpt_h->disk_guid.b)) {
+		guid_gen((u32 *)gd->start_addr_sp, guid);
+		memcpy(gpt_h->disk_guid.b, guid, sizeof(efi_guid_t));
+	}
+}
+
+/**
+ * gpt_fill(): Fill the GPT header
+ *
+ * @param dev_desc - block device descriptor
+ * @param partitions - list of partitions
+ * @param parts - number of partitions
+ */
+void gpt_fill(block_dev_desc_t *dev_desc, disk_partition_t *partitions[],
+		const int parts_count)
+{
+	gpt_header *gpt_h = calloc(sizeof(gpt_header), 1);
+	gpt_entry *gpt_e = calloc(sizeof(gpt_entry), GPT_ENTRY_NUMBERS);
+
+	/* Generate Primary GPT header (LBA1) */
+	gpt_fill_header(dev_desc, gpt_h);
+	gpt_fill_pte(gpt_h, gpt_e, partitions, parts_count);
+
+	puts("save the GPT ...\n");
+	set_gpt_table(dev_desc, gpt_h, gpt_e);
+
+	free(gpt_e);
+	free(gpt_h);
+}
+
 /*
  * Private functions
  */
@@ -453,4 +656,143 @@ static int is_pte_valid(gpt_entry * pte)
 		return 1;
 	}
 }
+
+/**
+ * set_protective_mbr(): Set the EFI protective MBR
+ * @param dev_desc - block device descriptor
+ *
+ * @return - zero on success, otherwise error
+ */
+static int set_protective_mbr(block_dev_desc_t *dev_desc)
+{
+	legacy_mbr p_mbr;
+
+	/* Setup the Protective MBR */
+	memset((u32 *) &p_mbr, 0x00, sizeof(p_mbr));
+	/* Append signature */
+	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) dev_desc->lba;
+
+	/* Write MBR sector to the MMC device */
+	if (dev_desc->block_write(dev_desc->dev, 0, 1, &p_mbr) != 1) {
+		printf("** Can't write to device %d **\n",
+			dev_desc->dev);
+		return -1;
+	}
+
+	return 0;
+}
+
+#ifdef DEBUG
+/**
+ * guid_dump(): Dump guid content
+ *
+ * @param guid - pinter to guid
+ * @param i - number of bytes to dump
+ */
+static void guid_dump(u8 *guid, int i)
+{
+	int k;
+
+	debug("GUID: ");
+	for (k = 0; k < i; k++, guid++)
+		debug(" %x ", *guid);
+	debug("\n");
+}
+#else
+static void guid_dump(u8 *guid, int i) {}
+#endif
+
+/**
+ * guid_gen(): Generate UUID
+ *
+ * @param pool - pointer to pseudo random data (e.g. SP)
+ * @param guid - pointer to guid table
+ *
+ * @return - generated UUID table
+ *
+ * NOTE: The entrophy of this function is small
+ */
+static void guid_gen(const u32 *pool, u8 *guid)
+{
+	int k = 0;
+	u32 *ptr = (u32 *) guid;
+
+	debug("%s: pool: 0x%p guid: 0x%p\n", __func__, pool, guid);
+	for (k = 0; k < 4; k++)
+		*(ptr + k) = crc32((u32) pool, (const void *) (pool - k), 512);
+
+	guid_dump(guid, sizeof(efi_guid_t));
+}
+
+/**
+ * convert_uuid(); Convert UUID stored as string to bytes
+ *
+ * @param uuid - UUID represented as string
+ * @param dst - GUID buffer
+ *
+ * @return return 0 on successful conversion
+ */
+static int convert_uuid(char *uuid, u8 *dst)
+{
+	efi_guid_t guid;
+	u16 b, c, d;
+	u64 e;
+	u32 a;
+	u8 *p;
+	u8 i;
+
+	const u8 uuid_str_len = 36;
+
+	/* The UUID is written in text: */
+	/* 1        9    14   19   24 */
+	/* xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx */
+
+	debug("%s: uuid: %s\n", __func__, uuid);
+
+	if (strlen(uuid) != uuid_str_len)
+		return -1;
+
+	for (i = 0; i < uuid_str_len; i++) {
+		if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) {
+			if (uuid[i] != '-')
+				return -1;
+		} else {
+			if (!isxdigit(uuid[i]))
+				return -1;
+		}
+	}
+
+	a = (u32)simple_strtoul(uuid, NULL, 16);
+	b = (u16)simple_strtoul(uuid + 9, NULL, 16);
+	c = (u16)simple_strtoul(uuid + 14, NULL, 16);
+	d = (u16)simple_strtoul(uuid + 19, NULL, 16);
+	e = (u64)simple_strtoull(uuid + 24, NULL, 16);
+
+	p = (u8 *) &e;
+	guid = EFI_GUID(a, b, c, d >> 8, d & 0xFF,
+			*(p + 5), *(p + 4), *(p + 3),
+			*(p + 2), *(p + 1) , *p);
+
+	guid_dump(guid.b, sizeof(efi_guid_t));
+	memcpy(dst, guid.b, sizeof(efi_guid_t));
+
+	return 0;
+}
+
+static void set_part_name(efi_char16_t *part_name, char *name)
+{
+	int k, j;
+	char p[PARTNAME_SZ];
+
+	memset(p, 0x00, sizeof(p));
+	for (k = 0, j = 0; k < strlen(name); k++, j += 2) {
+		p[j] = *(name + k);
+		p[j + 1] = '.';
+	}
+	memcpy(part_name, p, strlen(p));
+}
+
 #endif
diff --git a/include/part.h b/include/part.h
index 27ea283..40e175a 100644
--- a/include/part.h
+++ b/include/part.h
@@ -176,10 +176,18 @@ int   test_part_amiga (block_dev_desc_t *dev_desc);
 #endif
 
 #ifdef CONFIG_EFI_PARTITION
+#include <part_efi.h>
 /* disk/part_efi.c */
 int get_partition_info_efi (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
 void print_part_efi (block_dev_desc_t *dev_desc);
 int   test_part_efi (block_dev_desc_t *dev_desc);
+int set_gpt_table(block_dev_desc_t *dev_desc,
+		  gpt_header *gpt_h, gpt_entry *gpt_e);
+void gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
+		disk_partition_t *partitions[], int parts);
+void gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h);
+void gpt_fill(block_dev_desc_t *dev_desc, disk_partition_t *partitions[],
+		const int parts_count);
 #endif
 
 #endif /* _PART_H */
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 6/7] gpt: Support for new "gpt" command
  2012-11-09 10:48   ` [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Piotr Wilczek
  2012-11-09 10:48     ` [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration Piotr Wilczek
@ 2012-11-09 10:48     ` Piotr Wilczek
  2012-11-19 21:34       ` Stephen Warren
  2012-11-09 10:48     ` [U-Boot] [PATCH v4 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats Piotr Wilczek
  2012-11-19 19:39     ` [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Stephen Warren
  3 siblings, 1 reply; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-09 10:48 UTC (permalink / raw)
  To: u-boot

New command - "gpt" is supported. It restores the GPT partition table.
It looks into the "partitions" environment variable for partitions definition.
It can be enabled at target configuration file with CONFIG_CMD_GPT.
Simple UUID generator has been implemented. It uses the the gd->start_addr_sp
for entrophy pool. Moreover the pool address is used as crc32 seed.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Piotr Wilczek <p.wilczek@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v2:
- gpt command now accepts device medium and its number (e.g. gpt mmc 0)
- UUIDs can be passed via u-boot prompt when used with gpt command
- Format of restored GPT has been changed - now key=value pairs are used
  'name="PARTS_CSA",size=8MiB;\ '
  'name="PARTS_BOOTLOADER",size=60MiB; \'
- guid_gen now accepts "pool" pointer and guid pointer
- gd->start_addr_sp is used as a primary source of entrophy
- static buffers definitions have been removed
- remove memsize_to_blocks function with call to standard ustrtoul
- doxygen comments for functions added

Changes for v3:
- Remove unnecessary braces

Changes for v4:
- partions list can be passed as environment variable or directly as text
- each value in partions list can be passed as environment variable
---
 common/Makefile  |    1 +
 common/cmd_gpt.c |  300 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 301 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_gpt.c

diff --git a/common/Makefile b/common/Makefile
index 9e43322..741781f 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -192,6 +192,7 @@ COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
 COBJS-$(CONFIG_UPDATE_TFTP) += update.o
 COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
 COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o
+COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o
 endif
 
 ifdef CONFIG_SPL_BUILD
diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
new file mode 100644
index 0000000..171eeb3
--- /dev/null
+++ b/common/cmd_gpt.c
@@ -0,0 +1,300 @@
+/*
+ * cmd_gpt.c -- GPT (GUID Partition Table) handling command
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * author: Lukasz Majewski <l.majewski@samsung.com>
+ * author: Piotr Wilczek <p.wilczek@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <command.h>
+#include <mmc.h>
+#include <part_efi.h>
+#include <exports.h>
+
+/**
+ * extract_env(): Convert string from '&{env_name}' to 'env_name'
+ *
+ * @param p - pointer to string
+ *
+ * @return - zero on success
+ */
+static int extract_env(char *p)
+{
+	char *p1, *p2;
+
+	if (!p)
+		return -1;
+
+	p1 = strstr(p, "${");
+	p2 = strstr(p, "}");
+
+	if (p1 && p2) {
+		*p2 = '\0';
+		memmove(p, p+2, p2-p1-1);
+	} else {
+		return -2;
+	}
+
+	return 0;
+}
+
+/**
+ * extract_val(): Extract value from a key=value pair
+ *
+ * @param p - pointer to string
+ * @param tab - table to store extracted value
+ * @param i - actual tab element to work on
+ * @param key - extract only given key
+ *
+ * @return - zero on success; otherwise error
+ */
+static int extract_val(char **p, char *tab[], int i, char *key)
+{
+	char *t, *e, *tok = *p;
+	char *k;
+
+	t = strsep(&tok, ",");
+	k = t;
+	strsep(&t, "=");
+
+	if (key && strcmp(k, key))
+		return -2;
+
+	if (extract_env(t) == 0) {
+		e = getenv(t);
+		if (e == NULL)
+			return -1;
+		t = e;
+	}
+
+	tab[i] = calloc(strlen(t) + 1, 1);
+	if (tab[i] == NULL) {
+		printf("%s: calloc failed!\n", __func__);
+		return -1;
+	}
+	strcpy(tab[i], t);
+	*p = tok;
+
+	return 0;
+}
+
+/**
+ * set_gpt_info(): Fill gpt information for GPT header and partition entries
+ *
+ * @param dev_desc - block device descriptor
+ * @param str_uuid - string uuid representation
+ *
+ * @return - zero on success; otherwise error
+ *
+ */
+static int set_gpt_info(block_dev_desc_t *dev_desc, char *str_part,
+	disk_partition_t *partitions[], const int parts_count)
+{
+	char *ps[parts_count];
+	char *name[parts_count];
+	char *uuid[parts_count];
+	unsigned int size[parts_count];
+	char *tok, *p, *s, *ss;
+	int i, ret;
+
+	debug("%s: MMC lba num: 0x%x %d\n", __func__,
+	      (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba);
+
+	if (!str_part)
+		return -2;
+	ret = 0;
+
+	s = str_part;
+
+	printf("PARTITIONS: %s\n", s);
+	ss = calloc(strlen(s) + 1, 1);
+	if (ss == NULL) {
+		printf("%s: calloc failed!\n", __func__);
+		return -1;
+	}
+	memcpy(ss, s, strlen(s) + 1);
+
+	for (i = 0, p = ss; i < parts_count; i++) {
+		tok = strsep(&p, ";");
+		if (tok == NULL)
+			break;
+
+		if (extract_val(&tok, name, i, "name")) {
+			ret = -1;
+			goto err;
+		}
+
+		if (extract_val(&tok, ps, i, "size")) {
+			ret = -1;
+			free(name[i]);
+			goto err;
+		}
+
+		if (extract_val(&tok, uuid, i, "uuid")) {
+			/* uuid string length equals 37 */
+			uuid[i] = calloc(37, 1);
+			if (uuid[i] == NULL) {
+				printf("%s: calloc failed!\n", __func__);
+				ret = -1;
+				free(name[i]);
+				free(ps[i]);
+				goto err;
+			}
+		}
+	}
+
+	printf("found %d partitions\n", i);
+
+	for (i = 0; i < parts_count; i++) {
+		p = ps[i];
+		size[i] = ustrtoul(p, &p, 0);
+		size[i] /= dev_desc->blksz;
+	}
+
+	for (i = 0; i < parts_count; i++) {
+		partitions[i]->size = size[i];
+		partitions[i]->blksz = dev_desc->blksz;
+		strncpy((char *)&partitions[i]->name, name[i],
+				sizeof(partitions[i]->name));
+#ifdef CONFIG_PARTITION_UUIDS
+		strncpy((char *)&partitions[i]->uuid, uuid[i],
+			sizeof(partitions[i]->uuid));
+#endif
+	}
+
+	i = parts_count;
+ err:
+	for (i--; i >= 0; i--) {
+		free(name[i]);
+		free(uuid[i]);
+		free(ps[i]);
+	}
+
+	free(ss);
+	return ret;
+}
+
+static int gpt_mmc_default(int dev, char *str_part)
+{
+	int i;
+	u8 part_count;
+	char *s , *p;
+
+	struct mmc *mmc = find_mmc_device(dev);
+
+	if (mmc == NULL) {
+		printf("%s: mmc dev %d NOT available\n", __func__, dev);
+		return CMD_RET_FAILURE;
+	}
+
+	puts("Using default GPT UUID\n");
+
+	/* get partitions list string */
+	if (!str_part)
+#ifdef DEFAULT_PARTITIONS_ENV
+		str_part = DEFAULT_PARTITIONS_ENV;
+#else
+		str_part = "partitions";
+#endif
+	s = getenv(str_part);
+	if (s == NULL)
+		s = str_part;
+
+	/* calculate expected number of partitions */
+	part_count = 1;
+	p = s;
+	while (*p) {
+		if (*p++ == ';')
+			part_count++;
+	}
+
+	/* allocate memory for partitions */
+	disk_partition_t *partitions[part_count];
+	for (i = 0; i < part_count; i++) {
+		partitions[i] = calloc(sizeof(disk_partition_t), part_count);
+		if (partitions[i] == NULL)
+			goto err;
+	}
+
+	/* fill partitions */
+	if (!set_gpt_info(&mmc->block_dev, s, partitions, part_count))
+		/* save partions layout do disk */
+		gpt_fill(&mmc->block_dev, partitions, part_count);
+	else
+		printf("Partitions list incomplete\n");
+
+err:
+	/* free memory for partitions */
+	for (i--; i >= 0; i--)
+		free(partitions[i]);
+
+	return 0;
+}
+
+/**
+ * do_gpt(): Perform GPT operations
+ *
+ * @param cmdtp - command name
+ * @param flag
+ * @param argc
+ * @param argv
+ *
+ * @return zero on success; otherwise error
+ */
+static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int ret = CMD_RET_SUCCESS;
+	char *str_part = NULL;
+	int dev = 0;
+
+	if (argc < 3)
+		return CMD_RET_USAGE;
+
+	if (argc == 4) {
+		str_part = strdup(argv[3]);
+		if (!str_part) {
+			printf("%s: malloc failed!\n", __func__);
+			return CMD_RET_FAILURE;
+		}
+	}
+
+	if (strcmp(argv[1], "mmc") == 0) {
+		dev = (int)simple_strtoul(argv[2], NULL, 10);
+		if (gpt_mmc_default(dev, str_part))
+			return CMD_RET_FAILURE;
+	}
+
+	if (argc == 4)
+		free(str_part);
+
+	return ret;
+}
+
+U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
+	"GUID Partition Table",
+	"<interface> <dev> <partions list>\n"
+	" partions list is in format: name=..,size=..,uuid=..;...\n"
+	" and can be passed as env or string ex.:\n"
+	"    gpt mmc 0 partitions\n"
+	"    gpt mmc 0 \"name=..,size=..;name=..,size=..;...\"\n"
+	"    gpt mmc 0 \"name=${part1_name},size=..;name=..,size=..;...\"\n"
+	" - GUID partition table restoration\n"
+	" Restore GPT information on a device connected\n"
+	" to interface\n"
+);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats
  2012-11-09 10:48   ` [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Piotr Wilczek
  2012-11-09 10:48     ` [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration Piotr Wilczek
  2012-11-09 10:48     ` [U-Boot] [PATCH v4 6/7] gpt: Support for new "gpt" command Piotr Wilczek
@ 2012-11-09 10:48     ` Piotr Wilczek
  2012-11-19 19:39     ` [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Stephen Warren
  3 siblings, 0 replies; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-09 10:48 UTC (permalink / raw)
  To: u-boot

From: Lukasz Majewski <l.majewski@samsung.com>

Enable support for GPT partition table restoration at Samsung's Trats
development board.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
CC: Minkyu Kang <mk7.kang@samsung.com>
---
Changes for v2:
- New format for default GPT partitions (key=value pairs)
- replace size definitions with more readable description(1GiB instead of 1G)

Changes for v3:
- None

Changes for v4:
- Modified default partitions list
---
 include/configs/trats.h |   29 ++++++++++++++++++++++++++++-
 1 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/include/configs/trats.h b/include/configs/trats.h
index d7808aa..05e71c4 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -98,6 +98,7 @@
 #undef CONFIG_CMD_MTDPARTS
 #define CONFIG_CMD_MMC
 #define CONFIG_CMD_DFU
+#define CONFIG_CMD_GPT
 
 /* FAT */
 #define CONFIG_CMD_FAT
@@ -122,6 +123,25 @@
 #define CONFIG_BOOTBLOCK		"10"
 #define CONFIG_ENV_COMMON_BOOT		"${console} ${meminfo}"
 
+/* Tizen - partitions definitions */
+#define PARTS_CSA		"csa-mmc"
+#define PARTS_BOOTLOADER	"u-boot"
+#define PARTS_BOOT		"boot"
+#define PARTS_ROOT		"platform"
+#define PARTS_DATA		"data"
+#define PARTS_CSC		"csc"
+#define PARTS_UMS		"ums"
+
+#define PARTS_DEFAULT \
+	"name="PARTS_CSA",size=8MiB,uuid=${uuid_gpt_"PARTS_CSA"};" \
+	"name="PARTS_BOOTLOADER",size=60MiB," \
+		"uuid=${uuid_gpt_"PARTS_BOOTLOADER"};" \
+	"name="PARTS_BOOT",size=100MiB,uuid=${uuid_gpt_"PARTS_BOOT"};" \
+	"name="PARTS_ROOT",size=1GiB,uuid=${uuid_gpt_"PARTS_ROOT"};" \
+	"name="PARTS_DATA",size=3GiB,uuid=${uuid_gpt_"PARTS_DATA"};" \
+	"name="PARTS_CSC",size=150MiB,uuid=${uuid_gpt_"PARTS_CSC"};" \
+	"name="PARTS_UMS",size=-,uuid=${uuid_gpt_"PARTS_UMS"}\0" \
+
 #define CONFIG_DFU_ALT \
 	"dfu_alt_info=" \
 	"u-boot mmc 80 400;" \
@@ -171,7 +191,9 @@
 	"mmcbootpart=2\0" \
 	"mmcrootpart=3\0" \
 	"opts=always_resume=1\0" \
-	CONFIG_DFU_ALT
+	"uuid_gpt_disk=\0" \
+	"partitions=" PARTS_DEFAULT \
+	CONFIG_DFU_ALT \
 
 /* Miscellaneous configurable options */
 #define CONFIG_SYS_LONGHELP		/* undef to save memory */
@@ -208,6 +230,11 @@
 
 #define CONFIG_DOS_PARTITION
 
+/* GPT */
+#define CONFIG_EFI_PARTITION
+#define CONFIG_PARTITION_UUIDS
+#define DEFAULT_PARTITIONS_ENV "partitions"
+
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE)
 #define CONFIG_SYS_CACHELINE_SIZE       32
 
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 1/7] vsprintf:fix: Change type returned by ustrtoul
  2012-11-09  9:22   ` [U-Boot] [PATCH v4 1/7] vsprintf:fix: Change type returned by ustrtoul Piotr Wilczek
@ 2012-11-19 19:19     ` Stephen Warren
  0 siblings, 0 replies; 95+ messages in thread
From: Stephen Warren @ 2012-11-19 19:19 UTC (permalink / raw)
  To: u-boot

On 11/09/2012 02:22 AM, Piotr Wilczek wrote:
> From: Lukasz Majewski <l.majewski@samsung.com>
> 
> The ustrtoul shall convert string defined size (e.g. 1GiB) to unsigned
> long type (as its name implies).
> 
> Up till now it had returned int, which might cause problems with large
> numbers (GiB range), when interpreted as U2 signed numbers.

Reviewed-by: Stephen Warren <swarren@nvidia.com>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 3/7] gpt:doc: GPT (GUID Partition Table) documentation
  2012-11-09  9:22   ` [U-Boot] [PATCH v4 3/7] gpt:doc: GPT (GUID Partition Table) documentation Piotr Wilczek
@ 2012-11-19 19:28     ` Stephen Warren
  0 siblings, 0 replies; 95+ messages in thread
From: Stephen Warren @ 2012-11-19 19:28 UTC (permalink / raw)
  To: u-boot

On 11/09/2012 02:22 AM, Piotr Wilczek wrote:
> Documentation of the GPT format.

> diff --git a/doc/README.gpt b/doc/README.gpt

> +Introduction:
> +=============
> +This document describes the GPT partition table format when used with u-boot.


Why "when used with U-Boot"; U-Boot shouldn't influence the GPT
structure at all.

> +GPT for marking disks/partitions is using the UUID. It is supposed to be a
> +globally unique value. A UUID is a 16-byte (128-bit) number. The number of
> +theoretically possible UUIDs is therefore about 3 ? 10^38.
> +More often UUID is stored as 32 hexadecimal digits, displayed in 5 groups

I don't think "stored" is too likely; "displayed" is more likely.

> +Example usage:
> +==============

I would change that headline to something like "Creating GPTs in
U-Boot"; all the text above describes the GPT format itself, whereas
this text describes the specifics of some U-Boot commands, and so is not
an example of the preceding text.

> +To restore GUID partition table one needs to:
> +1. at ./include/configs/{board}.h

I don't think "at ./include/configs/{board}.h" is correct; you need to
define the partitions variable in the environment. The config file is
one way you could do this. I would re-write this as:

1. Define partition layout in the environment.
./include/configs/{board}.h may provide a value that describes the
recommended layout if desired.

> +   - define "partitions=" environment variable with format:
> +     "name=..,size=..,uuid=..;..."
> +     values for every key can be passed as text or environment variable
> +     examples:
> +     "name=u-boot,size=60M;name=kernel,size=60M;name=platform,size=1G;"
> +     "name=${uboot_name},size=${uboot_size},uuid=${uboot_uuid};..."
> +
> +2. From u-boot prompt type:
> +   gpt mmc 0
> +   or
> +   gpt mmc 0 partitions

Shouldn't that be "${partitions}" not "partitions"?

> +For "emergency" usage (or when list of UUIDs cannot be provided)  the internal
> +GUID generator shall be used. It uses gd->start_addr_sp as a primary source of
> +UUID generator (16B).

What does "(16B)" mean here?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 2/7] part:efi: Move part_efi.h file to ./include
  2012-11-09  9:22   ` [U-Boot] [PATCH v4 2/7] part:efi: Move part_efi.h file to ./include Piotr Wilczek
@ 2012-11-19 19:30     ` Stephen Warren
  2012-11-19 20:41       ` Tom Rini
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-11-19 19:30 UTC (permalink / raw)
  To: u-boot

On 11/09/2012 02:22 AM, Piotr Wilczek wrote:
> From: Lukasz Majewski <l.majewski@samsung.com>
> 
> This move is necessary to export gpt header and GPT partition entries to be
> used with other commands or subsystems (like DFU in the future)
> Additionally the part_efi.h file has been cleaned-up to supress checkpatch's
> warnings.

>  {disk => include}/part_efi.h |    0

I can understand the "gpt" command perhaps needing access to the
GPT-specific types, but I would hope that anything DFU-related would be
using types from include/part.h; I don't imagine that DFU would need to
know anything about GPT at all?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h>
  2012-11-09 10:48   ` [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Piotr Wilczek
                       ` (2 preceding siblings ...)
  2012-11-09 10:48     ` [U-Boot] [PATCH v4 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats Piotr Wilczek
@ 2012-11-19 19:39     ` Stephen Warren
  3 siblings, 0 replies; 95+ messages in thread
From: Stephen Warren @ 2012-11-19 19:39 UTC (permalink / raw)
  To: u-boot

On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
> Custom definitions of le_XX_to_int functions have been replaced with
> standard ones, defined at <compiler.h>
> 
> Replacement of several GPT related structures members with ones
> indicating its endianness and proper size.

> diff --git a/disk/part_efi.c b/disk/part_efi.c

>  		printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1),
> -			le64_to_int(gpt_pte[i].starting_lba),
> -			le64_to_int(gpt_pte[i].ending_lba),
> +			(u64) le64_to_cpu(gpt_pte[i].starting_lba),
> +			(u64) le64_to_cpu(gpt_pte[i].ending_lba),

I don't think there should be a space after the cast. Why doesn't
le64_to_cpu() return a u64? The same comments apply to many diffs in
this patch.

> -	if (calc_crc32 != le32_to_int(crc32_backup)) {
> +	if (calc_crc32 != le32_to_cpu(crc32_backup)) {
>  		printf("GUID Partition Table Header CRC is wrong:"
> -			"0x%08lX != 0x%08lX\n",
> -			le32_to_int(crc32_backup), calc_crc32);
> +			"0x%x != 0x%x\n",
> +		       (u32) le32_to_cpu(crc32_backup), calc_crc32);

Indentation looks wrong (some lines use spaces, some TABs).

> -	if (calc_crc32 != le32_to_int(pgpt_head->partition_entry_array_crc32)) {
> +	if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) {
>  		printf("GUID Partition Table Entry Array CRC is wrong:"
> -			"0x%08lX != 0x%08lX\n",
> -			le32_to_int(pgpt_head->partition_entry_array_crc32),
> +			"0x%x != 0x%x\n",
> +		       (u32)le32_to_cpu(pgpt_head->partition_entry_array_crc32),

Same here.

Aside from that, briefly,
Reviewed-by: Stephen Warren <swarren@nvidia.com>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-11-09 10:48     ` [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration Piotr Wilczek
@ 2012-11-19 20:16       ` Stephen Warren
  2012-11-21 13:18         ` Piotr Wilczek
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-11-19 20:16 UTC (permalink / raw)
  To: u-boot

On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
> The restoration of GPT table (both primary and secondary) is now possible.
> Simple GUID generation is supported.

> diff --git a/include/part.h b/include/part.h

> +int set_gpt_table(block_dev_desc_t *dev_desc,
> +		  gpt_header *gpt_h, gpt_entry *gpt_e);
> +void gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
> +		disk_partition_t *partitions[], int parts);
> +void gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h);

> +void gpt_fill(block_dev_desc_t *dev_desc, disk_partition_t *partitions[],
> +		const int parts_count);

Why const?

Some documentation for these functions (particularly high-level
information such as which order you'd expect to call them and why/what
for) would be useful in the header rather than the .c file; the header
is where people would go to find out what functions they can call, so
making them also go look in the .c file would be a bit annoying.

> diff --git a/disk/part_efi.c b/disk/part_efi.c

> +static int set_protective_mbr(block_dev_desc_t *dev_desc);
> +
> +static void guid_dump(u8 *guid, int i);
> +
> +static void guid_gen(const u32 *pool, u8 *guid);
> +
> +static int convert_uuid(char *uuid, u8 *dst);
> +
> +static void set_part_name(efi_char16_t *part_name, char *name);

There probably should be a CONFIG_ option required to enable this new
feature, so people who don't want it don't suffer code bloat.

Do you really need the blank lines between prototypes?

I suspect you can re-order the functions so that none of the prototypes
are needed anyway.

> +/**
> + * set_gpt_table() - Restore the GUID Partition Table

"write" would probably be better than "set".

> + *
> + * @param dev_desc - block device descriptor
> + * @param parts - number of partitions
> + * @param size - pointer to array with each partition size
> + * @param name - pointer to array with each partition name

Those last 3 lines don't match the prototype.

> + * @return - zero on success, otherwise error
> + */
> +int set_gpt_table(block_dev_desc_t *dev_desc,
> +		  gpt_header *gpt_h, gpt_entry *gpt_e)

Presumably the code assumes that gpt_e always has 128(?) entries.
Instead of taking a pointer, should the function take an array:
gpt_entry gpt_e[GPT_ENTRY_NUMBERS] to enforce this?

> +{
> +	const int pte_blk_num = (GPT_ENTRY_NUMBERS * sizeof(gpt_entry)) /
> +		dev_desc->blksz;

Related, this hard-codes the number of ptes as GPT_ENTRY_NUMBERS,
whereas ...

> +	u32 calc_crc32;
> +	u64 val;
> +
> +	debug("max lba: %x\n", (u32) dev_desc->lba);
> +	/* Setup the Protective MBR */
> +	if (set_protective_mbr(dev_desc) < 0)
> +		goto err;
> +
> +	/* 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));

... here, gpt_h->num_partition_entries is used instead. Should both
places use the same size (entry count) definition?

> +	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e)
> +	    != pte_blk_num)
> +		goto err;

Here, we assume GPT_ENTRY_NUMBERS entries in gpt_e. If the array isn't
that big, the block_write() above will read past the end of it.

> +	puts("GPT successfully written to block device!\n");

Isn't that something that a command should be doing, not a utility
function? I'd rather have this function not print anything, except
perhaps on errors, just like typical Unix command-line applications.

> +void gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
> +		disk_partition_t *partitions[], int parts)

Why is partitions an array of pointers rather than an array of partitions?

> +{
> +	u32 offset = (u32) le32_to_cpu(gpt_h->first_usable_lba);

I don't think there should be a space after the cast. The same comment
probably applies elsewhere.

> +	for (i = 0; i < parts; i++) {
> +		/* partition starting lba */
> +		start = partitions[i]->start;
> +		if (start && (offset <= start))
> +			gpt_e[i].starting_lba = cpu_to_le32(start);
> +		else
> +			gpt_e[i].starting_lba = cpu_to_le32(offset);

That seems a little odd. The else branch seems fine when !start, but
what about when (start && (offset > start))? Shouldn't that be an error,
rather than just ignoring the requested start value?

Why can't partitions be out of order? IIRC, the GPT spec allows it.

> +		/* partition ending lba */
> +		if (i != parts - 1)
> +			gpt_e[i].ending_lba =
> +				cpu_to_le64(offset - 1);
> +		else
> +			gpt_e[i].ending_lba = gpt_h->last_usable_lba;

Why extend the last partition to fill the disk; why not simply always
use the requested size? If a "fill to max size" option is implemented,
the user might not want it to apply to the last partition, but perhaps
some arbitrary partition in the middle of the list.

> +		/* partition type GUID*/
> +		memcpy(gpt_e[i].partition_type_guid.b,
> +			&PARTITION_BASIC_DATA_GUID, 16);

Shouldn't that be a user-specifiable option too? I suppose we could add
that later.

> +		str_uuid = NULL;
> +#ifdef CONFIG_PARTITION_UUIDS
> +		str_uuid = partitions[i]->uuid;
> +#endif

I think it should be required to enable that feature if creating GPTs;
writing a GPT without a value UUID seems wrong.

> +		if (convert_uuid(str_uuid, gpt_e[i].unique_partition_guid.b)) {
> +			guid_gen((((u32 *) gd->start_addr_sp) - i - 1),
> +				guid);
> +			memcpy(gpt_e[i].unique_partition_guid.b, guid,
> +			       sizeof(efi_guid_t));
> +		}

Shouldn't there be a difference between no specified UUID, and an error
converting a specified UUID?

> +		/* partition attributes */
> +		memset(&gpt_e[i].attributes, 0,
> +		       sizeof(gpt_entry_attributes));

(Perhaps in the future) We should allow specifying attributes too.

> +void gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h)

> +	gpt_h->first_usable_lba = cpu_to_le64(34);
> +	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);

Is lba the number of LBAs or the last LBA number? include/part.h says
its the number of LBAs, in which case I think that should be
dev_desc->lba - 1 - 34?

> +	s = getenv("uuid_gpt_disk");

I'd rather not depend on environment variables; can't this be a
command-line parameter to the gpt command?

> +void gpt_fill(block_dev_desc_t *dev_desc, disk_partition_t *partitions[],
> +		const int parts_count)

Rename to gpt_write()?

> +	puts("save the GPT ...\n");

Again, why print anything here?

> +	set_gpt_table(dev_desc, gpt_h, gpt_e);

Oh, so is set_gpt_table() an internal-only function? If so, shouldn't it
be static and not in the header file?

> +static int set_protective_mbr(block_dev_desc_t *dev_desc)
> +{
> +	legacy_mbr p_mbr;
> +
> +	/* Setup the Protective MBR */
> +	memset((u32 *) &p_mbr, 0x00, sizeof(p_mbr));

Why use a stack variable and memset() here, but use calloc() in
gpt_fill() above? That seems inconsistent.

> +#ifdef DEBUG
> +static void guid_dump(u8 *guid, int i)
> +{
> +	int k;
> +
> +	debug("GUID: ");
> +	for (k = 0; k < i; k++, guid++)
> +		debug(" %x ", *guid);
> +	debug("\n");
> +}
> +#else
> +static void guid_dump(u8 *guid, int i) {}
> +#endif

Wouldn't using the existing uuid_string be better?

> +static int convert_uuid(char *uuid, u8 *dst)

It's not too clear from the function name what kind of conversion is
being applied. string_uuid() would be more consistent with the existing
uuid_string(), or perhaps even better string_to_uuid().

> +static void set_part_name(efi_char16_t *part_name, char *name)

> +	for (k = 0, j = 0; k < strlen(name); k++, j += 2) {
> +		p[j] = *(name + k);
> +		p[j + 1] = '.';

Not '\0'?

> +	}
> +	memcpy(part_name, p, strlen(p));

Why not write directly to part_name?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 2/7] part:efi: Move part_efi.h file to ./include
  2012-11-19 19:30     ` Stephen Warren
@ 2012-11-19 20:41       ` Tom Rini
  2012-11-20 17:46         ` Lukasz Majewski
  0 siblings, 1 reply; 95+ messages in thread
From: Tom Rini @ 2012-11-19 20:41 UTC (permalink / raw)
  To: u-boot

On Mon, Nov 19, 2012 at 12:30:02PM -0700, Stephen Warren wrote:
> On 11/09/2012 02:22 AM, Piotr Wilczek wrote:
> > From: Lukasz Majewski <l.majewski@samsung.com>
> > 
> > This move is necessary to export gpt header and GPT partition entries to be
> > used with other commands or subsystems (like DFU in the future)
> > Additionally the part_efi.h file has been cleaned-up to supress checkpatch's
> > warnings.
> 
> >  {disk => include}/part_efi.h |    0
> 
> I can understand the "gpt" command perhaps needing access to the
> GPT-specific types, but I would hope that anything DFU-related would be
> using types from include/part.h; I don't imagine that DFU would need to
> know anything about GPT at all?

Indeed.  DFU must not get coupled to GPT (or for that matter,
partitions) in the general code.  There should be "DFU write to a
GPT-using backing store" code, if that's needed.  Not all eMMC would be
GPT-using, for example.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20121119/585a5e55/attachment.pgp>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration
  2012-11-09  9:22 ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Piotr Wilczek
                     ` (3 preceding siblings ...)
  2012-11-09 10:48   ` [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Piotr Wilczek
@ 2012-11-19 20:43   ` Tom Rini
  2012-12-06 20:40   ` Tom Rini
  5 siblings, 0 replies; 95+ messages in thread
From: Tom Rini @ 2012-11-19 20:43 UTC (permalink / raw)
  To: u-boot

On Fri, Nov 09, 2012 at 10:22:11AM +0100, Piotr Wilczek wrote:

> This patch series provides a new command - "gpt" for eMMC partition table
> (in the GPT format) restoration.
> 
> As a pre-work, some cleanup at the part_efi.c file was performed to
> remove custom macros and make GPT related structures more readable.
> 
> Moreover the part_efi.h file has been moved to ./include directory to
> be easily available from other subsystems.
> 
> The GPT detailed description has been written to README.gpt file.

Please make sure that 0/7 of v5 includes the summary of changes from v4
(and from v3 and v2 and ...).  patman helps you get this for free, btw
:)  Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20121119/1b02de87/attachment.pgp>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 6/7] gpt: Support for new "gpt" command
  2012-11-09 10:48     ` [U-Boot] [PATCH v4 6/7] gpt: Support for new "gpt" command Piotr Wilczek
@ 2012-11-19 21:34       ` Stephen Warren
  2012-11-21 11:22         ` Piotr Wilczek
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-11-19 21:34 UTC (permalink / raw)
  To: u-boot

On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
> New command - "gpt" is supported. It restores the GPT partition table.
> It looks into the "partitions" environment variable for partitions definition.
> It can be enabled at target configuration file with CONFIG_CMD_GPT.
> Simple UUID generator has been implemented. It uses the the gd->start_addr_sp
> for entrophy pool. Moreover the pool address is used as crc32 seed.

> diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c

> +U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
> +	"GUID Partition Table",
> +	"<interface> <dev> <partions list>\n"
> +	" partions list is in format: name=..,size=..,uuid=..;...\n"
> +	" and can be passed as env or string ex.:\n"
> +	"    gpt mmc 0 partitions\n"

I don't think that form makes sense. The user should just pass
"${partitions}" instead. The command can't know for certain whether the
user actually intended to pass the text "partitions" and made a mistake,
or whether they passed an environment variable. If you really want to be
able to pass an environment variable name, an explicit command-line
option such as:

gpt mmc 0 name=...                      # definition on cmd-line
gpt mmc 0 --from-environment partitions # definition in environment

seems best.

> +	"    gpt mmc 0 \"name=..,size=..;name=..,size=..;...\"\n"
> +	"    gpt mmc 0 \"name=${part1_name},size=..;name=..,size=..;...\"\n"
> +	" - GUID partition table restoration\n"
> +	" Restore GPT information on a device connected\n"
> +	" to interface\n"

Is writing a GPT to a device the only thing the gpt command will ever
do. It seems best to require the user to write "gpt write mmc 0 ..."
from the very start, so that if e.g. "gpt fix-crcs" or "gpt
interactive-edit" or "gpt delete-partition 5" are implemented in the
future, existing scripts won't have to change to add the "write" parameter.

> +/**
> + * extract_env(): Convert string from '&{env_name}' to 'env_name'

s/&/$/

It's doing more than that; it locates that syntax within an arbitrary
string and ignores anything before "${" or after "}". Is that intentional?

> +static int extract_env(char *p)

> +	p1 = strstr(p, "${");
> +	p2 = strstr(p, "}");
> +
> +	if (p1 && p2) {
> +		*p2 = '\0';
> +		memmove(p, p+2, p2-p1-1);

s/-1/-2/ I think, since the length of "${" is 2 not 1.

Spaces around operators? s/p+2/p + 2/ for example.

> +/**
> + * extract_val(): Extract value from a key=value pair
> + *
> + * @param p - pointer to string

Pointer to pointer to string, given its type?

> + * @param tab - table to store extracted value
> + * @param i - actual tab element to work on

Table? Why not just pass in char **tab and get rid of "i".

> +static int extract_val(char **p, char *tab[], int i, char *key)
> +{
> +	char *t, *e, *tok = *p;
> +	char *k;

Those variable names are not exactly descriptive.

> +	t = strsep(&tok, ",");
> +	k = t;
> +	strsep(&t, "=");
> +
> +	if (key && strcmp(k, key))
> +		return -2;
> +
> +	if (extract_env(t) == 0) {

Hmm. That only allows key=${value}. What about key=text${envothertext or
key=${env1}foo${env2}? Isn't there some generic code that can already
expand environment variables within strings so we don't have to
re-invent it here?

> +	tab[i] = calloc(strlen(t) + 1, 1);
> +	if (tab[i] == NULL) {
> +		printf("%s: calloc failed!\n", __func__);
> +		return -1;
> +	}
> +	strcpy(tab[i], t);

Isn't strdup() available?

> +static int set_gpt_info(block_dev_desc_t *dev_desc, char *str_part,
> +	disk_partition_t *partitions[], const int parts_count)
> +{
> +	char *ps[parts_count];

Can we call this sizes? Can't we call strtoul() and store int sizes[]
rather than storing the strings first and then converting to integers in
a separate piece of disconnected code?

> +	printf("PARTITIONS: %s\n", s);

Why print that?

> +	ss = calloc(strlen(s) + 1, 1);
> +	if (ss == NULL) {
> +		printf("%s: calloc failed!\n", __func__);
> +		return -1;
> +	}
> +	memcpy(ss, s, strlen(s) + 1);

Use strdup().

That duplicates the strdup() in do_gpt() some of the time.

> +	for (i = 0, p = ss; i < parts_count; i++) {

Why not calculate parts_count here, rather than splitting the parsing
logic between this function and gpt_mmc_default()?

> +		tok = strsep(&p, ";");
> +		if (tok == NULL)
> +			break;
> +
> +		if (extract_val(&tok, name, i, "name")) {
> +			ret = -1;
> +			goto err;
> +		}
> +
> +		if (extract_val(&tok, ps, i, "size")) {
> +			ret = -1;
> +			free(name[i]);
> +			goto err;
> +		}

I think that requires the parameters to be passed in order
name=foo,size=5,uuid=xxx. That seems inflexible. The syntax may as well
just be value,value,value rather than key=value,key=value,key=value in
that case (although the keys are useful in order to understand the data,
so I'd prefer parsing flexibility rather than removing key=).

> +		if (extract_val(&tok, uuid, i, "uuid")) {
> +			/* uuid string length equals 37 */
> +			uuid[i] = calloc(37, 1);

Shouldn't storage for the UUID always be allocated? After all, one must
always be written even if the user didn't explicitly specify one, so
U-Boot makes it up.

> +		p = ps[i];
> +		size[i] = ustrtoul(p, &p, 0);
> +		size[i] /= dev_desc->blksz;

What if the size isn't rounded correctly?

> +	for (i = 0; i < parts_count; i++) {
> +		partitions[i]->size = size[i];
> +		partitions[i]->blksz = dev_desc->blksz;

Why not just write to partitions[] directly in the first place instead
of using temporary variables and then copying them?

> +static int gpt_mmc_default(int dev, char *str_part)

> +	struct mmc *mmc = find_mmc_device(dev);
> +
> +	if (mmc == NULL) {
> +		printf("%s: mmc dev %d NOT available\n", __func__, dev);
> +		return CMD_RET_FAILURE;
> +	}

Why is this tied to MMC; shouldn't it work for e.g. USB storage as well?
Use get_device_and_partition() instead.

> +	puts("Using default GPT UUID\n");

Even when the user explicitly supplied a partition layout on the
command-line? Why print anything at all?

> +	/* allocate memory for partitions */
> +	disk_partition_t *partitions[part_count];

Don't variable declarations have to be at the start of a block in U-Boot?

> +static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	int ret = CMD_RET_SUCCESS;
> +	char *str_part = NULL;
> +	int dev = 0;
> +
> +	if (argc < 3)
> +		return CMD_RET_USAGE;
> +
> +	if (argc == 4) {
> +		str_part = strdup(argv[3]);
> +		if (!str_part) {
> +			printf("%s: malloc failed!\n", __func__);
> +			return CMD_RET_FAILURE;
> +		}
> +	}

The help text doesn't indicate that any of the command parameters are
optional...

Why does this need to strdup() anything anyway?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 2/7] part:efi: Move part_efi.h file to ./include
  2012-11-19 20:41       ` Tom Rini
@ 2012-11-20 17:46         ` Lukasz Majewski
  0 siblings, 0 replies; 95+ messages in thread
From: Lukasz Majewski @ 2012-11-20 17:46 UTC (permalink / raw)
  To: u-boot

Hi Tom,

> On Mon, Nov 19, 2012 at 12:30:02PM -0700, Stephen Warren wrote:
> > On 11/09/2012 02:22 AM, Piotr Wilczek wrote:
> > > From: Lukasz Majewski <l.majewski@samsung.com>
> > > 
> > > This move is necessary to export gpt header and GPT partition
> > > entries to be used with other commands or subsystems (like DFU in
> > > the future) Additionally the part_efi.h file has been cleaned-up
> > > to supress checkpatch's warnings.
> > 
> > >  {disk => include}/part_efi.h |    0
> > 
> > I can understand the "gpt" command perhaps needing access to the
> > GPT-specific types, but I would hope that anything DFU-related
> > would be using types from include/part.h; I don't imagine that DFU
> > would need to know anything about GPT at all?
> 
> Indeed.  DFU must not get coupled to GPT (or for that matter,
> partitions) in the general code.  There should be "DFU write to a
> GPT-using backing store" code, if that's needed.  Not all eMMC would
> be GPT-using, for example.
> 

Yes, the commit description is now a bit misleading. 
The idea here is to have access to part_efi.h from gpt command.

DFU will use higher level of abstraction (as Stephen once suggested).

-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 6/7] gpt: Support for new "gpt" command
  2012-11-19 21:34       ` Stephen Warren
@ 2012-11-21 11:22         ` Piotr Wilczek
  2012-11-24 18:00           ` Stephen Warren
  0 siblings, 1 reply; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-21 11:22 UTC (permalink / raw)
  To: u-boot

Dear Stephen,

> -----Original Message-----
> From: Stephen Warren [mailto:swarren at wwwdotorg.org]
> Sent: Monday, November 19, 2012 10:35 PM
> To: Piotr Wilczek
> Cc: u-boot at lists.denx.de; Minkyu Kang; Kyungmin Park; Chang Hyun Park;
> Lukasz Majewski; Stephen Warren; Tom Rini; Rob Herring
> Subject: Re: [PATCH v4 6/7] gpt: Support for new "gpt" command
> 
> On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
> > New command - "gpt" is supported. It restores the GPT partition
> table.
> > It looks into the "partitions" environment variable for partitions
> definition.
> > It can be enabled at target configuration file with CONFIG_CMD_GPT.
> > Simple UUID generator has been implemented. It uses the the
> > gd->start_addr_sp for entrophy pool. Moreover the pool address is
> used as crc32 seed.
> 
> > diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
> 
> > +U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
> > +	"GUID Partition Table",
> > +	"<interface> <dev> <partions list>\n"
> > +	" partions list is in format: name=..,size=..,uuid=..;...\n"
> > +	" and can be passed as env or string ex.:\n"
> > +	"    gpt mmc 0 partitions\n"
> 
> I don't think that form makes sense. The user should just pass
> "${partitions}" instead. The command can't know for certain whether the
> user actually intended to pass the text "partitions" and made a
> mistake, or whether they passed an environment variable. If you really
> want to be able to pass an environment variable name, an explicit
> command-line option such as:
> 
> gpt mmc 0 name=...                      # definition on cmd-line
> gpt mmc 0 --from-environment partitions # definition in environment
> 
> seems best.
> 
The intention was that the command automatically figures out whether user
passed environmental variable or directly partitions as text. Then the
command splits this string, checks if it is a valid partitions list and if
so the table is written to mmc. That is how the code is supposed to work.

The question here is, if it should work like that. If it is desired that
user explicitly states that the partitions list is passed from
environmental, then I should change the code.

> > +	"    gpt mmc 0 \"name=..,size=..;name=..,size=..;...\"\n"
> > +	"    gpt mmc 0
> \"name=${part1_name},size=..;name=..,size=..;...\"\n"
> > +	" - GUID partition table restoration\n"
> > +	" Restore GPT information on a device connected\n"
> > +	" to interface\n"
> 
> Is writing a GPT to a device the only thing the gpt command will ever
> do. It seems best to require the user to write "gpt write mmc 0 ..."
> from the very start, so that if e.g. "gpt fix-crcs" or "gpt
> interactive-edit" or "gpt delete-partition 5" are implemented in the
> future, existing scripts won't have to change to add the "write"
> parameter.
> 
I agree that the parameter "write" should be implemented.

> > +/**
> > + * extract_env(): Convert string from '&{env_name}' to 'env_name'
> 
> s/&/$/
> 
> It's doing more than that; it locates that syntax within an arbitrary
> string and ignores anything before "${" or after "}". Is that
> intentional?
> 
Yes, it was. The u-boot's shell expands to one only, so it allow to pass any
partition parameter as env when the partitions list itself is passed as env.

> > +static int extract_env(char *p)
> 
> > +	p1 = strstr(p, "${");
> > +	p2 = strstr(p, "}");
> > +
> > +	if (p1 && p2) {
> > +		*p2 = '\0';
> > +		memmove(p, p+2, p2-p1-1);
> 
> s/-1/-2/ I think, since the length of "${" is 2 not 1.
> 
p2-p1-1 gives length of the env name + trailing zero.
p2-p1-2 would give only the env's length and the trailing zero wouldn't be
moved.

> Spaces around operators? s/p+2/p + 2/ for example.
> 
Yes

> > +/**
> > + * extract_val(): Extract value from a key=value pair
> > + *
> > + * @param p - pointer to string
> 
> Pointer to pointer to string, given its type?
> 
Right

> > + * @param tab - table to store extracted value
> > + * @param i - actual tab element to work on
> 
> Table? Why not just pass in char **tab and get rid of "i".
> 
> > +static int extract_val(char **p, char *tab[], int i, char *key) {
> > +	char *t, *e, *tok = *p;
> > +	char *k;
> 
> Those variable names are not exactly descriptive.
> 
I change the names.

> > +	t = strsep(&tok, ",");
> > +	k = t;
> > +	strsep(&t, "=");
> > +
> > +	if (key && strcmp(k, key))
> > +		return -2;
> > +
> > +	if (extract_env(t) == 0) {
> 
> Hmm. That only allows key=${value}. What about key=text${envothertext
> or key=${env1}foo${env2}? Isn't there some generic code that can
> already expand environment variables within strings so we don't have to
> re-invent it here?
> 
I check it.

> > +	tab[i] = calloc(strlen(t) + 1, 1);
> > +	if (tab[i] == NULL) {
> > +		printf("%s: calloc failed!\n", __func__);
> > +		return -1;
> > +	}
> > +	strcpy(tab[i], t);
> 
> Isn't strdup() available?
> 
Yes, it is.

> > +static int set_gpt_info(block_dev_desc_t *dev_desc, char *str_part,
> > +	disk_partition_t *partitions[], const int parts_count) {
> > +	char *ps[parts_count];
> 
> Can we call this sizes? Can't we call strtoul() and store int sizes[]
> rather than storing the strings first and then converting to integers
> in a separate piece of disconnected code?
> 
If the size parameter is passed as env (and the partitions list is passed as
env) it has to be expanded manually and string allocation then needed. If we
decide to remove this feature then you are right.

> > +	printf("PARTITIONS: %s\n", s);
> 
> Why print that?
> 
Right.

> > +	ss = calloc(strlen(s) + 1, 1);
> > +	if (ss == NULL) {
> > +		printf("%s: calloc failed!\n", __func__);
> > +		return -1;
> > +	}
> > +	memcpy(ss, s, strlen(s) + 1);
> 
> Use strdup().
> 
Ok.

> That duplicates the strdup() in do_gpt() some of the time.
> 
> > +	for (i = 0, p = ss; i < parts_count; i++) {
> 
> Why not calculate parts_count here, rather than splitting the parsing
> logic between this function and gpt_mmc_default()?
> 
The 'parts_count' is needed for dynamic array size for 'partions' and it is
to passed to the 'gpt_fill' function. However I think of how to organize it
all in a better way.

> > +		tok = strsep(&p, ";");
> > +		if (tok == NULL)
> > +			break;
> > +
> > +		if (extract_val(&tok, name, i, "name")) {
> > +			ret = -1;
> > +			goto err;
> > +		}
> > +
> > +		if (extract_val(&tok, ps, i, "size")) {
> > +			ret = -1;
> > +			free(name[i]);
> > +			goto err;
> > +		}
> 
> I think that requires the parameters to be passed in order
> name=foo,size=5,uuid=xxx. That seems inflexible. The syntax may as well
> just be value,value,value rather than key=value,key=value,key=value in
> that case (although the keys are useful in order to understand the
> data, so I'd prefer parsing flexibility rather than removing key=).
> 
I would say that the "key=value" is flexible. The 'extract_env' function
tells you if the requested key was provided or not. Also, the order of keys
is not important.

> > +		if (extract_val(&tok, uuid, i, "uuid")) {
> > +			/* uuid string length equals 37 */
> > +			uuid[i] = calloc(37, 1);
> 
> Shouldn't storage for the UUID always be allocated? After all, one must
> always be written even if the user didn't explicitly specify one, so U-
> Boot makes it up.
> 
The 'set_gpt_info' was designed in a way that allocations for ps, name and
uuid are done when the value is assigned to them (the 'extract_env'
function). It just consistent with that.

> > +		p = ps[i];
> > +		size[i] = ustrtoul(p, &p, 0);
> > +		size[i] /= dev_desc->blksz;
> 
> What if the size isn't rounded correctly?
> 
Some checking should be added.

> > +	for (i = 0; i < parts_count; i++) {
> > +		partitions[i]->size = size[i];
> > +		partitions[i]->blksz = dev_desc->blksz;
> 
> Why not just write to partitions[] directly in the first place instead
> of using temporary variables and then copying them?
> 
The only advantage is that the partitions[] is modified only when the key
extraction was successful.

> > +static int gpt_mmc_default(int dev, char *str_part)
> 
> > +	struct mmc *mmc = find_mmc_device(dev);
> > +
> > +	if (mmc == NULL) {
> > +		printf("%s: mmc dev %d NOT available\n", __func__, dev);
> > +		return CMD_RET_FAILURE;
> > +	}
> 
> Why is this tied to MMC; shouldn't it work for e.g. USB storage as
> well?
> Use get_device_and_partition() instead.
> 
> > +	puts("Using default GPT UUID\n");
> 
> Even when the user explicitly supplied a partition layout on the
> command-line? Why print anything at all?
> 
> > +	/* allocate memory for partitions */
> > +	disk_partition_t *partitions[part_count];
> 
> Don't variable declarations have to be at the start of a block in U-
> Boot?
> 
Yes, you are right.

> > +static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const
> > +argv[]) {
> > +	int ret = CMD_RET_SUCCESS;
> > +	char *str_part = NULL;
> > +	int dev = 0;
> > +
> > +	if (argc < 3)
> > +		return CMD_RET_USAGE;
> > +
> > +	if (argc == 4) {
> > +		str_part = strdup(argv[3]);
> > +		if (!str_part) {
> > +			printf("%s: malloc failed!\n", __func__);
> > +			return CMD_RET_FAILURE;
> > +		}
> > +	}
> 
> The help text doesn't indicate that any of the command parameters are
> optional...
> 
> Why does this need to strdup() anything anyway?

Best regards,
Piotr Wilczek
--
Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-11-19 20:16       ` Stephen Warren
@ 2012-11-21 13:18         ` Piotr Wilczek
  2012-11-22 12:16           ` Lukasz Majewski
  2012-11-24 18:05           ` Stephen Warren
  0 siblings, 2 replies; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-21 13:18 UTC (permalink / raw)
  To: u-boot

Dear Stephen,

> -----Original Message-----
> From: Stephen Warren [mailto:swarren at wwwdotorg.org]
> Sent: Monday, November 19, 2012 9:17 PM
> To: Piotr Wilczek
> Cc: u-boot at lists.denx.de; Minkyu Kang; Kyungmin Park; Chang Hyun Park;
> Lukasz Majewski; Stephen Warren; Tom Rini; Rob Herring
> Subject: Re: [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table)
> restoration
> 
> On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
> > The restoration of GPT table (both primary and secondary) is now
> possible.
> > Simple GUID generation is supported.
> 
> > diff --git a/include/part.h b/include/part.h
> 
> > +int set_gpt_table(block_dev_desc_t *dev_desc,
> > +		  gpt_header *gpt_h, gpt_entry *gpt_e); void
> > +gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
> > +		disk_partition_t *partitions[], int parts); void
> > +gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h);
> 
> > +void gpt_fill(block_dev_desc_t *dev_desc, disk_partition_t
> *partitions[],
> > +		const int parts_count);
> 
> Why const?
> 
The const is not necessary.

> Some documentation for these functions (particularly high-level
> information such as which order you'd expect to call them and why/what
> for) would be useful in the header rather than the .c file; the header
> is where people would go to find out what functions they can call, so
> making them also go look in the .c file would be a bit annoying.
> 
That documentation should be moved to header files.

> > diff --git a/disk/part_efi.c b/disk/part_efi.c
> 
> > +static int set_protective_mbr(block_dev_desc_t *dev_desc);
> > +
> > +static void guid_dump(u8 *guid, int i);
> > +
> > +static void guid_gen(const u32 *pool, u8 *guid);
> > +
> > +static int convert_uuid(char *uuid, u8 *dst);
> > +
> > +static void set_part_name(efi_char16_t *part_name, char *name);
> 
> There probably should be a CONFIG_ option required to enable this new
> feature, so people who don't want it don't suffer code bloat.
> 
> Do you really need the blank lines between prototypes?
> 
> I suspect you can re-order the functions so that none of the prototypes
> are needed anyway.
> 
I try to reorder the functions and eliminate prototypes.

> > +/**
> > + * set_gpt_table() - Restore the GUID Partition Table
> 
> "write" would probably be better than "set".
> 
Yes, "write" is better.

> > + *
> > + * @param dev_desc - block device descriptor
> > + * @param parts - number of partitions
> > + * @param size - pointer to array with each partition size
> > + * @param name - pointer to array with each partition name
> 
> Those last 3 lines don't match the prototype.
> 
I should fix it.

> > + * @return - zero on success, otherwise error  */ int
> > +set_gpt_table(block_dev_desc_t *dev_desc,
> > +		  gpt_header *gpt_h, gpt_entry *gpt_e)
> 
> Presumably the code assumes that gpt_e always has 128(?) entries.
> Instead of taking a pointer, should the function take an array:
> gpt_entry gpt_e[GPT_ENTRY_NUMBERS] to enforce this?
> 
> > +{
> > +	const int pte_blk_num = (GPT_ENTRY_NUMBERS * sizeof(gpt_entry)) /
> > +		dev_desc->blksz;
> 
> Related, this hard-codes the number of ptes as GPT_ENTRY_NUMBERS,
> whereas ...
> 
> > +	u32 calc_crc32;
> > +	u64 val;
> > +
> > +	debug("max lba: %x\n", (u32) dev_desc->lba);
> > +	/* Setup the Protective MBR */
> > +	if (set_protective_mbr(dev_desc) < 0)
> > +		goto err;
> > +
> > +	/* 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));
> 
> ... here, gpt_h->num_partition_entries is used instead. Should both
> places use the same size (entry count) definition?
> 
> > +	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e)
> > +	    != pte_blk_num)
> > +		goto err;
> 
> Here, we assume GPT_ENTRY_NUMBERS entries in gpt_e. If the array isn't
> that big, the block_write() above will read past the end of it.
> 
> > +	puts("GPT successfully written to block device!\n");
> 
> Isn't that something that a command should be doing, not a utility
> function? I'd rather have this function not print anything, except
> perhaps on errors, just like typical Unix command-line applications.
> 
> > +void gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
> > +		disk_partition_t *partitions[], int parts)
> 
> Why is partitions an array of pointers rather than an array of
> partitions?
> 
The partitions is a variable size array stack allocated and each element
points to heap allocated disk_partition. I think of how to reorganize this
part of the code.

> > +{
> > +	u32 offset = (u32) le32_to_cpu(gpt_h->first_usable_lba);
> 
> I don't think there should be a space after the cast. The same comment
> probably applies elsewhere.
> 
> > +	for (i = 0; i < parts; i++) {
> > +		/* partition starting lba */
> > +		start = partitions[i]->start;
> > +		if (start && (offset <= start))
> > +			gpt_e[i].starting_lba = cpu_to_le32(start);
> > +		else
> > +			gpt_e[i].starting_lba = cpu_to_le32(offset);
> 
> That seems a little odd. The else branch seems fine when !start, but
> what about when (start && (offset > start))? Shouldn't that be an
> error, rather than just ignoring the requested start value?
> 
The idea is that if the user provided start address and the partitions does
not overlap, the partition is located at the start address. Otherwise
partitions are located next to each other.

> Why can't partitions be out of order? IIRC, the GPT spec allows it.
> 
> > +		/* partition ending lba */
> > +		if (i != parts - 1)
> > +			gpt_e[i].ending_lba =
> > +				cpu_to_le64(offset - 1);
> > +		else
> > +			gpt_e[i].ending_lba = gpt_h->last_usable_lba;
> 
> Why extend the last partition to fill the disk; why not simply always
> use the requested size? If a "fill to max size" option is implemented,
> the user might not want it to apply to the last partition, but perhaps
> some arbitrary partition in the middle of the list.
> 
> > +		/* partition type GUID*/
> > +		memcpy(gpt_e[i].partition_type_guid.b,
> > +			&PARTITION_BASIC_DATA_GUID, 16);
> 
> Shouldn't that be a user-specifiable option too? I suppose we could add
> that later.
> 
> > +		str_uuid = NULL;
> > +#ifdef CONFIG_PARTITION_UUIDS
> > +		str_uuid = partitions[i]->uuid;
> > +#endif
> 
> I think it should be required to enable that feature if creating GPTs;
> writing a GPT without a value UUID seems wrong.
> 
Yes, it should be checked if CONFIG_PARTITION_UUIDS is defined at all.

> > +		if (convert_uuid(str_uuid,
> gpt_e[i].unique_partition_guid.b)) {
> > +			guid_gen((((u32 *) gd->start_addr_sp) - i - 1),
> > +				guid);
> > +			memcpy(gpt_e[i].unique_partition_guid.b, guid,
> > +			       sizeof(efi_guid_t));
> > +		}
> 
> Shouldn't there be a difference between no specified UUID, and an error
> converting a specified UUID?
> 
Yes, it's a good idea.

> > +		/* partition attributes */
> > +		memset(&gpt_e[i].attributes, 0,
> > +		       sizeof(gpt_entry_attributes));
> 
> (Perhaps in the future) We should allow specifying attributes too.
> 
Ok

> > +void gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h)
> 
> > +	gpt_h->first_usable_lba = cpu_to_le64(34);
> > +	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
> 
> Is lba the number of LBAs or the last LBA number? include/part.h says
> its the number of LBAs, in which case I think that should be dev_desc-
> >lba - 1 - 34?
> 
> > +	s = getenv("uuid_gpt_disk");
> 
> I'd rather not depend on environment variables; can't this be a
> command-line parameter to the gpt command?
> 
> > +void gpt_fill(block_dev_desc_t *dev_desc, disk_partition_t
> *partitions[],
> > +		const int parts_count)
> 
> Rename to gpt_write()?
> 
Ok.

> > +	puts("save the GPT ...\n");
> 
> Again, why print anything here?
> 
> > +	set_gpt_table(dev_desc, gpt_h, gpt_e);
> 
> Oh, so is set_gpt_table() an internal-only function? If so, shouldn't
> it be static and not in the header file?
> 
It could be used by some other code in future.

> > +static int set_protective_mbr(block_dev_desc_t *dev_desc) {
> > +	legacy_mbr p_mbr;
> > +
> > +	/* Setup the Protective MBR */
> > +	memset((u32 *) &p_mbr, 0x00, sizeof(p_mbr));
> 
> Why use a stack variable and memset() here, but use calloc() in
> gpt_fill() above? That seems inconsistent.
> 
> > +#ifdef DEBUG
> > +static void guid_dump(u8 *guid, int i) {
> > +	int k;
> > +
> > +	debug("GUID: ");
> > +	for (k = 0; k < i; k++, guid++)
> > +		debug(" %x ", *guid);
> > +	debug("\n");
> > +}
> > +#else
> > +static void guid_dump(u8 *guid, int i) {} #endif
> 
> Wouldn't using the existing uuid_string be better?
> 
> > +static int convert_uuid(char *uuid, u8 *dst)
> 
> It's not too clear from the function name what kind of conversion is
> being applied. string_uuid() would be more consistent with the existing
> uuid_string(), or perhaps even better string_to_uuid().
> 
> > +static void set_part_name(efi_char16_t *part_name, char *name)
> 
> > +	for (k = 0, j = 0; k < strlen(name); k++, j += 2) {
> > +		p[j] = *(name + k);
> > +		p[j + 1] = '.';
> 
> Not '\0'?
> 
> > +	}
> > +	memcpy(part_name, p, strlen(p));
> 
> Why not write directly to part_name?
Right, I fix it.

Best regards,
Piotr Wilczek
--
Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-11-21 13:18         ` Piotr Wilczek
@ 2012-11-22 12:16           ` Lukasz Majewski
  2012-11-26 23:46             ` Stephen Warren
  2012-11-24 18:05           ` Stephen Warren
  1 sibling, 1 reply; 95+ messages in thread
From: Lukasz Majewski @ 2012-11-22 12:16 UTC (permalink / raw)
  To: u-boot

Hi Piotr,

> Dear Stephen,
> 
> > -----Original Message-----
> > From: Stephen Warren [mailto:swarren at wwwdotorg.org]
> > Sent: Monday, November 19, 2012 9:17 PM
> > To: Piotr Wilczek
> > Cc: u-boot at lists.denx.de; Minkyu Kang; Kyungmin Park; Chang Hyun
> > Park; Lukasz Majewski; Stephen Warren; Tom Rini; Rob Herring
> > Subject: Re: [PATCH v4 5/7] gpt: Support for GPT (GUID Partition
> > Table) restoration
> > 
> > On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
> > > The restoration of GPT table (both primary and secondary) is now
> > possible.
> > > Simple GUID generation is supported.
> > 
> > > diff --git a/include/part.h b/include/part.h
> > 
> > > +int set_gpt_table(block_dev_desc_t *dev_desc,
> > > +		  gpt_header *gpt_h, gpt_entry *gpt_e); void
> > > +gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
> > > +		disk_partition_t *partitions[], int parts); void
> > > +gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h);
> > 
> > > +void gpt_fill(block_dev_desc_t *dev_desc, disk_partition_t
> > *partitions[],
> > > +		const int parts_count);
> > 
> > Why const?
> > 
> The const is not necessary.
> 
> > Some documentation for these functions (particularly high-level
> > information such as which order you'd expect to call them and
> > why/what for) would be useful in the header rather than the .c
> > file; the header is where people would go to find out what
> > functions they can call, so making them also go look in the .c file
> > would be a bit annoying.
> > 
> That documentation should be moved to header files.
> 
> > > diff --git a/disk/part_efi.c b/disk/part_efi.c
> > 
> > > +static int set_protective_mbr(block_dev_desc_t *dev_desc);
> > > +
> > > +static void guid_dump(u8 *guid, int i);
> > > +
> > > +static void guid_gen(const u32 *pool, u8 *guid);
> > > +
> > > +static int convert_uuid(char *uuid, u8 *dst);
> > > +
> > > +static void set_part_name(efi_char16_t *part_name, char *name);
> > 
> > There probably should be a CONFIG_ option required to enable this
> > new feature, so people who don't want it don't suffer code bloat.
> > 
> > Do you really need the blank lines between prototypes?
> > 
> > I suspect you can re-order the functions so that none of the
> > prototypes are needed anyway.
> > 
> I try to reorder the functions and eliminate prototypes.
> 
> > > +/**
> > > + * set_gpt_table() - Restore the GUID Partition Table
> > 
> > "write" would probably be better than "set".
> > 
> Yes, "write" is better.
> 
> > > + *
> > > + * @param dev_desc - block device descriptor
> > > + * @param parts - number of partitions
> > > + * @param size - pointer to array with each partition size
> > > + * @param name - pointer to array with each partition name
> > 
> > Those last 3 lines don't match the prototype.
> > 
> I should fix it.
> 
> > > + * @return - zero on success, otherwise error  */ int
> > > +set_gpt_table(block_dev_desc_t *dev_desc,
> > > +		  gpt_header *gpt_h, gpt_entry *gpt_e)
> > 
> > Presumably the code assumes that gpt_e always has 128(?) entries.
> > Instead of taking a pointer, should the function take an array:
> > gpt_entry gpt_e[GPT_ENTRY_NUMBERS] to enforce this?
> > 
> > > +{
> > > +	const int pte_blk_num = (GPT_ENTRY_NUMBERS *
> > > sizeof(gpt_entry)) /
> > > +		dev_desc->blksz;
> > 
> > Related, this hard-codes the number of ptes as GPT_ENTRY_NUMBERS,
> > whereas ...
> > 
> > > +	u32 calc_crc32;
> > > +	u64 val;
> > > +
> > > +	debug("max lba: %x\n", (u32) dev_desc->lba);
> > > +	/* Setup the Protective MBR */
> > > +	if (set_protective_mbr(dev_desc) < 0)
> > > +		goto err;
> > > +
> > > +	/* 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));
> > 
> > ... here, gpt_h->num_partition_entries is used instead. Should both
> > places use the same size (entry count) definition?
> > 
> > > +	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num,
> > > gpt_e)
> > > +	    != pte_blk_num)
> > > +		goto err;
> > 
> > Here, we assume GPT_ENTRY_NUMBERS entries in gpt_e. If the array
> > isn't that big, the block_write() above will read past the end of
> > it.

The code allocates (and thereafter reads) the GPT_ENTRY_NUMBERS (which
is 128) * sizeof(struct pte). It will be changed to allocate only as
much space as needed. 

> > 
> > > +	puts("GPT successfully written to block device!\n");
> > 
> > Isn't that something that a command should be doing, not a utility
> > function? I'd rather have this function not print anything, except
> > perhaps on errors, just like typical Unix command-line applications.
> > 
> > > +void gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
> > > +		disk_partition_t *partitions[], int parts)
> > 
> > Why is partitions an array of pointers rather than an array of
> > partitions?
> > 
> The partitions is a variable size array stack allocated and each
> element points to heap allocated disk_partition. I think of how to
> reorganize this part of the code.
> 
> > > +{
> > > +	u32 offset = (u32) le32_to_cpu(gpt_h->first_usable_lba);
> > 
> > I don't think there should be a space after the cast. The same
> > comment probably applies elsewhere.
> > 
> > > +	for (i = 0; i < parts; i++) {
> > > +		/* partition starting lba */
> > > +		start = partitions[i]->start;
> > > +		if (start && (offset <= start))
> > > +			gpt_e[i].starting_lba =
> > > cpu_to_le32(start);
> > > +		else
> > > +			gpt_e[i].starting_lba =
> > > cpu_to_le32(offset);
> > 
> > That seems a little odd. The else branch seems fine when !start, but
> > what about when (start && (offset > start))? Shouldn't that be an
> > error, rather than just ignoring the requested start value?
> > 
> The idea is that if the user provided start address and the
> partitions does not overlap, the partition is located at the start
> address. Otherwise partitions are located next to each other.
> 
> > Why can't partitions be out of order? IIRC, the GPT spec allows it.
> > 
> > > +		/* partition ending lba */
> > > +		if (i != parts - 1)
> > > +			gpt_e[i].ending_lba =
> > > +				cpu_to_le64(offset - 1);
> > > +		else
> > > +			gpt_e[i].ending_lba =
> > > gpt_h->last_usable_lba;
> > 
> > Why extend the last partition to fill the disk; why not simply
> > always use the requested size? If a "fill to max size" option is
> > implemented, the user might not want it to apply to the last
> > partition, but perhaps some arbitrary partition in the middle of
> > the list.

Yes, you are right. User shall have the option to specify the size for
the last partition. I think, that it is welcome to specify a special
"mark" (e.g. size=- or size=0) to express that we want partition's size
up to the end of the device.

> > 
> > > +		/* partition type GUID*/
> > > +		memcpy(gpt_e[i].partition_type_guid.b,
> > > +			&PARTITION_BASIC_DATA_GUID, 16);
> > 
> > Shouldn't that be a user-specifiable option too? I suppose we could
> > add that later.
> > 
> > > +		str_uuid = NULL;
> > > +#ifdef CONFIG_PARTITION_UUIDS
> > > +		str_uuid = partitions[i]->uuid;
> > > +#endif
> > 
> > I think it should be required to enable that feature if creating
> > GPTs; writing a GPT without a value UUID seems wrong.
> > 
> Yes, it should be checked if CONFIG_PARTITION_UUIDS is defined at all.
> 
> > > +		if (convert_uuid(str_uuid,
> > gpt_e[i].unique_partition_guid.b)) {
> > > +			guid_gen((((u32 *) gd->start_addr_sp) -
> > > i - 1),
> > > +				guid);
> > > +			memcpy(gpt_e[i].unique_partition_guid.b,
> > > guid,
> > > +			       sizeof(efi_guid_t));
> > > +		}
> > 
> > Shouldn't there be a difference between no specified UUID, and an
> > error converting a specified UUID?
> > 
> Yes, it's a good idea.
> 
> > > +		/* partition attributes */
> > > +		memset(&gpt_e[i].attributes, 0,
> > > +		       sizeof(gpt_entry_attributes));
> > 
> > (Perhaps in the future) We should allow specifying attributes too.
> > 
> Ok
> 
> > > +void gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header
> > > *gpt_h)
> > 
> > > +	gpt_h->first_usable_lba = cpu_to_le64(34);
> > > +	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
> > 
> > Is lba the number of LBAs or the last LBA number? include/part.h
> > says its the number of LBAs, in which case I think that should be
> > dev_desc-
> > >lba - 1 - 34?

LBA is the number of blocks. So the addressable range is 0 to LBA-1.
The last_usable_lba is calculated with following equation (it is
similar with parted tool):

lba - 2 - ptes_size = lba -2 -32 = lba - 34

ptes_size = number_of_entries(128) * sizeof(pte_entry) (128) /
sector_size (512) = 32

> > 
> > > +	s = getenv("uuid_gpt_disk");
> > 
> > I'd rather not depend on environment variables; can't this be a
> > command-line parameter to the gpt command?

I think, that the uuid_gpt_disk shall be added as another key=value to
the partitions.

e.g. gpt
uuid_gpt_disk=6aa01a70-349d-11e2-ae74-001fd09285c0;name=boot,size=100MiB,uuid=xx;name=kernel,
size=200MiB,uuid=yy;....

> > 
> > > +void gpt_fill(block_dev_desc_t *dev_desc, disk_partition_t
> > *partitions[],
> > > +		const int parts_count)
> > 
> > Rename to gpt_write()?
> > 
> Ok.
> 
> > > +	puts("save the GPT ...\n");
> > 
> > Again, why print anything here?
Will be changed to debug().

> > 
> > > +	set_gpt_table(dev_desc, gpt_h, gpt_e);
> > 
> > Oh, so is set_gpt_table() an internal-only function? If so,
> > shouldn't it be static and not in the header file?
> > 
> It could be used by some other code in future.
> 
> > > +static int set_protective_mbr(block_dev_desc_t *dev_desc) {
> > > +	legacy_mbr p_mbr;
> > > +
> > > +	/* Setup the Protective MBR */
> > > +	memset((u32 *) &p_mbr, 0x00, sizeof(p_mbr));
> > 
> > Why use a stack variable and memset() here, but use calloc() in
> > gpt_fill() above? That seems inconsistent.

Good point. Consistency will be provided in the next version.

> > 
> > > +#ifdef DEBUG
> > > +static void guid_dump(u8 *guid, int i) {
> > > +	int k;
> > > +
> > > +	debug("GUID: ");
> > > +	for (k = 0; k < i; k++, guid++)
> > > +		debug(" %x ", *guid);
> > > +	debug("\n");
> > > +}
> > > +#else
> > > +static void guid_dump(u8 *guid, int i) {} #endif
> > 
> > Wouldn't using the existing uuid_string be better?

Since the guid_gen will be removed in a next version (the correct UUID
will be provided from command line/env), the guid_dump will be removed
as well.

> > 
> > > +static int convert_uuid(char *uuid, u8 *dst)
> > 
> > It's not too clear from the function name what kind of conversion is
> > being applied. string_uuid() would be more consistent with the
> > existing uuid_string(), or perhaps even better string_to_uuid().
> > 
> > > +static void set_part_name(efi_char16_t *part_name, char *name)
> > 
> > > +	for (k = 0, j = 0; k < strlen(name); k++, j += 2) {
> > > +		p[j] = *(name + k);
> > > +		p[j + 1] = '.';
> > 
> > Not '\0'?

Yes, this is a mistake. Will be fixed.

> > 
> > > +	}
> > > +	memcpy(part_name, p, strlen(p));
> > 
> > Why not write directly to part_name?
> Right, I fix it.
> 
> Best regards,
> Piotr Wilczek
> --
> Samsung Poland R&D Center | Linux Platform Group
> 
> 



-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 6/7] gpt: Support for new "gpt" command
  2012-11-21 11:22         ` Piotr Wilczek
@ 2012-11-24 18:00           ` Stephen Warren
  2012-11-26 13:08             ` Piotr Wilczek
  0 siblings, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-11-24 18:00 UTC (permalink / raw)
  To: u-boot

On 11/21/2012 04:22 AM, Piotr Wilczek wrote:
> Dear Stephen,
> 
>> Stephen Warren wrote at Monday, November 19, 2012 10:35 PM:
>> On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
>>> New command - "gpt" is supported. It restores the GPT partition table.
>>> It looks into the "partitions" environment variable for partitions definition.
>>> It can be enabled at target configuration file with CONFIG_CMD_GPT.
>>> Simple UUID generator has been implemented. It uses the the
>>> gd->start_addr_sp for entrophy pool. Moreover the pool address is used as crc32 seed.
>>
>>> diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
>>
>>> +U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
>>> +	"GUID Partition Table",
>>> +	"<interface> <dev> <partions list>\n"
>>> +	" partions list is in format: name=..,size=..,uuid=..;...\n"
>>> +	" and can be passed as env or string ex.:\n"
>>> +	"    gpt mmc 0 partitions\n"
>>
>> I don't think that form makes sense. The user should just pass
>> "${partitions}" instead. The command can't know for certain whether the
>> user actually intended to pass the text "partitions" and made a
>> mistake, or whether they passed an environment variable. If you really
>> want to be able to pass an environment variable name, an explicit
>> command-line option such as:
>>
>> gpt mmc 0 name=...                      # definition on cmd-line
>> gpt mmc 0 --from-environment partitions # definition in environment
>>
>> seems best.
>
> The intention was that the command automatically figures out whether user
> passed environmental variable or directly partitions as text. Then the
> command splits this string, checks if it is a valid partitions list and if
> so the table is written to mmc. That is how the code is supposed to work.
> 
> The question here is, if it should work like that. If it is desired that
> user explicitly states that the partitions list is passed from
> environmental, then I should change the code.

I personally prefer things to be explicit; that way, there can't be any
corner-case that isn't covered by the automatic mode.

>>> +/**
>>> + * extract_env(): Convert string from '&{env_name}' to 'env_name'
>>
>> s/&/$/
>>
>> It's doing more than that; it locates that syntax within an arbitrary
>> string and ignores anything before "${" or after "}". Is that
>> intentional?
>
> Yes, it was. The u-boot's shell expands to one only, so it allow to pass any
> partition parameter as env when the partitions list itself is passed as env.

OK. The issue here is that the comment doesn't exactly describe what the
code is doing.

Also, what if the user wrote "foo${var}bar"; I can't recall if the code
handles that correct; is the result of that just "${var}", or do "foo"
and "bar" actually make it into the result string?

>>> +static int extract_env(char *p)
>>
>>> +	p1 = strstr(p, "${");
>>> +	p2 = strstr(p, "}");
>>> +
>>> +	if (p1 && p2) {
>>> +		*p2 = '\0';
>>> +		memmove(p, p+2, p2-p1-1);
>>
>> s/-1/-2/ I think, since the length of "${" is 2 not 1.
>>
> p2-p1-1 gives length of the env name + trailing zero.
> p2-p1-2 would give only the env's length and the trailing zero wouldn't be
> moved.

Ah right. I tend to write things like that as:

p2-p1-2+1 /* strlen("${")==2, length '\0'==1

to make it obvious what's going on

>>> +		tok = strsep(&p, ";");
>>> +		if (tok == NULL)
>>> +			break;
>>> +
>>> +		if (extract_val(&tok, name, i, "name")) {
>>> +			ret = -1;
>>> +			goto err;
>>> +		}
>>> +
>>> +		if (extract_val(&tok, ps, i, "size")) {
>>> +			ret = -1;
>>> +			free(name[i]);
>>> +			goto err;
>>> +		}
>>
>> I think that requires the parameters to be passed in order
>> name=foo,size=5,uuid=xxx. That seems inflexible. The syntax may as well
>> just be value,value,value rather than key=value,key=value,key=value in
>> that case (although the keys are useful in order to understand the
>> data, so I'd prefer parsing flexibility rather than removing key=).
>>
> I would say that the "key=value" is flexible. The 'extract_env' function
> tells you if the requested key was provided or not. Also, the order of keys
> is not important.

The order of the keys shouldn't be important, but doesn't the code above
expect to find key "name" first, then key "size", etc., in tha specific
order, as it walks through the string?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-11-21 13:18         ` Piotr Wilczek
  2012-11-22 12:16           ` Lukasz Majewski
@ 2012-11-24 18:05           ` Stephen Warren
  2012-11-26 13:08             ` Piotr Wilczek
  1 sibling, 1 reply; 95+ messages in thread
From: Stephen Warren @ 2012-11-24 18:05 UTC (permalink / raw)
  To: u-boot

On 11/21/2012 06:18 AM, Piotr Wilczek wrote:
> Dear Stephen,
> 
>> Stephen Warren wrote at Monday, November 19, 2012 9:17 PM:
>> On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
>>> The restoration of GPT table (both primary and secondary) is now possible.
>>> Simple GUID generation is supported.
...
>>> +	for (i = 0; i < parts; i++) {
>>> +		/* partition starting lba */
>>> +		start = partitions[i]->start;
>>> +		if (start && (offset <= start))
>>> +			gpt_e[i].starting_lba = cpu_to_le32(start);
>>> +		else
>>> +			gpt_e[i].starting_lba = cpu_to_le32(offset);
>>
>> That seems a little odd. The else branch seems fine when !start, but
>> what about when (start && (offset > start))? Shouldn't that be an
>> error, rather than just ignoring the requested start value?
>
> The idea is that if the user provided start address and the partitions does
> not overlap, the partition is located at the start address. Otherwise
> partitions are located next to each other.

But if the user provided a start address, shouldn't it always be honored
exactly, or any error generated; silently ignoring a start address when
there's an overlap seems wrong. Also, the overlap checking seems a
little simplistic; it should really sort the partition array and then
walk through checking for overlaps, rather than maintaining a single
"highest used offset", since there's no requirement for the physical
order of partitions to match the order in the partition table, hence why
I asked:

>> Why can't partitions be out of order? IIRC, the GPT spec allows it.


>> Oh, so is set_gpt_table() an internal-only function? If so, shouldn't
>> it be static and not in the header file?
>
> It could be used by some other code in future.

Perhaps. It can always be made non-static at that time.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-11-24 18:05           ` Stephen Warren
@ 2012-11-26 13:08             ` Piotr Wilczek
  0 siblings, 0 replies; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-26 13:08 UTC (permalink / raw)
  To: u-boot


> -----Original Message-----
> From: Stephen Warren [mailto:swarren at wwwdotorg.org]
> Sent: Saturday, November 24, 2012 7:06 PM
> To: Piotr Wilczek
> Cc: u-boot at lists.denx.de; 'Minkyu Kang'; 'Kyungmin Park'; 'Chang Hyun
> Park'; Lukasz Majewski; 'Stephen Warren'; 'Tom Rini'; 'Rob Herring'
> Subject: Re: [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table)
> restoration
> 
> On 11/21/2012 06:18 AM, Piotr Wilczek wrote:
> > Dear Stephen,
> >
> >> Stephen Warren wrote at Monday, November 19, 2012 9:17 PM:
> >> On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
> >>> The restoration of GPT table (both primary and secondary) is now
> possible.
> >>> Simple GUID generation is supported.
> ...
> >>> +	for (i = 0; i < parts; i++) {
> >>> +		/* partition starting lba */
> >>> +		start = partitions[i]->start;
> >>> +		if (start && (offset <= start))
> >>> +			gpt_e[i].starting_lba = cpu_to_le32(start);
> >>> +		else
> >>> +			gpt_e[i].starting_lba = cpu_to_le32(offset);
> >>
> >> That seems a little odd. The else branch seems fine when !start, but
> >> what about when (start && (offset > start))? Shouldn't that be an
> >> error, rather than just ignoring the requested start value?
> >
> > The idea is that if the user provided start address and the
> partitions
> > does not overlap, the partition is located at the start address.
> > Otherwise partitions are located next to each other.
> 
> But if the user provided a start address, shouldn't it always be
> honored exactly, or any error generated; silently ignoring a start
> address when there's an overlap seems wrong. Also, the overlap checking
> seems a little simplistic; it should really sort the partition array
> and then walk through checking for overlaps, rather than maintaining a
> single "highest used offset", since there's no requirement for the
> physical order of partitions to match the order in the partition table,
> hence why I asked:
> 
You are right. Ignoring start address when there's overlap is a bad idea and
I change the code.

The overlap check method is simple: the offset points to the first address
where the next partition can start. At first it is equal to the first usable
lba, then is increased by size of the previous partition (now I see that
there's a bug in the code I posted, it should be: offset +=
partitions[i]->size);
I think that this simple overlap check method should be enough at the
moment.

> >> Why can't partitions be out of order? IIRC, the GPT spec allows it.
> 
> 
> >> Oh, so is set_gpt_table() an internal-only function? If so,
> shouldn't
> >> it be static and not in the header file?
> >
> > It could be used by some other code in future.
> 
> Perhaps. It can always be made non-static at that time.

Making it non-static I say that it was designed to be used by other code.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 6/7] gpt: Support for new "gpt" command
  2012-11-24 18:00           ` Stephen Warren
@ 2012-11-26 13:08             ` Piotr Wilczek
  2012-11-26 23:49               ` Stephen Warren
  0 siblings, 1 reply; 95+ messages in thread
From: Piotr Wilczek @ 2012-11-26 13:08 UTC (permalink / raw)
  To: u-boot


> -----Original Message-----
> From: Stephen Warren [mailto:swarren at wwwdotorg.org]
> Sent: Saturday, November 24, 2012 7:01 PM
> To: Piotr Wilczek
> Cc: u-boot at lists.denx.de; 'Minkyu Kang'; 'Kyungmin Park'; 'Chang Hyun
> Park'; Lukasz Majewski; 'Stephen Warren'; 'Tom Rini'; 'Rob Herring'
> Subject: Re: [PATCH v4 6/7] gpt: Support for new "gpt" command
> 
> On 11/21/2012 04:22 AM, Piotr Wilczek wrote:
> > Dear Stephen,
> >
> >> Stephen Warren wrote at Monday, November 19, 2012 10:35 PM:
> >> On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
> >>> New command - "gpt" is supported. It restores the GPT partition
> table.
> >>> It looks into the "partitions" environment variable for partitions
> definition.
> >>> It can be enabled at target configuration file with CONFIG_CMD_GPT.
> >>> Simple UUID generator has been implemented. It uses the the
> >>> gd->start_addr_sp for entrophy pool. Moreover the pool address is
> used as crc32 seed.
> >>
> >>> diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
> >>
> >>> +U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
> >>> +	"GUID Partition Table",
> >>> +	"<interface> <dev> <partions list>\n"
> >>> +	" partions list is in format: name=..,size=..,uuid=..;...\n"
> >>> +	" and can be passed as env or string ex.:\n"
> >>> +	"    gpt mmc 0 partitions\n"
> >>
> >> I don't think that form makes sense. The user should just pass
> >> "${partitions}" instead. The command can't know for certain whether
> >> the user actually intended to pass the text "partitions" and made a
> >> mistake, or whether they passed an environment variable. If you
> >> really want to be able to pass an environment variable name, an
> >> explicit command-line option such as:
> >>
> >> gpt mmc 0 name=...                      # definition on cmd-line
> >> gpt mmc 0 --from-environment partitions # definition in environment
> >>
> >> seems best.
> >
> > The intention was that the command automatically figures out whether
> > user passed environmental variable or directly partitions as text.
> > Then the command splits this string, checks if it is a valid
> > partitions list and if so the table is written to mmc. That is how
> the code is supposed to work.
> >
> > The question here is, if it should work like that. If it is desired
> > that user explicitly states that the partitions list is passed from
> > environmental, then I should change the code.
> 
> I personally prefer things to be explicit; that way, there can't be any
> corner-case that isn't covered by the automatic mode.
> 
Ok. The partitions list will be passed in two methods:
gpt create mmc 0 ${partitions_env_name} - from environmental
or
gpt create mmc 0 "name=..,size=..,uuid=..;..." - form text

In both cases any partition parameter can also be passes as env:
gpt create mmc 0 "name=..,size=${part1_size},uuid=..;..."

> >>> +/**
> >>> + * extract_env(): Convert string from '&{env_name}' to 'env_name'
> >>
> >> s/&/$/
> >>
> >> It's doing more than that; it locates that syntax within an
> arbitrary
> >> string and ignores anything before "${" or after "}". Is that
> >> intentional?
> >
> > Yes, it was. The u-boot's shell expands to one only, so it allow to
> > pass any partition parameter as env when the partitions list itself
> is passed as env.
> 
> OK. The issue here is that the comment doesn't exactly describe what
> the code is doing.
> 
> Also, what if the user wrote "foo${var}bar"; I can't recall if the code
> handles that correct; is the result of that just "${var}", or do "foo"
> and "bar" actually make it into the result string?

The 'bar' will be dropped, but to drop 'foo' a small modification is needed.

> 
> >>> +static int extract_env(char *p)
> >>
> >>> +	p1 = strstr(p, "${");
> >>> +	p2 = strstr(p, "}");
> >>> +
> >>> +	if (p1 && p2) {
> >>> +		*p2 = '\0';
> >>> +		memmove(p, p+2, p2-p1-1);
> >>
> >> s/-1/-2/ I think, since the length of "${" is 2 not 1.
> >>
> > p2-p1-1 gives length of the env name + trailing zero.
> > p2-p1-2 would give only the env's length and the trailing zero
> > wouldn't be moved.
> 
> Ah right. I tend to write things like that as:
> 
> p2-p1-2+1 /* strlen("${")==2, length '\0'==1
> 
> to make it obvious what's going on
> 
> >>> +		tok = strsep(&p, ";");
> >>> +		if (tok == NULL)
> >>> +			break;
> >>> +
> >>> +		if (extract_val(&tok, name, i, "name")) {
> >>> +			ret = -1;
> >>> +			goto err;
> >>> +		}
> >>> +
> >>> +		if (extract_val(&tok, ps, i, "size")) {
> >>> +			ret = -1;
> >>> +			free(name[i]);
> >>> +			goto err;
> >>> +		}
> >>
> >> I think that requires the parameters to be passed in order
> >> name=foo,size=5,uuid=xxx. That seems inflexible. The syntax may as
> >> well just be value,value,value rather than
> >> key=value,key=value,key=value in that case (although the keys are
> >> useful in order to understand the data, so I'd prefer parsing
> flexibility rather than removing key=).
> >>
> > I would say that the "key=value" is flexible. The 'extract_env'
> > function tells you if the requested key was provided or not. Also,
> the
> > order of keys is not important.
> 
> The order of the keys shouldn't be important, but doesn't the code
> above expect to find key "name" first, then key "size", etc., in tha
> specific order, as it walks through the string?

The key name is passed to 'extract_val' and the function should search that
key no matter what order the keys appear in searched string. I check it
again.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration
  2012-11-22 12:16           ` Lukasz Majewski
@ 2012-11-26 23:46             ` Stephen Warren
  0 siblings, 0 replies; 95+ messages in thread
From: Stephen Warren @ 2012-11-26 23:46 UTC (permalink / raw)
  To: u-boot

On 11/22/2012 05:16 AM, Lukasz Majewski wrote:
> Hi Piotr,
> 
>> Dear Stephen,
>>
>>> Stephen Warren  wrote at Monday, November 19, 2012 9:17 PM:
>>> On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
>>>> The restoration of GPT table (both primary and secondary) is now possible.
>>>> Simple GUID generation is supported.

>>>> +void gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header
>>>> *gpt_h)
>>>
>>>> +	gpt_h->first_usable_lba = cpu_to_le64(34);
>>>> +	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
>>>
>>> Is lba the number of LBAs or the last LBA number? include/part.h
>>> says its the number of LBAs, in which case I think that should be
>>> dev_desc-
>>>> lba - 1 - 34?
> 
> LBA is the number of blocks. So the addressable range is 0 to LBA-1.
> The last_usable_lba is calculated with following equation (it is
> similar with parted tool):
> 
> lba - 2 - ptes_size = lba -2 -32 = lba - 34
> 
> ptes_size = number_of_entries(128) * sizeof(pte_entry) (128) /
> sector_size (512) = 32

Ah right, I was forgetting that there is no protective MBR at the end of
the disk, so 1 less sector is used there.

>>>> +	s = getenv("uuid_gpt_disk");
>>>
>>> I'd rather not depend on environment variables; can't this be a
>>> command-line parameter to the gpt command?
> 
> I think, that the uuid_gpt_disk shall be added as another key=value to
> the partitions.
> 
> e.g. gpt
> uuid_gpt_disk=6aa01a70-349d-11e2-ae74-001fd09285c0;name=boot,size=100MiB,uuid=xx;name=kernel,
> size=200MiB,uuid=yy;....

I guess that'd work. Note that means the calculation of # of partitions
based on counting the # of ; different. Perhaps a separate command-line
argument would be simpler?

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 6/7] gpt: Support for new "gpt" command
  2012-11-26 13:08             ` Piotr Wilczek
@ 2012-11-26 23:49               ` Stephen Warren
  0 siblings, 0 replies; 95+ messages in thread
From: Stephen Warren @ 2012-11-26 23:49 UTC (permalink / raw)
  To: u-boot

On 11/26/2012 06:08 AM, Piotr Wilczek wrote:
> 
> Stephen Warren wrote at Saturday, November 24, 2012 7:01 PM:
>> On 11/21/2012 04:22 AM, Piotr Wilczek wrote:
>>> Dear Stephen,
>>>
>>>> Stephen Warren wrote at Monday, November 19, 2012 10:35 PM:
>>>> On 11/09/2012 03:48 AM, Piotr Wilczek wrote:
>>>>> New command - "gpt" is supported. It restores the GPT partition table.
>>>>> It looks into the "partitions" environment variable for partitions definition.
>>>>> It can be enabled at target configuration file with CONFIG_CMD_GPT.
>>>>> Simple UUID generator has been implemented. It uses the the
>>>>> gd->start_addr_sp for entrophy pool. Moreover the pool address is used as crc32 seed.

>>>>> +/**
>>>>> + * extract_env(): Convert string from '&{env_name}' to 'env_name'
>>>>
>>>> s/&/$/
>>>>
>>>> It's doing more than that; it locates that syntax within an arbitrary
>>>> string and ignores anything before "${" or after "}". Is that
>>>> intentional?
>>>
>>> Yes, it was. The u-boot's shell expands to one only, so it allow to
>>> pass any partition parameter as env when the partitions list itself
>> is passed as env.
>>
>> OK. The issue here is that the comment doesn't exactly describe what
>> the code is doing.
>>
>> Also, what if the user wrote "foo${var}bar"; I can't recall if the code
>> handles that correct; is the result of that just "${var}", or do "foo"
>> and "bar" actually make it into the result string?
> 
> The 'bar' will be dropped, but to drop 'foo' a small modification is needed.

Rather than modify the code to drop "foo", why not modify it so that
"bar" and "foo" are included in the result? That seem more like what the
user desired, and is consistent with what any other shell or scripting
language would do. If not, please return an error in this case so that
bad syntax can be fixed.

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration
  2012-11-09  9:22 ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Piotr Wilczek
                     ` (4 preceding siblings ...)
  2012-11-19 20:43   ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Tom Rini
@ 2012-12-06 20:40   ` Tom Rini
  2012-12-07  9:03     ` Piotr Wilczek
  5 siblings, 1 reply; 95+ messages in thread
From: Tom Rini @ 2012-12-06 20:40 UTC (permalink / raw)
  To: u-boot

On Fri, Nov 09, 2012 at 10:22:11AM +0100, Piotr Wilczek wrote:

> This patch series provides a new command - "gpt" for eMMC partition table
> (in the GPT format) restoration.
> 
> As a pre-work, some cleanup at the part_efi.c file was performed to
> remove custom macros and make GPT related structures more readable.
> 
> Moreover the part_efi.h file has been moved to ./include directory to
> be easily available from other subsystems.
> 
> The GPT detailed description has been written to README.gpt file.
> 
> Tested at:
>         - Exynos4210 rev.1 - TRATS Samsung development board

OK, for me, now at least, building for trats is broken after the whole
series is applied, along with every other board (I believe) that enabled
GPT today.  Please investigate and post a v5, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20121206/68fe640c/attachment.pgp>

^ permalink raw reply	[flat|nested] 95+ messages in thread

* [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration
  2012-12-06 20:40   ` Tom Rini
@ 2012-12-07  9:03     ` Piotr Wilczek
  0 siblings, 0 replies; 95+ messages in thread
From: Piotr Wilczek @ 2012-12-07  9:03 UTC (permalink / raw)
  To: u-boot

Dear Tom,

--
Samsung Poland R&D Center | Linux Platform Group

> -----Original Message-----
> From: Tom Rini [mailto:tom.rini at gmail.com] On Behalf Of Tom Rini
> Sent: Thursday, December 06, 2012 9:41 PM
> To: Piotr Wilczek
> Cc: u-boot at lists.denx.de; Stephen Warren; Kyungmin Park
> Subject: Re: [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT)
> restoration
> 
> On Fri, Nov 09, 2012 at 10:22:11AM +0100, Piotr Wilczek wrote:
> 
> > This patch series provides a new command - "gpt" for eMMC partition
> > table (in the GPT format) restoration.
> >
> > As a pre-work, some cleanup at the part_efi.c file was performed to
> > remove custom macros and make GPT related structures more readable.
> >
> > Moreover the part_efi.h file has been moved to ./include directory to
> > be easily available from other subsystems.
> >
> > The GPT detailed description has been written to README.gpt file.
> >
> > Tested at:
> >         - Exynos4210 rev.1 - TRATS Samsung development board
> 
> OK, for me, now at least, building for trats is broken after the whole
> series is applied, along with every other board (I believe) that
> enabled GPT today.  Please investigate and post a v5, thanks!
> 
I should send v5 very soon.

> --
> Tom

Regards,
Piotr Wilczek

^ permalink raw reply	[flat|nested] 95+ messages in thread

end of thread, other threads:[~2012-12-07  9:03 UTC | newest]

Thread overview: 95+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-24  8:13 [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
2012-08-24  8:13 ` [U-Boot] [PATCH 1/6] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
2012-09-05 19:31   ` Stephen Warren
2012-09-06  9:22     ` Lukasz Majewski
2012-08-24  8:13 ` [U-Boot] [PATCH 2/6] gpt: Replace the leXX_to_int() calls with ones defined at <compiler.h> Lukasz Majewski
2012-09-05 19:35   ` Stephen Warren
2012-09-06 10:20     ` Lukasz Majewski
2012-09-06 18:53       ` Stephen Warren
     [not found]         ` <SNT002-W181FE3CE14BE68990CDF80CCB920@phx.gbl>
2012-09-12 14:42           ` Lukasz Majewski
2012-09-05 19:45   ` Stephen Warren
2012-09-06 10:15     ` Lukasz Majewski
2012-08-24  8:13 ` [U-Boot] [PATCH 3/6] gpt: Replacement of GPT structures members with ones indicating endianness and size Lukasz Majewski
2012-09-05 19:41   ` Stephen Warren
2012-09-06 10:24     ` Lukasz Majewski
2012-08-24  8:13 ` [U-Boot] [PATCH 4/6] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
2012-09-05 19:49   ` Stephen Warren
2012-09-06 11:19     ` Lukasz Majewski
2012-09-06 18:55       ` Stephen Warren
2012-09-05 20:19   ` Stephen Warren
2012-10-03 23:00   ` [U-Boot] [U-Boot, " Tom Rini
2012-10-04  7:18     ` [U-Boot] [u-boot] Adding missing CONFIG_SYS_CACHELINE_SIZE to boards definitions Lukasz Majewski
2012-10-04  8:28       ` esw
2012-10-18 18:48         ` Albert ARIBAUD
2012-10-04  9:02       ` Helmut Raiger
2012-08-24  8:13 ` [U-Boot] [PATCH 5/6] gpt: Support for new "gpt" command Lukasz Majewski
2012-09-05 20:08   ` Stephen Warren
2012-09-06 14:01     ` Lukasz Majewski
2012-08-24  8:13 ` [U-Boot] [PATCH 6/6] gpt: Enable support for GPT partition table restoration at Samsung's Trats Lukasz Majewski
2012-08-24  8:48 ` [U-Boot] gpt: GUID/UUID - GPT restoration - open questions Lukasz Majewski
2012-09-05 20:21   ` Stephen Warren
2012-09-06 11:27     ` Lukasz Majewski
2012-09-06 12:27   ` Rob Herring
2012-09-06 14:14     ` Lukasz Majewski
2012-09-06 18:57       ` Stephen Warren
2012-09-07  6:45         ` Lukasz Majewski
2012-09-03  9:28 ` [U-Boot] gpt: GUID/UUID - GPT restoration - open questions - RESEND Lukasz Majewski
2012-10-02 13:46   ` Simon Glass
2012-10-02 16:39     ` Lukasz Majewski
2012-09-03  9:30 ` [U-Boot] [PATCH 0/6] gpt: GUID Partition Table (GPT) restoration Lukasz Majewski
2012-09-12 14:50 ` [U-Boot] [PATCH v2 0/7] " Lukasz Majewski
2012-09-12 14:50   ` [U-Boot] [PATCH v2 1/7] vsprintf:fix: Change type returned by ustrtoul Lukasz Majewski
2012-09-12 14:50   ` [U-Boot] [PATCH v2 2/7] part:efi: Move part_efi.h file to ./include Lukasz Majewski
2012-09-12 14:50   ` [U-Boot] [PATCH v2 3/7] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
2012-09-12 14:50   ` [U-Boot] [PATCH v2 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Lukasz Majewski
2012-09-12 14:50   ` [U-Boot] [PATCH v2 5/7] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
2012-09-12 17:22     ` Tom Rini
2012-09-12 14:50   ` [U-Boot] [PATCH v2 6/7] gpt: Support for new "gpt" command Lukasz Majewski
2012-09-12 17:21     ` Tom Rini
2012-09-12 14:50   ` [U-Boot] [PATCH v2 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats Lukasz Majewski
2012-09-12 17:23   ` [U-Boot] [PATCH v2 0/7] gpt: GUID Partition Table (GPT) restoration Tom Rini
2012-09-13  6:20     ` Lukasz Majewski
2012-09-13 17:39       ` Tom Rini
2012-09-13  8:09 ` [U-Boot] [PATCH v3 " Lukasz Majewski
2012-09-13  8:09   ` [U-Boot] [PATCH v3 1/7] vsprintf:fix: Change type returned by ustrtoul Lukasz Majewski
2012-09-13  8:10   ` [U-Boot] [PATCH v3 2/7] part:efi: Move part_efi.h file to ./include Lukasz Majewski
2012-09-13 18:54     ` Kim Phillips
2012-09-13  8:10   ` [U-Boot] [PATCH v3 3/7] gpt:doc: GPT (GUID Partition Table) documentation Lukasz Majewski
2012-09-17 17:58     ` Stephen Warren
2012-10-05 10:35       ` Lukasz Majewski
2012-10-05 15:19         ` Lukasz Majewski
2012-10-05 16:05         ` Stephen Warren
2012-09-13  8:10   ` [U-Boot] [PATCH v3 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Lukasz Majewski
2012-09-13  8:10   ` [U-Boot] [PATCH v3 5/7] gpt: Support for GPT (GUID Partition Table) restoration Lukasz Majewski
2012-09-17 18:07     ` Stephen Warren
2012-10-05 10:50       ` Lukasz Majewski
2012-09-13  8:10   ` [U-Boot] [PATCH v3 6/7] gpt: Support for new "gpt" command Lukasz Majewski
2012-09-13  8:10   ` [U-Boot] [PATCH v3 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats Lukasz Majewski
2012-11-09  9:22 ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Piotr Wilczek
2012-11-09  9:22   ` [U-Boot] [PATCH v4 1/7] vsprintf:fix: Change type returned by ustrtoul Piotr Wilczek
2012-11-19 19:19     ` Stephen Warren
2012-11-09  9:22   ` [U-Boot] [PATCH v4 2/7] part:efi: Move part_efi.h file to ./include Piotr Wilczek
2012-11-19 19:30     ` Stephen Warren
2012-11-19 20:41       ` Tom Rini
2012-11-20 17:46         ` Lukasz Majewski
2012-11-09  9:22   ` [U-Boot] [PATCH v4 3/7] gpt:doc: GPT (GUID Partition Table) documentation Piotr Wilczek
2012-11-19 19:28     ` Stephen Warren
2012-11-09 10:48   ` [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Piotr Wilczek
2012-11-09 10:48     ` [U-Boot] [PATCH v4 5/7] gpt: Support for GPT (GUID Partition Table) restoration Piotr Wilczek
2012-11-19 20:16       ` Stephen Warren
2012-11-21 13:18         ` Piotr Wilczek
2012-11-22 12:16           ` Lukasz Majewski
2012-11-26 23:46             ` Stephen Warren
2012-11-24 18:05           ` Stephen Warren
2012-11-26 13:08             ` Piotr Wilczek
2012-11-09 10:48     ` [U-Boot] [PATCH v4 6/7] gpt: Support for new "gpt" command Piotr Wilczek
2012-11-19 21:34       ` Stephen Warren
2012-11-21 11:22         ` Piotr Wilczek
2012-11-24 18:00           ` Stephen Warren
2012-11-26 13:08             ` Piotr Wilczek
2012-11-26 23:49               ` Stephen Warren
2012-11-09 10:48     ` [U-Boot] [PATCH v4 7/7] gpt: Enable support for GPT partition table restoration at Samsung's Trats Piotr Wilczek
2012-11-19 19:39     ` [U-Boot] [PATCH v4 4/7] gpt: The leXX_to_int() calls replaced with ones defined at <compiler.h> Stephen Warren
2012-11-19 20:43   ` [U-Boot] [PATCH v4 0/7] gpt: GUID Partition Table (GPT) restoration Tom Rini
2012-12-06 20:40   ` Tom Rini
2012-12-07  9:03     ` Piotr Wilczek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.