mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-19 13:41:31 +00:00
GPT: read partition table from device into a data structure
Make the partition table available for modification by reading it from the user-specified device into a linked list. Provide an accessor function for command-line testing. Signed-off-by: Alison Chaiken <alison@peloton-tech.com> [trini: Make this depend on CMD_GPT_RENAME, as it is the user of this code] Signed-off-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
parent
73d6d18b71
commit
09a49930e4
2 changed files with 132 additions and 0 deletions
125
cmd/gpt.c
125
cmd/gpt.c
|
@ -19,6 +19,9 @@
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <div64.h>
|
#include <div64.h>
|
||||||
#include <memalign.h>
|
#include <memalign.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
|
|
||||||
|
static LIST_HEAD(disk_partitions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* extract_env(): Expand env name from string format '&{env_name}'
|
* extract_env(): Expand env name from string format '&{env_name}'
|
||||||
|
@ -151,6 +154,122 @@ static bool found_key(const char *str, const char *key)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CMD_GPT_RENAME
|
||||||
|
static void del_gpt_info(void)
|
||||||
|
{
|
||||||
|
struct list_head *pos = &disk_partitions;
|
||||||
|
struct disk_part *curr;
|
||||||
|
while (!list_empty(pos)) {
|
||||||
|
curr = list_entry(pos->next, struct disk_part, list);
|
||||||
|
list_del(pos->next);
|
||||||
|
free(curr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct disk_part *allocate_disk_part(disk_partition_t *info, int partnum)
|
||||||
|
{
|
||||||
|
struct disk_part *newpart;
|
||||||
|
newpart = malloc(sizeof(*newpart));
|
||||||
|
if (!newpart)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
memset(newpart, '\0', sizeof(newpart));
|
||||||
|
|
||||||
|
newpart->gpt_part_info.start = info->start;
|
||||||
|
newpart->gpt_part_info.size = info->size;
|
||||||
|
newpart->gpt_part_info.blksz = info->blksz;
|
||||||
|
strncpy((char *)newpart->gpt_part_info.name, (const char *)info->name,
|
||||||
|
PART_NAME_LEN);
|
||||||
|
newpart->gpt_part_info.name[PART_NAME_LEN - 1] = '\0';
|
||||||
|
strncpy((char *)newpart->gpt_part_info.type, (const char *)info->type,
|
||||||
|
PART_TYPE_LEN);
|
||||||
|
newpart->gpt_part_info.type[PART_TYPE_LEN - 1] = '\0';
|
||||||
|
newpart->gpt_part_info.bootable = info->bootable;
|
||||||
|
#ifdef CONFIG_PARTITION_UUIDS
|
||||||
|
strncpy(newpart->gpt_part_info.uuid, (const char *)info->uuid,
|
||||||
|
UUID_STR_LEN);
|
||||||
|
/* UUID_STR_LEN is correct, as uuid[]'s length is UUID_STR_LEN+1 chars */
|
||||||
|
newpart->gpt_part_info.uuid[UUID_STR_LEN] = '\0';
|
||||||
|
#endif
|
||||||
|
newpart->partnum = partnum;
|
||||||
|
|
||||||
|
return newpart;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_gpt_info(void)
|
||||||
|
{
|
||||||
|
struct list_head *pos;
|
||||||
|
struct disk_part *curr;
|
||||||
|
|
||||||
|
list_for_each(pos, &disk_partitions) {
|
||||||
|
curr = list_entry(pos, struct disk_part, list);
|
||||||
|
printf("Partition %d:\n", curr->partnum);
|
||||||
|
printf("1st block %x, size %x\n", (unsigned)curr->gpt_part_info.start,
|
||||||
|
(unsigned)curr->gpt_part_info.size);
|
||||||
|
printf("Block size %lu, name %s\n", curr->gpt_part_info.blksz,
|
||||||
|
curr->gpt_part_info.name);
|
||||||
|
printf("Type %s, bootable %d\n", curr->gpt_part_info.type,
|
||||||
|
curr->gpt_part_info.bootable);
|
||||||
|
#ifdef CONFIG_PARTITION_UUIDS
|
||||||
|
printf("UUID %s\n", curr->gpt_part_info.uuid);
|
||||||
|
#endif
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read partition info into disk_partitions list where
|
||||||
|
* it can be printed or modified
|
||||||
|
*/
|
||||||
|
static int get_gpt_info(struct blk_desc *dev_desc)
|
||||||
|
{
|
||||||
|
/* start partition numbering at 1, as U-Boot does */
|
||||||
|
int valid_parts = 0, p, ret;
|
||||||
|
disk_partition_t info;
|
||||||
|
struct disk_part *new_disk_part;
|
||||||
|
|
||||||
|
if (disk_partitions.next == NULL)
|
||||||
|
INIT_LIST_HEAD(&disk_partitions);
|
||||||
|
|
||||||
|
for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
|
||||||
|
ret = part_get_info(dev_desc, p, &info);
|
||||||
|
if (ret)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Add 1 here because counter is zero-based but p1 is
|
||||||
|
the first partition */
|
||||||
|
new_disk_part = allocate_disk_part(&info, valid_parts+1);
|
||||||
|
if (IS_ERR(new_disk_part))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
list_add_tail(&new_disk_part->list, &disk_partitions);
|
||||||
|
valid_parts++;
|
||||||
|
}
|
||||||
|
if (valid_parts == 0) {
|
||||||
|
printf("** No valid partitions found **\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
return valid_parts;
|
||||||
|
out:
|
||||||
|
if (valid_parts >= 1)
|
||||||
|
del_gpt_info();
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* a wrapper to test get_gpt_info */
|
||||||
|
static int do_get_gpt_info(struct blk_desc *dev_desc)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = get_gpt_info(dev_desc);
|
||||||
|
if (ret > 0) {
|
||||||
|
print_gpt_info();
|
||||||
|
del_gpt_info();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set_gpt_info(): Fill partition information from string
|
* set_gpt_info(): Fill partition information from string
|
||||||
* function allocates memory, remember to free!
|
* function allocates memory, remember to free!
|
||||||
|
@ -455,6 +574,10 @@ static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
printf("Verify GPT: ");
|
printf("Verify GPT: ");
|
||||||
} else if (strcmp(argv[1], "guid") == 0) {
|
} else if (strcmp(argv[1], "guid") == 0) {
|
||||||
ret = do_disk_guid(blk_dev_desc, argv[4]);
|
ret = do_disk_guid(blk_dev_desc, argv[4]);
|
||||||
|
#ifdef CONFIG_CMD_GPT_RENAME
|
||||||
|
} else if (strcmp(argv[1], "read") == 0) {
|
||||||
|
ret = do_get_gpt_info(blk_dev_desc);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
return CMD_RET_USAGE;
|
return CMD_RET_USAGE;
|
||||||
}
|
}
|
||||||
|
@ -477,6 +600,8 @@ U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
|
||||||
" Example usage:\n"
|
" Example usage:\n"
|
||||||
" gpt write mmc 0 $partitions\n"
|
" gpt write mmc 0 $partitions\n"
|
||||||
" gpt verify mmc 0 $partitions\n"
|
" gpt verify mmc 0 $partitions\n"
|
||||||
|
" read <interface> <dev>\n"
|
||||||
|
" - read GPT into a data structure for manipulation\n"
|
||||||
" guid <interface> <dev>\n"
|
" guid <interface> <dev>\n"
|
||||||
" - print disk GUID\n"
|
" - print disk GUID\n"
|
||||||
" guid <interface> <dev> <varname>\n"
|
" guid <interface> <dev> <varname>\n"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <blk.h>
|
#include <blk.h>
|
||||||
#include <ide.h>
|
#include <ide.h>
|
||||||
#include <uuid.h>
|
#include <uuid.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
|
||||||
struct block_drvr {
|
struct block_drvr {
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -69,6 +70,12 @@ typedef struct disk_partition {
|
||||||
#endif
|
#endif
|
||||||
} disk_partition_t;
|
} disk_partition_t;
|
||||||
|
|
||||||
|
struct disk_part {
|
||||||
|
int partnum;
|
||||||
|
disk_partition_t gpt_part_info;
|
||||||
|
struct list_head list;
|
||||||
|
};
|
||||||
|
|
||||||
/* Misc _get_dev functions */
|
/* Misc _get_dev functions */
|
||||||
#ifdef CONFIG_PARTITIONS
|
#ifdef CONFIG_PARTITIONS
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue