mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-17 22:49:02 +00:00
cmd: gpt: Add command to swap partition order
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>
This commit is contained in:
parent
648140f77a
commit
7cc1d87d7e
3 changed files with 87 additions and 3 deletions
46
cmd/gpt.c
46
cmd/gpt.c
|
@ -856,8 +856,9 @@ static int do_rename_gpt_parts(struct blk_desc *dev_desc, char *subcomm,
|
||||||
u8 part_count = 0;
|
u8 part_count = 0;
|
||||||
int partlistlen, ret, numparts = 0, partnum, i = 1, ctr1 = 0, ctr2 = 0;
|
int partlistlen, ret, numparts = 0, partnum, i = 1, ctr1 = 0, ctr2 = 0;
|
||||||
|
|
||||||
if ((subcomm == NULL) || (name1 == NULL) || (name2 == NULL) ||
|
if (!subcomm || !name1 || !name2 ||
|
||||||
(strcmp(subcomm, "swap") && (strcmp(subcomm, "rename"))))
|
(strcmp(subcomm, "swap") && strcmp(subcomm, "rename") &&
|
||||||
|
strcmp(subcomm, "transpose")))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ret = get_disk_guid(dev_desc, disk_guid);
|
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;
|
ret = -EINVAL;
|
||||||
goto out;
|
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 */
|
} else { /* rename */
|
||||||
if (strlen(name2) > PART_NAME_LEN) {
|
if (strlen(name2) > PART_NAME_LEN) {
|
||||||
printf("Names longer than %d characters are truncated.\n", 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) {
|
} else if (strcmp(argv[1], "read") == 0) {
|
||||||
ret = do_get_gpt_info(blk_dev_desc, (argc == 5) ? argv[4] : NULL);
|
ret = do_get_gpt_info(blk_dev_desc, (argc == 5) ? argv[4] : NULL);
|
||||||
} else if ((strcmp(argv[1], "swap") == 0) ||
|
} 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]);
|
ret = do_rename_gpt_parts(blk_dev_desc, argv[1], argv[4], argv[5]);
|
||||||
} else if ((strcmp(argv[1], "set-bootable") == 0)) {
|
} else if ((strcmp(argv[1], "set-bootable") == 0)) {
|
||||||
ret = gpt_set_bootable(blk_dev_desc, argv[4]);
|
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"
|
" gpt swap <interface> <dev> <name1> <name2>\n"
|
||||||
" - change all partitions named name1 to name2\n"
|
" - change all partitions named name1 to name2\n"
|
||||||
" and vice-versa\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"
|
" gpt rename <interface> <dev> <part> <name>\n"
|
||||||
" - rename the specified partition\n"
|
" - rename the specified partition\n"
|
||||||
" gpt set-bootable <interface> <dev> <list>\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 swap mmc 0 foo bar\n"
|
||||||
" gpt rename mmc 0 3 foo\n"
|
" gpt rename mmc 0 3 foo\n"
|
||||||
" gpt set-bootable mmc 0 boot_a,boot_b\n"
|
" gpt set-bootable mmc 0 boot_a,boot_b\n"
|
||||||
|
" gpt transpose mmc 0 1 2\n"
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,6 +16,7 @@ Synopsis
|
||||||
gpt set-bootable <interface> <dev> <partition list>
|
gpt set-bootable <interface> <dev> <partition list>
|
||||||
gpt setenv <interface> <dev> <partition name>
|
gpt setenv <interface> <dev> <partition name>
|
||||||
gpt swap <interface> <dev> <name1> <name2>
|
gpt swap <interface> <dev> <name1> <name2>
|
||||||
|
gpt transpose <interface> <dev> <part1> <part2>
|
||||||
gpt verify <interface> <dev> [<partition string>]
|
gpt verify <interface> <dev> [<partition string>]
|
||||||
gpt write <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
|
all partitions named 'name2' to be 'name1'. CONFIG_CMD_GPT_RENAME=y is
|
||||||
required.
|
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
|
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::
|
Set the bootable flag for the 'boot' partition and clear it for all others::
|
||||||
|
|
||||||
=> gpt set-bootable mmc 0 boot
|
=> 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
|
||||||
|
|
|
@ -329,3 +329,22 @@ def test_gpt_write(state_disk_image, u_boot_console):
|
||||||
assert '0x00001000 0x00001bff "second"' in output
|
assert '0x00001000 0x00001bff "second"' in output
|
||||||
output = u_boot_console.run_command('gpt guid host 0')
|
output = u_boot_console.run_command('gpt guid host 0')
|
||||||
assert '375a56f7-d6c9-4e81-b5f0-09d41ca89efe' in output
|
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
|
||||||
|
|
Loading…
Add table
Reference in a new issue