Blame view
common/cmd_gpt.c
6.62 KB
8b0962376 gpt: Support for ... |
1 2 3 4 5 6 7 |
/* * 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> * |
1a4596601 Add GPL-2.0+ SPDX... |
8 |
* SPDX-License-Identifier: GPL-2.0+ |
8b0962376 gpt: Support for ... |
9 10 11 12 13 |
*/ #include <common.h> #include <malloc.h> #include <command.h> |
8b0962376 gpt: Support for ... |
14 15 16 |
#include <part_efi.h> #include <exports.h> #include <linux/ctype.h> |
3e34cf7bf gpt: fix partion ... |
17 |
#include <div64.h> |
8b0962376 gpt: Support for ... |
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
#ifndef CONFIG_PARTITION_UUIDS #error CONFIG_PARTITION_UUIDS must be enabled for CONFIG_CMD_GPT to be enabled #endif /** * extract_env(): Expand env name from string format '&{env_name}' * and return pointer to the env (if the env is set) * * @param str - pointer to string * @param env - pointer to pointer to extracted env * * @return - zero on successful expand and env is set */ static char extract_env(const char *str, char **env) { char *e, *s; if (!str || strlen(str) < 4) return -1; if ((strncmp(str, "${", 2) == 0) && (str[strlen(str) - 1] == '}')) { s = strdup(str); if (s == NULL) return -1; memset(s + strlen(s) - 1, '\0', 1); memmove(s, s + 2, strlen(s) - 1); e = getenv(s); free(s); if (e == NULL) { printf("Environmental '%s' not set ", str); return -1; /* env not set */ } *env = e; return 0; } return -1; } /** * extract_val(): Extract value from a key=value pair list (comma separated). * Only value for the given key is returend. * Function allocates memory for the value, remember to free! * * @param str - pointer to string with key=values pairs * @param key - pointer to the key to search for * * @return - pointer to allocated string with the value */ static char *extract_val(const char *str, const char *key) { char *v, *k; char *s, *strcopy; char *new = NULL; strcopy = strdup(str); if (strcopy == NULL) return NULL; s = strcopy; while (s) { v = strsep(&s, ","); if (!v) break; k = strsep(&v, "="); if (!k) break; if (strcmp(k, key) == 0) { new = strdup(v); break; } } free(strcopy); return new; } /** * set_gpt_info(): Fill partition information from string * function allocates memory, remember to free! * * @param dev_desc - pointer block device descriptor * @param str_part - pointer to string with partition information * @param str_disk_guid - pointer to pointer to allocated string with disk guid * @param partitions - pointer to pointer to allocated partitions array * @param parts_count - number of partitions * * @return - zero on success, otherwise error * */ static int set_gpt_info(block_dev_desc_t *dev_desc, const char *str_part, char **str_disk_guid, disk_partition_t **partitions, u8 *parts_count) { char *tok, *str, *s; int i; char *val, *p; int p_count; disk_partition_t *parts; int errno = 0; |
3e34cf7bf gpt: fix partion ... |
123 |
uint64_t size_ll, start_ll; |
8b0962376 gpt: Support for ... |
124 |
|
619f0fdf3 cmd/gpt: Support ... |
125 126 |
debug("%s: lba num: 0x%x %d ", __func__, |
8b0962376 gpt: Support for ... |
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
(unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba); if (str_part == NULL) return -1; str = strdup(str_part); /* extract disk guid */ s = str; tok = strsep(&s, ";"); val = extract_val(tok, "uuid_disk"); if (!val) { free(str); return -2; } if (extract_env(val, &p)) p = val; *str_disk_guid = strdup(p); free(val); if (strlen(s) == 0) return -3; i = strlen(s) - 1; if (s[i] == ';') s[i] = '\0'; /* calculate expected number of partitions */ p_count = 1; p = s; while (*p) { if (*p++ == ';') p_count++; } /* allocate memory for partitions */ parts = calloc(sizeof(disk_partition_t), p_count); |
1f8b546f9 Fix some obvious ... |
164 |
/* retrieve partitions data from string */ |
8b0962376 gpt: Support for ... |
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
for (i = 0; i < p_count; i++) { tok = strsep(&s, ";"); if (tok == NULL) break; /* uuid */ val = extract_val(tok, "uuid"); if (!val) { /* 'uuid' is mandatory */ errno = -4; goto err; } if (extract_env(val, &p)) p = val; if (strlen(p) >= sizeof(parts[i].uuid)) { printf("Wrong uuid format for partition %d ", i); errno = -4; goto err; } strcpy((char *)parts[i].uuid, p); free(val); /* name */ val = extract_val(tok, "name"); if (!val) { /* name is mandatory */ errno = -4; goto err; } if (extract_env(val, &p)) p = val; if (strlen(p) >= sizeof(parts[i].name)) { errno = -4; goto err; } strcpy((char *)parts[i].name, p); free(val); /* size */ val = extract_val(tok, "size"); if (!val) { /* 'size' is mandatory */ errno = -4; goto err; } if (extract_env(val, &p)) p = val; |
3e34cf7bf gpt: fix partion ... |
211 212 |
size_ll = ustrtoull(p, &p, 0); parts[i].size = lldiv(size_ll, dev_desc->blksz); |
8b0962376 gpt: Support for ... |
213 214 215 216 217 218 219 |
free(val); /* start address */ val = extract_val(tok, "start"); if (val) { /* start address is optional */ if (extract_env(val, &p)) p = val; |
3e34cf7bf gpt: fix partion ... |
220 221 |
start_ll = ustrtoull(p, &p, 0); parts[i].start = lldiv(start_ll, dev_desc->blksz); |
8b0962376 gpt: Support for ... |
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
free(val); } } *parts_count = p_count; *partitions = parts; free(str); return 0; err: free(str); free(*str_disk_guid); free(parts); return errno; } |
619f0fdf3 cmd/gpt: Support ... |
238 |
static int gpt_default(block_dev_desc_t *blk_dev_desc, const char *str_part) |
8b0962376 gpt: Support for ... |
239 240 241 242 243 |
{ int ret; char *str_disk_guid; u8 part_count = 0; disk_partition_t *partitions = NULL; |
8b0962376 gpt: Support for ... |
244 245 246 247 |
if (!str_part) return -1; /* fill partitions */ |
619f0fdf3 cmd/gpt: Support ... |
248 |
ret = set_gpt_info(blk_dev_desc, str_part, |
8b0962376 gpt: Support for ... |
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
&str_disk_guid, &partitions, &part_count); if (ret) { if (ret == -1) printf("No partition list provided "); if (ret == -2) printf("Missing disk guid "); if ((ret == -3) || (ret == -4)) printf("Partition list incomplete "); return -1; } /* save partitions layout to disk */ |
619f0fdf3 cmd/gpt: Support ... |
264 |
gpt_restore(blk_dev_desc, str_disk_guid, partitions, part_count); |
8b0962376 gpt: Support for ... |
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
free(str_disk_guid); free(partitions); 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; int dev = 0; |
619f0fdf3 cmd/gpt: Support ... |
285 286 |
char *ep; block_dev_desc_t *blk_dev_desc; |
8b0962376 gpt: Support for ... |
287 288 289 290 291 292 |
if (argc < 5) return CMD_RET_USAGE; /* command: 'write' */ if ((strcmp(argv[1], "write") == 0) && (argc == 5)) { |
619f0fdf3 cmd/gpt: Support ... |
293 294 295 296 297 |
dev = (int)simple_strtoul(argv[3], &ep, 10); if (!ep || ep[0] != '\0') { printf("'%s' is not a number ", argv[3]); return CMD_RET_USAGE; |
8b0962376 gpt: Support for ... |
298 |
} |
619f0fdf3 cmd/gpt: Support ... |
299 300 301 302 303 304 305 306 307 308 |
blk_dev_desc = get_dev(argv[2], dev); if (!blk_dev_desc) { printf("%s: %s dev %d NOT available ", __func__, argv[2], dev); return CMD_RET_FAILURE; } if (gpt_default(blk_dev_desc, argv[4])) return CMD_RET_FAILURE; |
8b0962376 gpt: Support for ... |
309 310 311 312 313 314 315 316 |
} else { return CMD_RET_USAGE; } return ret; } U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt, "GUID Partition Table", |
1f8b546f9 Fix some obvious ... |
317 318 |
"<command> <interface> <dev> <partitions_list> " |
8b0962376 gpt: Support for ... |
319 320 321 322 323 324 325 |
" - GUID partition table restoration " " Restore GPT information on a device connected " " to interface " ); |