diff options
-rw-r--r-- | cmd/gpt.c | 46 | ||||
-rw-r--r-- | doc/usage/cmd/gpt.rst | 25 | ||||
-rw-r--r-- | test/py/tests/test_gpt.py | 19 |
3 files changed, 87 insertions, 3 deletions
@@ -856,8 +856,9 @@ static int do_rename_gpt_parts(struct blk_desc *dev_desc, char *subcomm, u8 part_count = 0; int partlistlen, ret, numparts = 0, partnum, i = 1, ctr1 = 0, ctr2 = 0; - if ((subcomm == NULL) || (name1 == NULL) || (name2 == NULL) || - (strcmp(subcomm, "swap") && (strcmp(subcomm, "rename")))) + if (!subcomm || !name1 || !name2 || + (strcmp(subcomm, "swap") && strcmp(subcomm, "rename") && + strcmp(subcomm, "transpose"))) return -EINVAL; ret = get_disk_guid(dev_desc, disk_guid); @@ -918,6 +919,41 @@ static int do_rename_gpt_parts(struct blk_desc *dev_desc, char *subcomm, ret = -EINVAL; goto out; } + } else if (!strcmp(subcomm, "transpose")) { + int idx1, idx2; + struct disk_partition* first = NULL; + struct disk_partition* second= NULL; + struct disk_partition tmp_part; + + idx1 = simple_strtoul(name1, NULL, 10); + idx2 = simple_strtoul(name2, NULL, 10); + if (idx1 == idx2) { + printf("Cannot swap partition with itself\n"); + ret = -EINVAL; + goto out; + } + + list_for_each(pos, &disk_partitions) { + curr = list_entry(pos, struct disk_part, list); + if (curr->partnum == idx1) + first = &curr->gpt_part_info; + else if (curr->partnum == idx2) + second = &curr->gpt_part_info; + } + if (!first) { + printf("Illegal partition number %s\n", name1); + ret = -EINVAL; + goto out; + } + if (!second) { + printf("Illegal partition number %s\n", name2); + ret = -EINVAL; + goto out; + } + + tmp_part = *first; + *first = *second; + *second = tmp_part; } else { /* rename */ if (strlen(name2) > PART_NAME_LEN) { printf("Names longer than %d characters are truncated.\n", PART_NAME_LEN); @@ -1121,7 +1157,8 @@ static int do_gpt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } else if (strcmp(argv[1], "read") == 0) { ret = do_get_gpt_info(blk_dev_desc, (argc == 5) ? argv[4] : NULL); } else if ((strcmp(argv[1], "swap") == 0) || - (strcmp(argv[1], "rename") == 0)) { + (strcmp(argv[1], "rename") == 0) || + (strcmp(argv[1], "transpose") == 0)) { ret = do_rename_gpt_parts(blk_dev_desc, argv[1], argv[4], argv[5]); } else if ((strcmp(argv[1], "set-bootable") == 0)) { ret = gpt_set_bootable(blk_dev_desc, argv[4]); @@ -1174,6 +1211,8 @@ U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt, " gpt swap <interface> <dev> <name1> <name2>\n" " - change all partitions named name1 to name2\n" " and vice-versa\n" + " gpt transpose <interface> <dev> <part1> <part2>\n" + " - Swap the order of the entries for part1 and part2 in the partition table\n" " gpt rename <interface> <dev> <part> <name>\n" " - rename the specified partition\n" " gpt set-bootable <interface> <dev> <list>\n" @@ -1182,5 +1221,6 @@ U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt, " gpt swap mmc 0 foo bar\n" " gpt rename mmc 0 3 foo\n" " gpt set-bootable mmc 0 boot_a,boot_b\n" + " gpt transpose mmc 0 1 2\n" #endif ); diff --git a/doc/usage/cmd/gpt.rst b/doc/usage/cmd/gpt.rst index 288dd365c0..f6115ecb0e 100644 --- a/doc/usage/cmd/gpt.rst +++ b/doc/usage/cmd/gpt.rst @@ -16,6 +16,7 @@ Synopsis gpt set-bootable <interface> <dev> <partition list> gpt setenv <interface> <dev> <partition name> gpt swap <interface> <dev> <name1> <name2> + gpt transpose <interface> <dev> <part1> <part2> gpt verify <interface> <dev> [<partition string>] gpt write <interface> <dev> <partition string> @@ -126,6 +127,13 @@ Changes the names of all partitions that are named 'name1' to be 'name2', and all partitions named 'name2' to be 'name1'. CONFIG_CMD_GPT_RENAME=y is required. +gpt transpose +~~~~~~~~~~~~~ + +Swaps the order of two partition table entries with indexes 'part1' and 'part2' +in the partition table, but otherwise leaves the actual partition data +untouched. + gpt verify ~~~~~~~~~~ @@ -199,3 +207,20 @@ Get the GUID for a disk:: Set the bootable flag for the 'boot' partition and clear it for all others:: => gpt set-bootable mmc 0 boot + +Swap the order of the 'boot' and 'rootfs' partition table entries:: + => gpt setenv mmc 0 rootfs + => echo ${gpt_partition_entry} + 2 + => gpt setenv mmc 0 boot + => echo ${gpt_partition_entry} + 1 + + => gpt transpose mmc 0 1 2 + + => gpt setenv mmc 0 rootfs + => echo ${gpt_partition_entry} + 1 + => gpt setenv mmc 0 boot + => echo ${gpt_partition_entry} + 2 diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index b4c03bc3a2..6e135b663e 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -329,3 +329,22 @@ def test_gpt_write(state_disk_image, u_boot_console): assert '0x00001000 0x00001bff "second"' in output output = u_boot_console.run_command('gpt guid host 0') assert '375a56f7-d6c9-4e81-b5f0-09d41ca89efe' in output + +@pytest.mark.buildconfigspec('cmd_gpt') +@pytest.mark.buildconfigspec('cmd_gpt_rename') +@pytest.mark.buildconfigspec('cmd_part') +@pytest.mark.requiredtool('sgdisk') +def test_gpt_transpose(state_disk_image, u_boot_console): + """Test the gpt transpose command.""" + + u_boot_console.run_command('host bind 0 ' + state_disk_image.path) + output = u_boot_console.run_command('part list host 0') + assert '1\t0x00000800\t0x00000fff\t"part1"' in output + assert '2\t0x00001000\t0x00001bff\t"part2"' in output + + output = u_boot_console.run_command('gpt transpose host 0 1 2') + assert 'success!' in output + + output = u_boot_console.run_command('part list host 0') + assert '2\t0x00000800\t0x00000fff\t"part1"' in output + assert '1\t0x00001000\t0x00001bff\t"part2"' in output |