[U-Boot] [PATCH 1/3] disk: part_efi: parse and store partition UUID

From: Stephen Warren swarren@nvidia.com
Each EFI partition table entry contains a UUID. Extend U-Boot's struct disk_partition to be able to store this information, and modify get_partition_info_efi() to fill it in.
The implementation of uuid_string() was stolen from the Linux kernel.
Signed-off-by: Stephen Warren swarren@nvidia.com --- Note: I made this field part of struct disk_partition, and wrote a generic command to retrieve it, rather than adding an EFI-/GPT-specific command, since I imagine the kernel's PARTUUID support could be extended to support e.g. NT disk signatures, or other partition types, in the future.
disk/part.c | 3 +++ disk/part_efi.c | 21 +++++++++++++++++++++ include/part.h | 1 + 3 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/disk/part.c b/disk/part.c index 76f3939..266d77e 100644 --- a/disk/part.c +++ b/disk/part.c @@ -294,6 +294,9 @@ void init_part (block_dev_desc_t * dev_desc) int get_partition_info (block_dev_desc_t *dev_desc, int part , disk_partition_t *info) { + /* The common case is no UUID support */ + info->uuid[0] = 0; + switch (dev_desc->part_type) { #ifdef CONFIG_MAC_PARTITION case PART_TYPE_MAC: diff --git a/disk/part_efi.c b/disk/part_efi.c index 02927a0..199c054 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -154,6 +154,26 @@ void print_part_efi(block_dev_desc_t * dev_desc) return; }
+static void uuid_string(unsigned char *uuid, char *str) +{ + static const u8 le[16] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, + 12, 13, 14, 15}; + int i; + + for (i = 0; i < 16; i++) { + sprintf(str, "%02x", uuid[le[i]]); + str += 2; + switch (i) { + case 3: + case 5: + case 7: + case 9: + *str++ = '-'; + break; + } + } +} + int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, disk_partition_t * info) { @@ -183,6 +203,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, sprintf((char *)info->name, "%s", print_efiname(&gpt_pte[part - 1])); sprintf((char *)info->type, "U-Boot"); + uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid);
debug("%s: start 0x%lX, size 0x%lX, name %s", __func__, info->start, info->size, info->name); diff --git a/include/part.h b/include/part.h index e1478f4..52002f5 100644 --- a/include/part.h +++ b/include/part.h @@ -93,6 +93,7 @@ typedef struct disk_partition { ulong blksz; /* block size in bytes */ uchar name[32]; /* partition name */ uchar type[32]; /* string type description */ + char uuid[37]; /* filesystem UUID as string, if exists */ } disk_partition_t;
/* Misc _get_dev functions */

From: Stephen Warren swarren@nvidia.com
This implements the following:
partuuid mmc 0:1 -> prints the partition's UUID. partuuic mmc 0:1 uuid -> sets environment variable "uuid" to the partition's UUID.
This can be useful when writing a bootcmd which searches all known devices for something bootable, and then wants the kernel to use the same partition as the root device, e.g.:
partuuid ${devtype} ${devnum}:${rootpart} uuid setenv bootargs root=PARTUUID=${uuid} ...
Signed-off-by: Stephen Warren swarren@nvidia.com --- common/Makefile | 1 + common/cmd_partuuid.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 0 deletions(-) create mode 100644 common/cmd_partuuid.c
diff --git a/common/Makefile b/common/Makefile index 483eb4d..bc39997 100644 --- a/common/Makefile +++ b/common/Makefile @@ -129,6 +129,7 @@ COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o COBJS-$(CONFIG_CMD_NET) += cmd_net.o COBJS-$(CONFIG_CMD_ONENAND) += cmd_onenand.o COBJS-$(CONFIG_CMD_OTP) += cmd_otp.o +COBJS-$(CONFIG_CMD_PARTUUID) += cmd_partuuid.o ifdef CONFIG_PCI COBJS-$(CONFIG_CMD_PCI) += cmd_pci.o endif diff --git a/common/cmd_partuuid.c b/common/cmd_partuuid.c new file mode 100644 index 0000000..c85606c --- /dev/null +++ b/common/cmd_partuuid.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * made from cmd_ext2, which was: + * + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt reinhard.arlt@esd-electronics.com + * + * made from cmd_reiserfs by + * + * (C) Copyright 2003 - 2004 + * Sysgo Real-Time Solutions, AG <www.elinos.com> + * Pavel Bartusek pba@sysgo.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, see http://www.gnu.org/licenses/. + */ + +#include <common.h> +#include <config.h> +#include <command.h> +#include <part.h> +#include <vsprintf.h> + +int do_partuuid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int dev; + int part; + char *ep; + block_dev_desc_t *dev_desc; + disk_partition_t info; + + if (argc < 3) + return CMD_RET_USAGE; + + dev = (int)simple_strtoul(argv[2], &ep, 16); + dev_desc = get_dev(argv[1], dev); + if (dev_desc == NULL) { + printf("Block device %s %d not supported\n", argv[1], dev); + return 1; + } + + if (*ep) { + if (*ep != ':') { + puts("Invalid device; use dev[:part]\n"); + return 1; + } + part = (int)simple_strtoul(++ep, NULL, 16); + } else { + part = 1; + } + + if (get_partition_info(dev_desc, part, &info)) { + printf("Bad partition %d\n", part); + return 1; + } + + if (argc > 3) + setenv(argv[3], info.uuid); + else + printf("%s\n", info.uuid); + + return 0; +} + +U_BOOT_CMD( + partuuid, 4, 1, do_partuuid, + "partition UUID retrieval", + "<interface> <dev[:part]>\n" + " - show filesystem UUID of specified partition" + "<interface> <dev[:part]> <varname>\n" + " - write filesystem UUID to environmane variable" +);

On 08/16/2012 05:15 PM, Stephen Warren wrote:
This implements the following:
partuuid mmc 0:1 -> prints the partition's UUID. partuuic mmc 0:1 uuid -> sets environment variable "uuid" to the partition's UUID.
This can be useful when writing a bootcmd which searches all known devices for something bootable, and then wants the kernel to use the same partition as the root device, e.g.:
partuuid ${devtype} ${devnum}:${rootpart} uuid setenv bootargs root=PARTUUID=${uuid} ...
I guess one thing I might mention here:
I can imagine other partition-oriented commands existing, e.g. a command to find the bootable partition on a particular storage device. I'm not sure if we should create a single "part" command with various sub-options for this, e.g.:
part uuid mmc 0:1 part get-bootable mmc 0
or create separate commands:
partuuid mmc 0:1 part-get-bootable mmc 0

Hi Stephen,
On 08/16/2012 05:15 PM, Stephen Warren wrote:
This implements the following:
partuuid mmc 0:1 -> prints the partition's UUID. partuuic mmc 0:1 uuid -> sets environment variable "uuid" to the partition's UUID.
This can be useful when writing a bootcmd which searches all known devices for something bootable, and then wants the kernel to use the same partition as the root device, e.g.:
partuuid ${devtype} ${devnum}:${rootpart} uuid setenv bootargs root=PARTUUID=${uuid} ...
I guess one thing I might mention here:
I can imagine other partition-oriented commands existing, e.g. a command to find the bootable partition on a particular storage device. I'm not sure if we should create a single "part" command with various sub-options for this, e.g.:
part uuid mmc 0:1 part get-bootable mmc 0
I'm now working at restoring the GPT (GUID Partition Table) at MMC in u-boot.
I plan to implement a separate command - gptrestore However, I think that one single command would be more suitable for this purpose.
or create separate commands:
partuuid mmc 0:1 part-get-bootable mmc 0

On 08/17/2012 12:46 AM, Lukasz Majewski wrote:
Hi Stephen,
On 08/16/2012 05:15 PM, Stephen Warren wrote:
This implements the following:
partuuid mmc 0:1 -> prints the partition's UUID. partuuic mmc 0:1 uuid -> sets environment variable "uuid" to the partition's UUID.
This can be useful when writing a bootcmd which searches all known devices for something bootable, and then wants the kernel to use the same partition as the root device, e.g.:
partuuid ${devtype} ${devnum}:${rootpart} uuid setenv bootargs root=PARTUUID=${uuid} ...
I guess one thing I might mention here:
I can imagine other partition-oriented commands existing, e.g. a command to find the bootable partition on a particular storage device. I'm not sure if we should create a single "part" command with various sub-options for this, e.g.:
part uuid mmc 0:1 part get-bootable mmc 0
I'm now working at restoring the GPT (GUID Partition Table) at MMC in u-boot.
I plan to implement a separate command - gptrestore However, I think that one single command would be more suitable for this purpose.
What will gptrestore do?

On Fri, 17 Aug 2012 09:08:16 -0600 Stephen Warren swarren@wwwdotorg.org wrote:
On 08/17/2012 12:46 AM, Lukasz Majewski wrote:
Hi Stephen,
On 08/16/2012 05:15 PM, Stephen Warren wrote:
This implements the following:
partuuid mmc 0:1 -> prints the partition's UUID. partuuic mmc 0:1 uuid -> sets environment variable "uuid" to the partition's UUID.
This can be useful when writing a bootcmd which searches all known devices for something bootable, and then wants the kernel to use the same partition as the root device, e.g.:
partuuid ${devtype} ${devnum}:${rootpart} uuid setenv bootargs root=PARTUUID=${uuid} ...
I guess one thing I might mention here:
I can imagine other partition-oriented commands existing, e.g. a command to find the bootable partition on a particular storage device. I'm not sure if we should create a single "part" command with various sub-options for this, e.g.:
part uuid mmc 0:1 part get-bootable mmc 0
I'm now working at restoring the GPT (GUID Partition Table) at MMC in u-boot.
I plan to implement a separate command - gptrestore However, I think that one single command would be more suitable for this purpose.
What will gptrestore do?
It will write a GPT table on the eMMC memory. Definitions for partitions are read from u-boot environment variable.

From: Stephen Warren swarren@nvidia.com
This is extremely likely to be used from the boot.scr that Tegra's default bootcmd locates and executes.
Signed-off-by: Stephen Warren swarren@nvidia.com --- include/configs/tegra20-common-post.h | 5 +++++ include/configs/tegra20-common.h | 1 + 2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/include/configs/tegra20-common-post.h b/include/configs/tegra20-common-post.h index 42f270f..b7bbc0c 100644 --- a/include/configs/tegra20-common-post.h +++ b/include/configs/tegra20-common-post.h @@ -209,6 +209,11 @@ #undef CONFIG_CMD_USB #endif
+/* remove partuuid command support */ +#ifdef CONFIG_CMD_PARTUUID +#undef CONFIG_CMD_PARTUUID +#endif + #endif /* CONFIG_SPL_BUILD */
#endif /* __TEGRA20_COMMON_POST_H */ diff --git a/include/configs/tegra20-common.h b/include/configs/tegra20-common.h index c9e8b6b..c76eea4 100644 --- a/include/configs/tegra20-common.h +++ b/include/configs/tegra20-common.h @@ -113,6 +113,7 @@
/* include default commands */ #include <config_cmd_default.h> +#define CONFIG_CMD_PARTUUID
/* remove unused commands */ #undef CONFIG_CMD_FLASH /* flinfo, erase, protect */

On Thu, Aug 16, 2012 at 4:15 PM, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
This is extremely likely to be used from the boot.scr that Tegra's default bootcmd locates and executes.
Signed-off-by: Stephen Warren swarren@nvidia.com
Acked-by: Simon Glass sjg@chromium.org
include/configs/tegra20-common-post.h | 5 +++++ include/configs/tegra20-common.h | 1 + 2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/include/configs/tegra20-common-post.h b/include/configs/tegra20-common-post.h index 42f270f..b7bbc0c 100644 --- a/include/configs/tegra20-common-post.h +++ b/include/configs/tegra20-common-post.h @@ -209,6 +209,11 @@ #undef CONFIG_CMD_USB #endif
+/* remove partuuid command support */ +#ifdef CONFIG_CMD_PARTUUID +#undef CONFIG_CMD_PARTUUID +#endif
#endif /* CONFIG_SPL_BUILD */
#endif /* __TEGRA20_COMMON_POST_H */ diff --git a/include/configs/tegra20-common.h b/include/configs/tegra20-common.h index c9e8b6b..c76eea4 100644 --- a/include/configs/tegra20-common.h +++ b/include/configs/tegra20-common.h @@ -113,6 +113,7 @@
/* include default commands */ #include <config_cmd_default.h> +#define CONFIG_CMD_PARTUUID
/* remove unused commands */
#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */
1.7.0.4
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Dear Stephen Warren,
In message 1345158942-31512-1-git-send-email-swarren@wwwdotorg.org you wrote:
From: Stephen Warren swarren@nvidia.com
Each EFI partition table entry contains a UUID. Extend U-Boot's struct disk_partition to be able to store this information, and modify get_partition_info_efi() to fill it in.
The implementation of uuid_string() was stolen from the Linux kernel.
Signed-off-by: Stephen Warren swarren@nvidia.com
Can we please make this addition dependent on EFI support being enabled? Otherwise the increased memory footprint will hit all users, even if they never use EFI at all.
Best regards,
Wolfgang Denk

On 09/02/2012 10:45 AM, Wolfgang Denk wrote:
Dear Stephen Warren,
In message 1345158942-31512-1-git-send-email-swarren@wwwdotorg.org you wrote:
From: Stephen Warren swarren@nvidia.com
Each EFI partition table entry contains a UUID. Extend U-Boot's struct disk_partition to be able to store this information, and modify get_partition_info_efi() to fill it in.
The implementation of uuid_string() was stolen from the Linux kernel.
Signed-off-by: Stephen Warren swarren@nvidia.com
Can we please make this addition dependent on EFI support being enabled? Otherwise the increased memory footprint will hit all users, even if they never use EFI at all.
(I assume you're talking about the change to the partition info structure, since IIRC all the other code was already in either the EFI partition code already, or a new command under its own ifdef).
I'm also planning a patch that fills in this UUID field for MBR/DOS partition tables too. That'd require the ifdef to check 2 different config symbols, and perhaps more in the future. It seems a little messy to ifdef this just to save 4 bytes. Are you sure you want to do this?
participants (4)
-
Lukasz Majewski
-
Simon Glass
-
Stephen Warren
-
Wolfgang Denk