[U-Boot] [PATCH v2 1/3] part:efi: add GUID for linux file system data

Previously, Linux used the same GUID for the data partitions as Windows (Basic data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7). This created problems when dual-booting Linux and Windows in UEFI-GPT Setup, so a new GUID (Linux filesystem data: 0FC63DAF-8483-4772-8E79-3D69D8477DE4) was defined jointly by GPT fdisk and GNU Parted developers.
Signed-off-by: Patrick Delaunay patrick.delaunay73@gmail.com --- see https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs and nota 9
Changes in v2: - None
include/part_efi.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/part_efi.h b/include/part_efi.h index 3012b91..c8fc873 100644 --- a/include/part_efi.h +++ b/include/part_efi.h @@ -43,6 +43,9 @@ #define PARTITION_BASIC_DATA_GUID \ EFI_GUID( 0xEBD0A0A2, 0xB9E5, 0x4433, \ 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7) +#define PARTITION_LINUX_FILE_SYSTEM_DATA_GUID \ + EFI_GUID(0x0FC63DAF, 0x8483, 0x4772, \ + 0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4) #define PARTITION_LINUX_RAID_GUID \ EFI_GUID( 0xa19d880f, 0x05fc, 0x4d3b, \ 0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e)

code under flag CONFIG_PARTITION_TYPE_GUID add parameter "type" to select partition type guid
example of use with gpt command :
partitions = uuid_disk=${uuid_gpt_disk}; \ name=boot,size=0x6bc00,uuid=${uuid_gpt_boot}; \ name=root,size=0x7538ba00,uuid=${uuid_gpt_root}, \ type=0fc63daf-8483-4772-8e79-3d69d8477de4;
gpt write mmc 0 $partitions
Signed-off-by: Patrick Delaunay patrick.delaunay73@gmail.com ---
Changes in v2: - change guid to type in gpt command parameter - change guid to type_guid in disk_partition_t - remove 'S' at the end of some flag CONFIG_PARTITION_TYPE_GUID
common/cmd_gpt.c | 17 +++++++++++++++++ disk/part.c | 9 +++++++++ disk/part_efi.c | 25 +++++++++++++++++++++++++ include/part.h | 3 +++ 4 files changed, 54 insertions(+)
diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c index c56fe15..e3c0297 100644 --- a/common/cmd_gpt.c +++ b/common/cmd_gpt.c @@ -218,6 +218,23 @@ static int set_gpt_info(block_dev_desc_t *dev_desc, strcpy((char *)parts[i].uuid, p); free(val); } +#ifdef CONFIG_PARTITION_TYPE_GUID + /* guid */ + val = extract_val(tok, "type"); + if (val) { + /* 'type' is optional */ + if (extract_env(val, &p)) + p = val; + if (strlen(p) >= sizeof(parts[i].type_guid)) { + printf("Wrong type guid format for partition %d\n", + i); + errno = -4; + goto err; + } + strcpy((char *)parts[i].type_guid, p); + free(val); + } +#endif /* name */ val = extract_val(tok, "name"); if (!val) { /* name is mandatory */ diff --git a/disk/part.c b/disk/part.c index 43485c9..a47ec8c 100644 --- a/disk/part.c +++ b/disk/part.c @@ -391,6 +391,9 @@ int get_partition_info(block_dev_desc_t *dev_desc, int part, /* The common case is no UUID support */ info->uuid[0] = 0; #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + info->type_guid[0] = 0; +#endif
switch (dev_desc->part_type) { #ifdef CONFIG_MAC_PARTITION @@ -526,6 +529,9 @@ int get_device_and_partition(const char *ifname, const char *dev_part_str, #ifdef CONFIG_PARTITION_UUIDS info->uuid[0] = 0; #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + info->type_guid[0] = 0; +#endif
return 0; } @@ -610,6 +616,9 @@ int get_device_and_partition(const char *ifname, const char *dev_part_str, #ifdef CONFIG_PARTITION_UUIDS info->uuid[0] = 0; #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + info->type_guid[0] = 0; +#endif
ret = 0; goto cleanup; diff --git a/disk/part_efi.c b/disk/part_efi.c index 15627f2..c124143 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -283,6 +283,10 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid, UUID_STR_FORMAT_GUID); #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b, + info->type_guid, UUID_STR_FORMAT_GUID); +#endif
debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__, info->start, info->size, info->name); @@ -419,6 +423,10 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, char *str_uuid; unsigned char *bin_uuid; #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + char *str_type_guid; + unsigned char *bin_type_guid; +#endif
for (i = 0; i < parts; i++) { /* partition starting lba */ @@ -445,9 +453,26 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, else gpt_e[i].ending_lba = cpu_to_le64(offset - 1);
+#ifdef CONFIG_PARTITION_TYPE_GUID + str_type_guid = partitions[i].type_guid; + bin_type_guid = gpt_e[i].partition_type_guid.b; + if (strlen(str_type_guid)) { + if (uuid_str_to_bin(str_type_guid, bin_type_guid, + UUID_STR_FORMAT_GUID)) { + printf("Partition no. %d: invalid type guid: %s\n", + i, str_type_guid); + return -1; + } + } else { + /* default partition type GUID */ + memcpy(bin_type_guid, + &PARTITION_BASIC_DATA_GUID, 16); + } +#else /* partition type GUID */ memcpy(gpt_e[i].partition_type_guid.b, &PARTITION_BASIC_DATA_GUID, 16); +#endif
#ifdef CONFIG_PARTITION_UUIDS str_uuid = partitions[i].uuid; diff --git a/include/part.h b/include/part.h index 8ea9b30..8b5ac12 100644 --- a/include/part.h +++ b/include/part.h @@ -93,6 +93,9 @@ typedef struct disk_partition { #ifdef CONFIG_PARTITION_UUIDS char uuid[37]; /* filesystem UUID as string, if exists */ #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + char type_guid[37]; /* type GUID as string, if exists */ +#endif } disk_partition_t;
/* Misc _get_dev functions */

Hi Patrick,
On 21 October 2015 at 06:14, Patrick Delaunay patrick.delaunay73@gmail.com wrote:
code under flag CONFIG_PARTITION_TYPE_GUID add parameter "type" to select partition type guid
example of use with gpt command :
partitions = uuid_disk=${uuid_gpt_disk}; \ name=boot,size=0x6bc00,uuid=${uuid_gpt_boot}; \ name=root,size=0x7538ba00,uuid=${uuid_gpt_root}, \ type=0fc63daf-8483-4772-8e79-3d69d8477de4;
gpt write mmc 0 $partitions
Signed-off-by: Patrick Delaunay patrick.delaunay73@gmail.com
Changes in v2:
- change guid to type in gpt command parameter
- change guid to type_guid in disk_partition_t
- remove 'S' at the end of some flag CONFIG_PARTITION_TYPE_GUID
common/cmd_gpt.c | 17 +++++++++++++++++ disk/part.c | 9 +++++++++ disk/part_efi.c | 25 +++++++++++++++++++++++++ include/part.h | 3 +++ 4 files changed, 54 insertions(+)
Can you add some documentation somewhere for these patches?
Regards, Simon

On Wed, Oct 21, 2015 at 02:14:48PM +0200, Patrick Delaunay wrote:
code under flag CONFIG_PARTITION_TYPE_GUID add parameter "type" to select partition type guid
example of use with gpt command :
partitions = uuid_disk=${uuid_gpt_disk}; \ name=boot,size=0x6bc00,uuid=${uuid_gpt_boot}; \ name=root,size=0x7538ba00,uuid=${uuid_gpt_root}, \ type=0fc63daf-8483-4772-8e79-3d69d8477de4;
gpt write mmc 0 $partitions
Signed-off-by: Patrick Delaunay patrick.delaunay73@gmail.com
Reviewed-by: Tom Rini trini@konsulko.com
But I want to echo Simon's comment that we should update the docs a bit, perhaps a few more words and an example in doc/README.gpt.

Hi,
Ok. I will provided documentation update in version 3.
Patrick Le 23 oct. 2015 6:52 PM, "Tom Rini" trini@konsulko.com a écrit :
On Wed, Oct 21, 2015 at 02:14:48PM +0200, Patrick Delaunay wrote:
code under flag CONFIG_PARTITION_TYPE_GUID add parameter "type" to select partition type guid
example of use with gpt command :
partitions = uuid_disk=${uuid_gpt_disk}; \ name=boot,size=0x6bc00,uuid=${uuid_gpt_boot}; \ name=root,size=0x7538ba00,uuid=${uuid_gpt_root}, \ type=0fc63daf-8483-4772-8e79-3d69d8477de4;
gpt write mmc 0 $partitions
Signed-off-by: Patrick Delaunay patrick.delaunay73@gmail.com
Reviewed-by: Tom Rini trini@konsulko.com
But I want to echo Simon's comment that we should update the docs a bit, perhaps a few more words and an example in doc/README.gpt.
-- Tom

short strings can be used in type parameter of gpt command to replace the guid string for the types known by u-boot
partitions = name=boot,size=0x6bc00,type=data; \ name=root,size=0x7538ba00,type=linux; gpt write mmc 0 $partitions
and they are also used to display the type of partition in "part list" command
Partition Map for MMC device 0 -- Partition Type: EFI
Part Start LBA End LBA Name Attributes Type GUID Partition GUID 1 0x00000022 0x0000037f "boot" attrs: 0x0000000000000000 type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 type: data guid: d117f98e-6f2c-d04b-a5b2-331a19f91cb2 2 0x00000380 0x003a9fdc "root" attrs: 0x0000000000000000 type: 0fc63daf-8483-4772-8e79-3d69d8477de4 type: linux guid: 25718777-d0ad-7443-9e60-02cb591c9737
Signed-off-by: Patrick Delaunay patrick.delaunay73@gmail.com ---
Changes in v2: - guid change to type in gpt parameter - remove hardcoded array size and use ARRAY_SIZE - use guid in parameter name - array is renamed to list_guid (it could be not limited to partition type)
disk/part_efi.c | 4 ++++ include/uuid.h | 4 ++++ lib/uuid.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/disk/part_efi.c b/disk/part_efi.c index c124143..ea9c615 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -223,6 +223,10 @@ void print_part_efi(block_dev_desc_t * dev_desc) uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b; uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); printf("\ttype:\t%s\n", uuid); +#ifdef CONFIG_PARTITION_TYPE_GUID + if (!uuid_guid_get_str(uuid_bin, uuid)) + printf("\ttype:\t%s\n", uuid); +#endif uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b; uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); printf("\tguid:\t%s\n", uuid); diff --git a/include/uuid.h b/include/uuid.h index 93027c1..c3f423f 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -36,6 +36,10 @@ enum { int uuid_str_valid(const char *uuid); int uuid_str_to_bin(char *uuid_str, unsigned char *uuid_bin, int str_format); void uuid_bin_to_str(unsigned char *uuid_bin, char *uuid_str, int str_format); +#ifdef CONFIG_PARTITION_TYPE_GUID +int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin); +int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str); +#endif void gen_rand_uuid(unsigned char *uuid_bin); void gen_rand_uuid_str(char *uuid_str, int str_format); #endif diff --git a/lib/uuid.c b/lib/uuid.c index f6b4423..c8584ed 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -80,10 +80,65 @@ int uuid_str_valid(const char *uuid) return 1; }
+#ifdef CONFIG_PARTITION_TYPE_GUID +static const struct { + const char *string; + efi_guid_t guid; +} list_guid[] = { + {"system", PARTITION_SYSTEM_GUID}, + {"mbr", LEGACY_MBR_PARTITION_GUID}, + {"msft", PARTITION_MSFT_RESERVED_GUID}, + {"data", PARTITION_BASIC_DATA_GUID}, + {"linux", PARTITION_LINUX_FILE_SYSTEM_DATA_GUID}, + {"raid", PARTITION_LINUX_RAID_GUID}, + {"swap", PARTITION_LINUX_SWAP_GUID}, + {"lvm", PARTITION_LINUX_LVM_GUID} +}; + +/* + * uuid_guid_get_bin() - this function get GUID bin for string + * + * @param guid_str - pointer to partition type string + * @param guid_bin - pointer to allocated array for big endian output [16B] + */ +int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(list_guid); i++) { + if (!strcmp(list_guid[i].string, guid_str)) { + memcpy(guid_bin, &list_guid[i].guid, 16); + return 0; + } + } + return -ENODEV; +} + +/* + * uuid_guid_get_str() - this function get string for GUID. + * + * @param guid_bin - pointer to string with partition type guid [16B] + * @param guid_str - pointer to allocated partition type string [7B] + */ +int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str) +{ + int i; + + *guid_str = 0; + for (i = 0; i < ARRAY_SIZE(list_guid); i++) { + if (!memcmp(list_guid[i].guid.b, guid_bin, 16)) { + strcpy(guid_str, list_guid[i].string); + return 0; + } + } + return -ENODEV; +} +#endif + /* * uuid_str_to_bin() - convert string UUID or GUID to big endian binary data. * - * @param uuid_str - pointer to UUID or GUID string [37B] + * @param uuid_str - pointer to UUID or GUID string [37B] or GUID shorcut * @param uuid_bin - pointer to allocated array for big endian output [16B] * @str_format - UUID string format: 0 - UUID; 1 - GUID */ @@ -93,8 +148,13 @@ int uuid_str_to_bin(char *uuid_str, unsigned char *uuid_bin, int str_format) uint32_t tmp32; uint64_t tmp64;
- if (!uuid_str_valid(uuid_str)) + if (!uuid_str_valid(uuid_str)) { +#ifdef CONFIG_PARTITION_TYPE_GUID + if (!uuid_guid_get_bin(uuid_str, uuid_bin)) + return 0; +#endif return -EINVAL; + }
if (str_format == UUID_STR_FORMAT_STD) { tmp32 = cpu_to_be32(simple_strtoul(uuid_str, NULL, 16));

On Wed, Oct 21, 2015 at 02:14:49PM +0200, Patrick Delaunay wrote:
short strings can be used in type parameter of gpt command to replace the guid string for the types known by u-boot
partitions = name=boot,size=0x6bc00,type=data; \ name=root,size=0x7538ba00,type=linux; gpt write mmc 0 $partitions
and they are also used to display the type of partition in "part list" command
Partition Map for MMC device 0 -- Partition Type: EFI
Part Start LBA End LBA Name Attributes Type GUID Partition GUID 1 0x00000022 0x0000037f "boot" attrs: 0x0000000000000000 type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 type: data guid: d117f98e-6f2c-d04b-a5b2-331a19f91cb2 2 0x00000380 0x003a9fdc "root" attrs: 0x0000000000000000 type: 0fc63daf-8483-4772-8e79-3d69d8477de4 type: linux guid: 25718777-d0ad-7443-9e60-02cb591c9737
Signed-off-by: Patrick Delaunay patrick.delaunay73@gmail.com
Reviewed-by: Tom Rini trini@konsulko.com

On Wed, Oct 21, 2015 at 02:14:47PM +0200, Patrick Delaunay wrote:
Previously, Linux used the same GUID for the data partitions as Windows (Basic data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7). This created problems when dual-booting Linux and Windows in UEFI-GPT Setup, so a new GUID (Linux filesystem data: 0FC63DAF-8483-4772-8E79-3D69D8477DE4) was defined jointly by GPT fdisk and GNU Parted developers.
Signed-off-by: Patrick Delaunay patrick.delaunay73@gmail.com
Reviewed-by: Tom Rini trini@konsulko.com
participants (3)
-
Patrick Delaunay
-
Simon Glass
-
Tom Rini