mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-17 18:34:42 +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);
|
||||
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
|
||||
|
||||
/**
|
||||
|
@ -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) ||
|
||||
(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)) {
|
||||
ret = gpt_set_bootable(blk_dev_desc, argv[4]);
|
||||
#endif
|
||||
} else {
|
||||
return CMD_RET_USAGE;
|
||||
|
@ -1080,8 +1157,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
|
||||
);
|
||||
|
|
|
@ -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.
|
||||
|
||||
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
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Add table
Reference in a new issue