public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Joshua Watt <jpewhacker@gmail.com>
To: u-boot@lists.denx.de
Cc: Joshua Watt <JPEWhacker@gmail.com>,
	Heinrich Schuchardt <xypron.glpk@gmx.de>,
	Simon Glass <sjg@chromium.org>,
	Enric Balletbo i Serra <eballetb@redhat.com>
Subject: [PATCH v5 8/8] cmd: gpt: Add command to swap partition order
Date: Thu, 31 Aug 2023 10:51:41 -0600	[thread overview]
Message-ID: <20230831165144.592820-9-JPEWhacker@gmail.com> (raw)
In-Reply-To: <20230831165144.592820-1-JPEWhacker@gmail.com>

Adds a command called "gpt transpose" which will swap the order two
partition table entries in the GPT partition table (but leaves them
pointing to the same locations on disk).

This can be useful for swapping bootloaders in systems that use an A/B
partitioning scheme where the bootrom is hard coded to look for the
bootloader in a specific index in the GPT partition table.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 cmd/gpt.c                 | 46 ++++++++++++++++++++++++++++++++++++---
 doc/usage/cmd/gpt.rst     | 25 +++++++++++++++++++++
 test/py/tests/test_gpt.py | 19 ++++++++++++++++
 3 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/cmd/gpt.c b/cmd/gpt.c
index 927b6afa68..58b2c904a1 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -858,8 +858,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);
@@ -920,6 +921,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);
@@ -1123,7 +1159,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]);
@@ -1176,6 +1213,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"
@@ -1184,5 +1223,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
-- 
2.34.1


      parent reply	other threads:[~2023-08-31 16:53 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-15 16:26 [PATCH 0/6] cmd: gpt: GPT manipulation improvements Joshua Watt
2023-08-15 16:26 ` [PATCH 1/6] cmd: gpt: Remove confusing help text Joshua Watt
2023-08-18 14:23   ` Tom Rini
2023-08-23 23:57   ` Simon Glass
2023-08-15 16:26 ` [PATCH 2/6] cmd: gpt: Add command to set bootable flags Joshua Watt
2023-08-15 18:39   ` Simon Glass
2023-08-15 16:26 ` [PATCH 3/6] cmd: gpt: Add gpt_partition_bootable variable Joshua Watt
2023-08-15 16:26 ` [PATCH 4/6] cmd: gpt: Preserve type GUID if enabled Joshua Watt
2023-08-15 16:26 ` [PATCH 5/6] cmd: gpt: Preserve bootable flag Joshua Watt
2023-08-15 16:27 ` [PATCH 6/6] cmd: gpt: Add command to swap partition order Joshua Watt
2023-08-23 23:57   ` Simon Glass
2023-08-23 16:47 ` [PATCH v2 0/8] cmd: gpt: GPT manipulation improvements Joshua Watt
2023-08-23 16:47   ` [PATCH v2 1/8] cmd: gpt: Remove confusing help text Joshua Watt
2023-08-23 18:15     ` Tom Rini
2023-08-23 16:47   ` [PATCH v2 2/8] doc: Add gpt command documentation Joshua Watt
2023-08-23 18:15     ` Tom Rini
2023-08-23 23:57     ` Simon Glass
2023-08-23 16:47   ` [PATCH v2 3/8] tests: gpt: Remove test order dependency Joshua Watt
2023-08-23 23:57     ` Simon Glass
2023-08-24  3:29       ` Joshua Watt
2023-08-23 16:47   ` [PATCH v2 4/8] cmd: gpt: Add gpt_partition_bootable variable Joshua Watt
2023-08-23 23:57     ` Simon Glass
2023-08-23 16:47   ` [PATCH v2 5/8] cmd: gpt: Add command to set bootable flags Joshua Watt
2023-08-23 23:57     ` Simon Glass
2023-08-23 16:47   ` [PATCH v2 6/8] cmd: gpt: Preserve type GUID if enabled Joshua Watt
2023-08-23 23:57     ` Simon Glass
2023-08-23 16:47   ` [PATCH v2 7/8] cmd: gpt: Preserve bootable flag Joshua Watt
2023-08-23 23:57     ` Simon Glass
2023-08-23 16:47   ` [PATCH v2 8/8] cmd: gpt: Add command to swap partition order Joshua Watt
2023-08-25 19:38   ` [PATCH v3 0/8] cmd: gpt: GPT manipulation improvements Joshua Watt
2023-08-25 19:38     ` [PATCH v3 1/8] cmd: gpt: Remove confusing help text Joshua Watt
2023-08-25 19:38     ` [PATCH v3 2/8] doc: Add gpt command documentation Joshua Watt
2023-08-25 23:53       ` Simon Glass
2023-08-28 21:52         ` Joshua Watt
2023-08-26  1:57       ` Heinrich Schuchardt
2023-08-28 19:29         ` Joshua Watt
2023-08-28 20:01           ` Heinrich Schuchardt
2023-08-28 21:01             ` Joshua Watt
2023-08-25 19:38     ` [PATCH v3 3/8] tests: gpt: Remove test order dependency Joshua Watt
2023-08-25 19:38     ` [PATCH v3 4/8] cmd: gpt: Add gpt_partition_bootable variable Joshua Watt
2023-08-25 23:53       ` Simon Glass
2023-08-25 19:38     ` [PATCH v3 5/8] cmd: gpt: Add command to set bootable flags Joshua Watt
2023-08-25 19:38     ` [PATCH v3 6/8] cmd: gpt: Preserve type GUID if enabled Joshua Watt
2023-08-25 23:53       ` Simon Glass
2023-08-26  0:37       ` Heinrich Schuchardt
2023-08-25 19:38     ` [PATCH v3 7/8] cmd: gpt: Preserve bootable flag Joshua Watt
2023-08-25 19:38     ` [PATCH v3 8/8] cmd: gpt: Add command to swap partition order Joshua Watt
2023-08-25 23:53       ` Simon Glass
2023-08-26  1:00       ` Heinrich Schuchardt
2023-08-28 21:56     ` [PATCH v4 0/8] cmd: gpt: GPT manipulation improvements Joshua Watt
2023-08-28 21:56       ` [PATCH v4 1/8] cmd: gpt: Remove confusing help text Joshua Watt
2023-08-28 22:05         ` Heinrich Schuchardt
2023-08-28 21:56       ` [PATCH v4 2/8] doc: Add gpt command documentation Joshua Watt
2023-08-28 22:45         ` Heinrich Schuchardt
2023-08-28 22:59           ` Heinrich Schuchardt
2023-08-29 13:22             ` Joshua Watt
2023-08-28 21:56       ` [PATCH v4 3/8] tests: gpt: Remove test order dependency Joshua Watt
2023-08-28 21:56       ` [PATCH v4 4/8] cmd: gpt: Add gpt_partition_bootable variable Joshua Watt
2023-08-28 21:56       ` [PATCH v4 5/8] cmd: gpt: Add command to set bootable flags Joshua Watt
2023-08-28 22:54         ` Heinrich Schuchardt
2023-08-29 13:24           ` Joshua Watt
2023-08-28 21:56       ` [PATCH v4 6/8] cmd: gpt: Preserve type GUID if enabled Joshua Watt
2023-08-28 21:56       ` [PATCH v4 7/8] cmd: gpt: Preserve bootable flag Joshua Watt
2023-08-28 21:56       ` [PATCH v4 8/8] cmd: gpt: Add command to swap partition order Joshua Watt
2023-08-31 16:51       ` [PATCH v5 0/8] cmd: gpt: GPT manipulation improvements Joshua Watt
2023-08-31 16:51         ` [PATCH v5 1/8] cmd: gpt: Remove confusing help text Joshua Watt
2023-08-31 16:51         ` [PATCH v5 2/8] doc: Add gpt command documentation Joshua Watt
2023-08-31 16:51         ` [PATCH v5 3/8] tests: gpt: Remove test order dependency Joshua Watt
2023-09-12 15:17           ` Tom Rini
2023-08-31 16:51         ` [PATCH v5 4/8] cmd: gpt: Add gpt_partition_bootable variable Joshua Watt
2023-08-31 16:51         ` [PATCH v5 5/8] cmd: gpt: Add command to set bootable flags Joshua Watt
2023-08-31 16:51         ` [PATCH v5 6/8] cmd: gpt: Preserve type GUID if enabled Joshua Watt
2023-08-31 16:51         ` [PATCH v5 7/8] cmd: gpt: Preserve bootable flag Joshua Watt
2023-08-31 16:51         ` Joshua Watt [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230831165144.592820-9-JPEWhacker@gmail.com \
    --to=jpewhacker@gmail.com \
    --cc=eballetb@redhat.com \
    --cc=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox