uboot/cmd/part.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
   4 *
   5 * made from cmd_ext2, which was:
   6 *
   7 * (C) Copyright 2004
   8 * esd gmbh <www.esd-electronics.com>
   9 * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
  10 *
  11 * made from cmd_reiserfs by
  12 *
  13 * (C) Copyright 2003 - 2004
  14 * Sysgo Real-Time Solutions, AG <www.elinos.com>
  15 * Pavel Bartusek <pba@sysgo.com>
  16 */
  17
  18#include <common.h>
  19#include <config.h>
  20#include <command.h>
  21#include <env.h>
  22#include <part.h>
  23#include <vsprintf.h>
  24
  25enum cmd_part_info {
  26        CMD_PART_INFO_START = 0,
  27        CMD_PART_INFO_SIZE,
  28        CMD_PART_INFO_NUMBER
  29};
  30
  31static int do_part_uuid(int argc, char *const argv[])
  32{
  33        int part;
  34        struct blk_desc *dev_desc;
  35        struct disk_partition info;
  36
  37        if (argc < 2)
  38                return CMD_RET_USAGE;
  39        if (argc > 3)
  40                return CMD_RET_USAGE;
  41
  42        part = blk_get_device_part_str(argv[0], argv[1], &dev_desc, &info, 0);
  43        if (part < 0)
  44                return 1;
  45
  46        if (argc > 2)
  47                env_set(argv[2], info.uuid);
  48        else
  49                printf("%s\n", info.uuid);
  50
  51        return 0;
  52}
  53
  54static int do_part_list(int argc, char *const argv[])
  55{
  56        int ret;
  57        struct blk_desc *desc;
  58        char *var = NULL;
  59        bool bootable = false;
  60        int i;
  61
  62        if (argc < 2)
  63                return CMD_RET_USAGE;
  64
  65        if (argc > 2) {
  66                for (i = 2; i < argc ; i++) {
  67                        if (argv[i][0] == '-') {
  68                                if (!strcmp(argv[i], "-bootable")) {
  69                                        bootable = true;
  70                                } else {
  71                                        printf("Unknown option %s\n", argv[i]);
  72                                        return CMD_RET_USAGE;
  73                                }
  74                        } else {
  75                                var = argv[i];
  76                                break;
  77                        }
  78                }
  79
  80                /* Loops should have been exited at the last argument, which
  81                 * as it contained the variable */
  82                if (argc != i + 1)
  83                        return CMD_RET_USAGE;
  84        }
  85
  86        ret = blk_get_device_by_str(argv[0], argv[1], &desc);
  87        if (ret < 0)
  88                return 1;
  89
  90        if (var != NULL) {
  91                int p;
  92                char str[512] = { '\0', };
  93                struct disk_partition info;
  94
  95                for (p = 1; p < MAX_SEARCH_PARTITIONS; p++) {
  96                        char t[5];
  97                        int r = part_get_info(desc, p, &info);
  98
  99                        if (r != 0)
 100                                continue;
 101
 102                        if (bootable && !info.bootable)
 103                                continue;
 104
 105                        sprintf(t, "%s%x", str[0] ? " " : "", p);
 106                        strcat(str, t);
 107                }
 108                env_set(var, str);
 109                return 0;
 110        }
 111
 112        part_print(desc);
 113
 114        return 0;
 115}
 116
 117static int do_part_info(int argc, char *const argv[], enum cmd_part_info param)
 118{
 119        struct blk_desc *desc;
 120        struct disk_partition info;
 121        char buf[512] = { 0 };
 122        char *endp;
 123        int part;
 124        int err;
 125        int ret;
 126
 127        if (argc < 3)
 128                return CMD_RET_USAGE;
 129        if (argc > 4)
 130                return CMD_RET_USAGE;
 131
 132        ret = blk_get_device_by_str(argv[0], argv[1], &desc);
 133        if (ret < 0)
 134                return 1;
 135
 136        part = simple_strtoul(argv[2], &endp, 0);
 137        if (*endp == '\0') {
 138                err = part_get_info(desc, part, &info);
 139                if (err)
 140                        return 1;
 141        } else {
 142                part = part_get_info_by_name(desc, argv[2], &info);
 143                if (part < 0)
 144                        return 1;
 145        }
 146
 147        switch (param) {
 148        case CMD_PART_INFO_START:
 149                snprintf(buf, sizeof(buf), LBAF, info.start);
 150                break;
 151        case CMD_PART_INFO_SIZE:
 152                snprintf(buf, sizeof(buf), LBAF, info.size);
 153                break;
 154        case CMD_PART_INFO_NUMBER:
 155                snprintf(buf, sizeof(buf), "0x%x", part);
 156                break;
 157        default:
 158                printf("** Unknown cmd_part_info value: %d\n", param);
 159                return 1;
 160        }
 161
 162        if (argc > 3)
 163                env_set(argv[3], buf);
 164        else
 165                printf("%s\n", buf);
 166
 167        return 0;
 168}
 169
 170static int do_part_start(int argc, char *const argv[])
 171{
 172        return do_part_info(argc, argv, CMD_PART_INFO_START);
 173}
 174
 175static int do_part_size(int argc, char *const argv[])
 176{
 177        return do_part_info(argc, argv, CMD_PART_INFO_SIZE);
 178}
 179
 180static int do_part_number(int argc, char *const argv[])
 181{
 182        return do_part_info(argc, argv, CMD_PART_INFO_NUMBER);
 183}
 184
 185static int do_part_types(int argc, char * const argv[])
 186{
 187        struct part_driver *drv = ll_entry_start(struct part_driver,
 188                                                 part_driver);
 189        const int n_ents = ll_entry_count(struct part_driver, part_driver);
 190        struct part_driver *entry;
 191        int i = 0;
 192
 193        puts("Supported partition tables");
 194
 195        for (entry = drv; entry != drv + n_ents; entry++) {
 196                printf("%c %s", i ? ',' : ':', entry->name);
 197                i++;
 198        }
 199        if (!i)
 200                puts(": <none>");
 201        puts("\n");
 202        return CMD_RET_SUCCESS;
 203}
 204
 205static int do_part(struct cmd_tbl *cmdtp, int flag, int argc,
 206                   char *const argv[])
 207{
 208        if (argc < 2)
 209                return CMD_RET_USAGE;
 210
 211        if (!strcmp(argv[1], "uuid"))
 212                return do_part_uuid(argc - 2, argv + 2);
 213        else if (!strcmp(argv[1], "list"))
 214                return do_part_list(argc - 2, argv + 2);
 215        else if (!strcmp(argv[1], "start"))
 216                return do_part_start(argc - 2, argv + 2);
 217        else if (!strcmp(argv[1], "size"))
 218                return do_part_size(argc - 2, argv + 2);
 219        else if (!strcmp(argv[1], "number"))
 220                return do_part_number(argc - 2, argv + 2);
 221        else if (!strcmp(argv[1], "types"))
 222                return do_part_types(argc - 2, argv + 2);
 223        return CMD_RET_USAGE;
 224}
 225
 226U_BOOT_CMD(
 227        part,   CONFIG_SYS_MAXARGS,     1,      do_part,
 228        "disk partition related commands",
 229        "uuid <interface> <dev>:<part>\n"
 230        "    - print partition UUID\n"
 231        "part uuid <interface> <dev>:<part> <varname>\n"
 232        "    - set environment variable to partition UUID\n"
 233        "part list <interface> <dev>\n"
 234        "    - print a device's partition table\n"
 235        "part list <interface> <dev> [flags] <varname>\n"
 236        "    - set environment variable to the list of partitions\n"
 237        "      flags can be -bootable (list only bootable partitions)\n"
 238        "part start <interface> <dev> <part> <varname>\n"
 239        "    - set environment variable to the start of the partition (in blocks)\n"
 240        "      part can be either partition number or partition name\n"
 241        "part size <interface> <dev> <part> <varname>\n"
 242        "    - set environment variable to the size of the partition (in blocks)\n"
 243        "      part can be either partition number or partition name\n"
 244        "part number <interface> <dev> <part> <varname>\n"
 245        "    - set environment variable to the partition number using the partition name\n"
 246        "      part must be specified as partition name\n"
 247        "part types\n"
 248        "    - list supported partition table types"
 249);
 250