
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" +);