mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-26 15:28:50 +00:00
cmd: gpt: Add command to set bootable flags
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>
This commit is contained in:
parent
b1433affd9
commit
a1e793add5
3 changed files with 114 additions and 0 deletions
80
cmd/gpt.c
80
cmd/gpt.c
|
@ -970,6 +970,81 @@ static int do_rename_gpt_parts(struct blk_desc *dev_desc, char *subcomm,
|
||||||
free(partitions_list);
|
free(partitions_list);
|
||||||
return ret;
|
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
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1029,6 +1104,8 @@ static int do_gpt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||||
} else if ((strcmp(argv[1], "swap") == 0) ||
|
} else if ((strcmp(argv[1], "swap") == 0) ||
|
||||||
(strcmp(argv[1], "rename") == 0)) {
|
(strcmp(argv[1], "rename") == 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)) {
|
||||||
|
ret = gpt_set_bootable(blk_dev_desc, argv[4]);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
return CMD_RET_USAGE;
|
return CMD_RET_USAGE;
|
||||||
|
@ -1080,8 +1157,11 @@ U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
|
||||||
" and vice-versa\n"
|
" and vice-versa\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"
|
||||||
|
" - make partition names in list bootable\n"
|
||||||
" Example usage:\n"
|
" Example usage:\n"
|
||||||
" 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"
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,6 +13,7 @@ Synopsis
|
||||||
gpt read <interface> <dev> [<varname>]
|
gpt read <interface> <dev> [<varname>]
|
||||||
gpt rename <interface> <dev> <part> <name>
|
gpt rename <interface> <dev> <part> <name>
|
||||||
gpt repair <interface> <dev>
|
gpt repair <interface> <dev>
|
||||||
|
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 verify <interface> <dev> [<partition string>]
|
gpt verify <interface> <dev> [<partition string>]
|
||||||
|
@ -90,6 +91,13 @@ gpt repair
|
||||||
|
|
||||||
Repairs the GPT partition tables if it they become corrupted.
|
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.
|
||||||
|
|
||||||
gpt setenv
|
gpt setenv
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -187,3 +195,7 @@ Get the GUID for a disk::
|
||||||
=> gpt guid mmc gpt_disk_uuid
|
=> gpt guid mmc gpt_disk_uuid
|
||||||
=> echo ${gpt_disk_uuid}
|
=> echo ${gpt_disk_uuid}
|
||||||
bec9fc2a-86c1-483d-8a0e-0109732277d7
|
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
|
||||||
|
|
|
@ -222,6 +222,28 @@ def test_gpt_swap_partitions(state_disk_image, u_boot_console):
|
||||||
assert '0x00000800 0x00000fff "part2"' in output
|
assert '0x00000800 0x00000fff "part2"' in output
|
||||||
assert '0x00001000 0x00001bff "part1"' 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.boardspec('sandbox')
|
||||||
@pytest.mark.buildconfigspec('cmd_gpt')
|
@pytest.mark.buildconfigspec('cmd_gpt')
|
||||||
@pytest.mark.buildconfigspec('cmd_part')
|
@pytest.mark.buildconfigspec('cmd_part')
|
||||||
|
|
Loading…
Add table
Reference in a new issue