summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/gpt.c46
-rw-r--r--doc/usage/cmd/gpt.rst25
-rw-r--r--test/py/tests/test_gpt.py19
3 files changed, 87 insertions, 3 deletions
diff --git a/cmd/gpt.c b/cmd/gpt.c
index d5256035c3..d4068ee63d 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -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