
On 8/28/23 23:56, Joshua Watt wrote:
Adds a command that can be used to modify the GPT partition table to indicate which partitions should have the bootable flag set
Signed-off-by: Joshua Watt JPEWhacker@gmail.com
cmd/gpt.c | 80 +++++++++++++++++++++++++++++++++++++++ doc/usage/cmd/gpt.rst | 12 ++++++ test/py/tests/test_gpt.py | 22 +++++++++++ 3 files changed, 114 insertions(+)
diff --git a/cmd/gpt.c b/cmd/gpt.c index c6c8282ac9..45fbe07404 100644 --- a/cmd/gpt.c +++ b/cmd/gpt.c @@ -972,6 +972,81 @@ static int do_rename_gpt_parts(struct blk_desc *dev_desc, char *subcomm, free(partitions_list); return ret; }
+/**
- gpt_set_bootable() - Set bootable flags for partitions
- Sets the bootable flag for any partition names in the comma separated list of
- partition names. Any partitions not in the list have their bootable flag
- cleared
- @desc: block device descriptor
- @name: Comma separated list of partition names
- @Return: '0' on success and -ve error on failure
- */
+static int gpt_set_bootable(struct blk_desc *blk_dev_desc, char *const part_list) +{
- char *name;
- char disk_guid[UUID_STR_LEN + 1];
- struct list_head *pos;
- struct disk_part *curr;
- struct disk_partition *partitions = NULL;
- int part_count = 0;
- int ret = get_disk_guid(blk_dev_desc, disk_guid);
- if (ret < 0)
return ret;
- ret = get_gpt_info(blk_dev_desc);
- if (ret <= 0)
goto out;
- part_count = ret;
- partitions = malloc(sizeof(*partitions) * part_count);
- if (!partitions) {
ret = -ENOMEM;
goto out;
- }
- /* Copy partitions and clear bootable flag */
- part_count = 0;
- list_for_each(pos, &disk_partitions) {
curr = list_entry(pos, struct disk_part, list);
partitions[part_count] = curr->gpt_part_info;
partitions[part_count].bootable &= ~PART_BOOTABLE;
part_count++;
- }
- name = strtok(part_list, ",");
- while (name) {
bool found = false;
for (int i = 0; i < part_count; i++) {
if (strcmp((char *)partitions[i].name, name) == 0) {
partitions[i].bootable |= PART_BOOTABLE;
found = true;
}
}
if (!found) {
printf("Warning: No partition matching '%s' found\n",
name);
}
name = strtok(NULL, ",");
- }
- ret = gpt_restore(blk_dev_desc, disk_guid, partitions, part_count);
+out:
- del_gpt_info();
- if (partitions)
free(partitions);
- return ret;
+} #endif
/** @@ -1031,6 +1106,8 @@ static int do_gpt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } else if ((strcmp(argv[1], "swap") == 0) || (strcmp(argv[1], "rename") == 0)) { ret = do_rename_gpt_parts(blk_dev_desc, argv[1], argv[4], argv[5]);
- } else if ((strcmp(argv[1], "set-bootable") == 0)) {
#endif } else { return CMD_RET_USAGE;ret = gpt_set_bootable(blk_dev_desc, argv[4]);
@@ -1082,8 +1159,11 @@ U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt, " and vice-versa\n" " gpt rename <interface> <dev> <part> <name>\n" " - rename the specified partition\n"
- " gpt set-bootable <interface> <dev> <list>\n"
- " - make partition names in list bootable\n" " Example usage:\n" " gpt swap mmc 0 foo bar\n" " gpt rename mmc 0 3 foo\n"
- " gpt set-bootable mmc 0 boot_a,boot_b\n" #endif );
diff --git a/doc/usage/cmd/gpt.rst b/doc/usage/cmd/gpt.rst index b505b159d0..288dd365c0 100644 --- a/doc/usage/cmd/gpt.rst +++ b/doc/usage/cmd/gpt.rst @@ -13,6 +13,7 @@ Synopsis gpt read <interface> <dev> [<varname>] gpt rename <interface> <dev> <part> <name> gpt repair <interface> <dev>
- gpt set-bootable <interface> <dev> <partition list> gpt setenv <interface> <dev> <partition name> gpt swap <interface> <dev> <name1> <name2> gpt verify <interface> <dev> [<partition string>]
@@ -90,6 +91,13 @@ gpt repair
Repairs the GPT partition tables if it they become corrupted.
+gpt set-bootable +~~~~~~~~~~~~~~~~
+Sets the bootable flag for all partitions in the table. If the partition name +is in 'partition list' (separated by ','), the bootable flag is set, otherwise +it is cleared. CONFIG_CMD_GPT_RENAME=y is required.
Why should this feature be related to CONFIG_CMD_GPT_RENAME?
Why do we need this sub-command? You can use gpt read and gpt write for this rarely needed manipulation.
Best regards
Heinrich
- gpt setenv
@@ -187,3 +195,7 @@ Get the GUID for a disk:: => gpt guid mmc gpt_disk_uuid => echo ${gpt_disk_uuid} bec9fc2a-86c1-483d-8a0e-0109732277d7
+Set the bootable flag for the 'boot' partition and clear it for all others::
- => gpt set-bootable mmc 0 boot
diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index 946858800d..5d23f9b292 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -222,6 +222,28 @@ def test_gpt_swap_partitions(state_disk_image, u_boot_console): assert '0x00000800 0x00000fff "part2"' in output assert '0x00001000 0x00001bff "part1"' 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_set_bootable(state_disk_image, u_boot_console):
- """Test the gpt set-bootable command."""
- u_boot_console.run_command('host bind 0 ' + state_disk_image.path)
- parts = ('part2', 'part1')
- for bootable in parts:
output = u_boot_console.run_command(f'gpt set-bootable host 0 {bootable}')
assert 'success!' in output
for p in parts:
output = u_boot_console.run_command(f'gpt setenv host 0 {p}')
assert 'success!' in output
output = u_boot_console.run_command('echo ${gpt_partition_bootable}')
if p == bootable:
assert output.rstrip() == '1'
else:
assert output.rstrip() == '0'
- @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_gpt') @pytest.mark.buildconfigspec('cmd_part')